NNDL 作业11:优化算法比较

news2024/12/22 9:42:05

 

目录

1. 编程实现图6-1,并观察特征

2. 观察梯度方向

3. 编写代码实现算法,并可视化轨迹

4. 分析上图,说明原理(选做)

5. 总结SGD、Momentum、AdaGrad、Adam的优缺点(选做)

6. Adam这么好,SGD是不是就用不到了?(选做)

7. 增加RMSprop、Nesterov算法。(选做)

8. 基于MNIST数据集的更新方法的比较(选做)


参考:深度学习入门:基于Python的理论与实现 (ituring.com.cn)

1. 编程实现图6-1,并观察特征

 

 

 参考代码:

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


# https://blog.csdn.net/weixin_39228381/article/details/108511882

def func(x, y):
    return x * x / 20 + y * y


def paint_loss_func():
    x = np.linspace(-50, 50, 100)  # x的绘制范围是-50到50,从改区间均匀取100个数
    y = np.linspace(-50, 50, 100)  # y的绘制范围是-50到50,从改区间均匀取100个数

    X, Y = np.meshgrid(x, y)
    Z = func(X, Y)

    fig = plt.figure()  # figsize=(10, 10))
    ax = Axes3D(fig)
    plt.xlabel('x')
    plt.ylabel('y')

    ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='rainbow')
    plt.show()


paint_loss_func()

 2. 观察梯度方向

3. 编写代码实现算法,并可视化轨迹

SGD、Momentum、Adagrad、Adam

参考代码:

# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
from collections import OrderedDict


class SGD:
    """随机梯度下降法(Stochastic Gradient Descent)"""

    def __init__(self, lr=0.01):
        self.lr = lr

    def update(self, params, grads):
        for key in params.keys():
            params[key] -= self.lr * grads[key]


class Momentum:
    """Momentum SGD"""

    def __init__(self, lr=0.01, momentum=0.9):
        self.lr = lr
        self.momentum = momentum
        self.v = None

    def update(self, params, grads):
        if self.v is None:
            self.v = {}
            for key, val in params.items():
                self.v[key] = np.zeros_like(val)

        for key in params.keys():
            self.v[key] = self.momentum * self.v[key] - self.lr * grads[key]
            params[key] += self.v[key]


class Nesterov:
    """Nesterov's Accelerated Gradient (http://arxiv.org/abs/1212.0901)"""

    def __init__(self, lr=0.01, momentum=0.9):
        self.lr = lr
        self.momentum = momentum
        self.v = None

    def update(self, params, grads):
        if self.v is None:
            self.v = {}
            for key, val in params.items():
                self.v[key] = np.zeros_like(val)

        for key in params.keys():
            self.v[key] *= self.momentum
            self.v[key] -= self.lr * grads[key]
            params[key] += self.momentum * self.momentum * self.v[key]
            params[key] -= (1 + self.momentum) * self.lr * grads[key]


class AdaGrad:
    """AdaGrad"""

    def __init__(self, lr=0.01):
        self.lr = lr
        self.h = None

    def update(self, params, grads):
        if self.h is None:
            self.h = {}
            for key, val in params.items():
                self.h[key] = np.zeros_like(val)

        for key in params.keys():
            self.h[key] += grads[key] * grads[key]
            params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)


class RMSprop:
    """RMSprop"""

    def __init__(self, lr=0.01, decay_rate=0.99):
        self.lr = lr
        self.decay_rate = decay_rate
        self.h = None

    def update(self, params, grads):
        if self.h is None:
            self.h = {}
            for key, val in params.items():
                self.h[key] = np.zeros_like(val)

        for key in params.keys():
            self.h[key] *= self.decay_rate
            self.h[key] += (1 - self.decay_rate) * grads[key] * grads[key]
            params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)


class Adam:
    """Adam (http://arxiv.org/abs/1412.6980v8)"""

    def __init__(self, lr=0.001, beta1=0.9, beta2=0.999):
        self.lr = lr
        self.beta1 = beta1
        self.beta2 = beta2
        self.iter = 0
        self.m = None
        self.v = None

    def update(self, params, grads):
        if self.m is None:
            self.m, self.v = {}, {}
            for key, val in params.items():
                self.m[key] = np.zeros_like(val)
                self.v[key] = np.zeros_like(val)

        self.iter += 1
        lr_t = self.lr * np.sqrt(1.0 - self.beta2 ** self.iter) / (1.0 - self.beta1 ** self.iter)

        for key in params.keys():
            self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key])
            self.v[key] += (1 - self.beta2) * (grads[key] ** 2 - self.v[key])

            params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key]) + 1e-7)


def f(x, y):
    return x ** 2 / 20.0 + y ** 2


def df(x, y):
    return x / 10.0, 2.0 * y


init_pos = (-7.0, 2.0)
params = {}
params['x'], params['y'] = init_pos[0], init_pos[1]
grads = {}
grads['x'], grads['y'] = 0, 0

