欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

神经网络 优化器

程序员文章站 2022-06-27 10:33:39
...

前言

从这篇文章开始,分析神经网络的优化器以及其在keras框架中的实现。在前面讲过,神经网络的编写分成:准备数据、搭建网络结构、配置算法参数这几步,其中配置算法参数是关键的一步,而optimizer的配置是其中的重中之重。 神经网络的本质目的就是寻找合适的参数,使得损失函数的值尽可能小,该过程为称为最优化。解决这个问题的算法称为优化器。

理论模型

梯度下降法更新参数是常用的手段,举一个很简单的例子作为说明。

  • 现有三组训练数据(x,y^)(x,\hat{y})如下:
(0,1)
(1,2)
(2,3)
  • 构建神经网络为 y=ax+by = ax + b

  • 计算损失函数 loss(L)=12(yy^)2=12(ax+by^)2=12(b1)2+12(a+b2)2+12(2a+b3)2loss(L) = \frac{1}{2}\sum(y - \hat{y})^2 = \frac{1}{2}\sum(ax + b - \hat{y})^2 = \frac{1}{2}(b - 1)^2 + \frac{1}{2}(a + b - 2)^2 + \frac{1}{2}(2a+b-3)^2

  • 计算偏导数(梯度)

    • La=x(ax+by^)\frac{\partial{L}}{\partial{a}} = \sum x(ax + b - \hat{y})
    • Lb=(ax+by^)\frac{\partial{L}}{\partial{b}} = \sum (ax + b - \hat{y})
  • 更新参数

    • aaαLaa \gets a - \alpha * \frac{\partial{L}}{\partial{a}}
    • bbαLbb \gets b - \alpha * \frac{\partial{L}}{\partial{b}}

a,ba,b初始化为2,运行结果如下所示:

1.2 1.4
0.98 1.22
0.924 1.16
0.914 1.1348
0.9166 1.1202
0.9222 1.1091
0.9284 1.0997

source code:

global a,b,alpha
a = 2;b = 2;alpha = 0.1;train = [[0,1],[1,2],[2,3]]
def update():
    global a,b,alpha
    delta_a = 0;delta_b = 0
    for tmp in train:
        x = tmp[0];y = tmp[1]
        delta_a += x * (a * x + b - y);delta_b += (a * x + b - y)
    a = a - alpha * delta_a;b = b - alpha * delta_b
    return
while (a - 1) > 0.1 or (b - 1) > 0.1:
    update()
    print(round(a,4),round(b,4))

keras接口

基本optimizer

在调用compile函数时,在函数的参数中给定优化器,可以通过实例化的方法,也可以通过字符串声明。

# 实例化
opt = keras.optimizers.Adam(learning_rate=0.01)
model.compile(loss='categorical_crossentropy', optimizer=opt)
# 字符串声明
model.compile(loss='categorical_crossentropy', optimizer='adam')

自定义层

在新版本的keras中可以调用apply_gradients()函数,通过将gradients,model作为传入参数更新参数,官网给出的代码如下所示。

optimizer = tf.keras.optimizers.Adam()

# Iterate over the batches of a dataset.
for x, y in dataset:
    # Open a GradientTape.
    with tf.GradientTape() as tape:
        # Forward pass.
        logits = model(x)
        # Loss value for this batch.
        loss_value = loss_fn(y, logits)

    # Get gradients of loss wrt the weights.
    gradients = tape.gradient(loss_value, model.trainable_weights)

    # Update the weights of the model.
    optimizer.apply_gradients(zip(gradients, model.trainable_weights))

Learning rate decay / scheduling

通过这个接口,可以设定学习率随着时间变化,不过回调函数也可以做到这一点,后面会分析。

欢迎关注公众号BBIT
让我们共同学习共同进步!

神经网络 优化器