做網(wǎng)站品牌怎么注冊自己公司的網(wǎng)址
一、說明
? ? ? ? TensorFlow 2發(fā)布已經(jīng)接近5年時間,不僅繼承了Keras快速上手和易于使用的特性,同時還擴展了原有Keras所不支持的分布式訓(xùn)練的特性。3大設(shè)計原則:簡化概念,海納百川,構(gòu)建生態(tài).這是本系列的第三部分,我們將創(chuàng)建代價函數(shù)并在 TensorFlow 2 中使用它們。
?

二、關(guān)于代價函數(shù)
????????神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)將訓(xùn)練數(shù)據(jù)中的一組輸入映射到一組輸出。它通過使用某種形式的優(yōu)化算法來實現(xiàn)這一點,例如梯度下降、隨機梯度下降、AdaGrad、AdaDelta 或一些最近的算法,例如 Adam、Nadam 或 RMSProp。梯度下降中的“梯度”指的是誤差梯度。每次迭代后,網(wǎng)絡(luò)都會將其預(yù)測輸出與實際輸出進行比較,然后計算“誤差”。通常,對于神經(jīng)網(wǎng)絡(luò),我們尋求最小化錯誤。因此,用于最小化誤差的目標(biāo)函數(shù)通常稱為成本函數(shù)或損失函數(shù),并且由“損失函數(shù)”計算的值簡稱為“損失”。各種問題中使用的典型損失函數(shù) –
A。均方誤差
b.?均方對數(shù)誤差
C。二元交叉熵
d.?分類交叉熵
e.?稀疏分類交叉熵
????????在Tensorflow中,這些損失函數(shù)已經(jīng)包含在內(nèi),我們可以如下所示調(diào)用它們。
? ? ? ? 1 損失函數(shù)作為字符串
model.compile(損失='binary_crossentropy',優(yōu)化器='adam',指標(biāo)=['準(zhǔn)確性'])
????????或者,
????????2. 損失函數(shù)作為對象
從tensorflow.keras.losses導(dǎo)入mean_squared_error
model.compile(損失=mean_squared_error,優(yōu)化器='sgd')
????????將損失函數(shù)作為對象調(diào)用的優(yōu)點是我們可以在損失函數(shù)旁邊傳遞參數(shù),例如閾值。
從tensorflow.keras.losses導(dǎo)入mean_squared_error
model.compile(損失=均方誤差(參數(shù)=值),優(yōu)化器='sgd')
三、使用函數(shù)創(chuàng)建自定義損失:
????????為了使用函數(shù)創(chuàng)建損失,我們需要首先命名損失函數(shù),它將接受兩個參數(shù),y_true(真實標(biāo)簽/輸出)和y_pred(預(yù)測標(biāo)簽/輸出)。
def loss_function(y_true, y_pred):
***一些計算***
回波損耗
四、創(chuàng)建均方根誤差損失 (RMSE):
????????損失函數(shù)名稱 — my_rmse
????????目的是返回目標(biāo) (y_true) 和預(yù)測 (y_pred) 之間的均方根誤差。
????????RMSE 公式:
- 誤差:真實標(biāo)簽和預(yù)測標(biāo)簽之間的差異。
- sqr_error:誤差的平方。
- mean_sqr_error:誤差平方的平均值
- sqrt_mean_sqr_error:誤差平方均值的平方根(均方根誤差)。
import tensorflow as tf
import numpy as np
from tensorflow import keras
from tensorflow.keras import backend as K
#defining the loss function
def my_rmse(y_true, y_pred):#difference between true label and predicted labelerror = y_true-y_pred #square of the errorsqr_error = K.square(error)#mean of the square of the errormean_sqr_error = K.mean(sqr_error)#square root of the mean of the square of the errorsqrt_mean_sqr_error = K.sqrt(mean_sqr_error)#return the errorreturn sqrt_mean_sqr_error
#applying the loss function
model.compile (optimizer = 'sgd', loss = my_rmse)
五、創(chuàng)建 Huber 損失?

