图像识别模型每次都能猜出相同的类目。

问题描述 投票:0回答:1

我正在尝试训练默认的Squeezenet实现在 HAM10000皮肤病变数据库 而我的模型一直在猜测除了nv以外的任何东西。如果你看一下数据库,你会发现nv的病变明显多于其他类。在我的testtrain拆分后,我获得了这些数字。{0: 271, 1: 412, 2: 869, 3: 88, 4: 899, 5: 5367, 6: 119} 对于我的训练数据集, 5 这里代表的是nv。我尝试了几种不同的损失函数(categorical_crossentropy,categorical_hinge),几种不同的优化器(sgd,adam),和几种不同的实现class_weights的方法(totalcount,5367count,log(5367count),以及手动设置权重的 5 小于1)。) 经过这一切,我要么得到不停的nv猜测,要么我把nv的权重压得很低,得到次猜测的准确率。我已经没有办法了,不知道还能做什么。我也考虑过重做我的testtrain拆分,让test中每个类的计数是统一的,但我怕那样会花很多时间,只怕不行。

下面是模型的代码

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))
python tensorflow computer-vision image-recognition multiclass-classification
1个回答
0
投票

改变你的最终层的顺序。从。

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)
© www.soinside.com 2019 - 2024. All rights reserved.