首页 > 解决方案 > 训练一个 CNN 不兼容的 Shapes

问题描述

我正在尝试训练一个CNN应该预测包含四个不同字母的图像['A','B','C','D']。我已将我的数据集拆分为多个train,test and validation集。

这些是开始输入CNN模型的形状:

print(X_train.shape,y_train.shape,X_test.shape,y_test.shape,X_validation.shape,y_validation.shape)
     (2150, 256, 256, 1) (2150, 4) (672, 256, 256, 1) (672, 4) (538, 256, 256, 1) (538, 4)

然后我开始编写CNN模型:

def CNNModel():
    n_Filters= 60
    sizeof_filter1= (5,5)
    sizeof_filter2= (3,3)
    sizeofPool= (2,2)
    n_nodes= 500

    model = keras.Sequential(
        [
            layers.Conv2D(n_Filters,sizeof_filter1,input_shape=(256,256,1),activation='relu'),
            layers.Conv2D(n_Filters,sizeof_filter1,activation='relu'),
            layers.MaxPool2D(pool_size=sizeofPool),
            layers.Conv2D(n_Filters//2,sizeof_filter2,activation='relu'),
            layers.Conv2D(n_Filters//2,sizeof_filter2,activation='relu'),
            layers.MaxPool2D(pool_size=sizeofPool),
            layers.Dropout(0.5),
            layers.Dense(n_labels,activation='softmax')
        ]
    )
    model.compile(optimizer="Adam",loss='categorical_crossentropy',metrics=['accuracy'])
    return model

这是我的模型的摘要:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 252, 252, 60)      1560      
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 248, 248, 60)      90060     
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 124, 124, 60)      0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 122, 122, 30)      16230     
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 120, 120, 30)      8130      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 60, 60, 30)        0         
_________________________________________________________________
dropout (Dropout)            (None, 60, 60, 30)        0         
_________________________________________________________________
dense (Dense)                (None, 60, 60, 4)         124       
=================================================================
Total params: 116,104
Trainable params: 116,104
Non-trainable params: 0
_________________________________________________________________
None

然后我使用 keras flow 方法进行训练:

batch_size_value = 50
steps_per_Epoch_value = 2000
epochs_value = 10

history = model.fit(dataGen.flow(X_train,y_train,
                                batch_size=batch_size_value),
                                steps_per_epoch=steps_per_Epoch_value,
                                epochs=epochs_value,
                                validation_data=(X_validation,y_validation),
                                shuffle=1
                                )

如果对这个dataGen问题有用,则扩充对象如下:

dataGen = ImageDataGenerator(width_shift_range=0.1,
                             height_shift_range=0.1,
                             zoom_range=0.2,
                             shear_range=0.1,
                             rotation_range=10)

最后是我的错误:

ValueError: Shapes (None, None) and (None, 60, 60, 4) are incompatible

我在这里做错了什么?谢谢。

标签: pythontensorflowkerasconv-neural-network

解决方案


您直接输入 n_labels 的 3 维向量进行分类,这导致dimensional mismatch of y label and model output,您需要flatten正在进行的神经元才能达到输出,

我只是添加了错误解决方案,相应地微调模型

from keras import layers, models
import keras
n_labels = 4
def CNNModel():
    n_Filters= 60
    sizeof_filter1= (5,5)
    sizeof_filter2= (3,3)
    sizeofPool= (2,2)
    n_nodes= 500

model = keras.Sequential(
    [
        layers.Conv2D(n_Filters,sizeof_filter1,input_shape=(256,256,1),activation='relu'),
        layers.Conv2D(n_Filters,sizeof_filter1,activation='relu'),
        layers.MaxPool2D(pool_size=sizeofPool),
        layers.Conv2D(n_Filters//2,sizeof_filter2,activation='relu'),
        layers.Conv2D(n_Filters//2,sizeof_filter2,activation='relu'),
        layers.MaxPool2D(pool_size=sizeofPool),
        layers.Dropout(0.5),
        layers.Flatten(),
        layers.Dense(n_labels,activation='softmax')
        
    ]
)
model.compile(optimizer="Adam",loss='categorical_crossentropy',metrics=['accuracy'])
return model
model = CNNModel()

model.summary()

出去:

Model: "sequential_2"
_________________________________________________________________

Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_12 (Conv2D)           (None, 252, 252, 60)      1560      
_________________________________________________________________
conv2d_13 (Conv2D)           (None, 248, 248, 60)      90060     
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 124, 124, 60)      0         
_________________________________________________________________
conv2d_14 (Conv2D)           (None, 122, 122, 30)      16230     
_________________________________________________________________
conv2d_15 (Conv2D)           (None, 120, 120, 30)      8130      
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 60, 60, 30)        0         
_________________________________________________________________
dropout_3 (Dropout)          (None, 60, 60, 30)        0         
_________________________________________________________________
flatten (Flatten)            (None, 108000)            0         
_________________________________________________________________
dense_2 (Dense)              (None, 4)                 432004    
=================================================================
Total params: 547,984
Trainable params: 547,984
Non-trainable params: 0
_________________________________________________________________

推荐阅读