在自定义keras层的调用函数中传递附加参数 [英] Pass additional parameter in call function of custom keras layer

查看:39
本文介绍了在自定义keras层的调用函数中传递附加参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个定制的keras层,目的是在推理过程中手动更改上一层的激活.以下是简单地将激活次数与数字相乘的基本层.

I created a custom keras layer with the purpose of manually changing activations of previous layer during inference. Following is basic layer that simply multiplies the activations with a number.

import numpy as np
from keras import backend as K
from keras.layers import Layer
import tensorflow as tf

class myLayer(Layer):

    def __init__(self, n=None, **kwargs):
        self.n = n
        super(myLayer, self).__init__(**kwargs)

    def build(self, input_shape):

        self.output_dim = input_shape[1]
        super(myLayer, self).build(input_shape)

    def call(self, inputs):

        changed = tf.multiply(inputs, self.n)

        forTest  = changed
        forTrain = inputs

        return K.in_train_phase(forTrain, forTest)

    def compute_output_shape(self, input_shape):
        return (input_shape[0], self.output_dim)

当我将其与IRIS数据集一起使用时,效果很好

It works fine when I use it like this with IRIS dataset

model = Sequential()
model.add(Dense(units, input_shape=(5,)))
model.add(Activation('relu'))
model.add(myLayer(n=3))
model.add(Dense(units))
model.add(Activation('relu'))
model.add(Dense(3))
model.add(Activation('softmax'))
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
model.summary()

但是现在我想将'n'从 init 移至调用函数,以便在训练后可以使用不同的n值来评估模型.这个想法是在n处有一个占位符,可以在调用评估函数之前用一些值来初始化它.我不确定如何实现这一目标.正确的方法是什么?谢谢

However now I want to move 'n' from init to the call function so I can apply different values of n after training to evaluate model. The idea is to have a placeholder inplace of n which can be initialzed with some value before calling the evaluate function on it. I am not sure how to achieve this. What would the correct approach for this? Thanks

推荐答案

您应该以与

You should work the same way the Concatenate layer does. (Search for class Concatenate(_Merge): in that link).

这些接受多个输入的层依赖于在列表中传递的输入(和输入形状).

These layers taking multiple inputs rely on the inputs (and the input shapes) being passed in a list.

请参见 build call comput_output_shape 中的验证部分:

See the verification part in build, call and comput_output_shape:

def call(self,inputs):
    if not isinstance(inputs, list):
        raise ValueError('This layer should be called on a list of inputs.')

    mainInput = inputs[0]
    nInput = inputs[1]

    changed = tf.multiply(mainInput,nInput)
    #I suggest using an equivalent function in K instead of tf here, if you ever want to test theano or another backend later. 
    #if n is a scalar, then just "changed=nInput * mainInput" is ok

    #....the rest of the code....

然后,您将其称为列表传递给该层.但是为此,我强烈建议您远离 Sequential 模型.它们纯粹是局限性.

Then you call this layer passing a list to it. But for that, I strongly recommend you move away from Sequential models. They're pure limitation.

from keras.models import Model

inputTensor = Input((5,)) # the original input (from your input_shape)

#this is just a suggestion, to have n as a manually created var
#but you can figure out your own ways of calculating n later
nInput = Input((1,))
    #old answer: nInput = Input(tensor=K.variable([n]))

#creating the graph
out = Dense(units, input_shape=(5,),activation='relu')(inputTensor)

#your layer here uses the output of the dense layer and the nInput
out = myLayer()([out,nInput])
    #here you will have to handle n with the same number of samples as x. 
    #You can use `inputs[1][0,0]` inside the layer

out = Dense(units,activation='relu')(out)
out = Dense(3,activation='softmax')(out)

#create the model with two inputs and one output:
model = Model([inputTensor,nInput], out)
    #nInput is now a part of the model's inputs

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])

使用旧答案,并使用 Input(tensor = ...),该模型将不会像通常那样要求将2个输入传递给 fit predict 方法.

Using the old answer, with Input(tensor=...), the model will not demand, as usually would happen, that you pass 2 inputs to the fit and predict methods.

但是使用新选项,并使用 Input(shape = ...),它将需要两个输入,因此:

But using the new option, with Input(shape=...) it will demand two inputs, so:

nArray = np.full((X_train.shape[0],1),n)
model.fit([X_train,nArray],Y_train,....)

不幸的是,我不能使它仅与具有一个元素的 n 一起使用.它必须具有与之完全相同的样本数(这是keras的限制).

Unfortunately, I coulnd't make it work with n having only one element. It must have exactly the same number of samples as (this is a keras limitation).

这篇关于在自定义keras层的调用函数中传递附加参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