Keras神经网络输出函数参数/如何构造损失函数?

时间:2017-09-14 20:34:02

标签: python tensorflow neural-network keras loss-function

我正在研究基于Keras / TensorFlow的神经网络。我想做一些不同的事情。

通常,网络的输出层产生输出张量(即数字列表)。然后使用诸如均方误差的损失函数将这些数字直接与训练数据(标签)的目标列表进行比较。

但是,我希望网络的输出层是一个用作功能参数的数字列表。该函数对这些参数进行操作以生成新的数字列表。然后,损失函数成为函数输出和标签之间的MSE(而不是通常情况下,输出层和标签之间的MSE)。

据我所知,我需要编写一个Keras自定义丢失函数,该函数根据输出图层值计算目标函数的值,然后计算并返回目标函数输出和标签之间的MSE。我也意识到所有这些都需要在TensorFlow图中完成,并且目标函数需要是可微分的,以便可以计算梯度。我相信我对这一切都很了解。

这是我无法解决的问题。假设输出层中有四个神经元 - 称为a,b,c,d。它们中的每一个都是目标函数F(a,b,c,d)的单独参数。假设我迭代F(a,b,c,d)20次并得到一组20个值。即,F(a,b,c,d,1); F(a,b,c,d,2);然后我只想在这20个值和相应标签张量中的20个值之间取MSE。这将是损失函数。

我只是不了解Keras / Tensorflow后端,知道如何获得输出张量的各个元素。如何解决此张量中的第0,第1,第2等元素,以便我可以使用它们来计算函数值?我知道如何在整个张量上执行操作,但我不明白如何处理单个张量元素。

我希望我已经足够清楚地解释了这个问题。

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

由于预测结果和标签必须具有相同的形状,我们应该创建一个包含所需功能的整个模型(不将该功能留给损失函数)。

稍后我们可以获取前一层的输出,这将是所需的参数。

因此,假设您已准备好您的模型,直到输出参数的图层(最可能为Dense(4),这将为每个输入样本输出4个参数

让我们在它之后添加两个lambda图层。

  • 一个输出独立于样本的4个唯一参数,因为您希望稍后检索它们
  • 一个是实际功能a*sin(bx + c) + d

所以:

#add them to your model the usual way you do
model.add(Lambda(getParameters,output_shape=(4,),name='paramLayer'))
model.add(Lambda(yourFunction,output_shape=(1,),name='valueLayer'))

其中:

import keras.backend as K

def getParameters(x):

    #since x comes in as a batch with shape (20,4) -- (or any other batch size different from 20)

    #let's condense X in one sample only, because we want only 4 elements, not 20*4 elements
    xCondensed = K.mean(x,axis=0,keepdims=True)
        #I'm using keepdims because we will need that x end up with the same number of samples for compatibility purposes (keras rules)

    #let's expand x again (for compatibility purposes), now repeating the 4 values 20 (or more) times
    return K.ones_like(x) * xCondensed



def yourFunction(x):


    #now x has 4 parameters (assuming you had a Dense(4) before these lambda layers)
    a = x[:,0]
    b = x[:,1]
    c = x[:,2]
    d = x[:,3]

    #creating the 20 (or more) iterations
    ones = K.ones_like(x[:,0])
    iterationsStartingAt1= K.cumsum(ones)
    iterationsStartingAt0= iterationsStartingAt1 - 1
    iterations = #choose one of the above


    return (a * K.sin((b*iterations) + c)) + d

现在您可以通过标签训练此模型。

当您想要检索这四个参数时,您需要另一个模型,它早先结束:

from keras.models import Model

paramModel = Model(model.inputs,model.get_layer('paramLayer').output)
params = paramModel.predict(testOrTrainData)

结果将形如(20,4),但所有20行都将重复。