神经网络—学习笔记

卷积网络结构

在这里插入图片描述

AlexNet

输入

AlexNet是2012年ImageNet项目的大规模视觉识别挑战(ILSVRC)中的胜出这。AlexNet解决了图像分类的问题,输入是1000个不同类型图像(如猫、狗等)中的一个图像,输出是1000个数字的矢量。输出向量的第i个元素即为输入图像属于第i类图像的概率。因此,输出向量的所有元素之和为1。
AlexNet的输入是一个大小为256x256的RGB图像。因此所有的训练集图像和测试图像的大小都要是256x256.
如果输入图像的大小不是256x256,那么用它来训练神经网络之前需要将其转换成256x256的大小。
如果输入图像为灰度图像,可以通过复制单个通道将其转换成一个3通道的RGB图像。由256x256的图像可以产生随机大小的图像,其中大小为227x227的图像来填充AlexNet的第一层。

AlexNet网络结构

在这里插入图片描述

AlexNet由5个卷积层和3个全连接层组成,多个卷积内核可以提取图像中有趣的特征。通常,同一卷积层中内核的大小是相同的。例如AlexNet的第一个Conv层包含96个大小为11x11x3的内核。值得注意的是内核的宽度和高度通常是相同的,深度与通道的数量是相同的。
前两个卷积层后面是重叠的最大池化层,第三个、第四个和第五个卷积层都是直接相连的。第5个卷积层后面是一个重叠的最大池化层,它的输出会进入两个全连接层。第二个全连接层可以给softmax分类器提供1000类标签。
在所有的卷积层和全连接层之后,都应用了ReLUctant非线性函数。首先,第一和第二个卷积层都应用ReLU非线性函数,然后进行局部标准化,最后执行pooling操作方法。但后来研究人员发现标准化并不是很有用。

重叠最大池化

通常使用最大池化层来对张量的宽度和高度进行采样,且保持深度不变。重叠的最大池层与最大池层类似,除了重叠最大池层的相邻窗口是相互重叠的。作者使用的池化窗口是大小为3x3,相邻窗口步幅为2的窗口。在输出尺寸相同的情况下,与使用大小为2x2,相邻窗口为2的非重叠池化窗口相比,重叠池化窗口能够分别将第一名的错误率降低0.4%,第5名的错误率减低0.3%。

ReLU非线性

AlexNet的另一个重要特性就是使用了ReLU(整流线性单元)的非线性。Tanh或sigmoid激活函数曾是训练神经网络模型的常用方法。与使用像tanh或sigmoid这样的饱和激活函数相比,使用ReLU非线性可以使深度CNNs训练更快。本文的下图显示,与使用tanh(点线)的等效网络相比,使用ReLUs(solid曲线)的AlexNet能以6倍快的速度到达25%的训练错误率。这是在CIFAR-10数据集中完成的测试。
为什么用ReLUs训练的更快?ReLU函数为f(x)=max(0,x)。
在这里插入图片描述
上面是tanh和ReLU两个函数的图。Tanh函数在z值很高或很低时饱和,且函数的斜率接近于0,有助于减缓梯度下降。另一方面,当z为较大的正直时ReLU函数的斜率不接近于零,有助于最优化收敛的更快。Z为负值时斜率为零,但是神经网络中的大多数神经元最终都具有正值。Sigmoid函数也因为同样的原因,稍逊于ReLU。

减少过度拟合

