我想编写自己的Keras层来调用python函数。
所以我遇到tf.py_func
应该真正做到这一点。
我尝试了以下内容:在 MyLayer 类的调用方法中,我在tf.py_func
中包装了自定义python函数 myFunc 。所以call-method返回tf.py_func(myFunc, [input], tf.float32)
。
我收到以下错误消息:
TypeError: unsupported operand type(s) for %=: 'int' and 'NoneType'
在自定义Keras图层中调用python函数的正确方法是什么?我做错了什么?
答案 0 :(得分:1)
您必须显示图层的代码以及传递给pyfunc的函数,以便我们了解错误。 但是,尽管可以在自定义Keras层中嵌入tf函数,但在这种情况下,最好的选择可能是使用Keras lambda层: https://keras.io/layers/core/#lambda
这直接将python函数作为参数。与tf.py_func一样,它期望一个函数将numpy数组作为输入并输出一个numpy数组。
答案 1 :(得分:1)
如果在def build(self,input_shape):处声明权重,则必须在tf.py_func调用之后“使用”所有权重。
import tensorflow as tf
from keras import backend as K
from keras.engine.topology import Layer
class MultiplyLayer(Layer):
def __init__(self, **kwargs):
super(MultiplyLayer, self).__init__(**kwargs)
def build(self, input_shape):
self.filters = self.add_weight(name='Filters', shape=(1, input_shape[1]), initializer='uniform', trainable=True)
super(MultiplyLayer, self).build(input_shape) # Be sure to call this at the end
def call(self, x):
xw = x * self.filters
def my_func(x):
return 5 * x
X = tf.py_func(my_func, [xw], tf.float32)
return X + (self.filters - self.filters)
def compute_output_shape(self, input_shape):
return (input_shape)
def get_model():
model = Sequential()
model.add(MultiplyLayer(input_shape=(num_features,)))
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy'])
return model
model = get_model()
model.summary()
model.fit(X_train, y_train_hot, batch_size=batch_size, epochs=epochs, verbose=verbose, validation_data=(X_test, y_test_hot))
答案 2 :(得分:0)
您只需要使用Lambda图层包装函数。 这是一个例子:
def complex_tf_fn(x):
u, v = tf.nn.moments(x, axes=[1], keep_dims=True)
return (x - u) / tf.sqrt(v)
with tf.device('/cpu:0'):
model = tf.keras.Sequential([
tf.keras.layers.Lambda(complex_tf_fn, input_shape=[784]),
tf.keras.layers.Dense(1024, activation='relu'),
tf.keras.layers.Lambda(complex_tf_fn),
tf.keras.layers.Dense(10, activation='softmax')
])
答案 3 :(得分:0)
使用Lambda
层包装函数,并在函数中调用py_func
。
def my_func(x):
return 5 * x
def my_lambda_func(x):
return py_func(my_func,[x],tf.float32)
x = Lambda(my_lambda_func)(x)