#python #tensorflow #machine-learning #keras #automatic-differentiation
#python #тензорный поток #машинное обучение #keras #автоматическое дифференцирование
Вопрос:
Я хотел бы создать модель тензорного потока, в которой выходные данные соответствуют математическому условию, а именно, что выход 0 является скалярной функцией, а все последующие выходные данные являются ее частными производными от входных данных. Это потому, что мои наблюдения представляют собой скалярную функцию и ее части, и не использовать части для обучения было бы пустой тратой информации.
На данный момент простое использование tf.gradients работает, если я не создаю пользовательский цикл обучения, т. Е. Когда я не использую быстрое выполнение. Модель построена таким образом, и обучение работает так, как ожидалось:
import tensorflow as tf
from tensorflow.keras import losses
from tensorflow.keras import optimizers
from tensorflow.keras import callbacks
# Creating a model
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import (
Dense,
Dropout,
Flatten,
Concatenate,
Input,
Lambda,
)
# Custom activation function
from tensorflow.keras.layers import Activation
from tensorflow.keras import backend as K
import numpy
import matplotlib.pyplot as plt
import tensorboard
layer_width = 200
dense_layer_number = 3
def lambda_gradient(args):
layer = args[0]
inputs = args[1]
return tf.gradients(layer, inputs)[0]
# Input is a 2 dimensional vector
inputs = tf.keras.Input(shape=(2,), name="coordinate_input")
# Build `dense_layer_number` times a dense layers of width `layer_width`
stream = inputs
for i in range(dense_layer_number):
stream = Dense(
layer_width, activation="relu", name=f"dense_layer_{i}"
)(stream)
# Build one dense layer that reduces the 200 nodes to a scalar output
scalar = Dense(1, name="network_to_scalar", activation=custom_activation)(stream)
# Take the gradient of the scalar w.r.t. the model input
gradient = Lambda(lambda_gradient, name="gradient_layer")([scalar, inputs])
# Combine them to form the model output
concat = Concatenate(name="concat_scalar_gradient")([scalar, gradient])
# Wrap everything in a model
model = tf.keras.Model(inputs=inputs, outputs=concat)
loss = "MSE"
optimizer = "Adam"
# And compile
model.compile(loss=loss, optimizer=optimizer)
Однако теперь возникает проблема, когда я хочу провести онлайн-обучение (т. Е. С добавочным набором данных). В этом случае я бы не стал компилировать свою модель в самом конце. Вместо этого я пишу цикл как таковой (перед вызовом model.compile):
# ... continue from previous minus model.compile
loss_fn = tf.keras.losses.MeanSquaredError()
optimizer = tf.keras.optimizers.Adam()
# Iterate over the batches of a dataset and train.
for i_batch in range(number_of_batches):
with tf.GradientTape() as tape:
# Predict w.r.t. the inputs X
prediction_Y = model(batches_X[i_batch])
# Compare batch prediction to batch observation
loss_value = loss_fn(batches_Y[i_batch], prediction_Y)
gradients = tape.gradient(loss_value, model.trainable_weights)
optimizer.apply_gradients(zip(gradients, model.trainable_weights))
Однако это приводит к следующему исключению в prediction_Y = model(batches_X[i_batch])
:
RuntimeError: tf.gradients is not supported when eager execution is enabled. Use tf.GradientTape instead.
Поскольку большинство примеров, руководств и документации касаются исключительно использования градиентов для обучения, а не внутри модели, я не могу найти хороших ресурсов, как с этим справиться. Я пытался найти, как использовать градиентную ленту, но не могу понять, как использовать ее на этапе проектирования модели. Любые указатели будут оценены!
Используемые версии:
$ python --version
Python 3.8.5
$ python -c "import tensorflow as tf;print(tf.__version__);print(tf.keras.__version__)"
2.2.0
2.3.0-tf
Комментарии:
1. попробуйте сделать отступ в последних двух строках вправо, чтобы они стали под
with tape
инструкцией2. Привет, спасибо, что обратились. Это не работает, так как само прямое распространение даже не работает. Ошибка возникает уже на
prediction_Y = model(batches_X[i_batch])
.