神经网络的大小就是它的学习能力。一不小心,它也会在不理解概念的情况下记住训练数据中的例子。虽然神经网络在训练数据上表现的格外好,但是他们没有学习到真正的概念。在面对新的、未见过的测试数据时,它的表现就没有那么好了。这就是所谓的过度拟合。
AlexNet使用了几种不同的方法来减少过拟合。

  • 数据增强
    神经网络中涉及到同一图像的不同变化时有助于防止过度拟合。即强迫神经网络不去记忆!通常会从现有数据中生成额外的数据。
  • 通过镜像实现数据增强:如果训练集中有一只猫的图像,那么它的镜像也是一只猫。通过垂直轴简单的翻转图像,训练数据集可变为原来的两倍。
  • 通过随机裁剪实现数据增强:此外,随机裁剪原始图像也会导致额外的数据,即原始数据的移位版本。AlexNet的作者从大小为256x256的图像中随机裁剪出大小为227x227的图像,并作为网络的输入。使用这种方法将数据的大小变为原来的2048倍。值得注意的是,这四个随机裁剪的图像看起来非常相似,但它们并不完全相同。对神经网络来说,虽然像素有微小的移动,但图像仍然是一只猫。如果没有数据增强,作者会应为严重的过度拟合而无法使用如此庞大的网络。
  • Dropout
    在丢弃的过程中,一个神经元被从网络中丢弃的概率为0.5.当一个神经元被丢弃时,并不影响正向传播和反向传播。每个输入都经过不同的网络架构。因此,所学习的权重参数更可靠且不易被装配。在测试的过程中,全网络参与没有遗漏,但是由于神经元丢失输出变为原来的一半。丢弃技术使迭代次数收敛到2,如果没有使用丢弃技术,AlexNet的过拟合会更加严重。

激活函数

使用激活函数的原因

  • 如果不使用激励函数,每一层的输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合。
  • 使用激活函数,会给神经元引入非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。
  • 在单层感知机中,分类的结果大于某个值为一类,小于某个值为一类,这样就会使得输出结果在这个点发生阶跃,logistic函数解决了阶跃函数的突然阶跃问题,使得输出的为0-1的概率,使得结果变得更平滑,它是一个单调上升的函数,具有良好的连续性,不存在不连续点。

常用激活函数

softmax函数

映射区间[0,1],主要用于:离散化概率分布。
softmax是将神经网络得到的多个值,进行归一化处理,使得到的值在[0,1]之间,让结果变得可解释。即可以将结果看作是概率,某个类别概率越大,将样本归为该类别的可能性也就越高。softmax如下图所示:
在这里插入图片描述
假设有一个数组V, V i V_{i} Vi表示V中的第i个像素,那么这个元素的softmax值为:
在这里插入图片描述
在神经网络后面添加softmax,真实的标签(或者是类别)就相当于真实的分布,经过softmax得出的值就是预测的结果,因此可以用交叉熵函数来作为损失函数(交叉熵损失函数又叫softmax损失函数)。有了交叉熵的概念,我们可以得出softmax的损失函数:
在这里插入图片描述
其中 y i y_{i} yi是神经元的输出也可以作为预测结果, y ^ i \hat{y}_{i} y^i只能取0或1。在softmax中取以e为底的对数,因为都是e的指数形式,可以方便计算。损失函数的具体形式如下图所示:
在这里插入图片描述
为了计算反向传播,从最后一层开始,需要对softmax的输入 z i z_{i} zi求导,得:
在这里插入图片描述
所以:
在这里插入图片描述
多分类下为什么用softmax而不是用其他归一化方法
在多分类问题中softmax主要功能是能包所有类别输出和唯一,即可以把输出直接看作是该类的概率。但是很多其它的归一化方法也可以实现这一目的,softmax除了把数据范围映射到[0,1]还有下面的两个功能:

sigmoid函数

该函数能将负无穷到正无穷映射区间(0, 1),也称logistic函数,sigmoid就是极端情况(类别数为2)下的softmax。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

tanh函数

映射区间 (-1,1),也称双切正切函数。
在这里插入图片描述
在这里插入图片描述
sigmoid函数和tanh函数都存在一个问题
当神经网络的层数增多的时候,由于在进行反向传播的时候,链式求导,多项相乘,函数进入饱和区(导数接近于零的地方)就会逐层传递,这种现象被称为梯度消失。
比如:sigmoid函数与其导数的函数如下,可以看出梯度消失的问题。

在这里插入图片描述
在这里插入图片描述

ReLU函数

映射区间:[0,+∞)
在这里插入图片描述
RELU函数的优点

  • 相关大脑方面的研究表明生物神经元的信息编码通常是比较分散及稀疏的。通常情况下,大脑中在同一时间大概只有1%-4%的神经元处于活跃状态。使用线性修正以及正则化(regularization)可以对机器神经网络中神经元的活跃度(即输出为正值)进行调试;相比之下,逻辑函数在输入为0时达到1/2,即已经是半饱和的稳定状态,不够符合实际生物学对模拟神经网络的期望。不过需要指出的是,一般情况下,在一个使用修正线性单元(即线性整流)的神经网络中大概有50%的神经元处于激活状态;
  • 更加有效的梯度下降以及反向传播:避免了梯度爆炸和梯度消失问题;
  • 简化计算过程:没有了其它复杂激活函数中诸如指数函数的影响;同时活跃度分散性使得神经网络整体计算成本下降。
    RELU总结
  • 虽然ReLU函数大于零的部分和小于零的部分分别都是线性函数,但是整体并不是线性函数,所以仍然可以作为激活函数,ReLU函数其实是分段线性函数,把所有的负值都变为0,而正值不变,这种操作被称为单侧抑制。
  • 在训练数据的时候,由于对于不同的任务,可能某些神经元的输出影响就比较大,有些则小,甚至有些则无,类似于人的大脑,左脑和右闹分别管理逻辑能力与想象力,当使用右脑的时候,就抑制左脑,当使用左脑的时候,抑制右脑,ReLU函数正好可以实现小于0的数值接受到抑制,这就使得神经网络的激活更接近于生物学上的处理过程,给神经网络增加了生命。
    总结
  • 因为线性模型的表达能力不够,引入激活函数是为了添加非线性因素;
  • 然后发展出了很多的激活函数适用于各种模型的训练;
  • ReLU函数的引入给神经网络增加了生物学特性,可以称为灵魂激活函数。

学习率衰减(learning rate decay)

在训练神经网络时,使用学习率控制参数的更新速度。学习率较小时,会大大降低参数的更新速度,降低网络优化的速度,增加训练时间;学习率较大时,会使搜索过程中发生震荡,导致参数在极优值附近徘徊,可能导致最后的结果不会收敛,或者在一个较大的范围内摆动。为此,在训练过程中引入学习率衰减,根据训练的迭代次数调整学习率的大小,使学习率随着训练的进行逐渐衰减。
TensorFlow中实现的学习率衰减方法:

  • tf.train.piecewise_constant 分段常数衰减
  • tf.train.inverse_time_decay 反时限衰减
  • tf.train.polynomial_decay 多项式衰减
  • tf.train.exponential_decay 指数衰减
  • tf.train.natural_exp_decay 自然指数衰减
  • tf.train.cosine_decay 余弦衰减
  • tf.train.linear_cosine_decay 线性余弦衰减
  • tf.train.noisy_linear_cosine_decay 噪声线性余弦衰减

分段常数衰减

分段常数衰减就是在定义好的区间上,分别设置不同的常数值,作为学习率的初始值和后续衰减的取值。
函数

tf.trian.piecewise_constant(
x,          # 标量,指代训练次数
boundaries, #张量集合,学习率参数应用区间列表
values,     #张量集合,学习率列表,比boundaries长度多1
name=None   #操作的名称
)

示例

import tensorflow as tf
import matplotlib.pyplot as plt
num_epoch = tf.Variable(0, name='global_step', trainable=False)
boundaries = [10, 20, 30]
learning_rates = [0.1, 0.07, 0.025, 0.0125]
y = []
N = 40
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for num_epoch in range(N):
        learning_rate = tf.train.piecewise_constant(num_epoch,boundaries=boundaries,values=learning_rates)
        lr = sess.run([learning_rate])
        y.append(lr)
x = range(N)
plt.plot(x, y, 'r-', linewidth=2)
plt.title('piecewise_constant')
plt.xlabel('step')
plt.ylabel('learning_rate')
plt.show()

在这里插入图片描述

指数衰减

指数衰减是比较常用的衰减方法,学习率是跟当前的训练轮次指数相关的。
函数

tf.exponential_decay(
learning_rate, #初始学习率
global_step, #衰减计算的全局步骤,一次batch_size对应一次global_step
decay_steps,#衰减速度,间隔一次decay_steps更新一次learning_rate
decay_rate, #衰减系数,衰减速率,对应指数函数的基
staircase=False,#为True:阶梯型衰减,为False:标准指数衰减
name=None #操作名称
)

计算公式

