Tensorflow Autoencoder ValueError:没有为任何变量提供梯度

时间:2021-06-24 21:44:22

标签: python tensorflow keras autoencoder

我正在尝试使用 tensorflow 创建一个自动编码器,用于分析大学项目的汽车数据集。但是,代码在开始训练时输出错误,我似乎无法找到解决方案。

首先,我尝试阅读 fit 函数的 tensorflow 文档,但没有提及此错误。 接下来,我尝试在 StackOverflow 上搜索类似的错误,但找不到任何相关的内容。

import os
import pathlib

import cv2
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import backend as K
from tensorflow.keras.layers import (Activation, BatchNormalization, Conv2D,
                                     Conv2DTranspose, Dense, Flatten, Input,
                                     LeakyReLU, Reshape)
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam

# Configuration
HEIGHT = 28
WIDTH = 32
NUM_CHANNELS = 3
BATCH_SIZE = 32
LATENT_SPACE_DIM = 20
EPOCHS = 25

AUTOTUNE = tf.data.experimental.AUTOTUNE

# Download dataset
dataset_url = "http://ai.stanford.edu/~jkrause/car196/car_ims.tgz"
data_dir = tf.keras.utils.get_file(origin=dataset_url,
                                   fname='car_ims',
                                   untar=True)
data_dir = pathlib.Path(data_dir)

normalization_layer = tf.keras.layers.experimental.preprocessing.Rescaling(1./255)

# Load dataset
dataset = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    labels=None,
    image_size=(WIDTH, HEIGHT),
    seed=123,
    validation_split=0.3,
    subset="training",
    smart_resize=True,
    batch_size=BATCH_SIZE)

dataset = dataset.map(normalization_layer)
dataset = dataset.cache()
dataset = dataset.prefetch(buffer_size=AUTOTUNE)

# Load testset
testset = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    labels=None,
    image_size=(WIDTH, HEIGHT),
    seed=123,
    validation_split=0.3,
    subset="validation",
    smart_resize=True,
    batch_size=BATCH_SIZE)

testset = testset.map(normalization_layer)
testset = testset.cache()
testset = testset.prefetch(buffer_size=AUTOTUNE)

# Encoder
inputs = Input(shape =(WIDTH, HEIGHT, NUM_CHANNELS))

x = Conv2D(32, (3, 3), strides=2, padding="same")(inputs)
x = LeakyReLU(alpha=0.2)(x)
x = BatchNormalization()(x)

x = Conv2D(64, (3, 3), strides=2, padding="same")(x)
x = LeakyReLU(alpha=0.2)(x)
x = BatchNormalization()(x)

volumeSize = K.int_shape(x)
x = Flatten()(x)

# Latent space
latent = Dense(LATENT_SPACE_DIM, name="latent")(x)

#decoder
latentInputs = Input(shape=(LATENT_SPACE_DIM,))
y = Dense(np.prod(volumeSize[1:]))(latentInputs)
y = Reshape((volumeSize[1], volumeSize[2], volumeSize[3]))(y)

y = Conv2DTranspose(64, (3, 3), strides=2, padding="same")(y)
y = LeakyReLU(alpha=0.2)(y)
y = BatchNormalization()(y)

y = Conv2DTranspose(32, (3, 3), strides=2, padding="same")(y)
y = LeakyReLU(alpha=0.2)(y)
y = BatchNormalization()(y)

y = Conv2DTranspose(NUM_CHANNELS, (3, 3), padding="same")(y)
outputs = Activation("sigmoid", name="decoded")(y)

encoder = Model(inputs, latent, name="encoder")
decoder = Model(latentInputs, outputs, name="decoder")
autoencoder = Model(inputs=inputs, outputs=decoder(encoder(inputs)))

encoder.summary()
decoder.summary()
autoencoder.summary()

# Prepare model
autoencoder.compile(loss="mse", optimizer=Adam(learning_rate=1e-3))

# train the convolutional autoencoder
history = autoencoder.fit(
    dataset,
    validation_data=testset,
    epochs=EPOCHS,
    batch_size=BATCH_SIZE)

有错误的输出部分:

