畅游人工智能之海--Keras教程之回归损失函数(二)

畅游人工智能之海--Keras教程之回归损失函数(二)

前言

regression loss(1)中简单介绍了一些关于回归loss函数、相应的性质以及其在keras下的类实现,也就是在调用compile时的使用方法,这一次来简单看一下keras针对此定义的一些loss函数实现、相应的输入输出的shape以及一些编程的细节问题。

实现

以 mean_squared_error 为例

1
tf.keras.losses.mean_squared_error(y_true, y_pred)

一个关于使用该函数的例子如下所示(可运行):

1
2
3
4
5
6
7
8
import numpy as np
import tensorflow as tf
y_true = np.random.randint(0, 2, size=(2, 3))
y_pred = np.random.random(size=(2, 3))
loss = tf.keras.losses.mean_squared_error(y_true, y_pred)
print(y_true.shape,y_true)
print(y_pred.shape,y_pred)
print(loss.shape,np.array(loss))

输出为

1
2
3
4
5
6
7
(2, 3)
[[1 0 1]
[0 0 0]]
(2, 3)
[[0.76175565 0.00847085 0.58019956]
[0.45170964 0.95217628 0.82301612]]
(2,) Tensor("Mean:0", shape=(2,), dtype=float64)

其中输入的两个变量的shape是\((batch\_size,d_0, .. d_N)\),输出的loss的shape是\((batch\_size,d_0, .. d_{N-1})\)

借另外一个例子看一下这个过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(2, 3, 4)
[[[1 0 1 1]
[0 0 1 1]
[1 0 1 0]]
[[1 1 1 0]
[1 0 1 0]
[1 1 0 0]]]
(2, 3, 4)
[[[0.02513952 0.9691113 0.06320494 0.20428369]
[0.34093781 0.80876382 0.15684827 0.72119491]
[0.45385651 0.18147007 0.84950605 0.08463778]]
[[0.67112196 0.59363177 0.96954268 0.64257202]
[0.10844334 0.66677688 0.04690014 0.89629733]
[0.91571837 0.57628731 0.82937847 0.42718047]]]
(2, 3) Tensor("Mean:0", shape=(2, 3), dtype=float64)

第三个维度上的向量长度是4,在\(y\_true\)\(y\_pred\)对应位置的向量会被一次处理,比如上面这个例子中的\([1\ 0\ 1\ 1]\)\([0.02513952\ 0.9691113\ 0.06320494\ 0.20428369]\)会调用\(mse\)被处理成一个值。于是最后计算出来的loss就少一个维度了。

其它的

其余类似,总结一下,如下所示:

1
2
3
4
5
6
7
8
tf.keras.losses.mean_absolute_error(y_true, y_pred)
#loss = mean(abs(y_true - y_pred), axis=-1)
tf.keras.losses.mean_absolute_percentage_error(y_true, y_pred)
#loss = 100 * mean(abs(y_true - y_pred) / y_true, axis=-1)
tf.keras.losses.mean_squared_logarithmic_error(y_true, y_pred)
#loss = mean(square(log(y_true + 1) - log(y_pred + 1)), axis=-1)
tf.keras.losses.cosine_similarity(y_true, y_pred, axis=-1)
#loss = -sum(l2_norm(y_true) * l2_norm(y_pred))

huber class

首先定义\(x \gets y\_true - y\_pred\)

于是loss就如下计算

1
2
loss = 0.5 * x^2                  if |x| <= d
loss = 0.5 * d^2 + d * (|x| - d) if |x| > d

一个简单的例子如下所示:

1
2
3
4
5
6
>>> y_true = [[0, 1], [0, 0]]
>>> y_pred = [[0.6, 0.4], [0.4, 0.6]]
>>> # Using 'auto'/'sum_over_batch_size' reduction type.
>>> h = tf.keras.losses.Huber()
>>> h(y_true, y_pred).numpy()
0.155

在进行编译时的例子:

1
model.compile(optimizer='sgd', loss=tf.keras.losses.Huber())

对于这个loss函数的理解非常简单:当预测值和真实值相差很小的时候就用平方损失函数,否则通过一定的手段降低loss。