一、梯度下降算法
优化过程是原值减学习率乘梯度!!!
梯度学习
根据导数的定义,如果输入发生微小的变化,那么输出也会相应的变化:
对导数符号化后,有:
梯度下降的思路如下:
寻找一个参数w,使得损失函数J(w)的值最小,通过不断的迭代,w会不断更新,最后会达到或接近最小值点。
梯度下降算法原理图:
梯度下降算法实际上一种求解最小二乘法最优解的有效工具。
σ为学习率,该值越大学习速度越快,相反,也有可能因为过大而越过导致w变化过大导致始终无法达到最优点,所以应该适当的调整σ的大小。
可以得到参数的更新公式如下:
例如:
取更新率为0.2,在迭代10次后数值变为0.0605,此后w会不断的接近0,达到近似的最小值点。
求解多维
对于二维函数
可以利用偏导数来描述函数沿任意方向的变化率。
J的导数可以汇总为每一个偏导数组成的向量:
随机梯度下降
交叉熵损失函数的梯度下降需要计算:
随着数据的增加,计算总的损失函数需要更多的时间以及更多的运算代价。
采取随机抽样的形式每次抽取i’个样本最为迭代的参考有:
这样每次只需要对几百个样本进行计算即可。
这种方法准确度肯定不如对全部样本进行计算,但是它大大的缩短了迭代的运算量和时间。
因此,实际学习迭代过程中,通常使用部分全计算加部分随机梯度的方法进行。
二、反向传播
反向传播算法给出了一种高效地在所有参数上使用梯度下降算法的方式。
这种方法主要用于多层的时候,计算损失函数关于参数的梯度。
对于单层来说:
若Z(y),其中y=f(x),现在若计算反向Z关于x的梯度,就用到反向传播算法。
链式求导:
将链式求导扩充到向量上,有:
其中i,j分别代表向量x,和向量y的下标。
于是将偏导数汇聚成一个矩阵:
这样梯度就可以写成:
张量的链式法则
现假设一个四维的张量 i(i1,i2,i3,i4) 且中间层存在,有Y=g(X)的关系,z = f(Y),则:
三、自适应学习率算法
学习率决定迭代的收敛速度,和准确度,学习率相对越大迭代越快,但是可能会出现不稳定的问题。
因此,可以对每个参数设置不同的学习率。
早期的学习率自适应算法:
如果损失和某一个指定参数的偏导符号相同,那么学习率应该增加,若不同,则减小。
1、AdaGrad算法
①、从训练集中取出m个样本X,对应的目标用Y表示
②、以次数据为基础计算梯度
③、累计平方梯度
其中r初始为0
④、计算参数的更新量
⑤、根据更新的参数使
反复重复①~⑤步,直到参数收敛。
该算法的缺点:
因为算法在训练开始就对梯度平方进行了累计,在一些实验中,会发现这样的做法容易导致学习率过早和过量地减小。
2、RMSProp
相比于AdaGrad算法,RMSProp算法引入了衰减率ρ。
在AdaGrad的第三步进行带有衰减率的运算:
起到的效果是在参数空间更为平缓的方向,会取得更大的进步(因为平缓,所以历史梯度平方和较小,对应学习下降的幅度较小),并且能够使得陡峭的方向变得平缓,从而加快训练速度。
ρ取0.9,当参数更新较大时会对它进行「惩罚」
3、Adam算法
设全局学习率σ(默认0.001),矩估计的指数衰减速率为ρ1和ρ2(在【0,1】内),初始值为0的一阶和二阶矩变量s,r,时间步计数t。
①、从训练集中取出m个样本X,对应的目标用Y表示
②、以次数据为基础计算梯度
③、刷新时间步
④、更新一阶有偏矩估计
⑤、更新二阶有偏矩估计
⑥、对一阶矩的偏差进行修正
⑦、对二阶矩的偏差进行修正
⑧、计算参数的更新量
⑨、更新参数
四、TensorFlow提供的优化器
运用框架编程的好处,有些复杂的算法不需要人工亲自实现,直接调用就好了。
1、train.Optimizer()
基本的优化类,该类不常常被直接调用,而较多使用其子类,
比如GradientDescentOptimizer, AdagradOptimizer
或者MomentumOptimizer
2、train.GradientDescentOptimizer()
tf.compat.v1.train.GradientDescentOptimizer
__init__(
self,
learning_rate,
use_locking=False,
name='GradientDescent'
)
# learning_rate为学习率
# name为名称
3、train.AdagradOptimizer()
__init__(
self,
learning_rate,
initial_accumlator_ value=0.1,
use_locking=False,
name='Adagrad'
)
4、train.RMSPropOptimizer()
__init__(
self,
learning_rate,
decay=0.9,
momentum=0.0,
epsilon=1e-10,
use_locking=False,
centered = False,
name='RMSProp'
)
#decay为衰减率
#momentum=0.0动量值
#epsilon为小常数
5、train.AdamOptimizer()
__init__(
self,
learning_rate,
beta1=0.9,
beta2=0.999,
epsilon=1e-8,
use_locking=False,
name='RMSProp'
)
#beta1是第一个指数衰减率的预估值
#deta2是第二个指数衰减率的预估值
6、train.AdagradDAOptimizer()
__init__(
self,
learning_rate,
global_step,
initial_gradient_squared_accumulator_value=0.1,
11_reqularization_strength=0.0,
12_reqularization_strength=0.0,
use_locking=False,
name='AdagradDA'
)
7、train.AdadeltaOptimizer()
__init__(
self,
learning_rate,
rho = 0.95,
epsilon=1e-8,
use_locking=False,
name='Adadelta'
)
8、train.ProximalGradientDescentOptimizer()
9、train.ProximalAdadeltaOptimizer()
10、train.FtrlOptimizer()
8、9、10未曾涉猎不做记录。
五、学习率的独立设置
1、指数衰减的学习率
学习率既不能过大也不能过小,为了更好地设置学习率,可以逐步减小已经设置好的学习率。
tf.compat.v1.train.exponential_deccy()
(
learning_rate,
global_step,decay_steps,
decay_rate,
staircase,
name,
)
可以对学习率进行指数形式的衰减。
decayed_learning_rate = learning+rate × decay_rate (global_step/decay_steps)
#通常learning_rate设置为一个比较大的数(但是小于1)来获得一个较快的更新速度,然后随着迭代逐步减小学习率。
#decay_steps是衰减速度
#decay_rate 是衰减系数
#global_step是当前训练进行的轮数
实例:
import tensorflow as tf
import numpy as np
tf.compat.v1.disable_eager_execution()
x_data = np.random.rand(1000)
# 生成1000个随机点
y_data = x_data * 0.8+ 0.9
# 构造一个线性模型
eb = tf.Variable(0.)
#设估计函数的截距
ek = tf.Variable(0.)
#设估计函数的斜率
y = ek * x_data + eb
# 估计函数
loss = tf.reduce_mean(tf.square(y_data-y))
# 定义一个梯度下降法来进行训练的优化器
optimizer = tf.compat.v1.train.GradientDescentOptimizer(0.2)
# 其他值为默认,学习率为0.2
# 最小化代价函数
train = optimizer.minimize(loss)
init = tf.compat.v1.global_variables_initializer()
with tf.compat.v1.Session() as sess:
sess.run(init)
for step in range(201):
sess.run(train)
if step % 20 == 0:
print(sess.run([ek, eb]))
其结果如下:
......
......
......
Skipping registering GPU devices...
2020-07-04 21:19:25.827634: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2020-07-04 21:19:25.837992: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x2eb6a7dd6d0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-07-04 21:19:25.838416: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): Host, Default Version
2020-07-04 21:19:25.838793: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1102] Device interconnect StreamExecutor with strength 1 edge matrix:
2020-07-04 21:19:25.839094: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1108]
[0.29672217, 0.52490824]
[0.66420203, 0.9747524]
[0.7190399, 0.94456613]
[0.7517332, 0.92656946]
[0.7712242, 0.91584027]
[0.7828445, 0.9094436]
[0.78977215, 0.9056301]
[0.79390234, 0.90335655]
[0.7963648, 0.9020011]
[0.7978328, 0.901193]
[0.7987079, 0.90071124]
2、反时限学习率衰减
train.inverse_time_decay(
learinging_rate,
global_step,
decay_steps,
decay_rate,
staircase,
name
)