Модель распознавания изображений, каждый раз угадывающая один и тот же класс - PullRequest
0 голосов
/ 29 апреля 2020

Я пытаюсь обучить реализацию 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))

1 Ответ

0 голосов
/ 29 апреля 2020

Измените порядок ваших последних слоев. Изменение:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...