47.3_交叉熵误差
47.3 交叉熵误差
在线性回归中,我们使用均方误差作为损失函数,但在进行多分类时,需要使用专用的损失函数。最常用的是交叉熵误差(cross entropy error)。交叉熵误差的式子如下所示。
式子中的 表示训练数据的第 个维度的值。这个训练数据的元素值的记录规则为,类别正确的元素值是1,其他为0。这种表示方法叫作one-hot向量。式子中的 是使用了神经网络的softmax函数后的输出。
交叉熵误差的式子47.2有更简化的表达形式。例如有 , ,把它们代入式子47.2,得到 。这意味着交叉熵误差也可以通过提取正确类别编号的概率 来进行计算。因此,假设训练数据中正确类别的编号为 ,我们也可以通过下面的式子计算交叉熵误差。
式子中的 表示只从向量 中提取第 个元素。这个切片操作是本步骤开头向 DeZero 中添加的功能。

此处介绍的交叉熵误差针对的是数据只有一个的情况。如果有 个数据,我们应计算每个数据的交叉熵误差,将它们相加,然后除以 ,由此求出平均交叉熵误差。
下面实现交叉熵误差。我们将softmax函数和交叉熵误差合二为一,实现softmax CROSS_entropy-simple(x, t)函数。代码如下所示。
dezero/functions.py
def softmax CROSS_entropy-simple(x, t):
x, t = as_variable(x), as_variable(t)
N = x.shape[0]
p = softmax(x) # 或者 softmaxsimple(x)
p = clip(p, 1e-15, 1.0) # 为了防止log(0),将p设为大于1e-15的值
log_p = log(p) # 这个log是DeZero函数
tlog_p = log_p(np.arange(N), t.data]
y = -1 * sum(tlog_p) / N
return y上面代码中的输入参数 是使用神经网络的 softmax 函数之前的输出, 是训练数据。假设训练数据是正确类别的编号(标签,非 one-hot 向量)。
代码中 的 元素是 0 和 1 之间的值。在下一步进行 log 计算时,向 log 函数输入 0 会导致错误发生(准确来说是警告)。为了防止这种
情况出现,在输入为0的情况下,我们用一个较小的值1e-15来代替它。这个替换是由clip函数完成的。clip函数的用法是clip(x, x_min, x_max)。调用该函数时,如果x的元素(Variable实例)小于x_min,其值会被替换为x_min;如果大于x_max,其值会被替换为x_max。这里就不介绍clip函数的实现了(代码在dezero/functions.py中)。
另外,上面的代码通过np range(N)创建了 的ndarray实例。使用log_p[np.arange(N), t.data]可提取出对应于训练数据的模型输出log_p[0, t.data[0]]、log_p[1, t.data[1]]……这是一个一维数组。

上面的softmax CROSS_entropy-simple函数的实现比较简单。不过,dezero/functions.py中的softmax CROSS_entropy函数是更好的实现方式。为了帮助大家理解,本步骤采用了简单的实现方式。
下面对进行多分类的神经网络使用具体数据来计算交叉熵误差。
$\mathbf{x} = \mathbf{np}$ .array([0.2,-0.4],[0.3,0.5],[1.3,-3.2],[2.1,0.3]])
t $=$ np.array([2,0,1,0])
y $=$ model(x)
loss $=$ Fsoftmaxcross_entropy.simple(y,t)
#或者F softmaxcross_entropy(y,t)
print(loss)运行结果
variable(1.4967442524053058)上面的代码首先准备了输入数据 、训练数据 ,训练数据中记录了正确类别的编号,然后用 来变换数据,用 F. softmax CROSS_entropysimple(y, t) 来计算损失函数。现在我们已经做好实现多分类的准备了,下一步将实际进行操作。