【问题标题】:How to train a convolutional autoencoder in tensorflow 2.0?如何在 tensorflow 2.0 中训练卷积自动编码器?
【发布时间】:2021-10-06 20:53:56
【问题描述】:

我在tensorflow2(见下文)中创建了以下卷积自动编码器:

import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras import layers

image_height=480
image_width=640

class Autoencoder(Model):
  def __init__(self):
    super(Autoencoder, self).__init__()
    self.encoder = tf.keras.Sequential([
        layers.InputLayer(input_shape=(image_height, image_width, 1), name="layer1"),
        layers.Conv2D(16, (3, 3), activation='relu', name="layer2"),
        layers.MaxPooling2D(pool_size=(2, 2), name="layer3"),
        layers.Conv2D(8, (3, 3), activation='relu', name="layer4"),
        layers.MaxPooling2D(pool_size=(2, 2), name="layer5"),
        layers.Conv2D(8, (3, 3), activation='relu', name="layer6"),
        layers.MaxPooling2D(pool_size=(2, 2), name="layer7"),
        layers.Conv2D(8, (3, 3), activation='relu', name="layer8"),
        layers.MaxPooling2D(pool_size=(2, 2), name="layer9"),
        layers.Conv2D(8, (3, 3), activation='relu', name="layer10"),
        layers.MaxPooling2D(pool_size=(2, 2), name="layer11"),
        layers.Conv2D(8, (3, 3), activation='relu', name="layer12")
    ])
    self.decoder = tf.keras.Sequential([
        layers.UpSampling2D(size=(2,2), name="layer13"),
        layers.Conv2D(8, (3, 3), activation='relu', name="layer14"),
        layers.UpSampling2D(size=(2,2), name="layer15"),
        layers.Conv2D(8, (3, 3), activation='relu', name="layer16"),
        layers.UpSampling2D(size=(2,2), name="layer17"),
        layers.Conv2D(8, (3, 3), activation='relu', name="layer18"),
        layers.UpSampling2D(size=(2,2), name="layer19"),
        layers.Conv2D(16, (3, 3), activation='relu', name="layer20"),
        layers.UpSampling2D(size=(2,2), name="layer21"),
        layers.Conv2D(1, (3, 3), activation='relu', name="layer22")
    ])
    self._model = Model()

  def call(self, x):
    encoded = self.encoder(x)
    decoded = self.decoder(encoded)
    return decoded

我还将图像数据划分为两个单独的数据集:

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
        'path/to/imagedir',
        validation_split=0.2,
        label_mode=None,
        subset="training", 
        seed=123,
        image_size=(image_height,image_width),
        color_mode="grayscale"
    )
    val_ds = tf.keras.preprocessing.image_dataset_from_directory(
        'path/to/imagedir',
        validation_split=0.2,
        label_mode=None,
        subset="validation",
        seed=123,
        image_size=(image_height,image_width),
        color_mode="grayscale"
    )

创建自动编码器并编译后:

autoencoder = Autoencoder()
autoencoder.compile(loss='binary_crossentropy')

我想训练它:

autoencoder.fit(train_ds, train_ds, epochs=10, validation_data=(val_ds,val_ds))

很遗憾,我收到以下错误:

raise ValueError("`y` argument is not supported when using "
ValueError: `y` argument is not supported when using dataset as input.

问题是当 x 参数也是一个数据集时,拟合函数无法接收作为 y 参数的数据集。我也无法将图像保存为张量列表,因为我的数据集太大。

【问题讨论】:

    标签: tensorflow conv-neural-network tensorflow-datasets autoencoder


    【解决方案1】:

    很抱歉创建答案而不是评论,我没有足够的声誉。

    尝试构建您自己的自定义 train()train_step() 函数,就像在 Tensorflow 教程中一样:https://www.tensorflow.org/tutorials/generative/cvae

    【讨论】:

    • 不幸的是,我还尝试为我的班级构建自定义函数train()train_step(),但没有任何令人满意的结果。
    【解决方案2】:

    我现在已将以下代码添加到我的模型中:

    def train_step(self, data):
        # Unpack the data. Its structure depends on your model and
        # on what you pass to `fit()`.
        x = data
    
        with tf.GradientTape() as tape:
          y_pred = self(x, training=True)  # Forward pass
          # Compute the loss value
          # (the loss function is configured in `compile()`)
          loss = self.compiled_loss(x, y_pred, regularization_losses=self.losses)
    
        # Compute gradients
        trainable_vars = self.trainable_variables
        gradients = tape.gradient(loss, trainable_vars)
        # Update weights
        self.optimizer.apply_gradients(zip(gradients, trainable_vars))
        # Update metrics (includes the metric that tracks the loss)
        self.compiled_metrics.update_state(x, y_pred)
        # Return a dict mapping metric names to current value
        return {m.name: m.result() for m in self.metrics}
    

    现在在fit中使用它:

    autoencoder.fit(train_ds, epochs=10)
    

    我现在收到以下错误:

    ValueError: Dimensions must be equal, but are 480 and 290 for '{{node binary_crossentropy/mul}} = Mul[T=DT_FLOAT](IteratorGetNext, binary_crossentropy/Log)' with input shapes: [?,480,640,1], [?,290,450,1].
    

    我该如何解决这个问题?

    【讨论】:

      猜你喜欢
      • 2018-11-12
      • 1970-01-01
      • 2019-12-24
      • 1970-01-01
      • 1970-01-01
      • 2021-07-10
      • 2020-08-20
      • 1970-01-01
      • 2020-12-07
      相关资源
      最近更新 更多