【11】二分类问题下 Binary Cross Entropy 的使用注意事项

Colab连结

接着昨天讨论到的 Cross Entropy ,今天把重点放到了 BinaryCrossEntropy 上,顾名思义,之所以叫 Binary 就代表此工具主要是用於探讨二元分类的问题,我们会将资料集换成 cats_vs_dogs 。

NUM_OF_CLASS = 2

train_split, ds_info = tfds.load(
    'cats_vs_dogs',
    split='train[:75%]',
    shuffle_files=True,
    as_supervised=True,
    with_info=True)

test_split, ds_info = tfds.load(
    'cats_vs_dogs',
    split='train[75%:]',
    shuffle_files=True,
    as_supervised=True,
    with_info=True)

fig = tfds.show_examples(train_split, ds_info)

print(f'number of train: {len(train_split)}')
print(f'number of test: {len(test_split)}')

https://ithelp.ithome.com.tw/upload/images/20210925/20107299jivBxAE2bk.png

实验一: CategoricalCrossentropy

因相对 oxford_flowers102,cats_vs_dogs 问题简单很多,所以我们把 epoch 从100降低到30个,模型很快就能够收敛。

base = tf.keras.applications.MobileNetV2(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
net = tf.keras.layers.GlobalAveragePooling2D()(base.output)
net = tf.keras.layers.Dense(NUM_OF_CLASS)(net)

model = tf.keras.Model(inputs=[base.input], outputs=[net])

model.compile(
    optimizer=tf.keras.optimizers.SGD(LR),
    loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
    metrics=[tf.keras.metrics.CategoricalAccuracy()],
)

start = timeit.default_timer()
history = model.fit(
    ds_train,
    epochs=EPOCHS,
    validation_data=ds_test,
    verbose=True)

产出:

loss: 2.8140e-04 - categorical_accuracy: 1.0000 - val_loss: 0.0401 - val_categorical_accuracy: 0.9916

https://ithelp.ithome.com.tw/upload/images/20210925/20107299c6BqmrOzmc.png

可以看到训练非常快就收敛,第4个 epoch 就有98%的准确度。

实验二:BinaryCrossEntropy

训练前有一个需要注意的地方,就是在输出的dense layer中,节点要设为1,因为两个分类可以简化成一个0~100%的分数,靠0%代表分类一,靠100%代表分类二。

base = tf.keras.applications.MobileNetV2(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
net = tf.keras.layers.GlobalAveragePooling2D()(base.output)
net = tf.keras.layers.Dense(1)(net). # dense node = 1

model = tf.keras.Model(inputs=[base.input], outputs=[net])

model.compile(
    optimizer=tf.keras.optimizers.SGD(LR),
    loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
    metrics=[tf.keras.metrics.BinaryAccuracy()],
)

start = timeit.default_timer()
history = model.fit(
    ds_train,
    epochs=EPOCHS,
    validation_data=ds_test,
    verbose=True)

产出:

loss: 7.6595e-04 - binary_accuracy: 0.9997 - val_loss: 0.0360 - val_binary_accuracy: 0.9921

https://ithelp.ithome.com.tw/upload/images/20210925/20107299enxiqZCUhy.png

收敛速度也是非常快,得到的结果和CategoricalCrossentropy差不多。

实验三:另类的用法,用 BinaryCrossEntropy 训练多分类!?

我自己在尝试 BinaryCrossEntropy 训练猫狗分类时,一开始意外的把最後的 dense layer 节点设成2,结果也是可以训练,所以我就好奇了,那如果我用 BinaryCrossEntropy 训练 oxford_flowers102 的102个分类呢?

base = tf.keras.applications.MobileNetV2(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
net = tf.keras.layers.GlobalAveragePooling2D()(base.output)
net = tf.keras.layers.Dense(NUM_OF_CLASS)(net)

model = tf.keras.Model(inputs=[base.input], outputs=[net])

model.compile(
    optimizer=tf.keras.optimizers.SGD(LR),
    loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
    metrics=[tf.keras.metrics.CategoricalAccuracy()],
)

start = timeit.default_timer()
history = model.fit(
    ds_train,
    epochs=EPOCHS,
    validation_data=ds_test,
    verbose=True)

产出:

loss: 0.0418 - categorical_accuracy: 0.6373 - val_loss: 0.0516 - val_categorical_accuracy: 0.2980

结果是可以的(不过要把label 做 one-hot encoding),只是训练的成果并不太好,经过了100个 epochs 准确度不到三成就是了...。

以上就是 BinaryCrossentropy 使用上的几个小心得,希望大家使用上时可以注意这几点。


<<:  [Day11]什麽是智慧合约?

>>:  图的连通 (5)

Day10:【TypeScript 学起来】只有 TS 才有的型别 : any / unknow / void / never

Q: 身为工程师,你觉得有什麽工具大大提高了工作效率? A: 单身 看文章的人表示: 看个文章也中...

【Day 12】Rich Menu 主选单

我们拿 YouBike 微笑单车 官方帐号为例。 红色框框我们都会称作为「主选单」,很多官方帐号都...

Day12 CSS基础设定介绍_1

文字及字体 文字大小及字体是我们在网页中最常设定跟调整的,在预设的字体中你可能找不到你想要的字体类型...

Day10 - 补漏

今天事情比较多,没啥进度,就先对先前的内容补点漏洞。 登入 进站画面除了Day07的几个Patter...

DAY19 专案进度按钮功能实现-3

class Root_Team(): def content(self): flex_message...