我遇到了tensorflow 2.0的一段代码,用于计算损失。总损失由两部分组成:1)正则化损失,2)预测损失。我的问题是为什么model.losses正则化损失?model这是 的一个实例tf.keras.Model。我对 tensorflow 官方 API 文档有点困惑。tf.keras.Model,它说
与此层相关的损失。
访问此属性时会创建变量正则化张量,因此它非常安全:访问 a 下的损失
tf.GradientTape会将梯度传播回相应的变量。
为什么我们可以通过访问losses财产获得正则化损失?另外,什么是eager safe?如果losses属性返回正则化损失,为什么它被命名losses而不是regularization_loss?
with tf.GradientTape() as tape:
outputs = model(images, training=True)
regularization_loss = tf.reduce_sum(model.losses)
pred_loss = ...
total_loss = pred_loss + regularization_loss
Run Code Online (Sandbox Code Playgroud) 在回答这个问题之后,我在 tensorflow 2.0 中遇到了一些有趣但令人困惑的发现。logits对我来说看起来不正确的渐变。假设我们有logits和labels这里。
logits = tf.Variable([[0.8, 0.1, 0.1]], dtype=tf.float32)
labels = tf.constant([[1, 0, 0]],dtype=tf.float32)
with tf.GradientTape(persistent=True) as tape:
loss = tf.reduce_sum(tf.keras.losses.categorical_crossentropy(labels, logits,
from_logits=False))
grads = tape.gradient(loss, logits)
print(grads)
Run Code Online (Sandbox Code Playgroud)
由于logits已经是概率分布,所以我设置from_logits=False了损失函数。
我认为 tensorflow 将用于loss=-\Sigma_i(p_i)\log(q_i)计算损失,如果我们推导q_i,我们将得到导数-p_i/q_i。因此,预期的成绩应该是 [-1.25,0,0]。但是,tensorflow 将返回 [-0.25,1,1]。
阅读 的源代码后tf.categorical_crossentropy,我发现即使我们设置了from_logits=False,它仍然对概率进行了归一化。这将改变最终的梯度表达式。具体来说,梯度将为-p_i/q_i+p_i/sum_j(q_j)。如果p_i=1和sum_j(q_j)=1,最终梯度将加一。这就是梯度为 -0.25 的原因,但是,我还没有弄清楚为什么最后两个梯度为 1。
为了证明所有的梯度都增加了1/sum_j(q_j),我做了一个 logits,它不是概率分布,并设置为from_logits=False静止。
logits = tf.Variable([[0.5, 0.1, 0.1]], …Run Code Online (Sandbox Code Playgroud) 当我阅读tensorflow官方指南时,有一个示例显示了操作的显式设备放置。在示例中,为什么CPU执行时间少于GPU?通常,哪种操作会在GPU上更快地执行?
import time
def time_matmul(x):
start = time.time()
for loop in range(10):
tf.matmul(x, x)
result = time.time()-start
print("10 loops: {:0.2f}ms".format(1000*result))
# Force execution on CPU
print("On CPU:")
with tf.device("CPU:0"):
x = tf.random.uniform([1000, 1000])
assert x.device.endswith("CPU:0")
time_matmul(x)
# Force execution on GPU #0 if available
if tf.test.is_gpu_available():
print("On GPU:")
with tf.device("GPU:0"): # Or GPU:1 for the 2nd GPU, GPU:2 for the 3rd etc.
x = tf.random.uniform([1000, 1000])
assert x.device.endswith("GPU:0")
time_matmul(x)
### Output
# On CPU:
# 10 loops: 107.55ms
# On …Run Code Online (Sandbox Code Playgroud)