Насколько отличается model.fit от использования явного GradientTape для переменных model.trainable? - PullRequest
0 голосов
/ 20 февраля 2020

Итак, я экспериментировал как с Keras Model.fit (), так и с низкоуровневой TF GradientTape для оптимизации обучаемых параметров нейронной сети и заметил, что версия Keras значительно лучше.

Код для оптимизированной версии Keras, где конечная MSE:

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 Fit Deviation from Actual Values

Однако, когда Я оптимизирую модель Keras с помощью tf.GradientTape, как показано в следующем коде:

    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()

, и получаю следующий график для значений отклонения. Deviation Values for GradeintTape fit

Вы можете заметить, что значения в версии подгонки Keras ближе к фактическим значениям, чем значения, полученные с помощью GradientTape. Кроме того, значения Gradient Tape также не сильно различались для разных входных данных и работали вокруг среднего значения, в то время как Keras одно демонстрировало гораздо большее разнообразие.

Так как же использовать API низкого уровня GradientTape, чтобы иметь сопоставимые характеристики с API высокого уровня Keras? Что делает Model.fit, так сильно превосходит мою реализацию? Я пытался пройтись по исходному коду и не мог по сути его закрепить.

Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...