decayed_learning_rate = learning_rate * decay_rate ^ (global_step / decay_steps)  

示例

import tensorflow as tf
import matplotlib.pyplot as plt
num_epoch = tf.Variable(0, name='global_step', trainable=False)
y = []
z = []
N = 200
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for num_epoch in range(N):
        #阶梯型衰减
        learning_rate1 = tf.train.exponential_decay(learning_rate=0.5, gloable_step=num_epoch, decay_steps=10, decay_rate=0.9, staircase=True)
        #标准指数型衰减
        learning_rate2 = tf.train.exponential_decay(learning_rate=0.5, gloable_step=num_epoch, decay_steps=10, decay_rate=0.9, staircase=False)
        lr1,lr2 = sess.run([learning_rate1, learning_rate2])
        y.append(lr1)
        z.append(lr2)
x = range(N)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_ylim([0, 0.55])

plt.plot(x, y, 'r-', linewidth=2)
plt.plot(x, z, 'g-', linewidth=2)
plt.title('exponential_decay')
ax.set_xlabel('step')
ax.set_ylabel('learning rate')
plt.legend(labels = [ 'exponential_staircase', 'exponential_contimus'],
           loc='upper right')
plt.show()

在这里插入图片描述
在这里插入图片描述

自然指数衰减

自然指数衰减是指数衰减的一种特殊情况,学习率也是跟当前的训练轮次指数相关的,只不过以e为底数。自然指数衰减比指数衰减要快的多,一般用于较快收敛,容易训练的网络。
函数

tf.trian.natural_exp_decay(
learning_rate,#初始学习率
global_step,#用于衰减的全局步数,非负
decay_steps,衰减步数,用于离散梯度型衰减
decay_rate,#衰减率
staircase=False,#为True:离散梯度型衰减,为False:标准型衰减
name=None #操作的名称
)

计算公式

decayed_learning_rate = learning_rate * exp(-decay_rate * global_step)

示例

import matplotlib.pyplot as plt
import tensorflow as tf

num_epoch = tf.Variable(0, name='global_step', trainable=False)

y = []
z = []
w = []
m = []
N = 200

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for num_epoch in range(N):
        #阶梯型衰减
        learning_rate1 = tf.train.natural_exp_decay(learning_rate=0.5, global_step=num_epoch, decay_steps=10,
                                                    decay_rate=0.9,staircase=True)
        learning_rate3 = tf.train.exponential_decay(learning_rate=0.5, global_step=num_epoch, decay_steps=10,
                                                    decay_rate=0.9, staircase=True)
        # 标准指数型衰减
        learning_rate2 = tf.train.natural_exp_decay(learning_rate=0.5, global_step=num_epoch, decay_steps=10,
                                                    decay_rate=0.9, staircase=False)
        learning_rate4 = tf.train.exponential_decay(learning_rate=0.5, global_step=num_epoch, decay_steps=10,
                                                    decay_rate=0.9, staircase=False)
        lr1, lr2, lr3, lr4 = sess.run([learning_rate1, learning_rate2, learning_rate3, learning_rate4])
        y.append(lr1)
        z.append(lr2)
        w.append(lr3)
        m.append(lr4)
x = range(N)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_ylim(0, 0.55)

plt.plot(x, y, 'r-', linewidth=2)
plt.plot(x, z, 'g-', linewidth=2)
plt.plot(x, w, 'r--', linewidth=2)
plt.plot(x, m, 'g--', linewidth=2)

plt.title('natural_exp_decay')
ax.set_xlabel('step')
ax.set_ylabel('learning_rate')
plt.legend(labels = ['natural_staircase', 'natural_continus', 'exponential_staircase', 'exponential_contimus'],
           loc='upper right')
plt.show()

在这里插入图片描述
在这里插入图片描述

多项式衰减

函数

tf.train.polynomial_decay(
learning_rate, #初始学习率
global_step,#衰减计算的全局步数
decay_steps,#衰减步数
end_learning_rate=0.0001,#最小学习率,默认0.0001
power=1.0,#多项式的幂,默认为1
cycle=False,#表示达到最低学习率时,是否升高再降低,默认False
name=None #操作名称
)

