首页 > 解决方案 > 无法解决 ValueError: 层序贯_1 的输入 0 与层不兼容

问题描述

我无法解决此错误:

ValueError: Input 0 of layer sequential_1 is incompatible with the layer: expected axis -1 of input shape to have value 3 but received input with shape [None, 1050, 1300, 1]

我正在尝试创建一个基于 image.jpgs 的人脸生成器,在我创建GAN(生成对抗网络)之前,我一切正常。 注意:我已将所有(687)图像设置520x420 为图片,

如果有帮助,这是我的代码:

import numpy as np
import os
from PIL import Image
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.image import imread
import tensorflow as tf
from tensorflow.keras.layers import Dense, Reshape, Flatten, BatchNormalization, Conv2D, Conv2DTranspose, LeakyReLU, \
    Dropout
from tensorflow.keras.models import Sequential

images = []
dim1 = []
dim2 = []
images_path = 'images'
# no_of_images=len(images_path)
for image_name, num in zip(os.listdir(images_path), range(687)):
    full_path = os.path.join(images_path, image_name)
    image = imread(os.path.join(images_path, image_name))
    images.append(image)

# Number of images
# print(len(os.listdir(images_path)))


# Converting list into array
images = np.asarray(images)
# print(images.shape) = (687, 420, 520, 3)

images = images / 255

# setting minimum value of image array to -1 and max to +1
images = images.reshape(-1, 420, 520, 3) * 2 - 1
print(images.shape)

# Setting random seed
np.random.seed(42)
tf.random.set_seed(42)

# number of neurons in the smallest layer
coding_size = 200

# Creating Generator
generator = Sequential()
generator.add(Dense(int(420 / 4) * int(520 / 4) * 86, input_shape=[coding_size]))
generator.add(Reshape([int(420 / 4), int(520 / 4), 86]))
generator.add(BatchNormalization())
generator.add(Conv2DTranspose(64, kernel_size=5, strides=5, padding='same',
                              activation='relu'))
generator.add(BatchNormalization())
generator.add(Conv2DTranspose(1, kernel_size=5, strides=2, padding='same',
                              activation='tanh'))
generator.summary()

# Creating discriminator
discriminator = Sequential()
discriminator.add(Conv2D(64, kernel_size=5, strides=2, padding='same',
                         activation=LeakyReLU(0.3), input_shape=(420, 520, 3)))
discriminator.add(Dropout(0.5))
discriminator.add(Conv2D(128, kernel_size=5, strides=2, padding='same', activation=LeakyReLU(0.3)))
discriminator.add(Dropout(0.5))
discriminator.add(Flatten())
discriminator.add(Dense(1, activation='sigmoid'))

# Creating Generative Adversarial Network
GAN = Sequential([generator, discriminator])
discriminator.compile(loss='binary_crossentropy', optimizer='adam')
discriminator.trainable = False

GAN.compile(loss='binary_crossentropy', optimizer='adam')

# setting up batch_size
batch_size = 32  # training time is inversely proportional to batch_size

# my_data = x_train (for all numbers)
my_data = images
dataset = tf.data.Dataset.from_tensor_slices(my_data).shuffle(buffer_size=1000)
# for really large dataset use buffer-size

dataset = dataset.batch(batch_size=batch_size, drop_remainder=True).prefetch(1)
# drop_remainder = True because 687/64 = 10.73 is not an integer, so we remover the other images
# we have 10 batches
epochs = 20

# creating training loops
generator, discriminator = GAN.layers

for epoch in range(epochs):
    print(f"currently on epoch {epoch + 1}")
    i = 0
    for x_batch in dataset:
        i += 1
        if i % 100 == 0:
            print(f"\tcurrently on batch number:{i} of {len(my_data) // batch_size}")

        # discriminator training phase
        noise = tf.random.normal(shape=[batch_size, coding_size])
        gen_images = generator(noise)

        # concatonating generated images with real images

        x_fake_vs_real = tf.concat([gen_images, tf.dtypes.cast(x_batch, tf.float32)], axis=0)

        # setting target label
        y1 = tf.constant([[0.0]] * batch_size + [[1.0]] * batch_size)
        # 0 => fake generated images
        # 1 => real images

        # we want the discriminator now (after compiling GAN)
        discriminator.trainable = True
        discriminator.train_on_batch(x_fake_vs_real, y1)

        # training the generator (Phase:2)
        noise = tf.random.normal(shape=[batch_size, coding_size])
        y2 = tf.constant([[1.0]] * batch_size)
        # to avoid error
        discriminator.trainable = False
        GAN.train_on_batch(noise, y2)
print("TRAINING COMPLETE!")
# let us see whether generator can produce images like real images

# 10 fake images
noise = tf.random.normal(shape=[10, coding_size])

images_noise = generator(noise)
# images.shape = TensorShape([10,28,28])

for image in images_noise:
    plt.imshow(image.numpy().reshape(420, 520))
    plt.show()

输出:

C:\Users\astro\AppData\Local\Programs\Python\Python38\python.exe C:/Users/astro/Pythonprojects/generating_face/rough.py
2020-07-14 17:34:44.467116: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudart64_101.dll
(687, 420, 520, 3)
2020-07-14 17:35:16.908283: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library nvcuda.dll
2020-07-14 17:35:17.057551: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1561] Found device 0 with properties: 
pciBusID: 0000:01:00.0 name: GeForce GTX 1650 computeCapability: 7.5
coreClock: 1.515GHz coreCount: 14 deviceMemorySize: 4.00GiB deviceMemoryBandwidth: 178.84GiB/s
2020-07-14 17:35:17.058332: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudart64_101.dll
2020-07-14 17:35:17.099460: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cublas64_10.dll
2020-07-14 17:35:17.128073: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cufft64_10.dll
2020-07-14 17:35:17.135191: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library curand64_10.dll
2020-07-14 17:35:17.174991: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cusolver64_10.dll
2020-07-14 17:35:17.190853: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cusparse64_10.dll
2020-07-14 17:35:17.292639: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudnn64_7.dll
2020-07-14 17:35:17.293344: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1703] Adding visible gpu devices: 0
2020-07-14 17:35:17.296905: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2020-07-14 17:35:17.354537: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x1c93c31e7b0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-07-14 17:35:17.354746: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
2020-07-14 17:35:17.356677: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1561] Found device 0 with properties: 
pciBusID: 0000:01:00.0 name: GeForce GTX 1650 computeCapability: 7.5
coreClock: 1.515GHz coreCount: 14 deviceMemorySize: 4.00GiB deviceMemoryBandwidth: 178.84GiB/s
2020-07-14 17:35:17.357213: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudart64_101.dll
2020-07-14 17:35:17.357362: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cublas64_10.dll
2020-07-14 17:35:17.357506: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cufft64_10.dll
2020-07-14 17:35:17.357881: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library curand64_10.dll
2020-07-14 17:35:17.359120: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cusolver64_10.dll
2020-07-14 17:35:17.359266: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cusparse64_10.dll
2020-07-14 17:35:17.359694: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudnn64_7.dll
2020-07-14 17:35:17.359922: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1703] Adding visible gpu devices: 0
2020-07-14 17:35:20.123836: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1102] Device interconnect StreamExecutor with strength 1 edge matrix:
2020-07-14 17:35:20.124040: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1108]      0 
2020-07-14 17:35:20.124157: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1121] 0:   N 
2020-07-14 17:35:20.138550: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1247] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 2917 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1650, pci bus id: 0000:01:00.0, compute capability: 7.5)
2020-07-14 17:35:20.144365: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x1c94356c150 initialized for platform CUDA (this does not guarantee that XLA will be used). Devices:
2020-07-14 17:35:20.159393: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): GeForce GTX 1650, Compute Capability 7.5
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 1173900)           235953900 
_________________________________________________________________
reshape (Reshape)            (None, 105, 130, 86)      0         
_________________________________________________________________
batch_normalization (BatchNo (None, 105, 130, 86)      344       
_________________________________________________________________
conv2d_transpose (Conv2DTran (None, 525, 650, 64)      137664    
_________________________________________________________________
batch_normalization_1 (Batch (None, 525, 650, 64)      256       
_________________________________________________________________
conv2d_transpose_1 (Conv2DTr (None, 1050, 1300, 1)     1601      
=================================================================

我想我需要最后一层是(无、420、520、3),但我不知道怎么做。

Total params: 236,093,765
Trainable params: 236,093,465
Non-trainable params: 300
_________________________________________________________________
Traceback (most recent call last):
  File "C:/Users/astro/Pythonprojects/generating_face/rough.py", line 73, in <module>
    GAN = Sequential([generator, discriminator])
  File "C:\Users\astro\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\training\tracking\base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "C:\Users\astro\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\keras\engine\sequential.py", line 129, in __init__
    self.add(layer)
  File "C:\Users\astro\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\training\tracking\base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "C:\Users\astro\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\keras\engine\sequential.py", line 213, in add
    output_tensor = layer(self.outputs[0])
  File "C:\Users\astro\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 885, in __call__
    input_spec.assert_input_compatibility(self.input_spec, inputs,
  File "C:\Users\astro\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\keras\engine\input_spec.py", line 212, in assert_input_compatibility
    raise ValueError(
ValueError: Input 0 of layer sequential_1 is incompatible with the layer: expected axis -1 of input shape to have value 3 but received input with shape [None, 1050, 1300, 1]

Process finished with exit code 1

标签: pythonpython-3.xtensorflowkerasgenerative-adversarial-network

解决方案


我认为问题出在这一行,应该是 3 而不是 1:

generator.add(Conv2DTranspose(1, kernel_size=5, strides=2, padding='same',
                              activation='tanh'))

不过,我不确定你的形状是否会匹配,因为鉴别器期望input_shape=(420, 520, 3)但你传递的完整形状是[None, 1050, 1300, 1]. 但我认为这会更近一步。


推荐阅读