Keras: пользовательская предварительная обработка как часть вычислительного графа - PullRequest
0 голосов
/ 25 мая 2019

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

Из того, что я собрал, мне нужно передать полученный тензор в качестве входных данных в нейронную сеть, чтобы две части были соединены в графике.Важным примечанием является то, что предварительная обработка выполняется на всем обучающем наборе, что означает, что это нужно сделать только один раз.

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

Поскольку мой код довольно большой и сложный, я оставлю «полупсевдологический» код, чтобы просто показать суть того, что я пытаюсь сделать.

import tensorflow.keras.backend as K
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model

raw_data, target_data = load_data()
raw_tens = K.variable(raw_data)
out_tens = K.variable(target_data)

def preprocess(data_tens):
    input_tensor = ... # Preprocess the raw data using backend functions
    # Print statement to see when this operation is being performed
    input_tensor = K.print_tensor(input_tensor, message="Passed!")

    return input_tensor

in_tens = preprocess(raw_tens)

model_input = Input(tensor=in_tens)

# Define layers in the model
h = Dense(100, activation='tanh')(model_input)
...
output = Dense(1, activation='linear')(h)

# Define a custom loss function using the gradient wrt raw data
def custom_loss(y_true, y_pred):
    grad = K.gradients(y_pred, raw_tens)[0]

    loss = ... # some loss including the computed gradient
    return loss

# Define model and compile model using a custom loss function
model = Model(inputs=model_input, outputs=output)
model.compile(loss=custom_loss, optimizer='adam')

# Fit model
model.fit(y = out_tens, epochs = 1000, steps_per_epoch = 1)

В функции предварительной обработки я добавил оператор печати в тензор, который печатает каждый раз, когда вызывается функция, и он действительно печатается в каждую эпоху во время обучения.Это также происходит, даже если Я не включаю градиент в функцию потерь, показывая, что он, скорее всего, печатает в прямом проходе.Модель действительно , кажется, обучает и предсказывает, как и предполагалось, поэтому реализация кажется правильной.

В моей логике / понимании работы графа могут быть некоторые недостатки, и яЯ надеюсь, что есть простое решение моей проблемы.

Подводя итог:

  1. Как я могу подать "постоянный", дифференцируемый тензор в качестве входа в нейронную сеть, безтензор вычисляется заново при каждом прямом проходе по сети?

Поскольку предварительно обработанный тензор содержит все обучающих выборок, я также хотел бы разбить и обучить на более мелкие партии, поэтому:

Учитывая, что существует решение для 1., как пакетная подготовка связана с этим?Нужно ли создавать генератор и использовать fit_generator, или можно ли разрешить Keras справиться с ним fit?

Надеюсь, проблема была достаточно ясна, и я благодарен зався помощь / приводит!

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