计算公式
参数cycle防止神经网络训练后期学习率过小导致网络一直在某个局部最小值中震荡,通过增大学习率可以跳出局部极小值。

# 如果cycle=False
global_step = min(global_step, decay_steps)
decayed_learning_rate = (learning_rate - end_learning_rate) *
                          (1 - global_step / decay_steps) ^ (power) +
                          end_learning_rate
# 如果cycle=True
decay_steps = decay_steps * ceil(global_step / decay_steps)
decayed_learning_rate = (learning_rate - end_learning_rate) *
                          (1 - global_step / decay_steps) ^ (power) +
                          end_learning_rate

示例

import matplotlib.pyplot as plt
import tensorflow as tf

y = []
z = []
N = 200

num_epoch = tf.Variable(0, name='global_step', trainable=False)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for num_epoch in range(N):
        #cycly=False
        learning_rate1 = tf.train.polynomial_decay(learning_rate=0.1, global_step=num_epoch, decay_steps=50,
                                                   end_learning_rate=0.01, power=0.5, cycle=False)
        #cycly=True
        learning_rate2 = tf.train.polynomial_decay(learning_rate=0.1, global_step=num_epoch, decay_steps=50,
                                                   end_learning_rate=0.01, power=0.5, cycle=True)
        lr1, lr2 = sess.run([learning_rate1, learning_rate2])
        y.append(lr1)
        z.append(lr2)
x = range(N)
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(x, z, 'g-', linewidth=2)
plt.plot(x, y, 'r--', linewidth=2)
plt.title('polynomial_decay')
ax.set_xlabel('step')
ax.set_ylabel('learning rate')
plt.legend(labels=['cycle=True', 'cycle=False'], loc='upper right')
plt.show()

在这里插入图片描述
可以看到学习率在decay_steps=50迭代次数后到达最小值;同时,当cycle=False时,学习率达到预设的最小值后,就保持最小值不再变化;当cycle=True时,学习率将会瞬间增大,再降低。

多项式衰减中设置学习率可以往复升降的目的:时为了防止在神经网络训练后期由于学习率过小,导致网络参数陷入局部最优,将学习率升高,有可能使其跳出局部最优。

倒数衰减(又称反时限衰减)

倒数衰减指的是一个变量的大小与另一个变量的大小成反比的关系,具体到神经网络中就是学习率的大小跟训练次数有一定的反比关系。
函数

tf.train.inverse_time.decay(
learning_rate,#初始学习率
global_step,#用于衰减计算的全局步数
decay_steps,#衰减步数
decay_rates,衰减率
staircase=False,#是否应用离散阶梯型,否则Wie连续型
name=None #操作名称
)

计算公式

#staircase=False
decayed_learning_rate =learning_rate/(1+decay_rate* global_step/decay_step)
#staircase=True
decayed_learning_rate =learning_rate/(1+decay_rate*floor(global_step/decay_step))

示例

import tensorflow as tf
import matplotlib.pyplot as plt
num_epoch = tf.Variable(0, name='global_step', trainable=False)
y = []
z = []
N = 200
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for num_epoch in range(N):
        #阶梯型衰减
        learning_rate1 = tf.train.inverse_time_decay(learning_rate=0.1, global_step=num_epoch, decay_steps=20,
                                                    decay_rate=0.2, staircase=True)
        #标准指数型衰减
        learning_rate2 = tf.train.inverse_time_decay(learning_rate=0.1, global_step=num_epoch, decay_steps=20,
                                                    decay_rate=0.2, staircase=False)
        lr1, lr2 = sess.run([learning_rate1, learning_rate2])
        y.append(lr1)
        z.append(lr2)
x = range(N)
fig = plt.figure()
ax = fig.add_subplot(111)

plt.plot(x, y, 'r-', linewidth=2)
plt.plot(x, z, 'g-', linewidth=2)
plt.title('inverse_time_decay')
ax.set_xlabel('step')
ax.set_ylabel('learning rate')
plt.legend(labels = [ 'inverse_time_staircase', 'inverse_time_contimus'],
           loc='upper right')
plt.show()

在这里插入图片描述

余弦衰减

余弦的衰减机制跟余弦函数相关,形状也大体上是余弦形状。

标准余弦衰减

