Сериализация пользовательского динамического слоя c в тенорном потоке в керасе - PullRequest
0 голосов
/ 06 апреля 2020

Я довольно новичок в тензорном потоке, как и Python (перевод из R). В настоящее время я работаю над системой рекомендаций в python, используя керасы и тензор потока. Данные «одинарные», поэтому я знаю только, если кто-то нажал на что-то или нет.

Базовая модель построена с использованием функционального API и представляет собой базовую модель c (вход = матрица двоичного рейтинга с многократным горячим кодированием, выход = вероятность для класса) с одним скрытым слоем между ними. Чтобы упростить использование модели, я хочу иметь возможность добавлять метки классов и выводить прогнозы topN с метками классов и вероятностями. Поэтому вместо «Input = [[0,1,0,1,0,0,0,0]], Ouput = [[0.3,0.1,0.6,0.0]« я хочу иметь возможность делать как »Input = [['' apple ',' orange ',' bean ']], Ouput = [[' lemon ', banana'], [0.3,0.2]] ".

Для этого я тренирую основы c модель, а затем оберните два пользовательских слоя вокруг модели, один в начале и один в конце (как здесь: https://towardsdatascience.com/customize-classification-model-output-layer-46355a905b86) (я также пробовал feature_columns, они на самом деле не делали это для меня). Чтобы сделать входной пользовательский слой, мне нужно было установить для него значение «dynamici c = True», чтобы обеспечить активное выполнение. Я не мог найти способ создать слой для этой «токенизации» без использования стремительного выполнения. Пока все работает нормально.

Но теперь я не могу восстановить сохраненную модель (ни используя h5, ни save_model.pb). Я также указал метод «get_config» для пользовательских слоев, и все работает нормально, пока я сохраняю модель только со вторым пользовательским слоем в конце. Итак, я полагаю, что ошибка происходит, потому что первый слой - Dynami c. Итак, как мне реализовать динамический c пользовательский слой в керасах?

Я был бы очень признателен за любую помощь или даже мысли, так как я не смог найти подходящих topi c (или даже любого topi c покрытия Dynami c пользовательские слои в целом). Пожалуйста, найдите код здесь:

class LabelInputLayer(Layer):

    def __init__(self, labels, n_labels, **kwargs):
        self.labels = labels
        self.n_labels = n_labels
        super(LabelInputLayer, self).__init__(**kwargs)

    def call(self, x):
        batch_size = tf.shape(x)[0]

        tf_labels = tf.constant([self.labels], dtype="int32")
        n_labels = self.n_labels
        x = tf.constant(x)
        tf_labels = tf.tile(tf_labels,[batch_size,1])

# go through every instance and multi-hot encode labels

        for j in tf.range(batch_size):
            index = []
            for i in tf.range(n_labels):
                if tf_labels[j,i].numpy() in x[j,:].numpy():
                    index.append(True)
                else:
                    index.append(False)

# create initial rating matrix and append for each instance

            if j == 0:
                rating_te = tf.where(index,1,0)
            else:
                rating_row = tf.where(index,1,0)
                rating_te = tf.concat([rating_te,rating_row],0)

        rating_te = tf.reshape(rating_te, [batch_size,-1])

        return [rating_te]

    def compute_output_shape(self, input_shape):
        return tf.TensorShape([None, self.n_labels])

# define get_config to enable serialization of the layer

    def get_config(self):
        config={'labels':self.labels,
                'n_labels':self.n_labels}
        base_config = super(LabelInputLayer, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))

Здесь я создаю модель basi c:

#Create Functional Model---------------------

a = tf.keras.layers.Input(shape=[n_classes])
b = tf.keras.layers.Dense(4000, activation = "relu", input_dim = n_classes)(a)
c = tf.keras.layers.Dropout(rate = 0.2)(b)
d = tf.keras.layers.Dense(n_classes, activation = "softmax")(c)
nn_model = tf.keras.Model(inputs = a, outputs = d)

И это окончательная модель (работает в ноутбуке, но не может быть восстанавливается после сохранения, поэтому не используется в производстве):

input_layer = Input(shape = input_shape, name = "first_input")
encode_layer = LabelInputLayer(labels = labels, n_labels = n_labels, dynamic = True, input_shape = input_shape)(input_layer)
pre_trained = tf.keras.models.Sequential(nn_model.layers[1:])(encode_layer)
decode_layer = LabelLimitLayer(labels, n_preds)(pre_trained)
encoder_model = tf.keras.Model(inputs = input_layer, outputs = decode_layer)

Сохранение и восстановление модели:

tf.saved_model.save(encoder_model, "encoder_model")

model = tf.keras.models.load_model("encoder_model")

Это ошибка, которую я получаю, если хочу восстановить модель в другом Записная книжка (К сожалению, я также не могу использовать параметр «custom_objects» в методе загрузки, поскольку мне нужно развернуть модель только из файла сохранения):

ValueError: Could not find matching function to call loaded from the SavedModel. Got:
  Positional arguments (1 total):
    * Tensor("x:0", shape=(None, 10), dtype=float32)
  Keyword arguments: {}

Expected these arguments to match one of the following 0 option(s):

1 Ответ

0 голосов
/ 27 апреля 2020

Мне удалось обойти проблему, используя tf.functions вместо dynamic = True. Однако мне не удалось сохранить динамический слой c в Tensorflow. Может быть, это кому-то поможет.

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