博客專欄

        EEPW首頁 > 博客 > 獨家 | 使用TensorFlow 2創建自定義損失函數

        獨家 | 使用TensorFlow 2創建自定義損失函數

        發布人:數據派THU 時間:2021-05-26 來源:工程師 發布文章

        作者:Arjun Sarkar

        翻譯:陳之炎

        校對:歐陽錦

        1.png

        神經網絡利用訓練數據,將一組輸入映射成一組輸出,它通過使用某種形式的優化算法,如梯度下降、隨機梯度下降、AdaGrad、AdaDelta等等來實現,其中最新的算法包括Adam、Nadam或RMSProp。梯度下降中的“梯度”是指誤差梯度。每次迭代之后,網絡將其預測輸出與實際輸出進行比較,然后計算出“誤差”。

        通常,對于神經網絡,尋求的是將誤差最小化。將誤差最小化的目標函數通常稱之為成本函數或損失函數,由“損失函數”計算出的值稱為“損失”。在各種問題中使用的典型損失函數有:

        均方誤差;

        均方對數誤差;

        二元交叉熵;

        分類交叉熵;

        稀疏分類交叉熵。

        Tensorflow已經包含了上述損失函數,直接調用它們即可,如下所示:

        1. 將損失函數當作字符串進行調用

        model.compile (loss = ‘binary_crossentropy’,optimizer = ‘adam’, metrics = [‘accuracy’])

        2. 將損失函數當作對象進行調用

        from tensorflow.keras.losses importmean_squared_error
        model.compile(loss = mean_squared_error,optimizer=’sgd’)

        將損失函數當作對象進行調用的優點是可以在損失函數中傳遞閾值等參數。

        from tensorflow.keras.losses import mean_squared_error
        model.compile (loss=mean_squared_error(param=value),optimizer = ‘sgd’)

        利用現有函數創建自定義損失函數:

        利用現有函數創建損失函數,首先需要定義損失函數,它將接受兩個參數,y_true(真實標簽/輸出)和y_pred(預測標簽/輸出)。

        def loss_function(y_true, y_pred):
        ***some calculation***
        return loss

        創建均方誤差損失函數 (RMSE):

        定義損失函數名稱-my_rmse。目的是返回目標(y_true)與預測(y_pred)之間的均方誤差。

        RMSE的公式為:

        2.jpg

        • 誤差:真實標簽與預測標簽之間的差異。

        • sqr_error:誤差的平方。

        • mean_sqr_error:誤差平方的均值。

        • sqrt_mean_sqr_error:誤差平方均值的平方根(均方根誤差)。

        3.png

        創建Huber損失函數:

        4.png圖2:Huber損失函數(綠色)和平方誤差損失函數(藍色)(來源:Qwertyus— Own work,CCBY-SA4.0,https://commons.wikimedia.org/w/index.php?curid=34836380)

        Huber損失函數的計算公式:

        5.jpg

        在此處,δ是閾值,a是誤差(將計算出a,即實際標簽和預測標簽之間的差異)。

        當|a|≤δ時,loss = 1/2*(a)2

        當 |a|>δ時,loss = δ(|a|—(1/2)*δ)

        源代碼:

        6.png

        詳細說明:

        首先,定義一個函數—— my huber loss,它需要兩個參數:y_true和y_pred,

        設置閾值threshold = 1。

        計算誤差error a = y_true-y_pred。接下來,檢查誤差的絕對值是否小于或等于閾值,is_small_error返回一個布爾值(真或假)。

        當|a|≤δ時,loss= 1/2*(a)2,計算small_error_loss, 誤差的平方除以2。否則,當|a| >δ時,則損失等于δ(|a|-(1/2)*δ),用big_error_loss來計算這個值。

        最后,在返回語句中,首先檢查is_small_error是真還是假,如果它為真,函數返回small_error_loss,否則返回big_error_loss,使用tf.where來實現。

        可以使用下述代碼來編譯模型:

        7.png

        在上述代碼中,將閾值設為1。

        如果需要調整超參數(閾值),并在編譯過程中加入一個新的閾值的話,必須使用wrapper函數進行封裝,也就是說,將損失函數封裝成另一個外部函數。在這里需要用到封裝函數(wrapper function),因為損失函數在默認情況下只能接受y_true和y_pred值,而且不能向原始損失函數添加任何其他參數。

        使用封裝后的Huber損失函數

        封裝函數的源代碼:

        8.png

        此時,閾值不是硬編碼,可以在模型編譯過程中傳遞該閾值。

        9.png

        使用類實現Huber損失函數(OOP)

        10.png

        其中,MyHuberLoss是類名稱,隨后從tensorflow.keras.losses繼承父類“Loss”, MyHuberLoss繼承了Loss類,之后可以將MyHuberLoss當作損失函數來使用。

        __init__   初始化該類中的對象。執行類實例化對象時調用函數,init函數返回閾值,調用函數得到y_true和y_pred參數,將閾值聲明為一個類變量,可以給它賦一個初始值。

        在__init__函數中,將閾值設置為self.threshold。在調用函數中,self.threshold引用所有的閾值類變量。在model.compile中使用這個損失函數:

        11.png

        創建對比性損失(用于Siamese網絡):

        12.jpg

        Siamese網絡可以用來比較兩幅圖像是否相似,Siamese網絡使用的損失函數為對比性損失。

        在上文的公式中,Y_true是關于圖像相似性細節的張量,如果圖像相似,則為1,如果圖像不相似,則為0。

        D是圖像對之間的歐氏距離的張量。邊際為一個常量,用它來設置將圖像區別為相似或不同的最小距離。如果為Y_true=1,則方程的第一部分為D2,第二部分為0,所以,當Y_true接近1時,D2的權重則更重。

        如果Y_true=0,則方程的第一部分變為0,第二部分會產生一些結果,這給了最大項更多的權重,給了D平方項更少的權重,此時,最大項在損失計算中占了優勢。

        使用封裝器函數實現對比損失函數:

        13.png

        結論

        在Tensorflow中沒有的損失函數都可以利用函數、包裝函數或類似的類來創建。

        原文標題:

        Creating custom Loss functionsusing TensorFlow 2

        原文鏈接:

        https://towardsdatascience.com/creating-custom-loss-functions-using-tensorflow-2-96c123d5ce6c

        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。

        負離子發生器相關文章:負離子發生器原理
        離子色譜儀相關文章:離子色譜儀原理


        關鍵詞: Python

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 商洛市| 景德镇市| 西乌| 马边| 武冈市| 三门县| 南郑县| 周宁县| 镇远县| 弋阳县| 吉木乃县| 湖南省| 温泉县| 鄂伦春自治旗| 娱乐| 新巴尔虎左旗| 南昌县| 江永县| 富源县| 正定县| 嘉定区| 霍邱县| 和龙市| 瑞昌市| 扎兰屯市| 金乡县| 成武县| 新巴尔虎左旗| 海门市| 斗六市| 聂拉木县| 龙门县| 吉林省| 蓬溪县| 准格尔旗| 藁城市| 长丰县| 洛浦县| 萍乡市| 耒阳市| 霍城县|