为什么我的 Ml CNN Kaggle Cats / Dogs 预测只吐出一个错误?

Why does my Ml CNN Kaggle Cats / Dogs prection only spit out an error?

我是 ML 和计算机的新手 Vision.I 我正在尝试对猫/狗进行分类预测,0 作为猫,1 作为狗。但是我的 model.fit() 函数吐出了这个错误。
...

    ValueError: Input 0 of layer sequential_5 is incompatible with the layer: : expected min_ndim=4, found ndim=2. Full shape received: [None, 10000]

这是我的 ML 模型:

import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import cv2

#the images are stored in the Folders 'Cat/' and 'Dog/'
animal = ['Cat/','Dog/']
images_cat= []
images_dog=[]

# reads in the images 
for x in animal:
    for i in range(1,12500): # the are images from '1.jpg' till '12499.jpg' for each Cats and Dogs
        try:
            image_path = x+ str(i) +'.jpg'# this gets the path of the images for example 'Cat/1.jpg'
            #print(image_path)
            img = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2GRAY)
            img_resized = cv2.resize(img,dsize=(100,100))
            if x == 'Cat/':
                images_cat.append(img_resized)
            elif x == 'Dog/':
                images_dog.append(img_resized)
                
        except cv2.error as e:
            #some images spit out an errer and the apprently can't be read so therefore I just give them the first image to add to the list
            if x == 'Cat/':
                images_cat.append(images_cat[1])
            elif x == 'Dog/':
                images_dog.append(images_dog[1])

# assign targets to values

y_cat = np.zeros(len(images_cat)) # Cat == 0
y_dog = np.ones(len(images_dog)) # Dog == 1


# trainig_images = 80%   test_images= 20%
training_sample_count = round(0.8* len(y_cat))

#list slicing the images to get 80% of the images as calculated above
X_cat_train = images_cat [:training_sample_count]
y_cat_train_fin = y_cat[:training_sample_count]

X_dog_train = images_dog [:training_sample_count]
y_dog_train_fin = y_dog[:training_sample_count]

# create the final training list
X_train = X_cat_train + X_dog_train
y_train=[]

y_train.append(y_cat_train_fin.data)
y_train.append(y_dog_train_fin.data)

y_train = np.reshape(y_train,(19998,))
np.shape(y_train)# output: (19998,)

#normalizing the data
X_train = [x / 255.0 for x in X_train]
X_train = np.reshape(X_train,(19998,10000))
np.shape(X_train) #output: (19998, 10000)

from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Dropout, MaxPooling2D, Conv2D, Flatten 

model = Sequential()
model.add(Conv2D(32,kernel_size=(5,5),padding='same', activation ='relu'))
model.add(MaxPooling2D((3,3)))

model.add(Conv2D(32,kernel_size=(5,5),padding='same', activation ='relu'))
model.add(MaxPooling2D((3,3)))

model.add(Dropout(0.25))
model.add(Flatten())

model.add(Dense(1, activation='softmax'))
model.compile(optimizer='adam', loss="sparse_categorical_crossentropy", metrics=["accuracy"])

model.fit(
    X_train,
    y_train,
    epochs=10,
    batch_size=10000)

我还没有得到测试图像,但我基本上尝试为未来的数据训练这个模型(比如自己的猫或狗的图像然后被预测)。 如果有人能帮助我解决我的问题,我会很高兴,因为我被困在自动取款机上。干杯:)

Conv2D 层需要形状 (batch_size, x, y, depth) 的输入。您的 X_train 正在重塑为只有 (batch_size, x*y) 大小,这不是 Conv2D 所期望的大小。

仅删除此重塑可能会奏效:X_train = np.reshape(X_train,(19998,10000))。如果没有,您可以重塑为 (19998, 100, 100, 1).

您的模型存在一些问题 -

  1. 您正在进行二进制 class 化,但使用多 class 单标签 class 化的配置。改变你的损失和最后一层激活以获得正确的结果。请检查下面的table以供参考。

  1. 当需要 3D 张量时,您将每个样本的一维数组传递给 Conv2D 层。这就是错误 expected min_ndim=4, found ndim=2. 的原因。预期的维度是 (batch, height, width, channels) 而不是 (batch, pixels)。我添加了一个 model.add(Reshape((100,100,1), input_shape=(10000,))) 将 10000 像素重塑为 (100,100,1) 以便能够正确传递到 conv2d 层。

  2. 最后,您有 19998 张样本图像。虽然可能,但批量大小为 10000 没有意义。批量大小是将导致梯度更新的样本数。在您的情况下,每个时期将只有 2 次梯度更新,因为 19998/10000 ~ 2。我建议将批量大小设置为 128、64 或 32。我在 model.fit[=19 中将其设置为 128 =]

在下面找到更新的代码。

from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Dropout, MaxPooling2D, Conv2D, Flatten 

X_train = np.random.random((500, 10000))
Y_train = np.random.randint(0,2,(500,)) #0, 0, 1, 0, 1...

model = Sequential()
model.add(Reshape((100,100,1), input_shape=(10000,)))
model.add(Conv2D(32,kernel_size=(5,5), padding='same', activation ='relu'))
model.add(MaxPooling2D((3,3)))

model.add(Conv2D(32,kernel_size=(5,5),padding='same', activation ='relu'))
model.add(MaxPooling2D((3,3)))

model.add(Dropout(0.25))
model.add(Flatten())

model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss="binary_crossentropy", metrics=["accuracy"])

model.fit(
    X_train,
    Y_train,
    epochs=3,
    batch_size=128)
Epoch 1/3
4/4 [==============================] - 2s 498ms/step - loss: 0.7019 - accuracy: 0.4680
Epoch 2/3
4/4 [==============================] - 2s 534ms/step - loss: 0.6939 - accuracy: 0.5260
Epoch 3/3
4/4 [==============================] - 2s 524ms/step - loss: 0.6922 - accuracy: 0.5240