损失函数

神经网络是通过某个指标来表现现在的状态,然后,以这个指标为基准,寻找最优参数。
神经网络中的指标称为损失函数(loss function)。这个损失函数可以使用任意函数,但是一般用均方差误差和交叉熵误差。

均方差误差(mean squared error)=》回归问题:

均方误差是最有名的损失函数。式子如下:

在这里插入图片描述
其中
y k y_{k} yk是输出神经第k个神经元的输出;
t k t_{k} tk是输出神经第k个神经元的监督数据;
k k k表示输出的神经元的个数

比如:
在手写数字识别中, y y y t t t分别表示如下:
在这里插入图片描述
y是softmax 函数的输出
t是用one-hot的标签表示法,这个标签2为1,所以正确解为1

均方误差会计算神经网络的输出和正确解监督数据的各个元素之差的平方, 再求总和。

def mean_squared_error(y, t):    
	return 0.5 * np.sum((y-t)**2)

现在,我们使用这个函数,来实际地计算一下:

在这里插入图片描述
损失函数的值更小,和监督数据之间的误差较小。均方误差显示第一个例子的输出结果与监督数据更加吻合。

交叉熵误差(cross entropy error)=》分类问题:

除了均方差之外,交叉熵损失函数也经常,交叉熵误差如下式所示:
E = − ∑ k t k l o g ( y k ) E=- \sum_{k} t_{k} log(y_{k}) E=ktklog(yk)

t k t_{k} tk代表的是正确答案
y k y_{k} yk代表的是预测答案
交叉熵刻画的是两个概率分布的距离,也就是交叉熵值越小,说明两个概率靠的越近。

def cross_entropy_error(y, t):    
	delta = 1e-7    
	return -np.sum(t * np.log(y + delta))

通过 TensorFlow 实现过交叉熵:

  • tf.clip_by_value()把一个张量限制在一个范围内,避免运算错误( log(0)是无效的 )
  • 在实现交叉熵的代码中是直接将两个矩阵操作相乘(*),是将相对应的元素直接相乘,而不是矩阵乘法(matmul)
cross_entropy = -y_ * tf.log(tf.clip_by_value(y , le-10, 1.0))

在这里插入图片描述
第一个例子中,正确解标签对应的输出为0.6,此时的交叉熵误差大约为0.51。第二个例子中,正确解标签对应的输出为0.1的低值,此时的交叉熵误差大约为2.3。由此可以看出, 这些结果与我们前面讨论的内容是一致的。

上面介绍的损失函数的例子中考虑的都是针对单个数据的损失函数。如果要求所有训练数据的损失函数的总和,以交叉熵误差为例,可以写成下面的式子:
在这里插入图片描述
N表示一个批次(batch)的大小,求批次交叉熵要求批次的平均交叉熵。

通过 TensorFlow 实现过交叉熵:
tf.reduce mean 函数可以对整个矩阵求平均

cross_entropy = -tf . reduce_mean( y_ * tf.log(tf.clip_by_value(y , le-10, 1.0))) 
自定义损失函数

除了使用经典的损失函数,还可以使用自定义损失函数,这样可以使神经网络优化的结果更加符合实际问题的需求。

比如:一个商家准备预测明天需要准备多少货物 y ′ y^{'} y,货物的成本为1,利润为10。那么多预测一个就会损失1元,但是少预测一个就会损失10元,所以如果使用经典的损失函数是无法最大化预期的利润的。对于这个问题需要分情况讨论:以下公式给出了当预测多于真实值和预测值少于真实值时有不同损失函数:

在这里插入图片描述
y ′ y^{'} y 代表在一个batch中第i个数据神经网络得到的预测值
y y y代表在一个batch中第i个数据的真实值
a,b是常量,比如对于上面的问题,a就等于10(正确答案多于预测答案的代价),b就等于1(正确答案少于预测答案的代价)。

在tensorflow中可以通过以下代码来实现这个损失函数:

loss= tf.reduce sum(tf . where(tf.greater(v1,v2) ,(vl-v2) * a , (v2 - vl) * b)) 

tf.greater 和 tf.where 的用法:

import tensorflow as tf 
vl = tf.constant ([ l.0 , 2 . 0 , 3 . 0, 4 . 0 )) 
v2 = tf.constant([4 . 0, 3 . 0, 2 . 0, 1.0]) 
sess = tf.InteractiveSession() 
print tf.greater(vl, v2) . eval() 
#输出[ False False True True] 
print tf.where(tf.greater(vl , v2), vl , v2) . eval() 
#输出[ 4. 3. 3. 4. J sess. close () 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值