我正在构建一个CNN来识别图像中5种不同的分类/疾病。我非常确定,我可能在我的独热编码上出了问题……或者在创建我的train_y标签值时出了问题,但我无法找出如何修复它。任何帮助都将不胜感激!我一直收到以下错误:
ValueError: Shapes (None, 228, 228, 1) and (None, 1) are incompatible
这是我的代码:
DATADIR = "/Users/...pathname"CATEGORIES = ["disease0", "disease1", "disease2", "disease3", "non_disease"]training_data = []IMG_SIZE = 228 #for resizing the image, but need to find the right size for this, (5472,3648) is original image sizedef creating_training_data(): for category in CATEGORIES: path = os.path.join(DATADIR, category) # gets us into the path for 5 diseases directory class_num = CATEGORIES.index(category) #assign one hot encoding to each disease.. [1,0,0,0,0] for img in os.listdir(path): try: img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE) # convert images to an array, IMREAD_COLOR for rgb new_array = cv2.resize(img_array, (IMG_SIZE,IMG_SIZE), interpolation=cv2.INTER_AREA) #would be (5472,3648) at full size. INTER_AREA for shrinking an image training_data.append([new_array, class_num]) #would be img_array if not resizing except Exception as e: passcreating_training_data() #calling the functionrandom.shuffle(training_data) #shuffling the data#for sample in training_data[:10]: #print(sample[1])train_X = [] #packing shuffled data into the variables we will use right before feeding it to neural networktrain_y = [] # could also put validation set herefor features, label in training_data: #building out lists for features and labels train_X.append(features) train_y.append(label)#convert train_X into a numpy arraytrain_X = np.array(train_X).reshape(-1, IMG_SIZE, IMG_SIZE, 1) #-1 is how many features do we have..catch all for anything, any number. 3 is for RGB. 1 for grey#normalize the data by scaling...for pixel data min is 0 and max is 255train_X = train_X/255.0 #may need to use keras.utils.normalize to perform this insteadprint(train_X.shape)print(train_y.shape)#Creating our CNNmodel = Sequential()model.add(Conv2D(64, (3,3), input_shape=train_X.shape[1:])) #skip the -1...using the shape of the data (228,228,1)model.add(Activation('relu'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Conv2D(64, (3,3)))model.add(Activation('relu'))model.add(MaxPooling2D(pool_size=(2,2))) # Now we have a 2x64 CNNmodel.add(Flatten()) #Flatten the data because Convolutional is 2D whereas the dense layer wants a 1D data setmodel.add(Dense(64))#Adding Output Layermodel.add(Dense(1))model.add(Activation('softmax'))model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["sparse_categorical_accuracy"])model.fit(train_X, train_y, batch_size=5, epochs=10,validation_split=0.2)
回答:
尽管您在训练模型以预测5个类别,但在这一行中:
model.add(Dense(1))model.add(Activation('softmax'))
您指定了最后一个softmax层只能预测一个类别,您应该使最后的softmax层与您想要预测的类别数量匹配。
关于数据标记的编辑:
model.add(Dense(5))model.add(Activation('softmax'))
由于您在训练模型以预测5个类别,并且您的数据标记为5个类别。
关于标记列表,请尝试如下操作:
DATADIR = "/Users/...pathname"CATEGORIES = ["disease0", "disease1", "disease2", "disease3", "non_disease"]train_x = []train_y = []IMG_SIZE = 228 #for resizing the image, but need to find the right size for this, (5472,3648) is original image sizedef creating_training_data(): for category in CATEGORIES: labels = [0, 0, 0, 0, 0] path = os.path.join(DATADIR, category) # gets us into the path for 5 diseases directory class_num = CATEGORIES.index(category) #assign one hot encoding to each disease.. [1,0,0,0,0] labels[class_num] = 1 for img in os.listdir(path): try: img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE) # convert images to an array, IMREAD_COLOR for rgb new_array = cv2.resize(img_array, (IMG_SIZE,IMG_SIZE), interpolation=cv2.INTER_AREA) #would be (5472,3648) at full size. INTER_AREA for shrinking an image train_x.append(new_array) #would be img_array if not resizing train_y.append(labels) except Exception as e: passtrain_X = np.array(train_X).reshape(-1, IMG_SIZE, IMG_SIZE, 1)train_X = train_X/255.0 #may need to use keras.utils.normalize to perform this insteadprint(train_X.shape)print(train_y.shape)#Creating our CNNmodel = Sequential()model.add(Conv2D(64, (3,3), input_shape=train_X.shape[1:])) #skip the -1...using the shape of the data (228,228,1)model.add(Activation('relu'))model.add(MaxPooling2D(pool_size=(2,2)))model.add(Conv2D(64, (3,3)))model.add(Activation('relu'))model.add(MaxPooling2D(pool_size=(2,2))) # Now we have a 2x64 CNNmodel.add(Flatten()) #Flatten the data because Convolutional is 2D whereas the dense layer wants a 1D data setmodel.add(Dense(64))#Adding Output Layermodel.add(Dense(5))model.add(Activation('softmax'))model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])model.fit(train_X, train_y, batch_size=5, epochs=10,validation_split=0.2, shuffle=True)