损失函数(loss)

本文源自中国慕课网曹健老师《人工智能实践:Tensorflow笔记》一课听课笔记,课程地址:https://www.icourse163.org/learn/PKU-1002536002?tid=1452937471#/learn/content?type=detail&id=1229870565&sm=1

损失函数(loss):预测值(y)与已知答案(y_)的差距。在这里插入图片描述
均方误差mse:

loss_mse=tf.reduce_mean(tf.square(y_-y))
在这里插入图片描述
预测酸奶日销量y,x1、x2是影响日销量的因素。

建模前,应预先采集的数据有:每日x1、x2 和销量y_(即已知答案,最佳情况:产量=销量),拟造数据集X,Y_:y_=x1+x2 噪声:-0.05——+0.05 拟合可以预测销量的函数。

import tensorflow as tf
import numpy as np

SEED = 23455

rdm = np.random.RandomState(seed=SEED)  # 生成[0,1)之间的随机数
x = rdm.rand(32, 2)		#生成的随机数为32行,2列矩阵
y_ = [[x1 + x2 + (rdm.rand() / 10.0 - 0.05)] for (x1, x2) in x]  # 生成噪声[0,1)/10=[0,0.1); [0,0.1)-0.05=[-0.05,0.05)		#标准答案
x = tf.cast(x, dtype=tf.float32)		#转换类型

w1 = tf.Variable(tf.random.normal([2, 1], stddev=1, seed=1))		#初始权重设为 均值为0.5,方差为1的2行1列正态分布随机数

epoch = 15000		#循环次数设为15000
lr = 0.002			#初始学习率设为0.002

for epoch in range(epoch):
    with tf.GradientTape() as tape:
        y = tf.matmul(x, w1)		#矩阵相乘,即预测结果y=w1*x1+w2*x2
        loss_mse = tf.reduce_mean(tf.square(y_ - y))		#损失函数(均方误差)

    grads = tape.gradient(loss_mse, w1)		#求梯度,即损失函数下降最快的反向
    w1.assign_sub(lr * grads)		#更新权值w1,即w1=w1-lr*grads

    if epoch % 500 == 0:
        print("After %d training steps,w1 is " % (epoch))
        print(w1.numpy(), "\n")
print("Final w1 is: ", w1.numpy())

#程序运行结果:
After 0 training steps,w1 is 
[[-0.8096241]
 [ 1.4855157]]

After 500 training steps,w1 is 
[[-0.21934733]
 [ 1.6984866 ]] 
 ........
After 14500 training steps,w1 is 
[[1.0002553 ]
 [0.99838644]] 

Final w1 is:  [[1.0009792]
 [0.9977485]]

可以看到,最后的结果还是比较拟合y_=x1+x2

自定义损失函数:
如预测商品销量,预测多了,损失成本;预测少了,损失利润。
若利润≠成本,则mse产生的loss无法利益最大化。
自定义损失函数:y_数据集的标准答案 y计算出的预测答案。
在这里插入图片描述
loss_zdy=tf.reduce_sum(tf.where(tf.greater(y,y_),(y-y_)*cost,(y_-y)*profit))

如:预测酸奶销量,酸奶成本(cost)1元,酸奶利润(profit)99元。

预测少了损失利润99元,大于预测多了损失成本1元。预测少了损失大,希望生成的预测函数往多了预测。

import tensorflow as tf
import numpy as np

SEED = 23455
COST = 1
PROFIT = 99

rdm = np.random.RandomState(SEED)
x = rdm.rand(32, 2)		#生成的随机数为32行,2列矩阵
y_ = [[x1 + x2 + (rdm.rand() / 10.0 - 0.05)] for (x1, x2) in x]  # 生成噪声[0,1)/10=[0,0.1); [0,0.1)-0.05=[-0.05,0.05)
x = tf.cast(x, dtype=tf.float32)		#转换数据类型

w1 = tf.Variable(tf.random.normal([2, 1], stddev=1, seed=1))		##初始权重设为 均值为0.5,方差为1的2行1列正态分布随机数

epoch = 10000
lr = 0.002

for epoch in range(epoch):
    with tf.GradientTape() as tape:
        y = tf.matmul(x, w1)
        loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_) * COST, (y_ - y) * PROFIT))			#自定义损失函数

    grads = tape.gradient(loss, w1)
    w1.assign_sub(lr * grads)

    if epoch % 500 == 0:
        print("After %d training steps,w1 is " % (epoch))
        print(w1.numpy(), "\n")
print("Final w1 is: ", w1.numpy())

# 自定义损失函数
# 酸奶成本1元, 酸奶利润99元
# 成本很低,利润很高,人们希望多预测些,生成模型系数大于1,往多了预测

#程序运行结果:
After 0 training steps,w1 is 
[[2.0855923]
 [3.8476257]] 
 
After 500 training steps,w1 is 
[[1.1830753]
 [1.1627482]] 
 
 After 1000 training steps,w1 is 
[[1.1526372]
 [1.0175619]] 
 ...........
 
After 9500 training steps,w1 is 
[[1.1611756]
 [1.0651482]] 

Final w1 is:  [[1.1626335]
 [1.1191947]]

酸奶成本1元, 酸奶利润99元,可想而知,这种情况预测销量是偏大的。

但若酸奶成本99元, 酸奶利润1元呢?

After 9500 training steps,w1 is 
[[0.8998995 ]
 [0.82509875]] 

Final w1 is:  [[0.9205433]
 [0.9186459]]

可以看到,预测的销量是偏小的。

交叉熵:
交叉熵损失函数CE(Cross Entropy):表征两个概率分布之间的距离。
在这里插入图片描述
tf.losses.categorical_crossentropy(y_,y)
eg.二分类 已知答案y_=(1,0) 预测y1=(0.6,0.4) y2=(0.8,0.2)
哪个更接近标准答案?

H1((1,0),(0.6,0.4))=-(1ln0.6+0ln0.4)≈-(-0.511+0)=0.511
H2((1,0),(0.8,0.2))=-(1ln0.8+0ln0.2)≈-(-0.223+0)=0.223

因为H1>H2,所以y2预测更准。

softmax与交叉熵结合:
输出先过softmax函数,在计算y与y_的交叉熵损失函数。
tf.nn.softmax_cross_entropy_with_logits(y_,y)

当我们处理多分类任务时,通常需要使用Softmax Regression模型。即使是卷积神经网络或循环神经网络,如果是分类模型,最后一层也是Softmax Regression。它的基本原理是,将可以判定为某类的特征相加,然后将这些特征转化为判定是这一类的概率。
在这里插入图片描述
在这里插入图片描述

y_ = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 0, 0], [0, 1, 0]])
y = np.array([[12, 3, 2], [3, 10, 1], [1, 2, 5], [4, 6.5, 1.2], [3, 6, 1]])
y_pro = tf.nn.softmax(y)
loss_ce1 = tf.losses.categorical_crossentropy(y_,y_pro)
loss_ce2 = tf.nn.softmax_cross_entropy_with_logits(y_, y)

print('分步计算的结果:\n', loss_ce1)
print('结合计算的结果:\n', loss_ce2)

#程序运行结果:
分步计算的结果:
 tf.Tensor(
[1.68795487e-04 1.03475622e-03 6.58839038e-02 2.58349207e+00
 5.49852354e-02], shape=(5,), dtype=float64)
结合计算的结果:
 tf.Tensor(
[1.68795487e-04 1.03475622e-03 6.58839038e-02 2.58349207e+00
 5.49852354e-02], shape=(5,), dtype=float64)

以上内容,如有错误,敬请批评指正!谢谢!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值