簡體   English   中英

Keras 中的自定義損失 function:在循環中初始化並將值附加到張量

[英]Custom loss function in Keras: Initializing and appending values to a Tensor in loop

我正在使用 Keras 和 ZCB20B802A3F0255E054E4FB8821 后端函數 C 在 Keras 中編寫自定義損失 function 我想最小化 f(y_true) 和 f(y_pred) 之間的均方誤差,其中 f(y) 是非線性 function。

f(y) = [f1(y) f2(y)... f12(y)],並且 fk(y) = Xi_k*Theta_k(y),k = 1,2,...,12。 Xi_k 和 Theta_k(y) 是秩為 1 的張量。

由於 y_true 和 y_pred 的大小為 (batchSize x 15),我需要在一個循環中為訓練批次中的所有樣本計算 f(y) 的值(我相信避免循環是不可能的)。 循環操作的 output 的張量大小為 (batchSize x 12)

[[f(y_true[1,:])],[f(y_true[2,:])],...,[f(y_true[batchSize,:])]]

[[f(y_pred[1,:])],[f(y_pred[2,:])],...,[f(y_pred[batchSize,:])]]

通常,在處理 arrays 或矩陣時,我們會初始化所需大小的矩陣並在循環中為其分配值,或者我們在循環中創建一個空矩陣和 append 值給它。 但是我們如何對張量做同樣的事情呢?

下面是自定義損失 function 的簡化形式(僅計算 f1(y_true) 和 f1(y_pred))。 初始化和附加 function 不起作用,因為它們不是 tf/Keras 操作,我應該使用什么來代替這些以使其與張量一起使用?

matd = spio.loadmat('LPVmodel_iVarDeg.mat', squeeze_me=True) 
mate = spio.loadmat('PNLSS_model_modified.mat', squeeze_me=True)

def custom_loss_fn(y_true, y_pred):
    iVarDeg1 = tf.convert_to_tensor(matd['iVarDeg1'], dtype=tf.float32) # (XiSize(1) x 15)
    Xi1 = tf.convert_to_tensor(mate['Xim1'], dtype=tf.float32) # (XiSize(1) x 1) 

    batchSize = m 
    fy_true = [] # initialization
    fy_pred = [] # initialization

    for i in range(batchSize):
        yin = y_true[i,:]  # (1 x 15) network output
        tin = y_pred[i,:]  # (1 x 15) target
    
        ypowerD = tf.math.pow(yin,iVarDeg1) # element wise power (XiSize(1)x15)
        monomial = tf.math.reduce_prod(ypowerD) # column wise product of elements (XiSize(1)x1)
        Theta1 = monomial  # nonlinear basis for state eq 1 (XiSize(1)x1)
    
        ypowerD = tf.math.pow(tin,iVarDeg1)
        monomial = tf.math.reduce_prod(ypowerD)
        Gamma1 = monomial

        temp = tf.math.reduce_sum(tf.math.multiply(Xi1,Theta1)) # sum(element wise prod) 
        fy_true.append(temp)
    
        temp = tf.math.reduce_sum(tf.math.multiply(Xi1,Gamma1))
        fy_pred.append(temp)
    

    return Kb.mean(Kb.sum(Kb.square(fy_pred - fy_true))

在圖形模式下,如果要像列表一樣在循環中填充張量,可以使用 TensorArray:

'初始化' 例如:

ta = tf.TensorArray(tf.float32, size=0, dynamic_size=True, clear_after_read=False)

'附加':

ta = ta.write(1, 20)

將 TensorArray 轉換為張量:

ta.stack()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM