Keras API参考:损失

损失函数的目的是计算模型在训练期间应寻求最小化的量。

可用损失

请注意,所有损失都可以通过类句柄和函数句柄获得。类句柄使您能够将配置参数传递给构造函数(例如loss_fn = CategoricalCrossentropy(from_logits=True)),当以独立方式使用时,它们默认执行缩减(请参见下面的详细信息)。

概率损失

回归损失

用于“maximum-margin”分类的铰链损失

将损失与compile()&fit()一起使用

损失函数是编译Keras模型所需的两个参数之一:

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential()
model.add(layers.Dense(64, kernel_initializer='uniform', input_shape=(10,)))
model.add(layers.Activation('softmax'))

loss_fn = keras.losses.SparseCategoricalCrossentropy()
model.compile(loss=loss_fn, optimizer='adam')

所有内置的损失函数也可以通过它们的字符串标识符传递:

# pass optimizer by name: default parameters will be used
model.compile(loss='sparse_categorical_crossenropy', optimizer='adam')

损失函数通常通过实例化损失类(例如keras.losses.SparseCategoricalCrossenropy)创建。所有损耗也作为功能句柄(例如keras.losses.sparse_categorical_crossentropy).)提供。

使用类可以在实例化时传递配置参数,例如:

loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True)

单独使用损失

损失是使用参数loss_fn loss_fn(y_true, y_pred, sample_weight=None)调用的可调用对象:

  • y_true:基本真实值,形状 (batch_size, d0, ... dN)。对于稀疏损失函数,例如稀疏分类交叉点,形状应该是(batch_size, d0, ... dN-1)
  • y_pred:形状的预测值(batch_size, d0, .. dN)
  • sample_weight:可选的sample_weight用作每个样本损失的减去加权系数。如果提供标量,则损失只按给定值缩放。如果sample_weight是大小为[BATCH_SIZE]的张量,则批次的每个样本的总损失将由sample_weight矢量中的相应元素重新缩放。如果sample_weight的形状为(batch_size, d0, ... dN-1)(或者可以广播到该形状),则y_pred的每个损耗元素通过相应的sample_weight的值进行缩放。(注dN-1:所有损失函数减少1维,通常axis=-1。)。

默认情况下,损失函数为每个输入样本返回一个标量损失值,例如:

>>> tf.keras.losses.mean_squared_error(tf.ones((2, 2,)), tf.zeros((2, 2)))
<tf.Tensor: shape=(2,), dtype=float32, numpy=array([1., 1.], dtype=float32)>

但是,损失类实例有一个缩减构造函数参数,默认为“sum_over_batch_size”(即平均值)。允许值为“sum_over_batch_size”、“sum”和“none”:

  • “sum_over_batch_size”表示损失实例将返回批次中每个样本损失的平均值。
  • “sum”表示损失实例将返回批次中每个样本损失的总和。
  • “none”表示损失实例将返回每个样本损失的完整数组。
>>> loss_fn = tf.keras.losses.MeanSquaredError(reduction='sum_over_batch_size')
>>> loss_fn(tf.ones((2, 2,)), tf.zeros((2, 2)))
<tf.Tensor: shape=(), dtype=float32, numpy=1.0>
>>> loss_fn = tf.keras.losses.MeanSquaredError(reduction='sum')
>>> loss_fn(tf.ones((2, 2,)), tf.zeros((2, 2)))
<tf.Tensor: shape=(), dtype=float32, numpy=2.0>
>>> loss_fn = tf.keras.losses.MeanSquaredError(reduction='none')
>>> loss_fn(tf.ones((2, 2,)), tf.zeros((2, 2)))
<tf.Tensor: shape=(2,), dtype=float32, numpy=array([1., 1.], dtype=float32)>

请注意,这是tf.keras.losses.means_squared_error等损失函数与tf.keras.losses.MeanSquaredError等默认损失类实例之间的重要区别:函数版本不执行缩减,但默认情况下类实例执行缩减。

>>> loss_fn = tf.keras.losses.mean_squared_error
>>> loss_fn(tf.ones((2, 2,)), tf.zeros((2, 2)))
<tf.Tensor: shape=(2,), dtype=float32, numpy=array([1., 1.], dtype=float32)>
>>> loss_fn = tf.keras.losses.MeanSquaredError()
>>> loss_fn(tf.ones((2, 2,)), tf.zeros((2, 2)))
<tf.Tensor: shape=(), dtype=float32, numpy=1.0>

使用fit()时,这种差异是无关紧要的,因为减少是由框架处理的。

下面介绍如何将损失类实例用作简单培训循环的一部分:

loss_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam()

# Iterate over the batches of a dataset.
for x, y in dataset:
    with tf.GradientTape() as tape:
        logits = model(x)
        # Compute the loss value for this batch.
        loss_value = loss_fn(y, logits)

    # Update the weights of the model to minimize the loss value.
    gradients = tape.gradient(loss_value, model.trainable_weights)
    optimizer.apply_gradients(zip(gradients, model.trainable_weights))

创建自定义损失

任何带有签名loss_fn(y_true, y_pred)返回损失数组(输入批中的一个样本)的可调用函数都可以作为损失传递给compile()。请注意,对于任何此类损失,都会自动支持样本加权。

下面是一个简单的示例:

def my_loss_fn(y_true, y_pred):
    squared_difference = tf.square(y_true - y_pred)
    return tf.reduce_mean(squared_difference, axis=-1)  # Note the `axis=-1`

