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

三、評估指標metrics

KS指標適合二分類問題,其計算方式為 KS=max(TPR-FPR).

其中TPR=TP/(TP+FN) , FPR = FP/(FP+TN)
TPR曲線實際上就是正樣本的累積分布曲線(CDF),FPR曲線實際上就是負樣本的累積分布曲線(CDF)。

KS指標就是正樣本和負樣本累積分布曲線差值的最大值。

#類形式的自定義評估指標
class KS(metrics.Metric):
    
    def __init__(self, name = "ks", **kwargs):
        super(KS,self).__init__(name=name,**kwargs)
        self.true_positives = self.add_weight(
            name = "tp",shape = (101,), initializer = "zeros")
        self.false_positives = self.add_weight(
            name = "fp",shape = (101,), initializer = "zeros")
   
    @tf.function
    def update_state(self,y_true,y_pred):
        y_true = tf.cast(tf.reshape(y_true,(-1,)),tf.bool)
        y_pred = tf.cast(100*tf.reshape(y_pred,(-1,)),tf.int32)
        
        for i in tf.range(0,tf.shape(y_true)[0]):
            if y_true[i]:
                self.true_positives[y_pred[i]].assign(
                    self.true_positives[y_pred[i]]+1.0)
            else:
                self.false_positives[y_pred[i]].assign(
                    self.false_positives[y_pred[i]]+1.0)
        return (self.true_positives,self.false_positives)
    
    @tf.function
    def result(self):
    # cumsum,累加求和,結果為[[1],[2],[3],...[8]] reduce_sum 為求和,結果為8。二者相除。
        cum_positive_ratio = tf.truediv(
            tf.cumsum(self.true_positives),tf.reduce_sum(self.true_positives))
        cum_negative_ratio = tf.truediv(
            tf.cumsum(self.false_positives),tf.reduce_sum(self.false_positives))
        ks_value = tf.reduce_max(tf.abs(cum_positive_ratio - cum_negative_ratio)) 
        return ks_value


y_true = tf.constant([[1],[1],[1],[0],[1],[1],[1],[0],[0],[0],[1],[0],[1],[0]])
y_pred = tf.constant([[0.6],[0.1],[0.4],[0.5],[0.7],[0.7],
                      [0.7],[0.4],[0.4],[0.5],[0.8],[0.3],[0.5],[0.3]])

myks = KS()
myks.update_state(y_true,y_pred)
tf.print(myks.result())

四、優化器

https://zhuanlan.zhihu.com/p/32230623
在model.compile()時候,完成,損失函數,評估指標,優化器的設置。
深度學習優化算法大概經歷了 SGD -> SGDM -> NAG ->Adagrad -> Adadelta(RMSprop) -> Adam -> Nadam 這樣的發展歷程
在keras.optimizers子模塊中,它們基本上都有對應的類的實現。

SGD, 默認參數為純SGD, 設置momentum參數不為0實際上變成SGDM, 考慮了一階動量, 設置 nesterov為True后變成NAG,即 Nesterov Accelerated Gradient,在計算梯度時計算的是向前走一步所在位置的梯度。

Adagrad, 考慮了二階動量,對於不同的參數有不同的學習率,即自適應學習率。缺點是學習率單調下降,可能后期學習速率過慢乃至提前停止學習。

RMSprop, 考慮了二階動量,對於不同的參數有不同的學習率,即自適應學習率,對Adagrad進行了優化,通過指數平滑只考慮一定窗口內的二階動量。

Adadelta, 考慮了二階動量,與RMSprop類似,但是更加復雜一些,自適應性更強。

Adam, 同時考慮了一階動量和二階動量,可以看成RMSprop上進一步考慮了一階動量。

Nadam, 在Adam基礎上進一步考慮了 Nesterov Acceleration。

五、回調函數 callbacks

查看訓練模型的內在狀態和統計

model.fit(x,y,callbacks=[回調函數列表])


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM