Python 具有Lambda层的Keras

Python 具有Lambda层的Keras,python,machine-learning,lambda,keras,deep-learning,Python,Machine Learning,Lambda,Keras,Deep Learning,我对Keras比较陌生,我准备建立一个决斗Q网络来训练KI。我找到了一个代码片段来构建一个模型,这个模型似乎出人意料地有效。我只是不知道为什么,因为我不太熟悉Keras中的lambda表达式。谁能解释一下在下面的模型中创建lambda层是如何工作的? 非常感谢您的帮助 def build_model(): model = Sequential() model.add(Dense(units=16, activation='relu', input_dim = 2)) m

我对Keras比较陌生,我准备建立一个决斗Q网络来训练KI。我找到了一个代码片段来构建一个模型,这个模型似乎出人意料地有效。我只是不知道为什么,因为我不太熟悉Keras中的lambda表达式。谁能解释一下在下面的模型中创建lambda层是如何工作的? 非常感谢您的帮助

def build_model():

    model = Sequential()
    model.add(Dense(units=16, activation='relu', input_dim = 2))
    model.add(Dense(units=32, activation='relu'))
    model.add(Dense(units=9, activation='relu'))

    #I definitely don't understand how the following layer works:
    model.add(Lambda(lambda i: K.expand_dims(i[:,0],-1) + i[:,1:] - K.mean(i[:,1:], keepdims=True), output_shape=(8,)))

    model.add(Dense(units=8, activation='linear'))
    model.compile(loss='mse',
    optimizer = RMSprop(lr=0.001) )
    return model

我不熟悉您的特定研究领域,但我可以告诉您该层正在做什么。层是指您希望在输入上定义自定义操作的时候,这些输入不是来自于从Keras预定义的任何内容。具体来说,您希望对Keras尚未处理的层中的张量应用一些自定义操作

Lambda层的输入是一个输入,其中输入是进入该层的张量。但是请注意,您也可以在该层中指定任何函数或操作,而不必是匿名函数。。。只要它作用于输入张量并产生输出张量。然后定义要使用该输入张量执行的操作,它将创建一个相应的输出张量,该输出张量将被馈送到下一层。这种行为当然是假设一个前馈网络,这就是我在这里看到的。您可以将匿名函数视为用于执行操作的一次性函数,但您不希望它们在以后继续存在,因为在指定如何处理输入张量后,您不再需要它们

因此,lambda i表示您正在创建一个匿名函数,lambda层将对定义为i的输入张量进行操作。K.expand_dims可确保添加单个维度以用于。在这种情况下,我们希望获取输入张量i[:,0]的第一列,该列将成为1D数组,并确保输入张量是具有单个列的2D数组,即从N,数组到N x 1数组。-1参数是要展开的轴。将其设置为-1只会扩展最后一个维度,在本例中,最后一个维度是第一个也是唯一的维度

如果你不习惯广播,这个扩展阵列的加法运算有点难理解,但一旦你掌握了窍门,它就是计算中最强大的机制之一。I[,1:]对输入张量进行切片,以便我们考虑从第二列到结束的张量。在引擎盖下,将此切片张量与扩展的单列i[:,0]相加意味着此列将被复制,并分别添加到i[:,1:]中的每一列

例如,如果i[:,0]是[1,2,3,4],而i[:,1:]是[4,4,4],[5,5,5],[6,6,6,6],执行K.expand_dimsi[:,0],-1+i[:,1:]将导致[[5,6,7,8],[6,7,9],[7,8,9,10]

拼图的最后一块是:K.meani[:,1:,keepdims=True。我们取K.expand_dimsi[:,0],-1+i[:,1:],然后用K.meani[:,1:]减去它,keepdims=True。在此上下文中,K.mean将查找从第二列开始的所有行的张量中所有值的平均值。这是操作的默认行为。根据使用K.mean的方式,一个或多个维度可能会下降。K.mean的另一个输入是允许您指定哪个维度的轴要分析张量中的平均值的ons。例如,如果轴=0,则会分别查找每列的平均值。 这将减少为1D值张量。使用keepdims关键字,如果指定keepdims=True,这将确保张量仍然是2D,列数为1,即N x 1张量而不是N张量。默认行为为false

因此,通过进行K.mean运算,我们确保最终结果为1 x 1,并从K.expand_dimsi[:,0],-1+i[:,1:]结果的每个值中减去该值。由于广播,这也是可能的

最后,我们确保此操作的输出形状给出大小为8的一维张量

太长,读不下去了
这个操作是一个自定义操作,我们取输入张量的第一列,从第二列开始将其添加到所有其他列中,然后用第二列开始的所有其他列的平均值减去该结果的每个值。此外,我们约束张量的输出大小,使其为1D,带size 8。

太好了!详细的解释。但是,只有一件小事:Lambda层的输入是一个匿名函数。这不完全正确,因为你可以将任何函数传递到Lambda层,包括匿名函数。@今天哦,对了。谢谢。我已经更改了它。我可以投票吗?:当然:虽然,我不是问这个问题的人问:@今天每一点都有帮助!无论如何谢谢你!回答得很好!这让我了解了我在这里做什么。非常感谢!如果你不知道,请告诉我
艾德:没有更多的帮助了。谢谢你,你下面的回答完全解决了我理解这件事的问题: