【问题标题】:tf.keras convolutional architecture isn't workingtf.keras 卷积架构不起作用
【发布时间】:2020-04-16 21:54:45
【问题描述】:

以下问题是我在设计一个基本的自动编码器拱门时遇到的一个实际问题的简化版。 以下示例足以准确重现我遇到的错误。 我已经尝试了大约两天了,但我找不到任何办法。

import tensorflow as tf
import random
import os

RES = [256, 256]
def generator_data(n):
    for i in range(n):
        for j in range(6):
            yield tf.zeros((1, 256, 256, 3)), tf.zeros((1, 256, 256, 3))

def mymodel():
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Conv2D(8, (3, 3), activation='relu', padding='same'))
    # 256 x 256 x 8
    model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
    # 128 x 128 x 8
    model.add(tf.keras.layers.Conv2D(16, (3, 3), activation='relu', padding='same'))
    # 128 x 128 x 16
    model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
    # 64 x 64 x 16
    model.add(tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same'))
    # 64 x 64 x 32
    model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
    # 32 x 32 x 32

    # 32 x 32 x 32
    model.add(tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same'))
    # 32 x 32 x 32
    model.add(tf.keras.layers.UpSampling2D((2, 2)))
    # 64 x 64 x 32
    model.add(tf.keras.layers.Conv2D(16, (3, 3), activation='relu', padding='same'))
    # 64 x 64 x 16
    model.add(tf.keras.layers.UpSampling2D((2, 2)))
    # 128 x 128 x 16
    model.add(tf.keras.layers.Conv2D(8, (3, 3), activation='relu', padding='same'))
    # 128 x 128 x 8
    model.add(tf.keras.layers.UpSampling2D((2, 2)))
    # 256 x 256 x 8
    model.add(tf.keras.layers.Conv2D(1, (3, 3), activation='sigmoid', padding='same'))
    return model


if __name__ == "__main__":
    # import some data to play with
    x_val, y_val = zip(*generator_data(20))

    model = mymodel()
    optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
    model.compile(optimizer=optimizer, loss=tf.keras.losses.MeanSquaredError())
    model(tf.zeros((1, 256, 256, 3)))
    model.summary()

    # generator_data(train_list)
    model.fit(x=generator_data(1000),
        validation_data=(list(x_val), list(y_val)),
        verbose=1, epochs=1000)

首先我有一个 model.summary() 的奇怪行为,它包含:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d (Conv2D)              multiple                  224
_________________________________________________________________
max_pooling2d (MaxPooling2D) multiple                  0
_________________________________________________________________
conv2d_1 (Conv2D)            multiple                  1168
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 multiple                  0
_________________________________________________________________
conv2d_2 (Conv2D)            multiple                  4640
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 multiple                  0
_________________________________________________________________
conv2d_3 (Conv2D)            multiple                  9248
_________________________________________________________________
up_sampling2d (UpSampling2D) multiple                  0
_________________________________________________________________
conv2d_4 (Conv2D)            multiple                  4624
_________________________________________________________________
up_sampling2d_1 (UpSampling2 multiple                  0
_________________________________________________________________
conv2d_5 (Conv2D)            multiple                  1160
_________________________________________________________________
up_sampling2d_2 (UpSampling2 multiple                  0
_________________________________________________________________
conv2d_6 (Conv2D)            multiple                  73
=================================================================
Total params: 21,137
Trainable params: 21,137
Non-trainable params: 0

输出形状只有多个。 我已经查看了here,但解决方法似乎不起作用。 但其次,更重要的是我得到了错误:

ValueError: Error when checking model input: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 1 array(s), for inputs ['input_1'] but instead got the following list of 120 arrays: [<tf.Tensor: shape=(1, 256, 256, 3), dtype=float32, numpy=
array([[[[0., 0., 0.],
         [0., 0., 0.],
         [0., 0., 0.],
         ...,
         [0., 0., 0.],
         [0., 0., 0.],
         [0....

对于我的不理解,这根本没有意义。我的生成器返回[batch, x-dim, y-dim, channel](我也尝试过[batch, channel, x-dim, y-dim],但也没有运气)。在这种情况下,批次等于 1 而不是 120。 正如我所说,无论如何我都无法解决/调试这些问题,所以我非常感谢您的帮助。 我对 DL 很陌生,但不是在 python 中,我在 python-3.7 中使用 Tensorflow-2.1.0

非常感谢。

【问题讨论】:

    标签: python tensorflow keras tensorflow2.0 autoencoder


    【解决方案1】:

    这是工作代码。

    import tensorflow as tf
    import random
    import os
    import numpy as np
    
    RES = [256, 256]
    def generator_data(n):
        for i in range(n):
            for j in range(1):
                yield tf.zeros((1, 256, 256, 3)), tf.zeros((1, 256, 256, 3))
    
    def mymodel():
        model = tf.keras.Sequential()
        model.add(tf.keras.layers.Conv2D(8, (3, 3), activation='relu', padding='same'))
        # 256 x 256 x 8
        model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
        # 128 x 128 x 8
        model.add(tf.keras.layers.Conv2D(16, (3, 3), activation='relu', padding='same'))
        # 128 x 128 x 16
        model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
        # 64 x 64 x 16
        model.add(tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same'))
        # 64 x 64 x 32
        model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
        # 32 x 32 x 32
    
        # 32 x 32 x 32
        model.add(tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same'))
        # 32 x 32 x 32
        model.add(tf.keras.layers.UpSampling2D((2, 2)))
        # 64 x 64 x 32
        model.add(tf.keras.layers.Conv2D(16, (3, 3), activation='relu', padding='same'))
        # 64 x 64 x 16
        model.add(tf.keras.layers.UpSampling2D((2, 2)))
        # 128 x 128 x 16
        model.add(tf.keras.layers.Conv2D(8, (3, 3), activation='relu', padding='same'))
        # 128 x 128 x 8
        model.add(tf.keras.layers.UpSampling2D((2, 2)))
        # 256 x 256 x 8
        model.add(tf.keras.layers.Conv2D(1, (3, 3), activation='sigmoid', padding='same'))
        return model
    
    
    if __name__ == "__main__":
        # import some data to play with
        z = list(zip(*generator_data(2)))
    
        x_val = z[0][0]
        y_val = z[0][1]
    
        model = mymodel()
        optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
        model.compile(optimizer=optimizer, loss=tf.keras.losses.MeanSquaredError())
        model(tf.zeros((1, 256, 256, 3)))
        model.summary()
    
    
        print(x_val.numpy().shape)
        print(y_val.numpy().shape)
        model.fit(x=generator_data(10),
            validation_data=(x_val, y_val),
            verbose=1, epochs=1)
    

    您以错误的方式将解压缩与生成器一起使用。我将输出类型转换为列表,以便它可以订阅。其中一个有用的技巧是在每个步骤中打印 X、y 的形状和 len,以找出错误所在。

    更新:

    是的,但是你需要传递一个形状为 [batch, 256, 256, 3] 的张量。但是如果 a 是一个列表,并且 a[0] 的形状为 [1, 256, 256, 3],那么您需要将 a[0] 传递给模型,这就是我所做的。但是,你正在通过一个。但是 a 是一个列表,而不是一个 numpy 数组/张量,即使我们将它类型转换为一个 numpy 数组,我们也会得到 shape = (1, 1, 256, 256, 3) - 这是无效的。

    另外,为什么在您的 generator_data 中使用不必要的第二个循环?

    def generator_data(n):
        for i in range(n):
            for j in range(1): # ??????? Why?
                yield tf.zeros((1, 256, 256, 3)), tf.zeros((1, 256, 256, 3))
    

    【讨论】:

    • 感谢您的回复。你能提供一个可以做我打算做的工作示例吗?对我来说,这只是证明问题出在验证数据上的证据,对此表示感谢。您是从代码中还是从经验中阅读的?不仅如此,我不明白为什么输出形状是多重的,以及我应该如何提供我的数据进行验证。现在你只提供单个张量,这不是我想做的。
    • 如果我运行:x_val, y_val = zip(*generator_data(20)) a = list(x_val) b = list(y_val) 我会得到一个张量列表(在我看来应该完全没问题)。基本上这与您所做的等效,但您只提供一个用于验证的张量,而不是一个列表(或它们的集合),这是预期的。 (Pdb) print(type(a))&lt;class 'list'&gt;(Pdb) print(type(a[0]))&lt;class 'tensorflow.python.framework.ops.EagerTensor'&gt;(Pdb) print(a[0].shape)(1, 256, 256, 3)(Pdb)
    • 我不使用不必要的第二个循环。在我的初始代码中,我有 range(6)。我试图复制我的数据的样子,因为这是一个用于测试的示例。
    • 无论如何我找到了解决方案,但矛盾的是它必须首先使用 tensorflow 的版本。我首先通过更新到 nightly 2.2 然后使用 tf.data 模块解决了整个问题。
    【解决方案2】:

    我设法通过每晚更新到 tf-2.2 并使用 tf.data 模块来解决这些问题。

    如果您有同样的问题,请看这里:

    import tensorflow as tf
    import random
    import os
    from functools import partial
    
    RES = [256, 256]
    def generator_data(n):
        for i in range(n):
            for j in range(6):
                yield tf.zeros((1, 256, 256, 3)), tf.zeros((1, 256, 256, 3))
    
    def generator_data_val(n):
        for i in range(n):
            for j in range(6):
                yield tf.zeros((256, 256, 3)), tf.zeros((256, 256, 3))
    
    
    def model():
        model = tf.keras.Sequential()
        model.add(tf.keras.layers.Conv2D(8, (3, 3), activation='relu', padding='same', input_shape=(256, 256, 3)))
        # 256 x 256 x 8
        model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
        # 128 x 128 x 8
        model.add(tf.keras.layers.Conv2D(16, (3, 3), activation='relu', padding='same'))
        # 128 x 128 x 16
        model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
        # 64 x 64 x 16
        model.add(tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same'))
        # 64 x 64 x 32
        model.add(tf.keras.layers.MaxPooling2D((2, 2), padding='same'))
        # 32 x 32 x 32
    
        # 32 x 32 x 32
        model.add(tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same'))
        # 32 x 32 x 32
        model.add(tf.keras.layers.UpSampling2D((2, 2)))
        # 64 x 64 x 32
        model.add(tf.keras.layers.Conv2D(16, (3, 3), activation='relu', padding='same'))
        # 64 x 64 x 16
        model.add(tf.keras.layers.UpSampling2D((2, 2)))
        # 128 x 128 x 16
        model.add(tf.keras.layers.Conv2D(8, (3, 3), activation='relu', padding='same'))
        # 128 x 128 x 8
        model.add(tf.keras.layers.UpSampling2D((2, 2)))
        # 256 x 256 x 8
        model.add(tf.keras.layers.Conv2D(1, (3, 3), activation='sigmoid', padding='same'))
        return model
    
    
    if __name__ == "__main__":
        # import some data to play with
        x_val, y_val = zip(*generator_data_val(5))
        x_val, y_val = list(x_val), list(y_val)
    
    
        model = model()
        optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
        model.compile(optimizer=optimizer, loss=tf.keras.losses.MeanSquaredError())
        model(tf.zeros((1, 256, 256, 3)))
        model.summary()
        train_dataset = generator_data(5)
    
        gen = partial(generator_data, n=5)
        train_dataset = tf.data.Dataset.from_generator(
            gen, output_types=(tf.float32, tf.float32),
            output_shapes=(tf.TensorShape([1, 256, 256, 3]), tf.TensorShape([1, 256, 256, 3]))).repeat()
        val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val)).batch(2)
    
        # generator_data(train_list)
        model.fit(x=train_dataset,
            steps_per_epoch=40,
            validation_data=val_dataset,
            verbose=1, epochs=1000)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      • 2017-10-21
      • 2017-01-11
      相关资源
      最近更新 更多