我正在为20个课程编写CNN分类器。如标题中所述,这是我尝试fit
模型时遇到的错误。
我已经检查了以下答案:Error,但我已经(我认为)设置了categorical
转换。
这是我的代码:
1)图像生成器:
apply_data_augmentation = True
if apply_data_augmentation:
train_datagen = ImageDataGenerator(rotation_range=10, #Training data generator + validation split (20%)
width_shift_range=10,
height_shift_range=10,
zoom_range=0.3,
horizontal_flip=True,
vertical_flip=True,
fill_mode='constant',
cval=0,
rescale=1./255,
validation_split=0.2)
else:
train_datagen = ImageDataGenerator(rescale=1./255)
2)获取数据:
dataset_dir = os.path.join(cwd, 'Classification_Dataset')
bs = 8
# img shape
img_h = 28
img_w = 28
num_classes=20
decide_class_indices = False
if decide_class_indices:
classes = ['airplane', # 0
'bear', # 1
'calculator', # 2
'computer-monitor', # 3
'fireworks', # 4
'galaxy', # 5
'grand-piano', # 6
'kangaroo', # 7
'laptop', # 8
'lightbulb', # 9
'lightning', # 10
'mountain-bike', # 11
'owl', # 12
'school-bus', # 13
'sheet-music', # 14
'skyscraper', # 15
'sword', # 16
't-shirt', # 17
'waterfall', # 18
'wine-bottle'] # 19
else:
classes=None
print(classes)
# Training
training_dir = os.path.join(dataset_dir, 'training')
train_generator = train_datagen.flow_from_directory(
training_dir,
target_size=(img_h, img_w),
batch_size=bs,
class_mode='categorical',
classes=classes,
subset='training',
shuffle=True,
seed=SEED) # set as training data
validation_generator = train_datagen.flow_from_directory(
training_dir, # same directory as training data
target_size=(img_h, img_w),
batch_size=bs,
class_mode='categorical',
classes=classes,
subset='validation',
shuffle=False,
seed=SEED) # set as validation data
print(train_generator)
3)型号+适合:
from keras.datasets import mnist
import matplotlib.pyplot as plt
import numpy as np
from keras import Sequential
from keras.layers import Conv2D, AveragePooling2D, Flatten, Dense, Dropout
from keras.callbacks import EarlyStopping
model = Sequential()
model.add(Conv2D(filters=6, kernel_size=(3, 3), activation='relu', input_shape=(28,28,3)))
model.add(AveragePooling2D())
model.add(Conv2D(filters=16, kernel_size=(3, 3), activation='relu'))
model.add(AveragePooling2D())
model.add(Flatten())
model.add(Dense(units=120, activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(units=100, activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(units=20, activation='softmax'))
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
nb_epochs = 5
model.fit_generator(
train_generator,
steps_per_epoch = train_generator.samples // bs,
validation_data = validation_generator,
validation_steps = validation_generator.samples // bs,
epochs = nb_epochs)
我检查了许多问题中提到的所有可能的问题(例如缺少拼合层,分类转换,不匹配的输入等),但是(至少对我而言)一切都很好。 我不明白问题出在哪里。
答案 0 :(得分:1)
带有flow_from_directory
的{{1}}函数会生成一个热编码的2D标签(Ref),而class_mode='categorical'
则需要整数值。
您有两种方法可以解决此问题:
1.编译模型时,将损失函数更改为sparse_categorical_crossentropy
2.通过使用categorical_crossentropy
函数中的sparse
将标签更改为class_mode='sparse'
模式
简而言之,当标签是整数值(代表类)时,请使用flow_from_directory
,而标签是单次编码时,请使用sparse_categorical_crossentropy
作为损失函数。