优化过程是原值减学习率乘梯度!!!
根据导数的定义,如果输入发生微小的变化,那么输出也会相应的变化: 对导数符号化后,有: 梯度下降的思路如下: 寻找一个参数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),则:
学习率决定迭代的收敛速度,和准确度,学习率相对越大迭代越快,但是可能会出现不稳定的问题。 因此,可以对每个参数设置不同的学习率。
早期的学习率自适应算法: 如果损失和某一个指定参数的偏导符号相同,那么学习率应该增加,若不同,则减小。
①、从训练集中取出m个样本X,对应的目标用Y表示 ②、以次数据为基础计算梯度 ③、累计平方梯度 其中r初始为0 ④、计算参数的更新量 ⑤、根据更新的参数使
反复重复①~⑤步,直到参数收敛。
该算法的缺点: 因为算法在训练开始就对梯度平方进行了累计,在一些实验中,会发现这样的做法容易导致学习率过早和过量地减小。
相比于AdaGrad算法,RMSProp算法引入了衰减率ρ。 在AdaGrad的第三步进行带有衰减率的运算: 起到的效果是在参数空间更为平缓的方向,会取得更大的进步(因为平缓,所以历史梯度平方和较小,对应学习下降的幅度较小),并且能够使得陡峭的方向变得平缓,从而加快训练速度。
ρ取0.9,当参数更新较大时会对它进行「惩罚」
设全局学习率σ(默认0.001),矩估计的指数衰减速率为ρ1和ρ2(在【0,1】内),初始值为0的一阶和二阶矩变量s,r,时间步计数t。
①、从训练集中取出m个样本X,对应的目标用Y表示 ②、以次数据为基础计算梯度 ③、刷新时间步 ④、更新一阶有偏矩估计 ⑤、更新二阶有偏矩估计 ⑥、对一阶矩的偏差进行修正 ⑦、对二阶矩的偏差进行修正 ⑧、计算参数的更新量 ⑨、更新参数
运用框架编程的好处,有些复杂的算法不需要人工亲自实现,直接调用就好了。
基本的优化类,该类不常常被直接调用,而较多使用其子类, 比如GradientDescentOptimizer, AdagradOptimizer 或者MomentumOptimizer
8、9、10未曾涉猎不做记录。
学习率既不能过大也不能过小,为了更好地设置学习率,可以逐步减小已经设置好的学习率。
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]