tf2 误差损失函数代码实现


博主使用库版本:

  • python == 3.6
  • tensorflow == 2.0

在搭建完模型结构后,下一步就是选择合适的误差函数来计算误差。 常见的误差函数有均方差、 交叉熵、 KL 散度、 Hinge Loss 函数等,其中均方差函数和交叉熵函数在深度学习中比较常见,均方差函数主要用于回归问题,交叉熵函数主要用于分类问题

均方差误差函数

均方差(Mean Squared Error,简称 MSE)误差函数把输出向量和真实向量映射到笛卡尔坐标系的两个点上,通过计算这两个点之间的欧式距离(准确地说是欧式距离的平方)来衡量两个向量之间的距离:
M S E ( y , o ) = 1 d o u t ∑ i = 1 d o u t ( y i − o i ) 2 MSE(y, o) = \frac{1}{d_{out}}\sum_{i=1}^{d_{out}}(y_{i}-o_{i})^{2} MSE(y,o)=dout1i=1dout(yioi)2
MSE 误差函数的值总是大于等于 0,当 MSE 函数达到最小值 0 时, 输出等于真实标签,此时神经网络的参数达到最优状态。均方差误差函数广泛应用在回归问题中, 实际上, 分类问题中也可以应用均方差误差函数。

第一种实现方式

tensorflow代码实现如下:

o = tf.random.normal([2,10]) # 构造网络输出
y_onehot = tf.constant([1,3]) # 构造真实值
y_onehot = tf.one_hot(y_onehot, depth=10)
loss = keras.losses.MSE(y_onehot, o) # 计算均方差
loss

输出

<tf.Tensor: id=72, shape=(2,), dtype=float32, numpy=array([1.4416579, 1.633992 ], dtype=float32)>

特别要注意的是, MSE 函数返回的是每个样本的均方差,需要在样本维度上再次平均来获得平均样本的均方差,实现如下:

loss = tf.reduce_mean(loss) # 计算 batch 均方差
loss

输出

<tf.Tensor: id=74, shape=(), dtype=float32, numpy=1.5378249>

第二种实现方式

通过层方式实现:

loss = keras.losses.MeanSquaredError()(y_onehot,o) # 计算 batch 均方差
loss

输出

<tf.Tensor: id=95, shape=(), dtype=float32, numpy=1.5378249>

两种实现结果相同,计算得到的均方误差为1.5378249

交叉熵误差函数

熵在信息学科中也叫信息熵,或者香农熵。 熵越大,代表不确定性越大,信息量也就越大。 某个
分布𝑃(𝑖)的熵定义为

H ( p ) = − ∑ i p ( i ) log ⁡ 2 p ( i ) H(p) = - \sum_{i} p(i) \log_{2} p(i) H(p)=ip(i)log2p(i)
交叉熵(Cross Entropy)的定义:
H ( p ∣ q ) = − ∑ i p ( i ) l o g 2 q ( i ) H(p|q) = - \sum_{i} p(i) log_{2}q(i) H(pq)=ip(i)log2q(i)
代码实现

基础计算

import tensorflow as tf
import numpy as np
 
#logits代表wx+b的输出,并没有进行softmax(因为softmax后是一个和为1的概率)
logits = np.array([[1, 2, 7], [3, 5, 2], [6, 1, 3], [8, 2, 0],
                   [3, 6, 1]], dtype=np.float32)
#labels是[2,1,0,0,1]的ont-hot编码形式
labels = np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0], [1, 0, 0],
                   [0, 1, 0]], dtype=np.float32)
# 公式计算,-np.log(y*softmax_out)
# y=n*c,softmax_out是n*c,相当于将每个样本softmax的c个特征中最大的取出来,再取负就是求最小
softmax_out=tf.nn.softmax(logits)
cross_entropy1 = -tf.reduce_sum(labels * tf.math.log(softmax_out), axis=1)   #对应元素相乘,非矩阵乘法
print(softmax_out.numpy())
print(cross_entropy1.numpy())

输出

[[2.4561151e-03 6.6764127e-03 9.9086750e-01]
 [1.1419519e-01 8.4379470e-01 4.2010065e-02]
 [9.4649917e-01 6.3774614e-03 4.7123417e-02]
 [9.9719369e-01 2.4717962e-03 3.3452120e-04]
 [4.7123417e-02 9.4649917e-01 6.3774614e-03]]
[0.00917446 0.16984606 0.05498519 0.00281025 0.05498519]

tf.nn.softmax_cross_entropy_with_logits 实现

import tensorflow as tf
import numpy as np

logits = [[4.0, 2.0, 1.0], [0.0, 5.0, 1.0]]
labels = [[1.0, 0.0, 0.0], [0.0, 0.8, 0.2]]
loss = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits)
print(loss.numpy())

输出

[0.16984604 0.82474494]

TensorFlow针对分类问题,实现了四个交叉熵函数,分别是

tf.nn.sigmoid_cross_entropy_with_logits

tf.nn.softmax_cross_entropy_with_logits

tf.nn.sparse_softmax_cross_entropy_with_logits

tf.nn.weighted_cross_entropy_with_logits

详细内容参考API文档,这里不过多举例:
https://www.tensorflow.org/versions/master/api_docs/python/nn.html#sparse_softmax_cross_entropy_with_logits

参考文献:

  1. Tensorflow交叉熵的代码实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值