首页 > 解决方案 > Tensorflow Autoencoder ValueError:没有为任何变量提供梯度

问题描述

我正在尝试使用 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'].

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

标签: pythontensorflowkerasautoencoder

解决方案


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

将加载更改为这样解决了问题:

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)

推荐阅读