[深度之眼]TensorFlow2.0項目班-分類模型之自定義loss

準備工作:

from __future__ import absolute_import, division, print_function, unicode_literals

import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, Conv2D
from tensorflow.keras import Model
import numpy as np

# 很奇怪,pycharm不加這段報錯,anaconda加這段報錯,大家看情況
gpu = tf.config.experimental.list_physical_devices(device_type='GPU')
assert len(gpu) == 1
tf.config.experimental.set_memory_growth(gpu[0], True)

print(tf.__version__)
print(np.__version__)

我的版本 tf2.1.0 / np 1.18.4
載入數據並劃分數據集,預處理(歸一化,onehot編碼):

mnist = np.load("mnist.npz")
x_train, y_train, x_test, y_test = mnist['x_train'],mnist['y_train'],mnist['x_test'],mnist['y_test']

x_train, x_test = x_train / 255.0, x_test / 255.0
y_train = np.int32(y_train)
y_test = np.int32(y_test)
# Add a channels dimension
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]
y_train = tf.one_hot(y_train,depth=10)
y_test = tf.one_hot(y_test,depth=10)
train_ds = tf.data.Dataset.from_tensor_slices((x_train, y_train)).shuffle(10000).batch(32)
test_ds = tf.data.Dataset.from_tensor_slices((x_test, y_test)).shuffle(100).batch(32)

print(x_test.shape)

測試集輸入數據的shape:(10000, 28, 28, 1)
意味着一共10000張圖片,每張大小是28X28,灰度圖像
建立函數模型,並自定義損失函數,包括FocalLoss 和 經典的交叉熵損失函數:

def MyModel():
    inputs = tf.keras.Input(shape=(28,28,1), name='digits')
    x = tf.keras.layers.Conv2D(32, 3, activation='relu')(inputs)
    x = tf.keras.layers.Flatten()(x)
    x = tf.keras.layers.Dense(128, activation='relu')(x)
    outputs = tf.keras.layers.Dense(10,activation='softmax', name='predictions')(x)
    model = tf.keras.Model(inputs=inputs, outputs=outputs)
    return model

def FocalLoss(gamma=2.0,alpha=0.25):
    def focal_loss_fixed(y_true, y_pred):
        y_pred = tf.nn.softmax(y_pred,axis=-1)
        epsilon = tf.keras.backend.epsilon()
        y_pred = tf.clip_by_value(y_pred, epsilon, 1.0)
        y_true = tf.cast(y_true,tf.float32)
        loss = -  y_true * tf.math.pow(1 - y_pred, gamma) * tf.math.log(y_pred)
        loss = tf.math.reduce_sum(loss,axis=1)
        return  loss
    
    return focal_loss_fixed

def CCE():   #  CategoricalCrossentropy
    def CCE_fixed(y_true, y_pred):
        y_pred = tf.nn.softmax(y_pred,axis=-1)
        epsilon = tf.keras.backend.epsilon()
        y_pred = tf.clip_by_value(y_pred, epsilon, 1.0)
        y_true = tf.cast(y_true,tf.float32)
        loss = -  y_true * tf.math.log(y_pred)     
        loss = tf.math.reduce_sum(loss,axis=1)
        return  loss
    
    return CCE_fixed



model = MyModel()
model.compile(optimizer = tf.keras.optimizers.Adam(0.001), #優化器
              loss =  CCE(), #損失函數
              metrics = [tf.keras.metrics.CategoricalAccuracy()]
             ) #評估函數

model.fit(train_ds, epochs=5,validation_data=test_ds)

訓練結果:

Train for 1875 steps, validate for 313 steps
Epoch 1/5
1875/1875 [==============================] - 9s 5ms/step - loss: 1.5304 - categorical_accuracy: 0.9344 - val_loss: 1.4940 - val_categorical_accuracy: 0.9689
Epoch 2/5
1875/1875 [==============================] - 9s 5ms/step - loss: 1.4885 - categorical_accuracy: 0.9744 - val_loss: 1.4887 - val_categorical_accuracy: 0.9740
Epoch 3/5
1875/1875 [==============================] - 8s 4ms/step - loss: 1.4798 - categorical_accuracy: 0.9824 - val_loss: 1.4797 - val_categorical_accuracy: 0.9826
Epoch 4/5
1875/1875 [==============================] - 8s 4ms/step - loss: 1.4750 - categorical_accuracy: 0.9868 - val_loss: 1.4801 - val_categorical_accuracy: 0.9816
Epoch 5/5
1875/1875 [==============================] - 8s 4ms/step - loss: 1.4732 - categorical_accuracy: 0.9885 - val_loss: 1.4816 - val_categorical_accuracy: 0.9802
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章