首页 > 解决方案 > Tensorflow.Keras 表示输入与预期输入不同

问题描述

我正在编写一个简单的 CNN 来对卡通面孔的不同特征进行分类。我正在使用这个数据集。当我尝试运行我的代码时,我收到以下错误:

Traceback (most recent call last):
  File "cartoonKerasPy.py", line 86, in <module>
    model.fit(x_train, y_train, batch_size=8, epochs=3)
  File "C:\Users\befbr\Anaconda3\envs\Cartoon AI\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1536, in fit
    validation_split=validation_split)
  File "C:\Users\befbr\Anaconda3\envs\Cartoon AI\lib\site-packages\tensorflow\python\keras\engine\training.py", line 992, in _standardize_user_data
    class_weight, batch_size)
  File "C:\Users\befbr\Anaconda3\envs\Cartoon AI\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1154, in _standardize_weights
    exception_prefix='target')
  File "C:\Users\befbr\Anaconda3\envs\Cartoon AI\lib\site-packages\tensorflow\python\keras\engine\training_utils.py", line 293, in standardize_input_data
    str(len(data)) + ' arrays: ' + str(data)[:200] + '...')
ValueError: Error when checking model target: 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), but instead got the following list of 160 arrays: [0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0...

这是我的代码:

print("Importing Packages")
import os
import tensorflow as tf
from tensorflow import keras as k
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import pandas as pd
from PIL import Image

def createModel():
    model = k.models.Sequential([
      k.layers.Conv3D(filters=64, kernel_size=2, padding='same', activation='relu', input_shape=(500,500, 4, 1)),
      k.layers.MaxPooling3D(pool_size=2),
      k.layers.Dropout(0.2),
      k.layers.Flatten(),
      k.layers.Dense(1000, activation='relu'),
      k.layers.Dense(1, activation='softmax')

    ])
    model.compile(optimizer='adam',
                  loss='sparse_categorical_crossentropy',
                  metrics=['accuracy'])
    return model

def getFile(dir, getEveryNthLine):
    allFiles = list(os.listdir(dir))
    # print(allFiles)
    fileNameList = []
    numOfFiles = len(allFiles)
    i = 0
    for fichier in allFiles:
        if(i % getEveryNthLine == 0):
                # print(fichier)
                if(fichier.endswith(".csv")):
                    fileNameList.append(dir + "/" + fichier[0:-4])
        i += 1
    return fileNameList

print("Creating Model")
model = createModel()

# print("Model Summary")
# model.summary()

print("\nLoad Files")
files = getFile("F:/cartoonset10k/", 100)
print("Loaded " + str(len(files)) + " file names")

print("Split Data Into Train And Test")
train, test = train_test_split(files, test_size=0.2)

x_train = []
y_train = []
x_test = []
y_test = []

def getLabels(filePath):
    df = []
    with open(filePath, "r") as file:
        for line in list(file):
            tempList = line.replace("\n", "").replace('"', "").replace(" ", "").split(",")
            df.append({
                "attr": tempList[0],
                "value":int(tempList[1]),
                "maxValue":int(tempList[2])
            })
    return df

for i in range(len(train)):

    x_train.append([list(Image.open(train[i] + ".png").getdata())])
    y_train.append(pd.DataFrame(getLabels(train[i] + ".csv"))["value"][1])

print("Finished Formating\n\n")

x_train = np.reshape(x_train, (len(train), 500, 500, 4, 1))

with tf.device('/gpu'):
    model.fit(x_train, y_train, batch_size=8, epochs=3)

有谁知道是什么原因造成的?我认为问题与输入形状有关,但我可能错了。我在哪里可以找到正确的输入形状应该在哪里?

标签: pythontensorflowartificial-intelligenceconv-neural-networktf.keras

解决方案


我的朋友有几个问题:

首先,使用偶数的 kernal_size 是不好的做法,相反,我建议使用 (5, 5) 之类的东西,因为您的图像相当大

接下来,我认为您应该使用 Conv2D 而不是 Conv3D

此外,你的最后一层应该有一些输出,比如 2,可能代表那个卡通人物的 0 和不是那个卡通人物的 1。

最后,我不断感觉到你的模型会欠拟合,过拟合你的模型并使用诸如 L1、L2 权重正则化或 Drupout 层之类的策略来对抗它总是好的。

总的来说,您的模型应该是这样的,如果我错了,请随时给我打电话,因为我也不是这方面的专家:P:

def build_model():
    model = Sequential()

    model.add(Conv2D(64, (5, 5), input_shape=(500, 500, 4), activation="relu"))
    model.add(MaxPooling2D(pool_size=(2, 2))
    model.add(Droupout(0.2))

    model.add(Conv2D(128, (5, 5), activation="relu"))
    model.add(MaxPooling2D(pool_size=(2, 2))
    model.add(Droupout(0.2))

    model.add(Conv2D(256, (5, 5), activation="relu"))
    model.add(MaxPooling2D(pool_size=(2, 2))
    model.add(Droupout(0.2))

    model.add(Flatten())
    model.add(Dense(512, activation="relu"))
    model.add(Dropout(0.5))
    model.add(Dense(512, activation="relu"))
    model.add(Dropout(0.5))
    model.add(Dense(512, activation="relu"))
    model.add(Dropout(0.5))
    model.add(Dropout(2, activation="softmax"))

return model

我使用了一些导入语句,这样我就不必键入 k.blah.blah 等。CNN 模型通常是:conv -> maxpool -> dropout -> conv -> maxpool -> dropout ...... ... dropout -> Flatten -> Dense -> High Dropout rate -> Dense -> High Dropout rate -> ......... -> 输出

希望这可以帮助!再见

PS:你只有 13 岁,能够编写 CNN 之类的东西,我真的很佩服,你有才华,我的朋友。继续努力!:)


推荐阅读