我的 CNN Keras 做错了什么?

数据挖掘 机器学习 Python 喀拉斯 美国有线电视新闻网 图像分类
2022-02-22 17:54:47

在我的项目中,每个类(pdr 和 nonPdr)有 700 张图像,总计 1400 张图像。为了验证,我放了 28 个样本。

问题是我的验证损失和准确性不稳定。这是我的代码:

def ReadImages(Path):
    LabelList = list()
    ImageCV = list()
    classes = ["nonPdr", "pdr"]

    # Get all subdirectories
    FolderList = [f for f in os.listdir(Path) if not f.startswith('.')]

    # Loop over each directory
    for File in FolderList:
        for index, Image in enumerate(os.listdir(os.path.join(Path, File))):
            # Convert the path into a file
            ImageCV.append(cv2.resize(cv2.imread(os.path.join(Path, File) + os.path.sep + Image), (256,256)))
            #ImageCV[index]= np.array(ImageCV[index]) / 255.0
            LabelList.append(classes.index(os.path.splitext(File)[0])) 


            ImageCV[index] = cv2.addWeighted(ImageCV[index],4, cv2.GaussianBlur(ImageCV[index],(0,0), 256/30), -4, 128)


    return ImageCV, LabelList

visible = Input(shape=(256,256,3))
conv1 = Conv2D(16, kernel_size=(3,3), activation='relu', strides=(1, 1))(visible)
conv2 = Conv2D(16, kernel_size=(3,3), activation='relu', strides=(1, 1))(conv1)
bat1 = BatchNormalization()(conv2)
conv3 = ZeroPadding2D(padding=(1, 1))(bat1)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv3)

conv4 = Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid', kernel_regularizer=regularizers.l2(0.01))(pool1)
conv5 = Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid', kernel_regularizer=regularizers.l2(0.01))(conv4)
bat2 = BatchNormalization()(conv5)
pool2 = MaxPooling2D(pool_size=(1, 1))(bat2)

conv6 = Conv2D(64, kernel_size=(3,3), activation='relu',strides=(1, 1), padding='valid')(pool2)
conv7 = Conv2D(64, kernel_size=(3,3), activation='relu',strides=(1, 1), padding='valid')(conv6)
bat3 = BatchNormalization()(conv7)
conv7 = ZeroPadding2D(padding=(1, 1))(bat3)
pool3 = MaxPooling2D(pool_size=(1, 1))(conv7)

conv8 = Conv2D(128, kernel_size=(3,3), activation='relu', padding='valid', kernel_regularizer=regularizers.l2(0.01))(pool3)
conv9 = Conv2D(128, kernel_size=(2,2), activation='relu', strides=(1, 1), padding='valid')(conv8)
bat4 = BatchNormalization()(conv9)
pool4 = MaxPooling2D(pool_size=(1, 1))(bat4)

conv10 = Conv2D(256, kernel_size=(3,3), activation='relu', padding='valid', kernel_regularizer=regularizers.l2(0.02))(pool4)
conv11 = Conv2D(256, kernel_size=(3,3), activation='relu', padding='valid', kernel_regularizer=regularizers.l2(0.02))(conv10)
bat5 = BatchNormalization()(conv11)
pool5 = MaxPooling2D(pool_size=(1, 1))(bat5)

flat = Flatten()(pool5)

output = Dense(1, activation='sigmoid')(flat)
model = Model(inputs=visible, outputs=output)

opt = optimizers.adam(lr=0.001, decay=0.0)

model.compile(optimizer= opt, loss='binary_crossentropy', metrics=['accuracy'])



data, labels = ReadImages(TRAIN_DIR)

test, lt = ReadImages(TEST_DIR)

model.fit(np.array(data), np.array(labels), epochs=8, validation_data = (np.array(test), np.array(lt)))

model.save('model.h5')

运行后,我得到了以下回报:

Train on 1400 samples, validate on 28 samples
Epoch 1/8
1400/1400 [==============================] - 2289s 2s/step - loss: 10.5126 - acc: 0.9529 - val_loss: 9.6115 - val_acc: 1.0000
Epoch 2/8
1400/1400 [==============================] - 2245s 2s/step - loss: 9.8477 - acc: 0.9550 - val_loss: 9.1845 - val_acc: 0.9643
Epoch 3/8
1400/1400 [==============================] - 2271s 2s/step - loss: 8.3761 - acc: 0.9864 - val_loss: 7.6834 - val_acc: 1.0000
Epoch 4/8
1400/1400 [==============================] - 2225s 2s/step - loss: 7.7146 - acc: 0.9736 - val_loss: 15.1970 - val_acc: 0.5000
Epoch 5/8
1400/1400 [==============================] - 2204s 2s/step - loss: 7.8170 - acc: 0.9436 - val_loss: 6.5526 - val_acc: 1.0000
Epoch 6/8
1400/1400 [==============================] - 2215s 2s/step - loss: 7.1557 - acc: 0.9407 - val_loss: 5.8400 - val_acc: 1.0000
Epoch 7/8
1400/1400 [==============================] - 2267s 2s/step - loss: 6.4109 - acc: 0.9450 - val_loss: 5.2029 - val_acc: 1.0000
Epoch 8/8
1400/1400 [==============================] - 2269s 2s/step - loss: 5.8860 - acc: 0.9479 - val_loss: 13.2224 - val_acc: 0.5000

当我尝试预测一些测试的图像时,所有样本都返回 0 类(错误):PREDICT.py

model = load_model('model.h5')

for filename in os.listdir(r'v/'):
    if filename.endswith(".jpg") or filename.endswith(".png"):
        ImageCV = cv2.resize(cv2.imread(os.path.join(TEST_DIR) + os.path.sep + filename), (256,256))
        ImageCV = cv2.addWeighted(ImageCV,4, cv2.GaussianBlur(ImageCV,(0,0), 256/30), -4, 128)
        ImageCV = ImageCV.reshape(-1,256,256,3)
        print(model.predict(ImageCV))
        print(np.argmax(model.predict(ImageCV)))
[[0.]]
0
[[0.]]
0
[[0.]]
0

那么,我在项目中做错了什么?我该如何解决?

我很感激任何帮助

更新

添加此代码后:

perm = np.random.permutation(len(data))
data = data[perm]
labels = labels[perm]

返回此数字:

Train on 1400 samples, validate on 28 samples
Epoch 1/5
1400/1400 [==============================] - 2232s 2s/step - loss: 10.5725 - acc: 0.9629 - val_loss: 10.1279 - val_acc: 1.0000
Epoch 2/5
1400/1400 [==============================] - 2370s 2s/step - loss: 10.2828 - acc: 0.9729 - val_loss: 9.5293 - val_acc: 1.0000
Epoch 3/5
1400/1400 [==============================] - 2290s 2s/step - loss: 9.6735 - acc: 0.9707 - val_loss: 8.8646 - val_acc: 1.0000
Epoch 4/5
1400/1400 [==============================] - 2269s 2s/step - loss: 8.6198 - acc: 0.9950 - val_loss: 8.1976 - val_acc: 1.0000
Epoch 5/5
1400/1400 [==============================] - 2282s 2s/step - loss: 8.2455 - acc: 0.9836 - val_loss: 7.8586 - val_acc: 1.0000

值更好,但是当我尝试预测图像时,返回始终为 0 ..(但我正在传递 imgs 0 类和 1 类)

我现在该怎么办?

1个回答

我猜你的模型偏向于上半年。尽管 Keras 内置了shuffle=True参数model.fit(),但根据本文档,它可能在steps_per_epoch=None.

我建议在使用numpy.random.shuffle(array). 大概是这样的:

data = np.array(data)
labels = np.array(labels)

perm = np.random.permutation(len(data))
data = data[perm]
labels = labels[perm]
model.fit(data, labels, epochs=8, validation_data = (np.array(test), np.array(lt)))