嵌套模型时没有梯度提供Keras Tensorflow



我开始使用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)

对于培训,我使用了一些来自微软的数据集和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

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

谨致问候,MrDiver

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

  1. 你没有标签来训练你的自动编码器。我添加了train_x作为你的标签
  2. 我不认为稀疏类别交叉熵适用于您定义的架构。所以,我把它改为二进制交叉熵
  3. 当你给一个向量指定一个名称时,空格是不允许的,所以我更改了";自动编码器输入";至";自动编码器输入

这是代码

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)

最新更新