Toccata in Nowhere.

Tensorflow/Karas 的梯度带 GradientTape

2020.12.04

借助于 Keras,我们可以容易地构建神经网络结构,而 tf.GradientTape提供了一种同样简单的方法用以计算各个层间的梯度改变(gradient changes);本文将介绍在 Keras 手动使用 GradientTape 梯度带。

添加 / 初始化 Keras.Layer

一个简单的 Keras 序列可以是:

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(
            input_dim=1,
            units=1,
            activation='linear',
            kernel_initializer=tf.zeros_initializer(),
            bias_initializer=tf.zeros_initializer(),
)

也可以使用 TF2.0 时代的写法:

inputs = layers.Input(shape=(shape_x, shape_y, shape_channel), name='inputs')
outputs = layers.Dense(128, activation='relu')(inputs)
moodel = keras.Model(inputs, outputs)

定义误差函数

使用MSE作为Loss函数:

 def loss(predicted_y, desired_y):
    return tf.reduce_sum(tf.square(predicted_y - desired_y)) / len(predicted_y)

显然,这里解决的是一个线性回归问题。

定义训练函数

 def train(model, inputs, outputs, learning_rate):
    optimizer = tf.keras.optimizers.SGD(learning_rate=learning_rate)
    with tf.GradientTape() as t:
        current_loss = loss(model(inputs), outputs)
        # out_pred = model(inputs)
        # current_loss = tf.reduce_mean(tf.square(outputs - out_pred))
    gradient_Collection = t.gradient(target=current_loss, sources=model.variables)
    optimizer.apply_gradients(zip(gradient_Collection, model.variables))
    return current_loss

训练函数可以通过输入得到网络的输出值,并通过 tf.GradientTape给定的方法计算并更新网络。 训练函数也同时使用SGD训练策略。

训练模型

定义好训练函数之后就可以调用函数进行训练啦,不同于 model.fit 方法,train方法对输入和输出给定了更强的灵活性,同时也贴近神经网络的训练原理。model.fit则更为简单上手。

 for epoch in epoch_time:
    current_loss = train(model, inputs, outputs, learning_rate=0.05)
    print(current_loss)