1

我正在尝试将损失函数的梯度转换为另一个张量。但是梯度正乘以我输入模型的输入批量大小。

import tensorflow as tf
from tensorflow.keras import Sequential, layers

#Sample States and Returns
states = tf.random.uniform(shape = (100,4))
returns = tf.constant([float(i) for i in range(100)])

#Creating dataset to feed data to model
states = tf.data.Dataset.from_tensor_slices(states)
returns = tf.data.Dataset.from_tensor_slices(returns)

#zipping datasets into one
batch_size = 4
dataset = tf.data.Dataset.zip((states, returns)).batch(batch_size)

model = Sequential([layers.Dense(128, input_shape =(4,), activation = tf.nn.relu), 
                    layers.Dense(1, activation = tf.nn.tanh)])

for state_batch, returns_batch in dataset:
    with tf.GradientTape(persistent=True) as tape:
        values = model(state_batch)
        loss =  returns_batch - values  
    
    # d_loss/d_values should be -1.0,  but i'm getting -1.0 * batch_size
    print(tape.gradient(loss,values))
    break
Output:
tf.Tensor(
[[-4.]
 [-4.]
 [-4.]
 [-4.]], shape=(4, 1), dtype=float32)

Expected Output:
tf.Tensor(
[[-1.]
 [-1.]
 [-1.]
 [-1.]], shape=(4, 1), dtype=float32)

从代码中可以看出loss = returns - values。应该是这样d_loss/d_values = -1.0,但我得到的结果是d_loss/d_values = -1.0 * batch_size。有人请指出为什么会这样?我怎样才能得到真正的结果?

colab 链接:https ://colab.research.google.com/drive/1x4pyGJ5ccRVSMzDAeLzcPXRtO7cNFnJf?usp=sharing

4

1 回答 1

1

问题出在这一行:

loss = returns_batch - values  

这里,returns_batch有形(4,),但values有形(4, 1)。减法运算广播张量,产生一个loss形状为 的张量,有(4, 4)四个重复的列。因此,更改 的单个值values会影响 的四个元素returns_batch,因此会影响缩放的梯度值。例如,您可以像这样修复它:

loss = returns_batch - tf.squeeze(values, axis=1)
于 2020-06-26T16:07:30.450 回答