发布时间:2024-05-06 来源:网络
?神经网络参数优化器
博主微信公众号(左)、Python+智能大数据+AI学习交流群(右):欢迎关注和加群,大家一起学习交流,共同进步!
目录
?
? ? 待优化参数:w
? ? 损失函数:loss
? ? 学习率:lr
? ? 一次训练所选取的样本数:batch(训练时为了提高效率,数据集中的数据并不是一次喂入神经网络一组,而是以batch为单位,批量喂入神经网络,每个batch通常包含 2^n 组数据)
? ? 当前?batch?迭代的总次数:t
? ? 1、计算?t?时刻损失函数关于当前参数的梯度:让 loss?对当前的每个?w?求偏导数
? ? ? ? ?
? ? 2、计算 t?时刻 一阶动量?和?二阶动量
? ? 3、计算?t?时刻下降梯度:
? ? ?
? ? 4、计算?t+1?时刻参数:
? ? ?
? ? 一阶动量:与梯度相关的函数
? ? 二阶动量:与梯度平方相关的函数
? ? 不同的优化器实质上只是定义了不同的一阶动量和二阶动量公式。
? ? 1、SGD(无momentum),常用的梯度下降法。
? ? ? 随机梯度下降法(stochastic gradient descent),策略是朝着当前所在位置的梯度最大的方向前进。
? ? ? ? (1)公式
? ? ? ? ?
?
? ? ? ? (2)python代码实现参数更新公式
? ? ? ? ? ? w1.assign_sub(lr * grads[0])? ? #?参数 w 自更新
? ? ? ? ? ? b1.assign_sub(lr * grads[1])? ? #?参数 b?自更新
? ? ? ? (3)代码示例
? ? ? ? ? ? 训练+预测耗时:5.223658084869385
? ? ? ? ? ? 准确率:1.0
? ? ? ? ? ?
? ? ? ? ? ? github地址:SDG优化器实现鸢尾花分类
? ? 2、SGDM(含momentum的SGD),在SGD的基础上增加一阶动量。
? ? ? ? (1)公式
? ? ? ?
? ? ? ? ? ?这个公式表示各时刻梯度方向的指数滑动平均值。
? ? ? ? ? ? 和SGD相比,一阶动量的公式多了??这一项,?表示上一时刻的一阶动量。
? ? ? ? ? ? 上一时刻的一阶动量在这个公式中占有很大比重。因为??是个超参数,是个接近 1 的数值,经验值是 0.9。
? ? ? ? ? ? 二阶动量在SGDM中恒等于 1。
? ? ? ? (2)python代码实现参数更新公式
? ? ? ? ? ? ? ?
? ? ? ? ? ? m_w, m_b = 0, 0
? ? ? ? ? ? beta = 0.9
? ? ? ? ? ? # sgd-momentum
? ? ? ? ? ? m_w = beta * m_w + (1 - beta) * grads[0]
? ? ? ? ? ? m_b?= beta * m_b?+ (1 - beta) * grads[1]
? ? ? ? ? ? w1.assign_sub(lr * m_w)
? ? ? ? ? ? b1.assign_sub(lr * m_b)
? ? ? ? ? ? a、每一时刻的一阶动量 ,由上一时刻的一阶动量??和?当前时刻的梯度决定。
? ? ? ? ? ? b、第 1 个时刻的一阶动量是由第 0?时刻的一阶动量决定,第 0 时刻的一阶动量是 0,所以参数?w?和?参数?b?的一阶动量初始值都是 0。
? ? ? ? ? ? c、?是个超参数,经验值是 0.9。
? ? ? ? ? ? d、一阶动量?m?等于??乘以上一时刻的一阶动量?m,加上,?乘以当前时刻的梯度。
? ? ? ? ? ? e、带入自减操作,实现参数?w?和 b?的自更新。
? ? ? (3)代码示例
? ? ? ? ? ? 训练+预测耗时:5.400546550750732
? ? ? ? ? ? 准确率:1.0
? ? ? ? ?
? ? ? ? ? ? github地址:SGDM优化器实现鸢尾花分类
? ? 3、Adagrad优化器,在SGD基础上增加二阶动量。
? ? ? ? (1)公式
? ? ? ? ?
? ? ? ? ? ? Adagrad?是在SGD的基础上引入二阶动量,可以对模型中的每一个参数分配自适应学习率。
? ? ? ? ? ? Adagrad?的一阶动量和SGD一样,是当前的梯度;二阶动量是从开始时刻到现在梯度平方的累加和。
? ? ? ? ? ? 有了一阶动量和二阶动量,可以带入参数更新公式进行参数的更新。
? ? ? (2)python代码实现参数更新公式
? ? ? ? ? ? ? ?
? ? ? ? ? ? m_w, m_b = 0, 0
? ? ? ? ? ? # adagrad
? ? ? ? ? ? v_w += tf.square(grads[0])
? ? ? ? ? ? v_b += tf.square(grads[1])
? ? ? ? ? ? w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
? ? ? ? ? ? b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))
? ? ? ? ? ? a、Adagrad 的一阶动量 ?是当前时刻的梯度;二阶动量是梯度平方的累积和。
? ? ? ? ? ? b、设 0?时刻参数?w?和?参数?b?的二阶动量初始值都是 0。
? ? ? ? ? ? c、当前的二阶动量?v?等于梯度平方的累积和。
? ? ? ? ? ? d、把二阶动量 v_w?和 v_b?分别带入各自的参数更新公式,实现参数?w?和 b?的自更新。
? ? ? (3)代码示例
? ? ? ? ? ? 训练+预测耗时:5.2659077644348145
? ? ? ? ? ? 准确率:1.0
? ? ? ? ?
? ? ? ? ? ? github地址:Adagrad优化器实现鸢尾花分类
? ? 4、RMSProp,SGD基础上增加二阶动量
? ? ? ? (1)公式
? ? ? ? ?
? ? ? ? ? ? RMSProp?是在SGD的基础上引入二阶动量。
? ? ? ? ? ? RMSProp的一阶动量和SGD一样,是当前的梯度;二阶动量 V?使用指数滑动平均值计算,表征的是过去一段时间的平均值。
? ? ? ? ? ? 求出一阶动量和二阶动量,带入参数更新公式,实现参数的自更新。
? ? ? ? (2)python代码实现参数更新公式
? ? ? ? ? ?
? ? ? ? ? ? v_w, v_b = 0, 0
? ? ? ? ? ? beta = 0.9
? ? ? ? ? ? # RMSProp
? ? ? ? ? ? v_w = beta * v_w + (1 - beta) * tf.square(grads[0])? ?
? ? ? ? ? ? v_b = beta * v_b + (1 - beta) * tf.square(grads[1])
? ? ? ? ? ? w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
? ? ? ? ? ? b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))
? ? ? ? ? a、RMSProp?的一阶动量 ?是当前时刻的梯度;二阶动量是各时刻梯度平方的指数滑动平均值。
? ? ? ? ? ? b、设 0?时刻参数?w?和?参数?b?的二阶动量初始值都是 0。
? ? ? ? ? ? c、当前的二阶动量?v?等于??倍的上一时刻二阶动量 V?加上 ?倍的当前梯度平方。
? ? ? ? ? ? d、把二阶动量 v_w?和 v_b?分别带入各自的参数更新公式,实现参数?w?和 b?的自更新。
? ? ? (3)代码示例
? ? ? ? ? ? 训练+预测耗时:5.479531526565552
? ? ? ? ? ? 准确率:1.0
? ? ? ? ?
? ? ? ? ? github地址:RMSProp优化器实现鸢尾花分类
? ? 5、Adam,同时结合 SGDM?的一阶动量和 RMSProp?的二阶动量。
? ? ? ? (1)公式
? ? ? ? ?
? ? ? ? ? ? Adam?优化器同时引入了 SGDM?的一阶动量?和 RMSProp的二阶动量。
? ? ? ? ? ? 并在此基础上增加了两个修正项。
? ? ? ? ? ? 把修正后的一阶动量和二阶动量带入参数更新公式,实现参数自更新。
? ? ? (2)python代码实现参数更新公式
? ? ? ? ? ?
? ? ? ? ? ? m_w, m_b = 0, 0
? ? ? ? ? ? v_w, v_b = 0, 0
? ? ? ? ? ? beta1, beta2 = 0.9, 0.999
? ? ? ? ? ? delta_w, delta_b = 0, 0
? ? ? ? ? ? global_step = 0
? ? ? ? ? ? # RMSProp
? ? ? ? ? ? m_w = beta1 * m_w + (1 - beta1) * grads[0]
? ? ? ? ? ? m_b = beta1 * m_b + (1 - beta2) * grads[1]
? ? ? ? ? ? v_w = beta2 * v_w + (1 - beta2) * tf.square(grads[0])
? ? ? ? ? ? v_b = beta2 * v_b + (1 - beta2) * tf.square(grads[1])
? ? ? ? ? ? m_w_correction = m_w / (1 - tf.pow(beta1, int(global_step)))
? ? ? ? ? ? m_b_correction = m_b / (1 - tf.pow(beta1, int(global_step)))
? ? ? ? ? ? v_w_correction = v_w / (1 - tf.pow(beta2, int(global_step)))
? ? ? ? ? ? v_b_correction = v_b / (1 - tf.pow(beta2, int(global_step)))
? ? ? ? ? ? w1.assign_sub(lr * m_w_correction / tf.sqrt(v_w_correction))
? ? ? ? ? ? b1.assign_sub(lr * m_b_correction / tf.sqrt(v_b_correction))
? ? ? ? ? a、Adam?的一阶动量表达式和含 momentum?的 SGD?一阶动量是一样的;二阶动量表达式和 RMSProp?的二阶动量表达式是一样的。
? ? ? ? ? ? b、两个修正式将计算出来的一阶动量和二阶动量?分别除以 1?减去各自 beta?的 global_step?次方。
? ? ? ? ? ? c、这个global_step,是从训练开始到当前时刻所经历的总 batch?数。
? ? ? ? ? ? d、把修正项带入各自的参数更新公式,实现参数?w?和 b?的自更新。
? ? ? (3)代码示例
? ? ? ? ? ? 训练+预测耗时:6.441400527954102
? ? ? ? ? ? 准确率:1.0
? ? ? ? ?
? ? ? ? ? github地址:Adam优化器实现鸢尾花分类
优化器 | 一阶动量 | 二阶动量? | 学习率 lr | 参数更新公式 | epoch多少次accuracy达到1.0 | epoch 500?次所需时间 |
---|---|---|---|---|---|---|
SGD | 0.1 | ? | 186 | 5.22 | ||
SGDM | 0.1 | ? | 102 | 5.40 | ||
Adagrad | 0.1 | ? | 64 | 5.27 | ||
RMSProp | 0.01 | ? | 65 | 5.48 | ||
Adam | 0.1 | 一阶动量修正项:? ? 二阶动量修正项: ? ? ? | 12 | 6.44 |
?