?????????Huber損失的公式:
????????這里,
????????δ是閾值,
????????a是誤差(我們將計算 a ,標(biāo)簽和預(yù)測之間的差異)
????????所以,當(dāng)|a|?≤δ,損失= 1/2*(a)2
????????當(dāng)|a|>δ 時,損失 = δ(|a| — (1/2)*δ)
????????代碼:
# creating the Conv-Batch Norm blockdef conv_bn(x, filters, kernel_size, strides=1):x = Conv2D(filters=filters, kernel_size = kernel_size, strides=strides, padding = 'same', use_bias = False)(x)x = BatchNormalization()(x)
return x
????????解釋:
????????首先我們定義一個函數(shù) -?my huber loss,它接受 y_true 和 y_pred
????????接下來我們設(shè)置閾值 = 1。
????????接下來我們計算誤差?a = y_true-y_pred
????????接下來我們檢查誤差的絕對值是否小于或等于閾值。is_small_error返回一個布爾值(True 或 False)。
????????我們知道,當(dāng)|a|?≤δ,loss = 1/2*(a)2,因此我們將small_error_loss計算為誤差的平方除以2?。
????????否則,當(dāng)|a|?>δ,則損失等于 δ(|a| — (1/2)*δ)。我們在big_error_loss中計算這一點。
????????最后,在return語句中,我們首先檢查is_small_error是true還是false,如果是true,函數(shù)返回small_error_loss,否則返回big_error_loss。這是使用 tf.where 完成的。
????????然后我們可以使用下面的代碼編譯模型,
model.compile(optimizer='sgd', loss=my_huber_loss)
在前面的代碼中,我們始終使用閾值1。
但是,如果我們想要調(diào)整超參數(shù)(閾值)并在編譯期間添加新的閾值,該怎么辦?然后我們必須使用函數(shù)包裝,即將損失函數(shù)包裝在另一個外部函數(shù)周圍。我們需要一個包裝函數(shù),因為默認情況下任何損失函數(shù)只能接受 y_true 和 y_pred 值,并且我們不能向原始損失函數(shù)添加任何其他參數(shù)。
5.1 使用包裝函數(shù)的 Huber 損失
????????包裝函數(shù)代碼如下所示:
import tensorflow as tf
#wrapper function which accepts the threshold parameter
def my_huber_loss_with_threshold(threshold):def my_huber_loss(y_true, y_pred): error = y_true - y_pred is_small_error = tf.abs(error) <= threshold small_error_loss = tf.square(error) / 2 big_error_loss = threshold * (tf.abs(error) - (0.5 * threshold))return tf.where(is_small_error, small_error_loss, big_error_loss)return my_huber_loss
在這種情況下,閾值不是硬編碼的。相反,我們可以在模型編譯期間通過閾值。
model.compile(optimizer='sgd', loss=my_huber_loss_with_threshold(threshold=1.5))
5.2 使用類的 Huber 損失 (OOP)
import tensorflow as tf
from tensorflow.keras.losses import Lossclass MyHuberLoss(Loss): #inherit parent class#class attributethreshold = 1#initialize instance attributesdef __init__(self, threshold):super().__init__()self.threshold = threshold#compute lossdef call(self, y_true, y_pred):error = y_true - y_predis_small_error = tf.abs(error) <= self.thresholdsmall_error_loss = tf.square(error) / 2big_error_loss = self.threshold * (tf.abs(error) - (0.5 * self.threshold))return tf.where(is_small_error, small_error_loss, big_error_loss)
????????MyHuberLoss是類名。在類名之后,我們從tensorflow.keras.losses繼承父類'Loss'。所以MyHuberLoss繼承為Loss。這允許我們使用 MyHuberLoss 作為損失函數(shù)。
????????__init__從類中初始化對象。
????????從類實例化對象時執(zhí)行的調(diào)用函數(shù)
????????init 函數(shù)獲取閾值,call 函數(shù)獲取我們之前出售的 y_true 和 y_pred 參數(shù)。因此,我們將閾值聲明為類變量,這允許我們給它一個初始值。
????????在 __init__ 函數(shù)中,我們將閾值設(shè)置為 self.threshold。
????????在調(diào)用函數(shù)中,所有閾值類變量將由 self.threshold 引用。
????????以下是我們?nèi)绾卧?model.compile 中使用這個損失函數(shù)。
model.compile(optimizer='sgd', loss=MyHuberLoss(threshold=1.9))
六、創(chuàng)建對比損失(用于暹羅網(wǎng)絡(luò)):
????????連體網(wǎng)絡(luò)比較兩個圖像是否相似。對比損失是暹羅網(wǎng)絡(luò)中使用的損失函數(shù)。
????????在上面的公式中,
????????Y_true 是圖像相似度細節(jié)的張量。如果圖像相似,它們就是 1,如果不相似,它們就是 0。
????????D 是圖像對之間的歐幾里德距離的張量。
????????邊距是一個常量,我們可以用它來強制它們之間的最小距離,以便將它們視為相似或不同。
????????如果Y_true =1,則方程的第一部分變?yōu)?D2,第二部分變?yōu)榱恪R虼?#xff0c;當(dāng) Y_true 接近 1 時,D2 項具有更大的權(quán)重。
????????如果Y_true = 0,則方程的第一部分變?yōu)榱?#xff0c;第二部分產(chǎn)生一些結(jié)果。這為最大項賦予了更大的權(quán)重,而為 D 平方項賦予了更少的權(quán)重,因此最大項在損失的計算中占主導(dǎo)地位。
使用包裝函數(shù)的對比損失
def contrastive_loss_with_margin(margin):def contrastive_loss(y_true, y_pred):square_pred = K.square(y_pred)margin_square = K.square(K.maximum(margin - y_pred, 0))return K.mean(y_true * square_pred + (1 - y_true) * margin_square)return contrastive_loss
七、結(jié)論?
????????Tensorflow 中不可用的任何損失函數(shù)都可以使用函數(shù)、包裝函數(shù)或以類似的方式使用類來創(chuàng)建。阿瓊·薩卡