嵌套模型时 Keras Tensorflow 不提供梯度

No Gradients Provided Keras Tensorflow when nesting Models

我开始使用 Keras 一点点,但我 运行 遇到了这个问题,它告诉我没有提供渐变。我知道这个问题之前发布了 100 次,但解决方案总是在谈论使用 GradientTape 但我不明白为什么我应该这样做(而且我什至不明白它的作用)


import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt

physical_devices = tf.config.list_physical_devices('GPU')
tf.config.experimental.set_memory_growth(physical_devices[0], True)

class AutoEncoder:

    def create_encoder(self):
        encoder_input = keras.Input(shape=self.input_shape, name="original_img")
        encoder_output = layers.Conv2D(3, 3, activation="relu")(encoder_input)
        encoder = keras.Model(encoder_input, encoder_output)
        return encoder_input, encoder_output, encoder

    def create_decoder(self, eager_execution=False):
        decoder_input = keras.Input(shape=self.encoder_output.type_spec.shape[1:], batch_size=self.batch_size, name="encoded_img")
        decoder_output = layers.Conv2DTranspose(3, 3, activation="relu")(decoder_input)
        decoder = keras.Model(decoder_input, decoder_output)
        return decoder_input, decoder_output, decoder


    def create_autoencoder(self):
        auto_input = keras.Input(shape=self.input_shape, batch_size=self.batch_size, name="AutoEncoder Input")
        encoded = self.encoder(auto_input)
        auto_output = self.decoder(encoded)
        autoencoder = keras.Model(auto_input, auto_output, name="AutoEncoder")
        return auto_input, auto_output, autoencoder

    def __init__(self, input_shape=(256, 256, 3), batch_size=32, eager_execution=False):
        self.input_shape = input_shape
        self.batch_size = batch_size
        self.encoder_input, self.encoder_output, self.encoder = self.create_encoder()
        self.decoder_input, self.decoder_output, self.decoder = self.create_decoder()
        self.autoencoder_input, self.autoencoder_output, self.autoencoder = self.create_autoencoder()
        self.__call__ = self.autoencoder.predict
        self.fit = self.autoencoder.fit
        self.fit_generator = self.autoencoder.fit_generator

        # Compiling models

        self.autoencoder.compile(
            optimizer=keras.optimizers.Adagrad(),
            loss=keras.losses.SparseCategoricalCrossentropy(),
            metrics=keras.metrics.Accuracy(),
            run_eagerly=True,
        )


autoenc = AutoEncoder()
autoenc.autoencoder.fit(train_x)

对于培训,我使用了 Microsoft 的一些数据集和 PetImages。但这应该无关紧要。

我已经尝试重新排列所有内容,但每次调用模型然后使用该模型的输出创建另一个模型时都会弹出错误。