model.compile(optimizer='adam', loss=my_loss_fn)

add_loses()接口

应用于模型输出的损失函数并不是造成损失的唯一途径。

编写自定义层或子类模型的调用方法时,可能需要计算要在训练期间最小化的标量(例如,正则化损失)。您可以使用Add_Loss()层方法来跟踪此类损失条款。

以下是基于输入的L2范数添加稀疏正则化损失的层的示例:

from tensorflow.keras.layers import Layer

class MyActivityRegularizer(Layer):
  """Layer that creates an activity sparsity regularization loss."""

  def __init__(self, rate=1e-2):
    super(MyActivityRegularizer, self).__init__()
    self.rate = rate

  def call(self, inputs):
    # We use `add_loss` to create a regularization loss
    # that depends on the inputs.
    self.add_loss(self.rate * tf.reduce_sum(tf.square(inputs)))
    return inputs

通过add_loss添加的损失值可以在任何层或模型的.losses list属性中检索(它们是从每个底层递归检索的):

from tensorflow.keras import layers

class SparseMLP(Layer):
  """Stack of Linear layers with a sparsity regularization loss."""

  def __init__(self, output_dim):
      super(SparseMLP, self).__init__()
      self.dense_1 = layers.Dense(32, activation=tf.nn.relu)
      self.regularization = MyActivityRegularizer(1e-2)
      self.dense_2 = layers.Dense(output_dim)

  def call(self, inputs):
      x = self.dense_1(inputs)
      x = self.regularization(x)
      return self.dense_2(x)


mlp = SparseMLP(1)
y = mlp(tf.ones((10, 10)))

print(mlp.losses)  # List containing one float32 scalar

这些损失在每次向前传递开始时由顶层清除–它们不会累积。因此,layer.losses始终只包含最后一次向前传递过程中产生的损失。在编写训练循环时,您通常会在计算梯度之前对这些损失进行求和。

# Losses correspond to the *last* forward pass.
mlp = SparseMLP(1)
mlp(tf.ones((10, 10)))
assert len(mlp.losses) == 1
mlp(tf.ones((10, 10)))
assert len(mlp.losses) == 1  # No accumulation.

使用model.fit()时,会自动处理此类损失条件。

在编写自定义培训循环时,您应该手动从model.loses检索这些术语,如下所示:

loss_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam()

# Iterate over the batches of a dataset.
for x, y in dataset:
    with tf.GradientTape() as tape:
        # Forward pass.
        logits = model(x)
        # Loss value for this batch.
        loss_value = loss_fn(y, logits)
        # Add extra loss terms to the loss value.
        loss_value += sum(model.losses)

    # Update the weights of the model to minimize the loss value.
    gradients = tape.gradient(loss_value, model.trainable_weights)
    optimizer.apply_gradients(zip(gradients, model.trainable_weights))

有关更多详细信息,请参阅add_loses()文档。

00

Python

发表评论

邮箱地址不会被公开。 必填项已用*标注

什么阻碍了你实现迈入机器学习领域的目标?

什么阻碍了你实现迈入机器学习领域的目标?

2020-04-22 机器学习

如果你在为进入机器学习领域而挣扎,感觉到有什么东西阻止了自己的开始,那么你应该看看这篇文章。 在这篇文章中,我们会讨论阻止进入机器学习领域的自我限制的信念,让你明白面临的问题。 几乎总是一种自我限制的信念阻碍了你们的进步。 也许你会在一个或多个这样的信念中看到自己。如果是这样的话, [......]

了解详情

R语言机器学习迷你课程

R语言机器学习迷你课程

2020-08-12 机器学习

在这个迷你课程中,你将发现如何开始,构建精确的模型,并自信地完成在14天内使用R预测建模机器学习项目。 这是一个重要而重要的文章。你可能想把它书签。 了解如何准备数据,拟合机器学习模型,并用我的新书评估他们在r上的预测,包括14步教程、3个项目和完整源代码。 我们开始吧。 [......]

了解详情

关于机器学习的几点思考

关于机器学习的几点思考

2020-04-26 机器学习

机器学习是一个大的、跨学科的研究领域。 你可以通过机器学习获得令人印象深刻的结果,并找到非常具有挑战性的问题的解决方案。但这只是更广泛的机器学习领域的一小部分,通常被称为预测建模或预测分析。 在这篇文章中,你将发现如何改变你对机器学习的思考方式,以便更好地为你提供机器学习实践者的服务。 [......]

了解详情

找到你的机器学习部落

找到你的机器学习部落

2020-04-26 机器学习

机器学习是一个充满算法和数据的迷人而强大的研究领域。 问题是,有这么多不同类型的人对机器学习感兴趣,每个人都有不同的需求。重要的是要了解你想要从机器学习中得到什么,并根据这些需求调整你的自学。 如果你不这样做,你很容易就会陷入困境,迷失方向,失去兴趣,得不到你想要的东西。 找到 [......]

了解详情

应用机器学习过程

应用机器学习过程

2020-04-26 机器学习

随着时间的推移,在处理应用机器学习问题时,你会开发出一种模式或流程,以快速获得良好的正常结果。 一旦开发完成,你就可以在一个又一个项目上反复使用此过程。你的流程越健壮、越发达,你就能越快地获得可靠的结果。 在这篇文章中,我想与你分享我解决机器学习问题的过程框架。 你可以将其用作下一 [......]

了解详情