1

我正在研究基于 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 后端,无法知道如何获取输出张量的各个元素。如何处理此张量中的第零个、第一个、第二个等元素,以便我可以使用它们来计算函数值?我知道如何对整个张量执行操作,但我不明白如何处理单个张量元素。

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

谢谢你的帮助!

4

1 回答 1

3

由于预测结果和标签必须具有相同的形状,我们应该创建一个完整的模型,其中包含您想要的函数(而不是将函数留给损失函数)。

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

因此,假设您已将模型准备到输出参数的层(Dense(4)很可能是 A,它将为每个输入样本输出 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 行都将重复。

于 2017-09-14T22:59:08.840 回答