当前位置: 首页 > article >正文

鱼书--学习2

6. 与学习相关的技巧

6.1 参数的更新

(1) SGD的缺点:SGD低效的根本原因是,梯度的方向并没有指向最小值的方向

基于SGD的最优化的更新路径:呈“之”字形朝最小值(0, 0)移动,效率低

(2)Momentum
在这里插入图片描述

αv在物体不受任何力时,该项承担使物体逐渐减速的任务(α设定为0.9之类的值),对应物理上的地面摩擦或空气阻力。W表示要更新的权重参数, L关于W的偏导表示损失函数关于W的梯度,η表示学习率。
基于Momentum的最优化的更新路径
基于Momentum的最优化的更新路径

(3) AdaGrad
AdaGrad会为参数的每个元素适当地调整学习率,与此同时进行学习
在这里插入图片描述
变量h保存了以前的所有梯度值的平方和,可以按参数的元素进行学习率衰减,使变动大的参数的学习率逐渐减小。
在这里插入图片描述
基于AdaGrad的最优化的更新路径
(4)Adam
Adam,直观地讲,就是融合了Momentum和AdaGrad的方法。通过组合前面两个方法的优点,有望
实现参数空间的高效搜索。
在这里插入图片描述
基于Adam的最优化的更新路径

6.2 权重的初始值

设定了合适的权重初始值,则各层的激活值分布会有适当的广度,从而可以顺利地进行学习。

(1)梯度衰减
定义:梯度消失(Vanishing Gradient)指在深层神经网络反向传播过程中,梯度值随层数增加‌指数级衰减‌,导致浅层网络参数更新缓慢甚至停滞。

数学本质‌:反向传播中梯度通过链式法则连乘,若每层梯度绝对值小于1,累积后趋近于零‌

典型现象‌:靠近输入层的参数几乎不更新,深层网络退化为浅层网络,难以学习有效特征‌

解决方法之一:权重初始化方法
Xavier初始化‌:根据输入/输出维度调整初始权重范围,避免梯度衰减或爆炸‌(处理sigmoid等激活函数)
He初始化‌:针对ReLU激活函数优化,提高初始化权重的适应性‌(处理ReLU等激活函数)

(2) 隐藏层的激活值分布

import numpy as np
import matplotlib.pyplot as plt

def sigmoid(x):
    return  1 / (1 + np.exp(-x))

# 用于生成满足标准正态分布(均值为0,标准差为1)的随机数或随机数组
x = np.random.randn(1000,100)  # size : 1000*100
node_num = 100 # 隐藏层神经元个数
hidden_layer_size = 5 # 隐藏层层数
activations = {} # 保存每层输出的结果

for i in range(hidden_layer_size):
    if i != 0:
        x = activations[i-1]

    # 标准差为1的高斯分布
    w = np.random.randn(node_num,node_num)*1
    # w = np.random.randn(node_num,node_num)* 0.01  标准差则为0.01
    z = np.dot(x,w)
    a = sigmoid(z)
    activations[i] = a

# i 表示索引, a表示对应的值(数组)
for i,a in activations.items():
    # 用于在一个图形窗口中创建多个子图
    # 参数:行数,列数,当前子图的索引(第几个子图)
    plt.subplot(1,len(activations),i+1)
    plt.title(str(i+1)+"-layer")
    # 用于绘制直方图
    # 传入一维数组x,若为多为需扁平化; bins是柱状的个数,range表示x轴的范围
    plt.hist(a.flatten(),30,range=(0,1))
plt.show()

使用标准差为1的高斯分布作为权重初始值时的各层激活值的分布
在这里插入图片描述


使用标准差为0.01的高斯分布作为权重初始值时的各层激活值的分布
在这里插入图片描述
在这里插入图片描述


如果前一层的节点数为n,则初始值使用标准差为 1 n \frac{1}{\sqrt{n}} n 1的分布
在这里插入图片描述
在这里插入图片描述
使用Xavier初始值作为权重初始值时的各层激活值的分布
在这里插入图片描述


(3)ReLU的初始权重值
Xavier初始值是以激活函数是线性函数为前提而推导出来的。因为sigmoid函数和tanh函数左右对称,且中央附近可以视作线性函数,所以适合使用Xavier初始值。但当激活函数使用ReLU时,一般推荐使用ReLU专用的初始值,也就是Kaiming He等人推荐的初始值,也称为“He初始值”。当前一层的节点数为n时,He初始值使用标准差为 2 n \sqrt{\frac{2}{n}} n2 的高斯分布。

(4) 基于MNIST数据集的权重初始值的比较
在这里插入图片描述

6.3 Batch Normalization

Batch Norm的思路是调整各层的激活值分布使其拥有适当的广度。

(1) Batch Normalization 的算法

优点:

  • 可以使学习快速进行(可以增大学习率)。
  • 不那么依赖初始值(对于初始值不用那么神经质)。
  • 抑制过拟合(降低Dropout等的必要性)。

具体做法:进行使数据分布的均值为0、方差为1的正规化。
在这里插入图片描述
**将mini-batch的输入数据{x1, x2, … , xm}变换为均值为0、方差为1的数据在这里插入图片描述

然后,Batch Norm层会对正规化后的数据进行缩放和平移的变换
在这里插入图片描述
一开始γ = 1,β = 0,然后再通过学习调整到合适的值。

计算图:
在这里插入图片描述
(2) Batch Normalization的评估
在这里插入图片描述

6.4 正则化

(1)过拟合
定义:只能拟合训练数据,但不能很好地拟合不包含在训练数据中的其他数据的状态。

原因: 1.模型拥有大量参数、表现力强。 2.训练数据少。

(2) 权值衰减
权值衰减是一直以来经常被使用的一种抑制过拟合的方法。该方法通过在学习的过程中对大的权重进行惩罚,来抑制过拟合。

(3)Dropout
Dropout是一种在学习的过程中随机删除神经元的方法。训练时,随机选出隐藏层的神经元,然后将其删除。被删除的神经元不再进行信号的传递

6.5 超参数的验证

超参数是指,比如各层的神经元数量、batch大小、参数更新时的学习率或权值衰减等

(1)验证数据
为什么不能用测试数据评估超参数的性能呢?
这是因为如果使用测试数据调整超参数,超参数的值会对测试数据发生过拟合。换句话说,用测试数据确认超参数的值的“好坏”,就会导致超参数的值被调整为只拟合测试数据。这样的话,可能就会得到不能拟合其他数据、泛化能力低的模型。因此,调整超参数时,必须使用超参数专用的确认数据。用于调整超参数的数据,一般称为验证数据

(2)超参数的最优化
步骤0:设定超参数的范围。

步骤1:从设定的超参数范围中随机采样。

步骤2:使用步骤1中采样到的超参数的值进行学习,通过验证数据评估识别精度(但是要将epoch设置得很小)。

步骤3:重复步骤1和步骤2(100次等),根据它们的识别精度的结果,缩小超参
数的范围。

(3)超参数最优化实现

6.6 小结

• 参 数 的 更 新 方 法,除 了 SGD 之 外,还 有 Momentum、AdaGrad、Adam等方法。
• 权重初始值的赋值方法对进行正确的学习非常重要。
• 作为权重初始值,Xavier初始值、He初始值等比较有效。
• 通过使用Batch Normalization,可以加速学习,并且对初始值变得
健壮。
• 抑制过拟合的正则化技术有权值衰减、Dropout等。
• 逐渐缩小“好值”存在的范围是搜索超参数的一个有效方法。

7.卷积神经网络

7.1 整体结构

之前介绍的神经网络中,相邻层的所有神经元之间都有连接,这称为全连接(fully-connected)。另外,我们用Affine层实现了全连接层。如果使用这个Affine层,一个5层的全连接的神经网络就可以通过图所示的网络结构来实现。(Affine层,即仿射变换,通过矩阵乘法和偏置加法实现线性变换,公式为 y = xw+b)
在这里插入图片描述


基于CNN的网络的例子:
在这里插入图片描述

7.2 卷积层

(1) 全连接层存在的问题
全连接层存在什么问题呢?那就是数据的形状被“忽视”了。比如,输入数据是图像时,图像通常是高、长、通道方向上的3维形状。但是,向全连接层输入时,需要将3维数据拉平为1维数据。图像是3维形状,这个形状中应该含有重要的空间信息。

卷积层可以保持形状不变。当输入数据是图像时,卷积层会以3维数据的形式接收输入数据,并同样以3维数据的形式输出至下一层。因此,在CNN中,可以(有可能)正确理解图像等具有形状的数据。

CNN 中,有时将卷积层的输入输出数据称为特征图其中,卷积层的输入数据称为输入特征图(input feature map),输出数据称为输出特征图(output feature map)

