1

因此,我一直在尝试使用 Keras 的 Model.fit() 和低级 TF GradientTape 来优化神经网络的可训练参数,并注意到 Keras 版本明显更好。

最终 MSE 为的 Keras 优化版本的代码:

from tensorflow import keras
import tensorflow as tf

from sklearn.datasets import load_boston
X,y = load_boston(return_X_y=True)
X_tf = tf.cast(X, dtype=tf.float32)


model = keras.Sequential()
model.add(keras.layers.Dense(100, activation = 'relu', input_shape = (13,)), )
model.add(keras.layers.Dense(100, activation = 'relu'))
model.add(keras.layers.Dense(100, activation = 'relu'))
model.add(keras.layers.Dense(1, activation = 'linear'))

model.compile(optimizer = tf.keras.optimizers.Adam(0.01),
             loss = tf.keras.losses.MSE
             )

model.fit(X, y, epochs=1000)enter code here

这给出了图表:Keras 拟合与实际值的偏差

但是,当我使用 tf.GradientTape 优化 Keras 模型时,如下代码所示:

    from tensorflow import keras
    import tensorflow as tf
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt

    from sklearn.datasets import load_boston
    X,y = load_boston(return_X_y=True)
    X_tf = tf.cast(X, dtype=tf.float32)



    model = keras.Sequential()
    model.add(keras.layers.Dense(100, activation = 'relu', input_shape = (np.shape(X)[1],)), 
     )
    model.add(keras.layers.Dense(100, activation = 'relu'))
    model.add(keras.layers.Dense(100, activation = 'relu'))
    model.add(keras.layers.Dense(1, activation = 'linear'))

    optimizer = tf.keras.optimizers.Adam(learning_rate = 0.01)

    def loss_func(pred, target):
        return tf.reduce_mean(tf.square(pred - target))

    trainable_params = model.trainable_variables

     def train_step():
         with tf.GradientTape() as tape:
             y_tild = model(X_tf)
             loss = loss_func(y_tild, y)
     grads = tape.gradient(loss, trainable_params)
     optimizer.apply_gradients(zip(grads, trainable_params))
     print("Loss : " + str(loss.numpy()))

     epochs = 1000

     for ii in range(epochs):
        train_step()

并获得下图的偏差值。GradeintTape fit 的偏差值

您会注意到,Keras 拟合版本中的值比使用 GradientTape 获得的值更接近实际值。此外,Gradient Tape 值最终对于不同的输入也没有太大变化,并且在平均值附近工作,而 Keras 则表现出更多的多样性。

那么如何使用 GradientTape 低级 API 来获得与 Keras 高级 API 相当的性能呢?Model.fit 所做的比我的实现要好得多的原因是什么?我尝试浏览源代码,但基本上无法确定它。

提前致谢。

4

0 回答 0