Traceback (most recent call last):
  File "/home/user/PycharmProjects/pythonProject1/main.py", line 148, in <module>
    autoenc.autoencoder.fit(train_x)
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 1100, in fit
    tmp_logs = self.train_function(iterator)
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 805, in train_function
    return step_function(self, iterator)
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 795, in step_function
    outputs = model.distribute_strategy.run(run_step, args=(data,))
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py", line 1259, in run
    return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py", line 2730, in call_for_each_replica
    return self._call_for_each_replica(fn, args, kwargs)
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/distribute/distribute_lib.py", line 3417, in _call_for_each_replica
    return fn(*args, **kwargs)
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/autograph/impl/api.py", line 572, in wrapper
    return func(*args, **kwargs)
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 788, in run_step
    outputs = model.train_step(data)
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py", line 757, in train_step
    self.optimizer.minimize(loss, self.trainable_variables, tape=tape)
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py", line 498, in minimize
    return self.apply_gradients(grads_and_vars, name=name)
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py", line 598, in apply_gradients
    grads_and_vars = optimizer_utils.filter_empty_gradients(grads_and_vars)
  File "/home/user/miniconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/keras/optimizer_v2/utils.py", line 78, in filter_empty_gradients
    raise ValueError("No gradients provided for any variable: %s." %
ValueError: No gradients provided for any variable: ['conv2d/kernel:0', 'conv2d/bias:0', 'conv2d_transpose/kernel:0', 'conv2d_transpose/bias:0'].

Process finished with exit code 1

所有版本

# Name                    Version                   Build  Channel
tensorflow                2.2.0           gpu_py38hb782248_0  
tensorflow-base           2.2.0           gpu_py38h83e3d50_0  
tensorflow-datasets       4.1.0                    pypi_0    pypi
tensorflow-estimator      2.4.0                    pypi_0    pypi
tensorflow-gpu            2.4.0                    pypi_0    pypi
tensorflow-metadata       0.26.0                   pypi_0    pypi
tensorflow-probability    0.12.0                   pypi_0    pypi
tensorflow-serving-api    2.3.0                    pypi_0    pypi

System 
    Archlinux 
    linux-5.10.3.arch1-1
    cuda-11.2.0-2
    cudnn-8.0.5.39-1

我希望有人知道我应该改变什么才能让它发挥作用。

此致, 潜水员先生

我修复了你的代码。当您遇到该错误时,您的损失函数和可训练变量之间的图表中没有路径,这在您的情况下是正确的。

  1. 您没有用于训练自动编码器的标签。我添加了 train_x 作为你的标签。
  2. 我认为 SparseCategoricalCrossentropy 不适用于您定义的架构。所以,我将其更改为 BinaryCrossEntropy
  3. 给向量命名时,不允许有空格,所以我将“AutoEncoder Input”改为“AutoEncoder_Input”

这是代码

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt
from tensorflow.keras.preprocessing.image import ImageDataGenerator

#physical_devices = tf.config.list_physical_devices('GPU')
#tf.config.experimental.set_memory_growth(physical_devices[0], True)

class AutoEncoder:

    def create_encoder(self):
        encoder_input = keras.Input(shape=self.input_shape, name="original_img")
        encoder_output = layers.Conv2D(3, 3, activation="relu")(encoder_input)
        encoder = keras.Model(encoder_input, encoder_output)
        return encoder_input, encoder_output, encoder

    def create_decoder(self, eager_execution=False):
        decoder_input = keras.Input(shape=self.encoder_output.shape[1:], batch_size=self.batch_size, name="encoded_img")
        decoder_output = layers.Conv2DTranspose(3, 3, activation="relu")(decoder_input)
        decoder = keras.Model(decoder_input, decoder_output)
        return decoder_input, decoder_output, decoder


    def create_autoencoder(self):
        auto_input = keras.Input(shape=self.input_shape, batch_size=self.batch_size, name="AutoEncoder_Input")
        encoded = self.encoder(auto_input)
        auto_output = self.decoder(encoded)
        autoencoder = keras.Model(auto_input, auto_output, name="AutoEncoder")
        return auto_input, auto_output, autoencoder

    def __init__(self, input_shape=(256, 256, 3), batch_size=32, eager_execution=False):
        self.input_shape = input_shape
        self.batch_size = batch_size
        self.encoder_input, self.encoder_output, self.encoder = self.create_encoder()
        self.decoder_input, self.decoder_output, self.decoder = self.create_decoder()
        self.autoencoder_input, self.autoencoder_output, self.autoencoder = self.create_autoencoder()
        self.__call__ = self.autoencoder.predict
        self.fit = self.autoencoder.fit
        self.fit_generator = self.autoencoder.fit_generator

        # Compiling models

        self.autoencoder.compile(
            optimizer=keras.optimizers.Adagrad(),
            loss=keras.losses.BinaryCrossentropy(),
            metrics=keras.metrics.Accuracy(),
            run_eagerly=True,
        )
        



train_x = tf.random.normal(shape=(100,256,256,3),dtype=tf.float32)
autoenc = AutoEncoder()
print(autoenc.autoencoder.summary())
autoenc.autoencoder.fit(train_x,train_x)