因此,我一直在尝试使用 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
但是,当我使用 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()
您会注意到,Keras 拟合版本中的值比使用 GradientTape 获得的值更接近实际值。此外,Gradient Tape 值最终对于不同的输入也没有太大变化,并且在平均值附近工作,而 Keras 则表现出更多的多样性。
那么如何使用 GradientTape 低级 API 来获得与 Keras 高级 API 相当的性能呢?Model.fit 所做的比我的实现要好得多的原因是什么?我尝试浏览源代码,但基本上无法确定它。
提前致谢。