1. 程式人生 > 實用技巧 >tensorflow中階API (啟用函式,損失函式,評估指標,優化器,回撥函式)

tensorflow中階API (啟用函式,損失函式,評估指標,優化器,回撥函式)

一、啟用函式

1、從ReLU到GELU,一文概覽神經網路的啟用函式:
https://zhuanlan.zhihu.com/p/98863801
2、tensorflow使用啟用函式:一種是作為某些層的activation引數指定,另一種是顯式新增layers.Activation啟用層

import tensorflow as tf
from tensorflow.keras import layers,models
model = models.Sequential()
model.add(layers.Dense(32,input_shape = (None,16),activation = tf.nn.relu)) #通過activation引數指定
model.add(layers.Dense(10))
model.add(layers.Activation(tf.nn.softmax))  # 顯式新增layers.Activation啟用層

二、損失函式

1、內建損失函式
監督學習的目標函式由損失函式和正則化項組成。(Objective = Loss + Regularization)
損失函式在模型編譯時指定
迴歸模型: 均方誤差損失函式 mean_squared_error
二分類模型:二元交叉熵損失函式 binary_crossentropy
多分類模型:label 為one-hot編碼,則類別交叉熵損失函式 categorical_crossentropy
label為類別序號編碼,使用稀疏類別交叉熵損失函式sparse_categorical_crossentropy

model.compile(optimizer = "rmsprop",
        loss = "binary_crossentropy",metrics = ["AUC"])

2、自定義損失函式

2.1 自定義損失函式接收兩個張量y_true,y_pred作為輸入引數,並輸出一個標量作為損失函式值。
2.2 對tf.keras.losses.Loss進行子類化,重寫call方法實現損失的計算邏輯,從而得到損失函式的類的實現
自定義Focal Loss,一種對binary_crossentropy的改進損失函式形式
它在樣本不均衡和存在較多易分類的樣本時相比binary_crossentropy具有明顯的優勢。
它有兩個可調引數,alpha引數和gamma引數。其中alpha引數主要用於衰減負樣本的權重,gamma引數主要用於衰減容易訓練樣本的權重。
從而讓模型更加聚焦在正樣本和困難樣本上。
詳見《5分鐘理解Focal Loss與GHM——解決樣本不平衡利器》

https://zhuanlan.zhihu.com/p/80594704

\[focal\_loss(y,p) = \begin{cases} -\alpha (1-p)^{\gamma}\log(p) & \text{if y = 1}\\ -(1-\alpha) p^{\gamma}\log(1-p) & \text{if y = 0} \end{cases}\]

def focal_loss(gamma=2., alpha=0.75):
    
    def focal_loss_fixed(y_true, y_pred):
        bce = tf.losses.binary_crossentropy(y_true, y_pred)
        p_t = (y_true * y_pred) + ((1 - y_true) * (1 - y_pred))
        alpha_factor = y_true * alpha + (1 - y_true) * (1 - alpha)
        modulating_factor = tf.pow(1.0 - p_t, gamma)
        loss = tf.reduce_sum(alpha_factor * modulating_factor * bce,axis = -1 )
        return loss
    return focal_loss_fixed
class FocalLoss(tf.keras.losses.Loss):
    
    def __init__(self,gamma=2.0,alpha=0.75,name = "focal_loss"):
        self.gamma = gamma
        self.alpha = alpha

    def call(self,y_true,y_pred):
        bce = tf.losses.binary_crossentropy(y_true, y_pred)
        p_t = (y_true * y_pred) + ((1 - y_true) * (1 - y_pred))
        alpha_factor = y_true * self.alpha + (1 - y_true) * (1 - self.alpha)
        modulating_factor = tf.pow(1.0 - p_t, self.gamma)
        loss = tf.reduce_sum(alpha_factor * modulating_factor * bce,axis = -1 )
        return loss