Использование кода Python с tf.py_func в пользовательском слое Keras - PullRequest
0 голосов
/ 05 мая 2018

Я хочу написать свой собственный слой Keras, который вызывает функцию python. Итак, я наткнулся на tf.py_func, который на самом деле должен делать эту работу.

Я попробовал следующее: В методе вызова класса MyLayer я обернул свою пользовательскую функцию python myFunc в tf.py_func. Таким образом, call-метод возвращает tf.py_func(myFunc, [input], tf.float32).

Я получаю следующее сообщение об ошибке:

TypeError: unsupported operand type(s) for %=: 'int' and 'NoneType'

Как правильно вызывать функцию python в пользовательском слое Keras? Что я делаю не так?

Ответы [ 4 ]

0 голосов
/ 17 сентября 2018

Если вы объявляете веса в 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))
0 голосов
/ 05 мая 2018

Вам просто нужно обернуть свою функцию слоем 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')
    ])
0 голосов
/ 03 сентября 2018

Оберните вашу функцию слоем 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)
0 голосов
/ 05 мая 2018

Вам нужно будет показать код вашего слоя и функцию, которую вы передаете pyfunc, чтобы мы поняли ошибку. Однако, хотя есть возможность встроить функции tf в пользовательские слои Keras, лучшим вариантом в этом случае, вероятно, является использование лямбда-слоя Keras: https://keras.io/layers/core/#lambda

Это напрямую принимает функцию python в качестве параметра. Как и tf.py_func, он ожидает функцию, которая принимает массив numpy в качестве входных данных и выводит массив numpy.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...