簡體   English   中英

調試 tensorflow 適配沒有意義

[英]Debugging tensorflow fit not making sense

因此,我使用自行實現的代碼和 Tensorflow 結果得到了不同的結果。 我想測試每個值,看看我的錯誤在哪里(損失、梯度、優化器等)。

因此,我做了一個測試代碼,就像這個 repo中受時尚 mnist 示例啟發的代碼一樣。 為簡單起見,我將在問題末尾復制粘貼它。

邏輯:

基本上,我在 1 個批次上做 1 個 epoch。 然后保存:

  1. 訓練前的體重
  2. 漸變
  3. 僅在一個時期和批次之后的權重。

因為我使用默認的 SGD TensorFlow 算法,所以保存的梯度應該等於(initial_weights - final_weights)/0.01 這個想法是從這里得到的。

但是,這不會發生,更重要的是,如果我除以 0.0001 而不是 0.01 (奇怪的是 0.01^2),結果會更接近。

我的邏輯有錯誤嗎? 測試代碼? 我找不到它了。

PS:我嘗試在 Linux 上使用 tf 版本 2.2.0 和 2.4.1。


import tensorflow as tf
import numpy as np
from pdb import set_trace


def get_dataset():
    fashion_mnist = tf.keras.datasets.fashion_mnist
    (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
    return (train_images, train_labels), (test_images, test_labels)


def get_model(init1='glorot_uniform', init2='glorot_uniform'):
    tf.random.set_seed(1)
    model = tf.keras.Sequential([
        tf.keras.layers.Flatten(input_shape=(28, 28)),
        tf.keras.layers.Dense(128, activation='relu', kernel_initializer=init1),
        tf.keras.layers.Dense(10, kernel_initializer=init2)
    ])
    model.compile(optimizer='sgd',
                  loss=tf.keras.losses.CategoricalCrossentropy(from_logits=False),
                  metrics=['accuracy'])
    return model


def train(model, x_fit, y_fit):
    np.save("initial_weights.npy", np.array(model.get_weights()))
    with tf.GradientTape() as g:
        y_pred = model(x_fit)
        loss = tf.keras.losses.categorical_crossentropy(y_pred=y_pred, y_true=y_fit)
        np.save("loss.npy", np.array(loss))
        gradients = g.gradient(loss, model.trainable_weights)
    np.save("gradients.npy", np.array(gradients))
    model.fit(x_fit, y_fit, epochs=1, batch_size=100)
    np.save("final_weights.npy", np.array(model.get_weights()))


if __name__ == "__main__":
    (train_images, train_labels), (test_images, test_labels) = get_dataset()
    model = get_model()
    y_fit = np.zeros((100, 10))
    for i, val in enumerate(train_labels[:100]):
        y_fit[i][val] = 1.
    train(model, train_images[:100], y_fit)
    results = {
        "loss": np.load("loss.npy", allow_pickle=True),
        "init_weights": np.load("initial_weights.npy", allow_pickle=True),
        "gradients": np.load("gradients.npy", allow_pickle=True),
        "final_weights": np.load("final_weights.npy", allow_pickle=True)
    }
    for i_w, f_w, gr in zip(results["init_weights"], results["final_weights"], results["gradients"]):
        gr = gr.numpy()
        print(np.allclose(gr, (i_w - f_w) / 0.01))
    # set_trace()

看起來對fit的調用是對批量大小的梯度進行平均。 我不知道這是否是設計的錯誤。

當你手動計算梯度時,你可以調用model.optimizer.apply_gradients來更新你的權重,你應該得到正確的結果。

def train(model, x_fit, y_fit):
    np.save("initial_weights.npy", np.array(model.get_weights()))
    with tf.GradientTape() as g:
        y_pred = model(x_fit)
        loss = tf.keras.losses.categorical_crossentropy(y_pred=y_pred, y_true=y_fit)
        np.save("loss.npy", np.array(loss))
        gradients = g.gradient(loss, model.trainable_weights)
    np.save("gradients.npy", np.array(gradients))
    model.optimizer.apply_gradients(zip(gradients,  model.trainable_weights))
    np.save("final_weights.npy", np.array(model.get_weights()))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM