200类分类NASNet-验证集中的精度为0.5%top1和100.00%top5

时间:2019-07-15 19:31:00

标签: python tensorflow keras

我想在微小的imagenet上训练神经网络,是imagenet的子集,其中包含200个班级,100个培训和每个班级50个验证示例。我制作了自己的自制软件模型,经过几个小时的训练,结果还是不错的,准确率大约为50%(相比之下,随机猜测器的名义准确度为0.5%)。

我决定尝试对数据集使用NASNet Mobile ,只是为了进行比较。微小的imagenet是64x64,因此我必须从头开始进行培训。 训练集的统计数据是正常的,其行为与我的模型相似:损失随着时间的推移而下降,top1的准确度提高,top5的准确度仍然两倍。但是,验证集的统计数据非常奇怪。损耗徘徊在16左右, top1精度徘徊在标称值0.5%左右,top5精度在某种程度上徘徊在100%左右! ,则值恰好是16.0375、0.0050和1.0000。只是要重申/澄清,当我使用我的原始模型时,这些统计数据表现正常(即比训练统计数据稍差),因此验证数据集极不可能出现任何问题。

您知道这里可能发生什么吗?

每个时期的确切值:

loss,    top1,   top5
 9.2969, 0.0089, 0.0400
 8.7959, 0.0078, 0.0321
10.6961, 0.0045, 0.0285
15.5161, 0.0047, 0.6299
16.0365, 0.0050, 0.9990
16.0375, 0.0050, 1.0000
16.0375, 0.0050, 1.0000
15.9631, 0.0052, 0.3202
14.9192, 0.0067, 0.0397
15.4905, 0.0079, 0.0325
15.1849, 0.0088, 0.0931
16.0348, 0.0050, 0.8777
16.0332, 0.0050, 0.9470
15.9706, 0.0050, 0.1261
16.0375, 0.0050, 1.0000
16.0375, 0.0050, 0.9708
16.0375, 0.0050, 1.0000
16.0375, 0.0050, 1.0000
16.0361, 0.0050, 0.8446
16.0375, 0.0050, 0.9984
16.0375, 0.0050, 1.0000
16.0375, 0.0050, 1.0000
16.0375, 0.0050, 0.9921
16.0375, 0.0050, 0.9999
16.0375, 0.0050, 1.0000
16.0303, 0.0051, 0.8937
16.0375, 0.0050, 0.9972
16.0326, 0.0050, 0.9060
16.0375, 0.0050, 0.9999
16.0375, 0.0050, 0.9847
15.9857, 0.0064, 0.7041
15.9492, 0.0079, 0.6022
15.9534, 0.0069, 0.4905

我为NASNet设置的代码:

def build_nas_model(image_shape):
    base_model = NASNetMobile(weights=None, include_top=False, input_shape=image_shape)

    x = base_model.output
    x = GlobalAveragePooling2D()(x)
    x = Dense(1024, activation='relu')(x)

    predictions = Dense(num_classes, activation='softmax')(x)

    model = Model(inputs=base_model.input, outputs=predictions)

    model.compile(loss=keras.losses.categorical_crossentropy,
        optimizer=keras.optimizers.RMSprop(),
        metrics=['accuracy', 'top_k_categorical_accuracy'])

    return model

用于运行模型的代码,两个模型使用的代码完全相同:

batch_size = 100
num_classes = 200
epochs = 1000
img_rows, img_cols, img_channels = 64, 64, 3

def main():
    augmenter = ImageDataGenerator(rescale=1./255, rotation_range=30, width_shift_range=0.1, height_shift_range=0.1, zoom_range=0.1, horizontal_flip=True)
    train_data = augmenter.flow_from_directory("./tiny-imagenet-200/train/", target_size=(64, 64), batch_size=batch_size)
    validation_data = ImageDataGenerator(rescale=1./255).flow_from_directory("./tiny-imagenet-200/val/", target_size=(64, 64), batch_size=batch_size, shuffle=True)

    model = build_nas_model(image_shape=(img_rows, img_cols, img_channels))

    model.fit_generator(
        generator=train_data,
        steps_per_epoch=len(train_data) / 5,
        epochs=epochs,
        verbose=1,
        validation_data=validation_data,
        validation_steps=len(validation_data),
        callbacks=callbacks
    )

还有我的工作模型供参考:

def build_my_model(image_shape):
    model = Sequential()

    model.add(Conv2D(32, (3, 3), input_shape=image_shape))

    # then a bunch of conv, batchnorm, relu, dense, etc.  

    model.add(Dense(num_classes, activation='softmax'))

    model.compile(loss=keras.losses.categorical_crossentropy,
        optimizer=keras.optimizers.Adadelta(),
        metrics=['accuracy', 'top_k_categorical_accuracy'])

    return model

1 个答案:

答案 0 :(得分:1)

这是由于模型针对给定示例预测了大多数类别的0.00000000。 Keras使用in_top_k来计算top_k_categorical_accuracy度量。在文档中:

  

请注意,InTopK的行为在处理联系方面与TopK op不同。如果多个类别具有相同的预测值并跨越顶部k边界,则所有这些类别均被视为位于顶部k中。

因此,所有0的预测都是并列的,只要4个或更少的预测为非零,就将计为顶部“ 5”的一部分。这意味着所有200个类别均排在前5名,因此该指标的准确性为1.0000。

相关GitHub问题:#10767