Sco*_*nce 6 keras tensorflow loss-function
在tensorflow/keras中是否有一种自然/简单的方法来实现使用模型输出相对于模型输入的导数的自定义损失函数?
我想到了一些大致的内容(不用介意实际的公式——这只是一个演示):
def my_loss_function(y_desired, y_model, x):
return abs(y_desired - y_model) + abs(tf.gradients(y_model,x[0]))
Run Code Online (Sandbox Code Playgroud)
这有两个问题。首先,损失函数通常无法访问输入。我的理解是,我可以通过直接引用该层来解决这个问题Input,例如作为全局变量。(当然,所有代码都只是示意性的。)
input_layer = Layer(...)
def my_loss(y1, y2):
return abs(y1-y2)*input_layer[0]
Run Code Online (Sandbox Code Playgroud)
input_layer第二个问题更严重:在执行图中似乎无法访问 , 的梯度。
这里有一个非常相似的问题,但没有解决方案:Custom loss function涉及Keras/Tensorflow中的梯度。我也曾沿着同样的路线进行过尝试,但没有运气。(对我来说,这不是正确的方法,而不是以Layer始终跟踪导数的方式包装 s ,这并不明显。)
小智 3
我无法使用自动fit方法实施培训。然而,这当然可以通过手动编写循环来完成。我将提供仅使用梯度来学习函数的示例。
for epoch in range(epochs):
print("\nStart of epoch %d" % (epoch,))
# Iterate over the batches of the dataset.
for step, (x_batch_train, y_batch_train) in enumerate(train_dataset):
# Open a GradientTape to record the operations run
# during the forward pass, which enables auto-differentiation.
with tf.GradientTape(persistent=True) as tape:
# Create tensor that you will watch
x_tensor = tf.convert_to_tensor(x_batch_train, dtype=tf.float64)
tape.watch(x_tensor)
# Feed forward
output = model(x_tensor, training=True)
# Gradient and the corresponding loss function
o_x = tape.gradient(output, x_tensor)
loss_value = loss_fn(y_batch_train, o_x)
# Use the gradient tape to automatically retrieve
# the gradients of the trainable variables with respect to the loss.
grads = tape.gradient(loss_value, model.trainable_weights)
# Run one step of gradient descent by updating
# the value of the variables to minimize the loss.
optimizer.apply_gradients(zip(grads, model.trainable_weights))
# Log every 200 batches.
if step % 200 == 0:
print(
"Training loss (for one batch) at step %d: %.4f"
% (step, float(loss_value))
)
print("Seen so far: %s samples" % ((step + 1) * 64))
Run Code Online (Sandbox Code Playgroud)
loss_fn在这种情况下很简单
loss_fn = tf.keras.losses.MeanSquaredError()
Run Code Online (Sandbox Code Playgroud)
请记住,您正在使用二阶导数来训练函数,并且with tf.GradientTape(persistent=True) as tape:会产生警告,这对于这种情况是可以的。另外根据我的经验,这种方法对激活函数的选择特别敏感。ReLU 的连续可微变体可能是正确的选择。
| 归档时间: |
|
| 查看次数: |
3535 次 |
| 最近记录: |