【问题标题】:Keras neural network outputting function parameters / how to construct loss function?Keras神经网络输出函数参数/如何构造损失函数?
【发布时间】:2018-02-23 22:51:45
【问题描述】:

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

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

感谢您的帮助!

【问题讨论】:

  • 我认为你需要把它变得更具体,看看它是否可行。输出将如何用作函数参数?请注意,如果我们谈论的是具有多个神经元的神经网络,则神经网络的单个输出是向量,而参数是矩阵。假设您这样做了,那么您将使用什么作为该函数的输入? (顺便想想这样的问题很酷,它会产生有助于理解的其他问题的连锁反应)
  • 让我看看我是否可以进一步澄清。想象一下输出层有四个神经元。每个神经元输出一个标量值。所以有四个标量 a、b、c、d 来自输出层。我想计算一个函数 F(a, b, c, d, x) = Asin(bx+c)+d。对于每个训练操作/时间间隔,我将运行 F(a, b, c, d, 1) 到 F(a, b, c, d, 20) 以生成 20 个输出。然后我将计算这 20 个输出和标签张量中的 20 个值之间的 MSE。
  • 在 F(a,b,c,d,x) 中,x 是什么?
  • X 是值 1 到 20。也就是说,我想通过运行 Asin(B*1+C)+D、Asin(B*2+C)+D 等生成 20 个元素. 目标是有一个 20 元素的标签张量,和一个 20 元素的输出张量,这样我就可以取匹配元素之间的 MSE。
  • 澄清一下,X 是否是包含 [1, 2, 3, ..., 20] 的张量,或者我是否迭代调用 F(a, b, c, d, 1),然后是 F(a, b, c, d, 2) 等。对我来说重要的是我生成一个 20 元素的输出张量来匹配 20 元素的标签张量。

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


【解决方案1】:

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

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

因此,假设您已将模型准备到输出参数的层(最有可能是 A 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 行都将重复。

【讨论】:

  • 太棒了。这正是我所需要的。我已经开始意识到 lambda 层将成为要走的路,但是您对完整解决方案的解释会很有帮助。非常感谢。
  • 太棒了 :) -- 请考虑将此答案标记为正确。
  • 完成! - 这个复选标记并不是 UI 中最明显的部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-25
  • 2020-11-05
  • 2019-06-27
  • 2019-09-02
  • 2020-01-26
  • 2019-10-06
  • 1970-01-01
相关资源
最近更新 更多