(2) 卷积运算
卷积运算的例子:用符号表示卷积运算
在这里插入图片描述
对于输入数据,卷积运算以一定间隔滑动滤波器的窗口并应用。这里所说的窗口是灰色的3 × 3的部分。将各个位置上滤波器的元素和输入的对应元素相乘,然后再求和(有时将这个计算称为乘积
累加运算)。然后,将这个结果保存到输出的对应位置。将这个过程在所有位置都进行一遍,就可以得到卷积运算的输出。
在这里插入图片描述


加上偏置的完整算法:
在这里插入图片描述
(3)填充
在进行卷积层的处理之前,有时要向输入数据的周围填入固定的数据(比如0等),这称为填充(padding),是卷积运算中经常会用到的处理。 使用填充主要是为了调整输出的大小。因此,卷积运算就可以在保持空间大小不变的情况下将数据传给下一层。

幅度为1的填充:用幅度为1像素的0填充周围
在这里插入图片描述

(4) 步幅
应用滤波器的位置间隔称为步幅(stride)。
在这里插入图片描述


对于填充和步幅,如何计算输出大小
在这里插入图片描述

(5)3维数据的卷积运算
通道方向上有多个特征图时,会按通道进行输入数据和滤波器的卷积运算,并将结果相加,从而得到输出。
在这里插入图片描述


具体计算顺序:
在这里插入图片描述
需要注意的是,在3维数据的卷积运算中,输入数据和滤波器的通道数要设为相同的值。

(6)结合方块思考
把3维数据表示为多维数组时,书写顺序为(channel, height, width)。比如,通道数为C、高度为H、
长度为W的数据的形状可以写成(C, H, W)。滤波器也一样,要按(channel, height, width)的顺序书写。比如,通道数为C、滤波器高度为FH(Filter Height)、长度为FW(Filter Width)时,可以写成(C, FH, FW)。
在这里插入图片描述


通过应用FN个滤波器,输出特征图也生成了FN个。如果将这FN个特征图汇集在一起,就得到了形状为(FN, OH, OW)的方块。将这个方块传给下一层,就是CNN的处理流。

在这里插入图片描述
作为4维数据,滤波器的权重数据要按(output_channel, input_channel, height, width)的顺序书写。比如,通道数为3、大小为5 × 5的滤波器有20个时,可以写成(20, 3, 5, 5)。


卷积运算的处理流(追加了偏置项)
在这里插入图片描述
(7)批处理
在各个数据的开头添加了批用的维度。像这样,数据作为4维的形状在各层间传递。这里需要注意的是,网络间传递的是4维数据,对这N个数据进行了卷积运算。也就是说,批处理将N次的处理汇总成了1次进行。
在这里插入图片描述

7.3 池化层

池化是缩小高、长方向上的空间的运算。

例:Max池化的处理顺序
在这里插入图片描述
一般来说,池化的窗口大小会和步幅设定成相同的值。

除了Max池化之外,还有Average池化等。相对于Max池化是从目标区域中取出最大值,Average池化则是计算目标区域的平均值。在图像识别领域,主要使用Max池化。因此,本书中说到“池化层”时,指的是Max池化。

池化层的特征

  1. 没有要学习的参数
    池化层和卷积层不同,没有要学习的参数。池化只是从目标区域中取最
    大值(或者平均值),所以不存在要学习的参数。

  2. 通道数不发生变化
    经过池化运算,输入数据和输出数据的通道数不会发生变化。如图7-15
    所示,计算是按通道独立进行的。

  3. 对微小的位置变化具有鲁棒性(健壮)
    输入数据发生微小偏差时,池化仍会返回相同的结果。因此,池化对输入数据的微小偏差具有鲁棒性。

在这里插入图片描述


7.4 卷积层和池化层的实现

(1)四维数组