Epoch 1/25
Traceback (most recent call last):
  File "/home/mightymime/repos/TA-2021/src/main.py", line 111, in <module>
    history = autoencoder.fit(
  File "/home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/keras/engine/training.py", line 1183, in fit
    tmp_logs = self.train_function(iterator)
  File "/home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/eager/def_function.py", line 889, in __call__
    result = self._call(*args, **kwds)
  File "/home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/eager/def_function.py", line 933, in _call
    self._initialize(args, kwds, add_initializers_to=initializers)
  File "/home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/eager/def_function.py", line 763, in _initialize
    self._stateful_fn._get_concrete_function_internal_garbage_collected(  # pylint: disable=protected-access
  File "/home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/eager/function.py", line 3050, in _get_concrete_function_internal_garbage_collected
    graph_function, _ = self._maybe_define_function(args, kwargs)
  File "/home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/eager/function.py", line 3444, in _maybe_define_function
    graph_function = self._create_graph_function(args, kwargs)
  File "/home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/eager/function.py", line 3279, in _create_graph_function
    func_graph_module.func_graph_from_py_func(
  File "/home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/framework/func_graph.py", line 999, in func_graph_from_py_func
    func_outputs = python_func(*func_args, **func_kwargs)
  File "/home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/eager/def_function.py", line 672, in wrapped_fn
    out = weak_wrapped_fn().__wrapped__(*args, **kwds)
  File "/home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/framework/func_graph.py", line 986, in wrapper
    raise e.ag_error_metadata.to_exception(e)
ValueError: in user code:

    /home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/keras/engine/training.py:855 train_function  *
        return step_function(self, iterator)
    /home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/keras/engine/training.py:845 step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    /home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/distribute/distribute_lib.py:1285 run
        return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
    /home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/distribute/distribute_lib.py:2833 call_for_each_replica
        return self._call_for_each_replica(fn, args, kwargs)
    /home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/distribute/distribute_lib.py:3608 _call_for_each_replica
        return fn(*args, **kwargs)
    /home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/keras/engine/training.py:838 run_step  **
        outputs = model.train_step(data)
    /home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/keras/engine/training.py:799 train_step
        self.optimizer.minimize(loss, self.trainable_variables, tape=tape)
    /home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py:530 minimize
        return self.apply_gradients(grads_and_vars, name=name)
    /home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py:630 apply_gradients
        grads_and_vars = optimizer_utils.filter_empty_gradients(grads_and_vars)
    /home/mightymime/.local/lib/python3.9/site-packages/tensorflow/python/keras/optimizer_v2/utils.py:75 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', 'batch_normalization/gamma:0', 'batch_normalization/beta:0', 'conv2d_1/kernel:0', 'conv2d_1/bias:0', 'batch_normalization_1/gamma:0', 'batch_normalization_1/beta:0', 'latent/kernel:0', 'latent/bias:0', 'dense/kernel:0', 'dense/bias:0', 'conv2d_transpose/kernel:0', 'conv2d_transpose/bias:0', 'batch_normalization_2/gamma:0', 'batch_normalization_2/beta:0', 'conv2d_transpose_1/kernel:0', 'conv2d_transpose_1/bias:0', 'batch_normalization_3/gamma:0', 'batch_normalization_3/beta:0', 'conv2d_transpose_2/kernel:0', 'conv2d_transpose_2/bias:0'].

谁能帮我调试一下?提前致谢

1 个答案:

答案 0 :(得分:0)

问题出在数据集加载上。显然,数据集是一种应该包含自动编码器的输入和预期输出(标签)的结构。但是,我加载的方式不包括标签。

把加载改成这样就解决了问题:

listset = tf.data.Dataset.list_files(str(data_dir / "*"))

def convert_path_to_image(file_path):
  # load the raw data from the file as a string
  img = tf.io.read_file(file_path)
  img = tf.image.decode_png(img, channels=3)
  img = tf.image.convert_image_dtype(img, tf.float32)
  img = tf.keras.preprocessing.image.smart_resize(img, [WIDTH,HEIGHT])
  return img, img

dataset = listset.map(convert_path_to_image, num_parallel_calls = AUTOTUNE)
dataset = dataset.cache()
dataset = dataset.batch(batch_size=BATCH_SIZE)
dataset = dataset.prefetch(buffer_size=AUTOTUNE)