【问题标题】:Keras Why binary classification isn't as accurate as categorical calssificationKeras 为什么二进制分类不如分类分类准确
【发布时间】:2019-12-19 12:50:50
【问题描述】:

我正在尝试创建一个可以判断图像中是否有鸟的模型。

我使用分类来训练模型以识别 Bird vs.花,结果在识别这两个类方面非常成功。

但是,当我将其更改为二元分类以检测图像中是否存在鸟类时,准确度急剧下降。

我改用二进制分类的原因是,如果我 为我的分类分类训练模型提供了一条狗,它 认出这只狗是一只鸟。

顺便说一句,这是我的数据集结构:

培训: 5000 张鸟类图片和 2000 张非鸟类图片

验证: 1000 张鸟类图片和 500 张非鸟类图片

有人说,不平衡的数据集也会出问题。是真的吗?

有人能指出我在以下代码中哪里出错了吗?

def get_num_files(path):
    if not os.path.exists(path):
        return 0
    return sum([len(files) for r, d, files in os.walk(path)])

def get_num_subfolders(path):
    if not os.path.exists(path):
        return 0
    return sum([len(d) for r, d, files in os.walk(path)])

def create_img_generator():
    return ImageDataGenerator(
        preprocessing_function=preprocess_input,
        rotation_range=30,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True
    )

INIT_LT = 1e-3
Image_width, Image_height = 299, 299
Training_Epochs = 30
Batch_Size = 32
Number_FC_Neurons = 1024
Num_Classes = 2

train_dir = 'to my train folder'
validate_dir = 'to my validation folder'


num_train_samples = get_num_files(train_dir)
num_classes = get_num_subfolders(train_dir)
num_validate_samples = get_num_files(validate_dir)

num_epoch = Training_Epochs
batch_size = Batch_Size

train_image_gen = create_img_generator()
test_image_gen = create_img_generator()

train_generator = train_image_gen.flow_from_directory(
    train_dir,
    target_size=(Image_width, Image_height),
    batch_size = batch_size,
    seed = 42
)

validation_generator = test_image_gen.flow_from_directory(
    validate_dir,
    target_size=(Image_width, Image_height),
    batch_size=batch_size,
    seed=42
)

Inceptionv3_model = InceptionV3(weights='imagenet', include_top=False)
print('Inception v3 model without last FC loaded')

x = Inceptionv3_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(Number_FC_Neurons, activation='relu')(x)
predictions = Dense(num_classes, activation='softmax')(x)

# model = Model(inputs=Inceptionv3_model.input, outputs=predictions)
v3model = Model(inputs=Inceptionv3_model.input, outputs=predictions)
# Use new Sequential model to add v3model and add a bath normalization layer after
model = Sequential()
model.add(v3model)
model.add(BatchNormalization()) # added normalization
print(model.summary())

print('\nFine tuning existing model')

Layers_To_Freeze = 172
for layer in model.layers[:Layers_To_Freeze]:
    layer.trainable = False
for layer in model.layers[Layers_To_Freeze:]:
    layer.trainable = True

optizer = Adam(lr=INIT_LT, decay=INIT_LT / Training_Epochs)
# optizer = SGD(lr=0.0001, momentum=0.9)
model.compile(optimizer=optizer, loss='binary_crossentropy', metrics=['accuracy'])

cbk_early_stopping = EarlyStopping(monitor='val_acc', mode='max')

history_transfer_learning = model.fit_generator(
    train_generator,
    steps_per_epoch = num_train_samples,
    epochs=num_epoch,
    validation_data=validation_generator,
    validation_steps = num_validate_samples,
    class_weight='auto',
    callbacks=[cbk_early_stopping]
)

model.save('incepv3_transfer_mini_binary.h5', overwrite=True, include_optimizer=True)

【问题讨论】:

  • 在最后一个 Dense 层中使用 sigmoid 而不是 softmax 进行二进制分类。
  • 感谢@VivekMehta,一旦完成,我会试一试并更新。谢谢

标签: tensorflow machine-learning keras deep-learning


【解决方案1】:

分类

  • 使用Num_Classes = 2
  • 使用 one-hot-encoded 目标(例如:Bird = [1, 0]、Flower = [0, 1])
  • 使用'softmax'激活
  • 使用'categorical_crossentropy'

二进制

  • 使用Num_Classes = 1
  • 使用二进制目标(例如:is flower = 1 | not flower = 0)
  • 使用'sigmoid'激活
  • 使用'binary_crossentropy'

详情请看:Using categorical_crossentropy for only two classes

【讨论】:

  • 嗨丹尼尔,非常感谢您的回答。我是 AI 领域的新手,你能给我一些代码来演示它是什么意思 -> 使用二进制目标吗?我的文件夹结构如下:train/birds、train/notbirds、validate/birds、validate/notbirds。你说的是这个吗?
  • 嗨,如果我的假设是正确的,我已经相应地更新了我的代码并开始了我的训练。我的观察是准确度真的很低。它已经训练了 450/1200,但准确率只有 32%。而之前,我观察到准确度非常高。我应该增加数据集的大小吗?
  • 您的y_train 必须为(samples, 1),其值为0=not bird 和1=bird。如果您使用的是 keras ImageDataGenerator,请使用 class_mode='binary'(我不知道这样做的结果是什么,但您必须检查生成器输出的内容)
  • 如果你擅长分类,为什么要改为二进制?
  • 是的,更多的非鸟类图像,不完全是数量,而是各种不同的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-21
  • 2021-05-02
  • 2022-01-12
  • 2019-10-19
  • 2017-05-10
  • 2018-11-23
相关资源
最近更新 更多