iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
AI & Data

30 天在 Colab 嘗試的 30 個影像分類訓練實驗系列 第 11

【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 使用上的幾個小心得,希望大家使用上時可以注意這幾點。


上一篇
【10】多分類問題下 Sparse Cross Entropy 與 Categorical Cross Entropy 的用法差異
下一篇
【12】新手容易忽略的 logit 與 loss 之間的搭配
系列文
30 天在 Colab 嘗試的 30 個影像分類訓練實驗31

尚未有邦友留言

立即登入留言