图像识别模型每次都猜同 Class
Image Recognition Model Guessing the Same Class Every Time
我正在尝试在 HAM10000 skin lesion database 上训练默认的 Squeezenet 实现,而我的模型一直在猜测 nv。如果您查看数据库,您会发现 nv 病变明显多于任何其他 class。 test/train 拆分后,我获得了这些数字:{0: 271, 1: 412, 2: 869, 3: 88, 4: 899, 5: 5367, 6: 119}
作为我的训练数据集。 5
这里代表nv。我尝试了几种不同的损失函数(categorical_crossentropy、categorical_hinge)、几种不同的优化器(sgd、adam)和几种不同的实现方法class_weights(total/count、5367/ count, log(5367/count),以及手动设置 5
的权重小于 1)。在所有这一切之后,我要么得到不间断的 nv 猜测,要么我给 nv 赋予非常低的权重并获得子猜测准确率。我 运行 没有想法,想知道我还能做些什么。我还考虑过重做我的 test/train 拆分,以便测试中每个 class 的计数是统一的,但我担心这会花费很多时间而无法工作。
这是模型的代码
img_input = Input(shape=input_shape)
x = Conv2D(64, (3, 3), strides=(2, 2), padding='valid', name='conv1')(img_input)
x = Activation('relu', name='relu_conv1')(x)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x)
x = fire_module(x, fire_id=2, squeeze=16, expand=64)
x = fire_module(x, fire_id=3, squeeze=16, expand=64)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool3')(x)
x = fire_module(x, fire_id=4, squeeze=32, expand=128)
x = fire_module(x, fire_id=5, squeeze=32, expand=128)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool5')(x)
x = fire_module(x, fire_id=6, squeeze=48, expand=192)
x = fire_module(x, fire_id=7, squeeze=48, expand=192)
x = fire_module(x, fire_id=8, squeeze=64, expand=256)
x = fire_module(x, fire_id=9, squeeze=64, expand=256)
x = Dropout(0.5, name='drop9')(x)
x = Conv2D(7, (1, 1), padding='valid', name='conv10')(x) #uses classes
x = Activation('softmax', name='loss')(x)
x = GlobalAveragePooling2D(data_format='channels_last')(x)
inputs = img_input
model = Model(inputs, x, name='squeezenet')
这是我用于 运行
的代码
np.random.seed(333)
train_data_dir = 'data/imgs/train'
validation_data_dir = 'data/imgs/test'
nb_train_samples = 8025
nb_validation_samples = 1990
epochs = 100 #todo change
batch_size = 32
img_width = 600
img_height = 450
class_weight = {0: 2.99, 1: 2.56, 2: 1.82, 3: 4.11, 4: 1.79, 5: 0.3, 6: 3.8} #this is the class weight for my most recent run, which is currently oscillating between always guessing nv and <15% accuracy
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_height)
else:
input_shape = (img_width, img_height, 3)
name = 'Squeezenet'
model = initModel(name, input_shape) # This gets the model from the above code snippit
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
train_datagen = ImageDataGenerator(rescale=1. / 255
,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical')
history = model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples // batch_size,
class_weight=class_weight)
model.save('models/{0}_cat.h5'.format(name))
更改最后一层的顺序。更改自:
x = Activation('softmax', name='loss')(x)
x = GlobalAveragePooling2D(data_format='channels_last')(x)
到
x = GlobalAveragePooling2D(data_format='channels_last')(x)
x = Activation('softmax', name='loss')(x)
我正在尝试在 HAM10000 skin lesion database 上训练默认的 Squeezenet 实现,而我的模型一直在猜测 nv。如果您查看数据库,您会发现 nv 病变明显多于任何其他 class。 test/train 拆分后,我获得了这些数字:{0: 271, 1: 412, 2: 869, 3: 88, 4: 899, 5: 5367, 6: 119}
作为我的训练数据集。 5
这里代表nv。我尝试了几种不同的损失函数(categorical_crossentropy、categorical_hinge)、几种不同的优化器(sgd、adam)和几种不同的实现方法class_weights(total/count、5367/ count, log(5367/count),以及手动设置 5
的权重小于 1)。在所有这一切之后,我要么得到不间断的 nv 猜测,要么我给 nv 赋予非常低的权重并获得子猜测准确率。我 运行 没有想法,想知道我还能做些什么。我还考虑过重做我的 test/train 拆分,以便测试中每个 class 的计数是统一的,但我担心这会花费很多时间而无法工作。
这是模型的代码
img_input = Input(shape=input_shape)
x = Conv2D(64, (3, 3), strides=(2, 2), padding='valid', name='conv1')(img_input)
x = Activation('relu', name='relu_conv1')(x)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x)
x = fire_module(x, fire_id=2, squeeze=16, expand=64)
x = fire_module(x, fire_id=3, squeeze=16, expand=64)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool3')(x)
x = fire_module(x, fire_id=4, squeeze=32, expand=128)
x = fire_module(x, fire_id=5, squeeze=32, expand=128)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool5')(x)
x = fire_module(x, fire_id=6, squeeze=48, expand=192)
x = fire_module(x, fire_id=7, squeeze=48, expand=192)
x = fire_module(x, fire_id=8, squeeze=64, expand=256)
x = fire_module(x, fire_id=9, squeeze=64, expand=256)
x = Dropout(0.5, name='drop9')(x)
x = Conv2D(7, (1, 1), padding='valid', name='conv10')(x) #uses classes
x = Activation('softmax', name='loss')(x)
x = GlobalAveragePooling2D(data_format='channels_last')(x)
inputs = img_input
model = Model(inputs, x, name='squeezenet')
这是我用于 运行
的代码np.random.seed(333)
train_data_dir = 'data/imgs/train'
validation_data_dir = 'data/imgs/test'
nb_train_samples = 8025
nb_validation_samples = 1990
epochs = 100 #todo change
batch_size = 32
img_width = 600
img_height = 450
class_weight = {0: 2.99, 1: 2.56, 2: 1.82, 3: 4.11, 4: 1.79, 5: 0.3, 6: 3.8} #this is the class weight for my most recent run, which is currently oscillating between always guessing nv and <15% accuracy
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_height)
else:
input_shape = (img_width, img_height, 3)
name = 'Squeezenet'
model = initModel(name, input_shape) # This gets the model from the above code snippit
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
train_datagen = ImageDataGenerator(rescale=1. / 255
,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical')
history = model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples // batch_size,
class_weight=class_weight)
model.save('models/{0}_cat.h5'.format(name))
更改最后一层的顺序。更改自:
x = Activation('softmax', name='loss')(x)
x = GlobalAveragePooling2D(data_format='channels_last')(x)
到
x = GlobalAveragePooling2D(data_format='channels_last')(x)
x = Activation('softmax', name='loss')(x)