(2)基于 im2col的展开
im2col是一个函数,将输入数据展开以适合滤波器(权重)。对于输入数据,将应用滤波器的区域(3维方块)横向展开为1列。im2col会在所有应用滤波器的地方进行这个展开处理。(返回值是一个二维数组,第一维是输入数据展开后的一维数组,第二维是滤波器的行数
在这里插入图片描述


使用im2col展开输入数据后,之后就只需将卷积层的滤波器(权重)纵向展开为1列,并计算2个矩阵的乘积即可。这和全连接层的Affine层进行的处理基本相同。
在这里插入图片描述
(3)卷积层的实现

class Convolution:
	def __init__(self, W, b, stride=1, pad=0):
		self.W = W
		self.b = b
		self.stride = stride
		self.pad = pad
	def forward(self, x):
		FN, C, FH, FW = self.W.shape
		N, C, H, W = x.shape
		out_h = int(1 + (H + 2*self.pad - FH) / self.stride)
		out_w = int(1 + (W + 2*self.pad - FW) / self.stride)
		col = im2col(x, FH, FW, self.stride, self.pad)  # 形状为 (out_h*out_w , sum)
		# -1 表示总元素 除以已分配的维度的结果  例:总元素为750,FN = 10,因此 -1 会变为75
		col_W = self.W.reshape(FN, -1).T # 滤波器的展开,并转置,形状为  (sum,FN)
		out = np.dot(col, col_W) + self.b  # out的形状为  out_h*out_w , FN
		out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)# 将(N,H,W,C)=> (N,C,H,W)
		return out

(4) 池化层的实现
池化的情况下,在通道方向上是独立的,这一点和卷积层不同。具体地讲,池化的应用区域按通道单独展开。 以三维数据举例,卷积层以一个立方体为一体化为一维数组再进行卷积,而池化层以一个池化窗口大小为一体化为一维数组,再在每个一维数组中取池化目标。
在这里插入图片描述


像这样展开之后,只需对展开的矩阵求各行的最大值,并转换为合适的形状即可
在这里插入图片描述


代码示例:

class Pooling:
    def __init__(self, pool_h, pool_w, stride=1, pad=0):
        self.pool_h = pool_h
        self.pool_w = pool_w
        self.stride = stride
        self.pad = pad
    def forward(self, x):
        N, C, H, W = x.shape
        out_h = int(1 + (H - self.pool_h) / self.stride)
        out_w = int(1 + (W - self.pool_w) / self.stride)
        # 展开(1)
        col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)
        col = col.reshape(-1, self.pool_h*self.pool_w)
        # 最大值(2)
        out = np.max(col, axis=1)
        # 转换(3)
        out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)
        return out

7.5 CNN的实现

简单CNN的网络构成
在这里插入图片描述

7.6 CNN的可视化

卷积层的滤波器会提取边缘或斑块等原始信息。而刚才实现的CNN会将这些原始信息传递给后面的层。最开始的层对简单的边缘有响应,接下来的层对纹理有响应,再后面的层对更加复杂的物体
部件有响应。也就是说,随着层次加深,神经元从简单的形状向“高级”信息变化。换句话说,就像我们理解东西的“含义”一样,响应的对象在逐渐变化。

7.7 具有代表性的CNN

(1) LeNet
在这里插入图片描述
LeNet中使用sigmoid函数,而现在的CNN中主要使用ReLU函数。此外,原始的LeNet中使用子采样(subsampling)缩小中间数据的大小,而现在的CNN中Max池化是主流。

(2) AlexNet
在这里插入图片描述
AlexNet和LeNet的差异:

  • 激活函数使用ReLU
  • 使用进行局部正规化的LRN(Local Response Normalization)层
  • 使用Dropout

7.8 小结

8. 深度学习


http://www.kler.cn/a/597603.html

相关文章:

  • MySQL 中,分库分表机制和分表分库策略
  • Ubuntu搭建Battery Historian环境
  • (八)Reactor响应式框架之核心特性
  • 5、MySQL为什么使用 B+树 来作索引【高频】
  • 矩阵可相似对角化
  • G-Star 校园开发者计划·黑科大|开源第一课之 Git 入门
  • 强化学习中循环神经网络在序列决策中的应用研究
  • 2025新版懒人精灵零基础安装调试+lua基础+UI设计交互+常用方法封装+项目实战+项目打包安装板块-视频教程(初学者必修课)
  • 基于javaweb的SpringBoot医院管理系统设计与实现(源码+文档+部署讲解)
  • maven在windows系统上的详细安装和配置
  • 无阻塞UI:通过Web Worker提升用户体验的新途径
  • 基于LabVIEW的Windows平台高速闭环控制
  • windows+ragflow+deepseek实战之一excel表查询
  • 第19章:StatefulSet:有状态应用部署最佳实践
  • dify案例分享-儿童故事绘本语音播报视频工作流
  • Lustre 语言的 Rust 生成相关的工作
  • 高考志愿填报管理系统基于Spring Boot SSM
  • 流程图软件推荐,好用的流程图工具分享
  • 西门子200smart之modbus_TCP(做主站与第三方设备)通讯
  • 常考计算机操作系统面试习题(四)