您可以使用NumPy操作在Keras中编写自定义损失函数吗?

2024-05-23 23:11:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我想训练一个ANN,其中不是最小化y_真和y_pred之间的均方误差,而是最小化f(y_真)和f(y_pred)之间的均方误差

f:R^15-->;R^12是一个非线性函数。f(y)=[f1(y)f2(y)…f12(y)]^T,以及

fk(y)=Xi_k*θk,k=1,2,3,…,12

Xi_k是系数的行向量,θ_k是列向量,其每个元素是y中的单项式,即θ_k的每个元素如下所示:

y(1)^a1*y(2)^a2*..*y(15)^a15

为了编写我的自定义损失函数,我需要进行所有这些计算,并加载包含Xi_k向量和每个k的不同度数组合(a1、a2、…、a15)的文件

我不确定是否可以使用Keras后端库实现这一点,因此我使用了NumPy操作。 但是当我运行model.compile()时,它会被卡住,持续运行数小时。我不知道是什么 这个问题。我以前没有python或Keras方面的经验

import keras.backend as Kb
import numpy as np

def custom_loss_fn(y_true, y_pred):

    # ytrue, ypred - (batchSize x 15)
    # fy_true, fy_pred - (batchSize x 12)

    matd = spio.loadmat('LPVmodel_iVarDeg.mat', squeeze_me=True) 
    # iVarDegk: degree of y to form monomials (NLbasisSize(k) x 15), k =1,2,3,...,12
    # NLbasisSize: number of different combinations of degree (a1,...,a15) foe each k (1x12)

    mate = spio.loadmat('PNLSS_model_modified.mat', squeeze_me=True)
    # Xi_k coefficient vectors

    bSize = matd['NLbasisSize']

    iVarDeg1 = matd['iVarDeg1'] # (bSize(1) x 15) array
    iVarDeg2 = matd['iVarDeg2']
    iVarDeg3 = matd['iVarDeg3']
    iVarDeg4 = matd['iVarDeg4']
    iVarDeg5 = matd['iVarDeg5']
    iVarDeg6 = matd['iVarDeg6']
    iVarDeg7 = matd['iVarDeg7']
    iVarDeg8 = matd['iVarDeg8']
    iVarDeg9 = matd['iVarDeg9']
    iVarDeg10 = matd['iVarDeg10']
    iVarDeg11 = matd['iVarDeg11']
    iVarDeg12 = matd['iVarDeg12']

        
    Xi1 = np.transpose(mate['Xim1']) # (1xbSize(1)) array
    Xi2 = np.transpose(mate['Xim2'])
    Xi3 = np.transpose(mate['Xim3'])
    Xi4 = np.transpose(mate['Xim4'])
    Xi5 = np.transpose(mate['Xim5'])
    Xi6 = np.transpose(mate['Xim6'])
    Xi7 = np.transpose(mate['Xim7'])
    Xi8 = np.transpose(mate['Xim8'])
    Xi9 = np.transpose(mate['Xim9'])
    Xi10 = np.transpose(mate['Xim10'])
    Xi11 = np.transpose(mate['Xim11'])
    Xi12 = np.transpose(mate['Xim12'])

    batchSize = m  
    fy_true = []
    fy_pred = []

    for i in range(batchSize):
        yin = y_true[i,:]
        tin = y_pred[i,:]
        Theta1 = NonlinearBasis(yin, iVarDeg1, bSize[0])
        Theta2 = NonlinearBasis(yin, iVarDeg2, bSize[1])
        Theta3 = NonlinearBasis(yin, iVarDeg3, bSize[2])
        Theta4 = NonlinearBasis(yin, iVarDeg4, bSize[3])
        Theta5 = NonlinearBasis(yin, iVarDeg5, bSize[4])
        Theta6 = NonlinearBasis(yin, iVarDeg6, bSize[5])
        Theta7 = NonlinearBasis(yin, iVarDeg7, bSize[6])
        Theta8 = NonlinearBasis(yin, iVarDeg8, bSize[7])
        Theta9 = NonlinearBasis(yin, iVarDeg9, bSize[8])
        Theta10 = NonlinearBasis(yin, iVarDeg10, bSize[9])
        Theta11 = NonlinearBasis(yin, iVarDeg11, bSize[10])
        Theta12 = NonlinearBasis(yin, iVarDeg12, bSize[11])

        Gamma1 = NonlinearBasis(tin, iVarDeg1, bSize[0])
        Gamma2 = NonlinearBasis(tin, iVarDeg2, bSize[1])
        Gamma3 = NonlinearBasis(tin, iVarDeg3, bSize[2])
        Gamma4 = NonlinearBasis(tin, iVarDeg4, bSize[3])
        Gamma5 = NonlinearBasis(tin, iVarDeg5, bSize[4])
        Gamma6 = NonlinearBasis(tin, iVarDeg6, bSize[5])
        Gamma7 = NonlinearBasis(tin, iVarDeg7, bSize[6])
        Gamma8 = NonlinearBasis(tin, iVarDeg8, bSize[7])
        Gamma9 = NonlinearBasis(tin, iVarDeg9, bSize[8])
        Gamma10 = NonlinearBasis(tin, iVarDeg10, bSize[9])
        Gamma11 = NonlinearBasis(tin, iVarDeg11, bSize[10])
        Gamma12 = NonlinearBasis(tin, iVarDeg12, bSize[11])

        temp_p = np.array([np.matmul(Xi1,Gamma1),np.matmul(Xi2,Gamma2),np.matmul(Xi3,Gamma3),np.matmul(Xi4,Gamma4),np.matmul(Xi5,Gamma5),np.matmul(Xi6,Gamma6),np.matmul(Xi7,Gamma7),np.matmul(Xi8,Gamma8),np.matmul(Xi9,Gamma9),np.matmul(Xi10,Gamma10),np.matmul(Xi11,Gamma11),np.matmul(Xi12,Gamma12)])

        temp_t = np.array([np.matmul(Xi1,Theta1),np.matmul(Xi2,Theta2),np.matmul(Xi3,Theta3),np.matmul(Xi4,Theta4),np.matmul(Xi5,Theta5),np.matmul(Xi6,Theta6),np.matmul(Xi7,Theta7),np.matmul(Xi8,Theta8),np.matmul(Xi9,Theta9),np.matmul(Xi10,Theta10),np.matmul(Xi11,Theta11),np.matmul(Xi12,Theta12)])
   
        fy_true.append(temp_t)
        fy_pred.append(temp_p)

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


# this function calculates the monomial vector given y and the combination of degree of each element of y

def NonlinearBasis(yin, iVarDeg, basisSize):
    # iVarDeg: degree of y to form monomials (basisSize x 15)
    # basisSize: number of different combinations of degree (a1,...,a15)

    nlb = []
    for i in range(basisSize):
        ypowerV = np.power(yin,iVarDeg[i,:])
        monomial = np.prod(ypowerV)
        nlb.append(monomial)

    return np.transpose(nlb) # column vector

Tags: oftruenpmatetransposetinpredxi