Я пытаюсь обучить реализацию Squeez enet по умолчанию на базе HAM10000 поражений кожи , и моя модель постоянно угадывает только nv. Если вы посмотрите на базу данных, вы увидите, что nv поражений значительно больше, чем в любом другом классе. После того, как я разделил тест / поезд, я получил эти числа: {0: 271, 1: 412, 2: 869, 3: 88, 4: 899, 5: 5367, 6: 119}
для своего набора данных обучения. 5
здесь представляет nv. Я пробовал несколько разных функций потерь (categoryorical_crossentropy, categoryorical_hinge), несколько разных оптимизаторов (sgd, adam) и несколько разных методов реализации class_weights (total / count, 5367 / count, log (5367 / count), а также ручную настройку вес 5
должен быть ниже 1). После всего этого я либо получаю нон-стоп догадки nv, либо я на самом деле низко оцениваю nv и получаю проценты точности подгадывания. У меня заканчиваются идеи, и мне интересно, что еще я могу сделать. Я также подумал о том, чтобы повторить разделение теста / поезда так, чтобы счет каждого класса в тесте был одинаковым, но я боюсь, что это займет много времени, только чтобы не работать.
Вот код для модели
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))