函数

tf.trian.cosine_decay(
learning_rate,#初始学习率
global_step,#迭代次数
decay_steps,#衰减周期
alpha=0.0,#最小学习率,默认为0.0
name=None #操作名称
)

计算公式

global_step = min(global_step, decay_steps)
cosine_decay = 0.5 * (1 + cos(pi * global_step / decay_steps))
decayed = (1 - alpha) * cosine_decay + alpha
decayed_learning_rate = learning_rate * decayed

重启余弦衰减

函数

tf.train.cosine_decay_restarts(
learning_rate,#初始学习率
global_step,#迭代次数
first_decay_steps,#衰减周期
t_mul=2.0,#用于导出第i个周期中的迭代次数
m_mul=1.0,#用于导出第i个周期的初始学习率
alpha=0.0,#最小学习率,默认为0
name=None #操作名称
)

线性余弦衰减

函数

tf.train.linear_consine_decay(
learning_rate,#初始学习率
global_step,#迭代次数
num_periods=0.5,#衰减的余弦部分的周期数
alpha=0.0,#最小学习率
beta=0.001,#最小学习率
name=None #操作名称
)

计算公式

global_step = min(global_step, decay_steps)
linear_decay = (decay_steps - global_step) / decay_steps)
cosine_decay = 0.5 * (1 + cos(pi * 2 * num_periods * global_step / decay_steps))
decayed = (alpha + linear_decay) * cosine_decay + beta
decayed_learning_rate = learning_rate * decayed

噪声余弦衰减

函数

tf.train.noisy_linear_cosine_decay(
    learning_rate,#初始学习率
    global_step,#迭代次数
    decay_steps,#衰减周期
    initial_variance=1.0,#噪声的初始方程
    variance_decay=0.55,#衰减噪声的方程
    num_periods=0.5,#衰减的余弦部分的周期数
    alpha=0.0,#最小学习率
    beta=0.001,#偏置系数
    name=None #操作名称
    )

计算公式

global_step = min(global_step, decay_steps)
linear_decay = (decay_steps - global_step) / decay_steps)
cosine_decay = 0.5 * (
    1 + cos(pi * 2 * num_periods * global_step / decay_steps))
decayed = (alpha + linear_decay + eps_t) * cosine_decay + beta
decayed_learning_rate = learning_rate * decayed

示例

import matplotlib.pyplot as plt
import tensorflow as tf

y = []
z = []
w = []
m = []
N = 200
num_epoch = tf.Variable(0, name='global_step', trainable=False)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for num_epoch in range(N):
        # 余弦衰减
        learing_rate1 = tf.train.cosine_decay(learning_rate=0.1, global_step=num_epoch, decay_steps=50)
        # 重启余弦衰减
        learing_rate2 = tf.train.cosine_decay_restarts(learning_rate=0.1, global_step=num_epoch,
                                                       first_decay_steps=50)
        # 线性余弦衰减
        learing_rate3 = tf.train.linear_cosine_decay(learning_rate=0.1, global_step=num_epoch, decay_steps=50,
                                                     num_periods=0.2, alpha=0.5, beta=0.2)
        # 噪声线性余弦衰减
        learing_rate4 = tf.train.noisy_linear_cosine_decay(learning_rate=0.1, global_step=num_epoch, decay_steps=50,
                                                            initial_variance=0.01, variance_decay=0.1, num_periods=2,
                                                            alpha=0.5, beta=0.2)
        lr1, lr2, lr3, lr4 = sess.run([learing_rate1, learing_rate2, learing_rate3, learing_rate4])
        y.append(lr1)
        z.append(lr2)
        w.append(lr3)
        m.append(lr4)

x = range(N)
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(x, y, 'r-', linewidth=2)
plt.plot(x, z, 'g--', linewidth=2)
plt.plot(x, w, 'b-', linewidth=2)
plt.plot(x, m, 'y-', linewidth=2)
plt.title('cosine_decay')
ax.set_xlabel('step')
ax.set_ylabel('learing rate')
plt.legend(labels=['consine_decay', 'consine_decay_restarts', 'linear_consine_decay', 'noisy_linear_consine_decay'], loc='upper right')
plt.show()

