gpt4 book ai didi

tensorflow - Tensorflow 2 "InaccessibleTensorError"中的错误子类化模型

转载 作者:行者123 更新时间:2023-12-04 15:10:11 25 4
gpt4 key购买 nike

背景
我的问题基于 Geron 的 Hands-On Machine Learning 第 12 章:自定义模型中的一个示例。
此示例的目的是创建自定义神经网络模型。该型号有 5 Dense隐藏层。自定义部分是我们添加了 reconstruction输出之前的图层。重建层的目的是重建输入。然后我们取差值reconstruction-inputs ,得到 MSE,并将这个值应用到损失函数上。这应该是一个正则化步骤。
最小(应该是)工作示例
以下代码几乎直接来自教科书,但不起作用。

import numpy as np

num_training=10;
num_dim=2;

X = np.random.random((10,2))
y = np.random.random(10)

import tensorflow as tf
import tensorflow.keras as keras

class ReconstructingRegressor(keras.models.Model):
def __init__(self, output_dim, **kwargs):
super().__init__(**kwargs)
self.hidden = [keras.layers.Dense(30, activation="selu",
kernel_initializer="lecun_normal")
for _ in range(5)]
self.out = keras.layers.Dense(output_dim)

def build(self, batch_input_shape):
n_inputs = batch_input_shape[-1]
self.reconstruct = keras.layers.Dense(n_inputs)
super().build(batch_input_shape)

def call(self, inputs, training=None):
Z = inputs
for layer in self.hidden:
Z = layer(Z)
reconstruction = self.reconstruct(Z)
recon_loss = tf.reduce_mean(tf.square(reconstruction - inputs))
self.add_loss(0.05 * recon_loss)
return self.out(Z)

model = ReconstructingRegressor(1)
model.compile(loss="mse", optimizer="nadam")
history = model.fit(X, y, epochs=2)
错误信息
但是,在调用 model.fit() 时出现以下错误:
---------------------------------------------------------------------------
InaccessibleTensorError Traceback (most recent call last)
<ipython-input-10-b7211d3022fa> in <module>
34 model = ReconstructingRegressor(1)
35 model.compile(loss="mse", optimizer="nadam")
---> 36 history = model.fit(X, y, epochs=2)
并且,在错误消息的末尾:

InaccessibleTensorError: The tensor 'Tensor("mul:0", shape=(), dtype=float32)' cannot be accessed here: it is defined in another function or code block. Use return values, explicit Python locals or TensorFlow collections to access it. Defined in: FuncGraph(name=build_graph, id=140602287140624); accessed from: FuncGraph(name=train_function, id=140602287108640).


故障排除
如果我注释掉计算损失的代码,即
        #recon_loss = tf.reduce_mean(tf.square(reconstruction - inputs))
#self.add_loss(0.05 * recon_loss)
call ,但我保持其他一切不变,然后我收到以下警告

WARNING:tensorflow:Gradients do not exist for variables ['dense/kernel:0', 'dense/bias:0'] when minimizing the loss.


不确定这是否相关。

最佳答案

我不是 100% 确定,但我相信问题是由于您通过 self.add_loss 添加的损失造成的。指的是在计算主损失期间未使用的层,并且可能在主图中进行了优化。因此,当您想访问它们时,张量是不可访问的。
我认为最简单的方法是稍微不同地重写网络:

  • 使用 training parameter of model.call 仅在训练期间使用重建层。
  • 覆盖 model.train_step仍然可以使用 fit . (参见指南:Customize what happens in Model.fit)。

  • 使用 training model.call 的论据,我们设置为使用 reconstruct层仅在训练期间,我们使网络返回机器人预测和重建。然而,当我们想要进行预测时,我们只返回预测。
    覆盖 train_step只是在这里仍然可以使用 fit ,而不必从头开始编写训练循环。我们不需要覆盖 test_step在那种情况下,因为用例如果相当简单。
    import tensorflow as tf
    import tensorflow.keras as keras
    import numpy as np

    num_training = 10
    num_dim = 2

    X = np.random.random((10, 2)).astype(np.float32)
    y = np.random.random((10,)).astype(np.float32)


    class ReconstructingRegressor(keras.models.Model):
    def __init__(self, output_dim, **kwargs):
    super().__init__(**kwargs)
    self.hidden = [
    keras.layers.Dense(
    30,
    activation="selu",
    kernel_initializer="lecun_normal",
    name=f"hidden_{idx}",
    )
    for idx in range(5)
    ]
    self.out = keras.layers.Dense(output_dim, name="output")

    def build(self, batch_input_shape):
    n_inputs = batch_input_shape[-1]
    self.reconstruct = keras.layers.Dense(n_inputs, name="reconstruct")
    super().build(batch_input_shape)

    @staticmethod
    def reconstruction_loss(reconstruction, inputs, rate=0.05):
    return tf.reduce_mean(tf.square(reconstruction - inputs)) * rate

    def train_step(self, data):
    x, y = data
    with tf.GradientTape() as tape:
    y_pred, recon = self(x, training=True)
    loss = self.compiled_loss(y, y_pred)
    loss += self.reconstruction_loss(recon, x)
    gradients = tape.gradient(loss, self.trainable_variables)

    # Update weights
    self.optimizer.apply_gradients(zip(gradients, self.trainable_variables))

    # Update metrics (includes the metric that tracks the loss)
    self.compiled_metrics.update_state(y, y_pred)
    # Return a dict mapping metric names to current value
    return {m.name: m.result() for m in self.metrics}

    def call(self, inputs, training=None):
    Z = inputs
    for layer in self.hidden:
    Z = layer(Z)
    if training:
    return self.out(Z), self.reconstruct(Z)

    return self.out(Z)


    model = ReconstructingRegressor(1)

    model.compile(optimizer="nadam", loss="mse")
    history = model.fit(X, y, epochs=10)
    history = model.evaluate(X, y)

    关于tensorflow - Tensorflow 2 "InaccessibleTensorError"中的错误子类化模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65334652/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com