optimizers = OrderedDict()
optimizers["SGD"] = SGD(lr=0.95)
optimizers["Momentum"] = Momentum(lr=0.1)
optimizers["AdaGrad"] = AdaGrad(lr=1.5)
optimizers["Adam"] = Adam(lr=0.3)

idx = 1

for key in optimizers:
    optimizer = optimizers[key]
    x_history = []
    y_history = []
    params['x'], params['y'] = init_pos[0], init_pos[1]

    for i in range(30):
        x_history.append(params['x'])
        y_history.append(params['y'])

        grads['x'], grads['y'] = df(params['x'], params['y'])
        optimizer.update(params, grads)

    x = np.arange(-10, 10, 0.01)
    y = np.arange(-5, 5, 0.01)

    X, Y = np.meshgrid(x, y)
    Z = f(X, Y)
    # for simple contour line
    mask = Z > 7
    Z[mask] = 0

    # plot
    plt.subplot(2, 2, idx)
    idx += 1
    plt.plot(x_history, y_history, 'o-', color="red")
    plt.contour(X, Y, Z)  # 绘制等高线
    plt.ylim(-10, 10)
    plt.xlim(-10, 10)
    plt.plot(0, 0, '+')
    plt.title(key)
    plt.xlabel("x")
    plt.ylabel("y")

plt.subplots_adjust(wspace=0, hspace=0)  # 调整子图间距
plt.show()

4. 分析上图,说明原理(选做)

  1. 为什么SGD会走“之字形”?其它算法为什么会比较平滑?
  2. MomentumAdaGrad对SGD的改进体现在哪里?速度?方向?在图上有哪些体现?
  3. 仅从轨迹来看,Adam似乎不如AdaGrad效果好,是这样么?
  4. 四种方法分别用了多长时间?是否符合预期?
  5. 调整学习率、动量等超参数,轨迹有哪些变化?

5. 总结SGD、MomentumAdaGrad、Adam的优缺点(选做)

6. Adam这么好,SGD是不是就用不到了?(选做)

7. 增加RMSprop、Nesterov算法。(选做)

对比Momentum与Nesterov、AdaGrad与RMSprop。

8. 基于MNIST数据集的更新方法的比较(选做)

在原图基础上,增加RMSprop、Nesterov算法。

编程实现,并谈谈自己的看法。

 优化算法代码可参考前面的内容。

 MNIST数据集的更新方法的比较

# coding: utf-8
import os
import sys
sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from common.util import smooth_curve
from common.multi_layer_net import MultiLayerNet
from common.optimizer import *


# 0:读入MNIST数据==========
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True)

train_size = x_train.shape[0]
batch_size = 128
max_iterations = 2000


# 1:进行实验的设置==========
optimizers = {}
optimizers['SGD'] = SGD()
optimizers['Momentum'] = Momentum()
optimizers['AdaGrad'] = AdaGrad()
optimizers['Adam'] = Adam()
#optimizers['RMSprop'] = RMSprop()

networks = {}
train_loss = {}
for key in optimizers.keys():
    networks[key] = MultiLayerNet(
        input_size=784, hidden_size_list=[100, 100, 100, 100],
        output_size=10)
    train_loss[key] = []    


# 2:开始训练==========
for i in range(max_iterations):
    batch_mask = np.random.choice(train_size, batch_size)
    x_batch = x_train[batch_mask]
    t_batch = t_train[batch_mask]
    
    for key in optimizers.keys():
        grads = networks[key].gradient(x_batch, t_batch)
        optimizers[key].update(networks[key].params, grads)
    
        loss = networks[key].loss(x_batch, t_batch)
        train_loss[key].append(loss)
    
    if i % 100 == 0:
        print( "===========" + "iteration:" + str(i) + "===========")
        for key in optimizers.keys():
            loss = networks[key].loss(x_batch, t_batch)
            print(key + ":" + str(loss))


# 3.绘制图形==========
markers = {"SGD": "o", "Momentum": "x", "AdaGrad": "s", "Adam": "D"}
x = np.arange(max_iterations)
for key in optimizers.keys():
    plt.plot(x, smooth_curve(train_loss[key]), marker=markers[key], markevery=100, label=key)
plt.xlabel("iterations")
plt.ylabel("loss")
plt.ylim(0, 1)
plt.legend()
plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/32524.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python威布尔分布

文章目录威布尔分布及其性质在Python中生成威布尔分布的随机数指数分布和拉普拉斯分布的对比威布尔分布及其性质 威布尔分布,即Weibull distribution,又被译为韦伯分布、韦布尔分布等,是仅分布在正半轴的连续分布。 在numpy.random中&#…

python中urllib库的使用

1. 获取目标页面的源码 以获取百度页面源码为例 #使用urllib获取百度首页的源码 import urllib.request#1 定义一个url 作为需要访问的网址 url http://www.baidu.com#2 模拟浏览器向服务器发送请求 response响应 response urllib.request.urlopen(url)#3 获取响应中的页面…

Monkey测试

一、什么是 Monkey 测试 Monkey 测试是通过向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对应用程序客户端的稳定性测试;通俗来说,Monkey 测试即“猴子测试”,是指像猴子一样&a…

JVM垃圾回收算法整理

JVM垃圾回收算法整理前言关键概念了解标记–清除算法复制算法标记–整理算法分代收集算法仰天大笑出门去,我辈岂是蓬蒿人前言 大概内容: jvm垃圾回收算法: 1、“标记–清除”算法;首先标记出所有需要被回收的对象,然…

搭建自己的SSR

Vue SSR介绍 是什么 官方文档:https://ssr.vuejs.org/Vue SSR(Vue.js Server-Side Rendering) 是 Vue.js 官方提供的一个服务端渲染(同构应用)解 决方案使用它可以构建同构应用还是基于原有的 Vue.js 技术栈 官方文档…

XXL-JOB逻辑自测及执行参数配置踩坑

概述 关于XXL-JOB的使用遇到的问题记录。对XXL-JOB不熟的,可以先参考分布式任务调度平台XXL-JOB深度实战 实战 业务DTO定义如下: Data public class AdAccountDTO {private String accountId;/*** yyyy-MM-dd HH:mm:ss*/private String startCreateT…

ThingBoard源码解析-缓存

配置 TB支持两种缓存:Caffeine和Redis,通过配置cache.type来指定使用哪种缓存。 位于 org.thingsboard.server.cache Caffeine 配置类:CaffeineCacheConfiguration Configuration ConditionalOnProperty(prefix "cache", value "t…

HTML CSS 个人网页设计 WEB前端大作业代码

🎉精彩专栏推荐👇🏻👇🏻👇🏻 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业…

【计算机毕业设计】7.线上花店系统maven源码

一、系统截图(需要演示视频可以私聊) 摘 要 随着互联网突飞猛进的发展及其对人们的生活产生至关重要的影响,线上购花,送货到家的购物方式受到了越来越多顾客的接受与喜爱。线上花卉小铺的设计与实现不仅可以带来更广泛的选择与实…

餐饮业如何现业绩突破性增长?

疫情反复无常,餐饮人每天都面临着极大的挑战:无法预测的关店通知、突如其来的禁止堂食命令......餐饮店客流减少,业绩下滑成为不可避免的趋势。 在这种情形下,不少餐饮老板拒绝“躺平”,上演“花式自救”:…

cpu设计和实现(数据预取)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面说过了一条指令经过cpu处理的时候需要经历几个阶段。通过实验,我们发现,哪怕是再简单的ori指令也要经历取指、译码、执…

MyBatis是什么?使用方式?

目录 前言: 一、概念讲述 1.什么是MyBatis? 2.官网网址 二、使用方式 1.pom.xml里面添加依赖包 2.新建统一配置文件(俗称数据库连接文件) 3.新建立映射文件 (俗称数据库表对应xml) 4.建立数据库表…

ArcMap中之提取影像数据边界

1、前言 手里有一些经过裁剪的不规则多边形影像数据(如图例所示),希望能批量获取该类影像的边界信息,即影像对应的面信息,边界线信息。这里我们提供一种利用镶嵌数据集Footprint图层的方法来获取,面&#…

基于Python机器学习及深度学习在空间模拟与时间预测应用

了解机器学习的发展历史、计算原理、基本定义,熟悉机器学习方法的分类,常用机器学习方法,以及模型的评估与选择;熟悉数据预处理的流程,掌握python程序包的使用;理解机器学习在生态水文中的应用,…

超实用的图片处理技巧,一分钟轻松完成图片编辑

图片想必大家都很熟悉,无论是我们平时在聊天的时候使用的表情包或者是在工作中插入的插图都属于图片,在使用图片的时候大家会遇到各种各样的问题,比如上传的图片格式不对、使用的图片尺寸太大等等,都会导致图片无法正常使用&#…

[附源码]java毕业设计医院就诊流程管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

c++旅行商问题 (暴力解)

目录一、旅行商问题简介旅行商问题问题概述问题由来二、枚举所有方案1、思路2、代码3、复杂度分析三、深度优先搜索1、思路2、代码3、复杂度分析一、旅行商问题简介 旅行商问题 TSP,即旅行商问题,又称TSP问题(Traveling Salesman Problem&am…

白盒测试与黑盒测试

白盒测试技术 白盒测试技术也称结构性测试,是一种设计测试用例的方法,一般用于分析程序的内部结构,使用该方法测试程序时测试者可以看到被测试程序,并分析其内部结构。 按照被测试测试时是否需要执行测试程序可以分为静态和动态…

RK3399平台开发系列讲解(中断篇)中断控制器驱动初始化

🚀返回专栏总目录 文章目录 一、设备树源文件1.1、gic控制器节点1.2、timer节点二、中断控制器匹配表三、中断控制器初始化3.1、函数of_irq_init3.2、函数gicv3_of_init3.3、函数gic_init_bases沉淀、分享、成长,让自己和他人都能有所收获!😄 一、设备树源文件 ARM64架构…

web前端网页制作课作业:甜甜圈蛋糕店(HTML+CSS+JavaScript)

🎀 精彩专栏推荐👇🏻👇🏻👇🏻 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业…