在这里插入图片描述

梯度下降优化算法

梯度下降法是最小化目标函数 J ( θ ) J(\theta) J(θ)的一种方法,其中 θ ∈ R d \theta \in R^{d} θRd为模型参数,梯度下降法利用目标函数关于参数的梯度 ▽ θ J ( θ ) \bigtriangledown_{\theta}J(\theta) θJ(θ)的反方向更新参数。学习率 η \eta η决定达到最小值或者局部最小值过程中所采用的步长的大小。即,沿着目标函数的斜面下降的方向,直到到达谷底。

梯度下降法的变形形式

批梯度下降法

在这里插入图片描述

for i in range(nb_epochs):
    params_grad = evaluate_gradient(loss_function, data, params)
    params = params - learning_rate * params_grad

对于给定的迭代次数,首先,我们利用全部数据集计算损失函数关于参数向量params的梯度向量params_grad。然后利用梯度的方向和学习率更新参数,学习率决定将以多大的步长更新参数。对于凸误差函数,批梯度下降法能够保证收敛到全局最小值,对于非凸函数,则收敛到一个局部最小值。

随机梯度下降法

在这里插入图片描述
在这里插入图片描述
与批梯度下降法的收敛会使得损失函数陷入局部最小相比,由于SGD的波动性,一方面,波动性使得SGD可以跳到新的和潜在更好的局部最优。另一方面,这使得最终收敛到特定最小值的过程变得复杂,因为SGD会一直持续波动。然而,已经证明当我们缓慢减小学习率,SGD与批梯度下降法具有相同的收敛行为,对于非凸优化和凸优化,可以分别收敛到局部最小值和全局最小值。

for i in range(nb_epochs):
    np.random.shuffle(data)
    for example in data:
        params_grad = evaluate_gradient(loss_function, example, params)
        params = params - learning_rate * params_grad

小批量梯度下降法

在这里插入图片描述

for i in range(nb_epochs):
    np.random.shuffle(data)
    for batch in get_batches(data, batch_size=50):
        params_grad = evaluate_gradient(loss_function, batch, params)
        params = params - learning_rate * params_grad

梯度下降优化算法

动量法

在这里插入图片描述
动量法在参数的更新过程中:对于在梯度点处具有相同的方向的维度,其动量项增大,对于在梯度点处改变方向的维度,其动量项减少。因此,可以得到更快的收敛速度,同时可以减少摇摆。

Nesterov加速梯度下降法

在这里插入图片描述
在这里插入图片描述

Adagrad

Adagrad是这样的一种基于梯度的优化算法:让学习率适应参数,对于出现次数较少的特征,我们对其采用更大的学习率,对于出现次数较多的特征,我们对其采用较小的学习率。因此,Adagrad非常适合处理稀疏数据。
在这里插入图片描述

Adadelta

在这里插入图片描述
在这里插入图片描述

RMSprop

在这里插入图片描述

Adam

在这里插入图片描述

损失函数

均方误差损失(Mean Square Error,MSE)

在这里插入图片描述

交叉熵损失(Cross Entropy,CE)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

梯度消失

梯度消失跟损失函数的计算方法和激活函数有关。

MSE均方误差+sigmoid激活函数

MSE均方误差+sigmoid激活函数:输出层神经元学习率缓慢。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

交叉熵损失+Sigmoid激活函数

在这里插入图片描述
在这里插入图片描述

交叉熵损失+ReLU激活函数

在这里插入图片描述
在这里插入图片描述

梯度爆炸

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考资料

  1. 【神经网络】激活函数softmax,sigmoid,tanh,relu总结
  2. 机器学习与人工智能技术分享-第五章 深度神经网络
  3. 从LeNet-5到DenseNet
  4. AlexNet到底是什么?
  5. 图示Softmax及交叉熵损失函数
  6. 多类分类下为什么用softmax而不是用其他归一化方法?
  7. TensorFlow学习--学习率衰减/learning rate decay
  8. tensorflow中常用学习率更新策略
  9. TensorFlow中设置学习率的方式
  10. 梯度下降优化算法综述
  11. 复习:常见的损失函数
  12. TF里几种loss和注意事项
  13. 常见损失函数小结
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值