【TensorFlow1.X】系列学习笔记【入门四】

news2025/2/26 9:44:41

【TensorFlow1.X】系列学习笔记【入门四】

大量经典论文的算法均采用 TF 1.x 实现, 为了阅读方便, 同时加深对实现细节的理解, 需要 TF 1.x 的知识

【TensorFlow1.X】系列学习文章目录


文章目录

  • 【TensorFlow1.X】系列学习笔记【入门四】
  • 前言
  • 损失函数作用
  • 均方误差(MSE)
  • 交叉熵(Cross Entropy)
  • 自定义损失函数
  • 总结


前言

实现神经网络的搭建,下一步需要学习神经网络优化原理和实现细节,本篇博文将详解损失函数作用。


损失函数作用

损失函数在深度学习中起着重要的作用,它用于衡量模型预测结果与实际标签之间的差异,指导模型的训练过程,是评估模型性能和优化模型参数的关键组成部分。损失函数具有以下几个主要作用:

  1. 衡量模型性能:损失函数用于衡量模型在给定数据上的性能。通过计算预测结果与真实标签之间的差异,可以评估模型的准确性和误差大小。
  2. 反映优化目标:损失函数定义了优化算法的目标,即最小化损失函数的值。通过最小化损失函数,模型可以尽量减少预测结果与真实标签之间的差异,并提高模型的性能。
  3. 指导参数更新:在优化过程中,损失函数的梯度被用于指导参数的更新方向和幅度。通过计算损失函数对于模型参数的梯度,可以确定参数更新的方向,使得损失函数的值逐渐减小。
  4. 支持模型选择和比较:不同的损失函数适用于不同的任务和问题。选择适合任务的损失函数可以帮助模型更好地学习和拟合数据。此外,通过比较不同模型在相同损失函数下的性能,可以选择最佳的模型架构和超参数。

深度学习常见的损失函数包括:

  • 均方误差(Mean Squared Error,MSE):适用于回归问题,衡量预测值和真实值之间的平均平方差。
  • 交叉熵(Cross Entropy):适用于分类问题,衡量预测概率分布与真实概率分布之间的差异。

选择合适的损失函数取决于任务类型、数据特征和模型要解决的问题。不同的损失函数对模型的训练和优化过程产生不同的影响,因此需要仔细选择和调整以达到最佳结果。


均方误差(MSE)

均方误差mse:n 个样本的预测值 y y y与真实值 y _ y\_ y_之差的平方和,再求平均值。
M S E ( y _ , y ) = ∑ i = 1 n ( y − y _ ) 2 n MSE({\rm{y\_}},y) = \frac{{\sum\nolimits_{i =1 }^n {{{(y - y\_)}^2}} }}{n} MSE(y_,y)=ni=1n(yy_)2
在 Tensorflow1.X中用 loss_mse = tf.reduce_mean(tf.square(y_ - y))
举个小案例:两个神经网络模型解决二分类问题中,已知标准答案为 y _ = ( 1 , 0 ) {\rm{y\_ = (1, 0)}} y_=(1,0),第一个神经网络模型预测结果为 y 1 = ( 0.7 , 0.5 ) {\rm{y_1= (0.7, 0.5)}} y1=(0.7,0.5),第二个神经网络模型预测结果为 y 2 = ( 0.8 , 0.1 ) {\rm{y_2= (0.8, 0.1)}} y2=(0.8,0.1),判断哪个神经网络模型预测的结果更接近标准答案。
根据均方误差的计算公式得:
M S E _ 1 ( ( 1 , 0 ) , ( 0 . 7 , 0 . 5 ) ) = ( 0 . 7 − 1 ) 2 + ( 0 . 5 − 0 ) 2 = 0 . 34 {\rm{MSE\_1((1,0),(0}}{\rm{.7, 0}}{\rm{.5)) = (0}}{\rm{.7 - 1}}{{\rm{)}}^2} + {{\rm{(0}}{\rm{.5 - 0)}}^2} = {\rm{0}}{\rm{.34}} MSE_1((1,0),(0.7,0.5))=(0.71)2+(0.50)2=0.34
M S E _ 2 ( ( 1 , 0 ) , ( 0 . 8 , 0 . 1 ) ) = ( 0 . 8 − 1 ) 2 + ( 0 . 1 − 0 ) 2 = 0 . 05 {\rm{MSE\_2((1,0),(0}}{\rm{.8, 0}}{\rm{.1)) = (0}}{\rm{.8 - 1}}{{\rm{)}}^2} + {{\rm{(0}}{\rm{.1 - 0)}}^2} ={\rm{0}}{\rm{.05}} MSE_2((1,0),(0.8,0.1))=(0.81)2+(0.10)2=0.05
由于0.34>0.05,所以预测值 y 2 y_2 y2与真实值 y _ y\_ y_更接近, y 2 y_2 y2预测更准确。

对于多分类问题,MSE并不是一个常用的评估指标

在上一篇博文【TensorFlow1.X入门三】中的线性回归和非线性回归中都用到了此方法。


交叉熵(Cross Entropy)

交叉熵 Cross Entropy:n 个样本的预测值 y y y与真实值 y _ y\_ y_的概率分布之间的距离,交叉熵越大,两个概率分布距离越远,两个概率分布越相异;交叉熵越小,两个概率分布距离越近,两个概率分布越相似。
H ( y _ , y ) = − ∑ i = 1 n y _ ∗ log ⁡ y H({\rm{y\_}},y) = - \sum\nolimits_{i = 1}^n {y\_} *\log y H(y_,y)=i=1ny_logy
在 Tensorflow1.X中用loss_ce = -tf.reduce_mean(y_* tf.log(tf.clip_by_value(y, 1e-12, 1.0)))
同一个小案例,根据交叉熵的计算公式得:
H _ 1 ( ( 1 , 0 ) , ( 0.7 , 0.5 ) ) = − ( 1 ∗ l o g 0.7 + 0 ∗ l o g 0.3 ) ≈ 0.36 H\_1\left( {\left( {1,0} \right),\left( {0.7,0.5} \right)} \right){\rm{ }} = {\rm{ }} - \left( {1*log0.7{\rm{ }} + {\rm{ }}0*log0.3} \right) \approx {\rm{ }}0.36 H_1((1,0),(0.7,0.5))=(1log0.7+0log0.3)0.36
H _ 2 ( ( 1 , 0 ) , ( 0.8 , 0.1 ) ) = − ( 1 ∗ l o g 0.8 + 0 ∗ l o g 0.1 ) ≈ 0.22 H\_2\left( {\left( {1,0} \right),\left( {0.8,0.1} \right)} \right){\rm{ }} = {\rm{ }} - \left( {1*log0.8{\rm{ }} + {\rm{ }}0*log0.1} \right) \approx {\rm{ }}0.22 H_2((1,0),(0.8,0.1))=(1log0.8+0log0.1)0.22
由于0.36>0.22,所以预测值 y 2 y_2 y2与真实值 y _ y\_ y_更接近, y 2 y_2 y2预测更准确。

这里 n n n分类的输出概率并没有什么联系,而且通常会将每个概率值都压缩在min和max之间:小于min的值等于min,大于max的值等于max。tf.clip_by_value(y, 1e-12, 1.0)即在0到1之间,这样的话上面的H_1的值就被压缩成是 H _ 1 ( ( 1 , 0 ) , ( 0.7 , 0.3 ) ) ≈ 0.36 H\_1\left( {\left( {1,0} \right),\left( {0.7,0.3} \right)} \right){\rm{ }}\approx {\rm{ }}0.36 H_1((1,0),(0.7,0.3))0.36,所以 H _ 1 H\_1 H_1公式博主并没有写错。

在深度学习中,一般让模型的输出经过softmax函数,以获得输出分类的概率分布,再与真实值对比,求出交叉熵,得到损失函数。softmax函数要求 n n n分类的输出满足以下概率分布要求的函数: p ( X = x i ) ∈ [ 0 , 1 ] p(X = {x_i}) \in [0,1] p(X=xi)[0,1] ∑ i n p ( X = x i ) = 1 \sum\nolimits_i^n {p(X = {x_i}) = 1} inp(X=xi)=1,softmax函数具体表示为: p ( X = x i ) = s o f t m a x ( x i ) = e x i ∑ i = 1 n e x i p(X = {x_i}) = {\rm{softmax}}({x_i}) = \frac{{{e^{{x_i}}}}}{{\sum\nolimits_{i = 1}^n {{e^{{x_i}}}} }} p(X=xi)=softmax(xi)=i=1nexiexi
在 Tensorflow1.X中结合softmax和Cross Entropy后用loss_ce = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1)))
同一个小案例,根据改良版本的交叉熵的计算公式得:
H _ 1 ( ( 1 , 0 ) , s o f t m a x ( 0.7 , 0.5 ) ) ≈ H _ 1 ( ( 1 , 0 ) , ( 0.57 , 0.43 ) ) = 0.56 H\_1\left( {\left( {1,0} \right),softmax\left( {0.7,0.5} \right)} \right) \approx H\_1\left( {\left( {1,0} \right),\left( {0.57,0.43} \right)} \right){\rm{ }} = {\rm{ }}0.56 H_1((1,0),softmax(0.7,0.5))H_1((1,0),(0.57,0.43))=0.56
H _ 2 ( ( 1 , 0 ) , s o f t m a x ( 0.8 , 0.1 ) ) ≈ H _ 1 ( ( 1 , 0 ) , ( 0.79 , 0.21 ) ) = 0.24 H\_2\left( {\left( {1,0} \right),softmax\left( {0.8,0.1} \right)} \right) \approx H\_1\left( {\left( {1,0} \right),\left( {0.79,0.21} \right)} \right){\rm{ }} = {\rm{ }}0.24 H_2((1,0),softmax(0.8,0.1))H_1((1,0),(0.79,0.21))=0.24
由于0.56>0.24,所以预测值 y 2 y_2 y2与真实值 y _ y\_ y_更接近, y 2 y_2 y2预测更准确。
在上一篇博文【TensorFlow1.X入门三】中的逻辑回归中都用到了此方法。


自定义损失函数

根据问题的实际情况,定制合理的损失函数。
举个例子:对于预测酸奶日销量问题,如果预测销量大于实际销量则会损失成本;如果预测销量小于实际销量则会损失利润。在实际生活中,往往制造一盒酸奶的成本和销售一盒酸奶的利润是不等价的。因此,需要使用符合该问题的自定义损失函数: l o s s = ∑ i = 0 n f ( y _ , y ) loss = \sum\nolimits_{i = 0}^n {f(y\_,y)} loss=i=0nf(y_,y)
自定义损失函数制作为分段函数: f ( y _ , y ) = { p r o f i t × ( y _ − y ) , y < y _ c o s t × ( y _ − y ) , y > = y _ f(y\_,y) = \left\{ {\begin{array}{cc} {profit \times (y\_ - y),y < y\_}\\ {cost \times (y\_ - y),y > = y\_} \end{array}} \right. f(y_,y)={profit×(y_y),y<y_cost×(y_y),y>=y_
若预测结果 y 小于标准答案 y_,损失函数为利润乘以预测结果 y 与标准答案 y_之差;
若预测结果 y 大于标准答案 y_,损失函数为成本乘以预测结果 y 与标准答案 y_之差。
在 Tensorflow1.X中用loss = tf.reduce_sum(tf.where(tf.greater(y,y_),COST(y-y_),PROFIT(y_-y)))
自定义损失函数的完整的代码:

#coding:utf-8
#酸奶成本1元, 酸奶利润9元
#预测少了损失大,故不要预测少,故生成的模型会多预测一些
#0导入模块,生成数据集
import tensorflow as tf
import numpy as np
BATCH_SIZE = 8
SEED = 23455
COST = 8
PROFIT = 2

rdm = np.random.RandomState(SEED)
X = rdm.rand(32,2)
# 假设市场的真实利润Y=3*COST+2*PROFIT
Y = [[3*x1+2*x2+(rdm.rand()/10.0-0.05)] for (x1, x2) in X]

# 定义神经网络的输入、参数和输出,定义前向传播过程。
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))
# 希望训练好的网络权重接近w=(a,b)接近(3,2)
w = tf.Variable(tf.random_normal([2, 1], stddev=1, seed=1))
y = tf.matmul(x, w)

#定义损失函数及反向传播方法。
loss = tf.reduce_sum(tf.where(tf.greater(y, y_), (y - y_)*COST, (y_ - y)*PROFIT))
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)

#生成会话,训练STEPS轮。
with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    STEPS = 3000
    for i in range(STEPS):
        start = (i*BATCH_SIZE) % 32
        end = (i*BATCH_SIZE) % 32 + BATCH_SIZE
        sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
        if i % 1000 == 0:
            print ("After %d training steps, w1 is: " % (i))
            print (sess.run(w), "\n")
    print ("Final w1 is: \n", sess.run(w))


采用均方损失函数的完整的代码:

只需要修改loss部分

#coding:utf-8
#酸奶成本1元, 酸奶利润9元
#预测少了损失大,故不要预测少,故生成的模型会多预测一些
#0导入模块,生成数据集
import tensorflow as tf
import numpy as np
BATCH_SIZE = 8
SEED = 23455
COST = 8
PROFIT = 2

rdm = np.random.RandomState(SEED)
X = rdm.rand(32,2)
# 假设市场的真实利润Y=3*COST+2*PROFIT
Y = [[3*x1+2*x2+(rdm.rand()/10.0-0.05)] for (x1, x2) in X]

# 定义神经网络的输入、参数和输出,定义前向传播过程。
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))
# 希望训练好的网络权重接近w=(a,b)接近(3,2)
w = tf.Variable(tf.random_normal([2, 1], stddev=1, seed=1))
y = tf.matmul(x, w)

#定义损失函数及反向传播方法。
loss = tf.reduce_mean(tf.square(y_ - y))
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)

#生成会话,训练STEPS轮。
with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    STEPS = 3000
    for i in range(STEPS):
        start = (i*BATCH_SIZE) % 32
        end = (i*BATCH_SIZE) % 32 + BATCH_SIZE
        sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
        if i % 1000 == 0:
            print ("After %d training steps, w1 is: " % (i))
            print (sess.run(w), "\n")
    print ("Final w1 is: \n", sess.run(w))


由执行结果可知,无论怎么修改COST和PROFIT的值,采用自定义损失函数预测的权重(2.98,1.98)都比采用均方误差预测的权重(1.88,2.83)更接近真实值(3,2),更符合实际需求。

总结

损失函数在机器学习和深度学习中起着非常重要的作用。它是用来衡量模型预测结果与真实标签之间的差异或误差的函数。通过最小化损失函数,我们可以训练模型的参数以使其能够更好地拟合训练数据,并在新的未见数据上做出准确的预测。博文对深度学习常见的损失函数进行的讲解,并根据问题的实际情况,举例分析讲解了如何定制合理的损失函数。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1126646.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能医疗:互联网医院开发的挑战与机会

随着技术的不断进步&#xff0c;互联网医院的发展为医疗保健带来了巨大的机遇&#xff0c;但同时也带来了一系列挑战。本文将探讨互联网医院开发中的一些关键挑战和机会&#xff0c;以及如何应对这些挑战。 挑战一&#xff1a;数据隐私和安全性 在互联网医院开发中&#xff…

Kubernetes技术与架构-网络 2

Kubernetes集群支持IP地址以及DNS访问Pod或者Service。 Service域名解析 Service域名解析包括A/AAAA记录以及SRV记录 A/AAAA记录 域名&#xff1a;my-svc.my-namespace.svc.cluster-domain.example 该域名对应的service名称是my-svc、service的命名空间是my-namespace、servic…

Qt之自定义model读写CSV文件

一.效果 本文基于QAbstractTableModel实现了一个支持读写CSV文件的TableModel。CSV数据格式虽然很简单,但是网上大多数读写方式其实都是有bug的,没考虑到字段里包含逗号或换行符这种复杂数据的情况。 二.原理 CSV(Comma-Separated Values)文件是一种简单类型的纯文本文件…

GoLong的学习之路(三)语法之运算符

书接上回&#xff0c;我们进展到了GoLong的基本数据类型&#xff0c;接下来说运算符&#xff08;其实和常见的编程语言的逻辑规则一样&#xff09; 运算符 运算符用于在程序运行时执行数学或逻辑运算。&#xff08;不可谓不重要&#xff09; Go 语言内置的运算符有&#xff…

python基础语法(4)

基础语法 前言文件文件是什么文件路径文件操作1.打开文件2. 关闭文件3.写文件4. 读文件5.上下文管理器 库使用库标准库第三方库 前言 本文基于pycharm编译器&#xff0c;也可以使用Anaconda 里的编译器&#xff0c;将讲解一些python的一些基础语法知识&#xff0c;是对上篇文章…

element-ui的日历组件el-calendar高度咋调小

最近项目首页有个空余 不知道放啥 打算放个日历card 充充位置&#xff0c; el-calendar日历组件的整体宽度可以用el-row el-col :gutter :span来控制自适应 但是官网文档没说高度咋缩小 细长一条好难看 自己尝试改了改element的样式没整出来 最后照着这位博主的方法改是好使滴…

STM32 HAL库串口使用printf

STM32 HAL库串口使用printf 背景配置说明在usart.h中添加在usart.c中添加在工程中选中微库&#xff1a; 测试 背景 在我们使用CubeMX生成好STM32 HAL库工程之后&#xff0c;我们想使用printf函数来打印一些信息&#xff0c;配置如下&#xff1a; 配置说明 在usart.h中添加 …

postgresql|数据库迁移|ora2pg工具的web界面介绍

前言&#xff1a; ora2pg是一个比较强大的数据库迁移工具&#xff0c;那根据名字来说&#xff0c;也可以看出来&#xff0c;这个工具主要是用来配置去O化&#xff0c;将在运行的oracle数据库迁移到postgresql数据库内的 当然了&#xff0c;我们使用此工具主要还是用命令行&am…

WeTab谷歌浏览器的AI助手,附WeTab下载地址

点击进入WeTab新标签页的&#xff0c;获取WeTab https://microsoftedge.microsoft.com/addons/detail/wetabai%E6%96%B0%E6%A0%87%E7%AD%BE%E9%A1%B5/bpelnogcookhocnaokfpoeinibimbeff?utm_sourceSteamDB 注&#xff1a;可能谷歌浏览器打开get按钮是灰色的&#xff0c;那就换…

Unity Hub报错:No valid Unity Editor license found. Please activate your license.

最近 遇到一个问题&#xff0c;打开高版本时Hub抛出异常&#xff1a;No valid Unity Editor license found. Please activate your license. 首先你必须排除是否登录Unity Hub&#xff0c;并且激活许可证。 方法一&#xff1a;禁用网络&#xff08;这个可能无效&#xff09; …

算法进阶——数组中的逆序对

题目 在数组中的两个数字&#xff0c;如果前面一个数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007 数据范围&#xff1a;对于 50% 的数据, size≤104 对…

Linux系统CH347应用—SPI功能

Linux/安卓系统使用CH347转接SPI功能有三种应用方式&#xff1a; 1. 使用CH34X_MPHSI_Master总线驱动为系统扩展原生SPI Master&#xff0c;此方式无需进行单独的应用层编程&#xff1b; 2. 使用CH341PAR_LINUX字符设备驱动&#xff0c;此方式需要配合使用厂商提供的库文件&a…

js创建 ajax 过程

目录 前言&#xff1a;AJAX 技术的重要性 详解&#xff1a;创建 AJAX 请求的步骤 1. 创建 XMLHttpRequest 对象 2. 配置请求 3. 处理响应 4. 发送请求 5. 处理异步请求 解析&#xff1a;AJAX 请求的重要性和限制 总结&#xff1a; 前言&#xff1a;AJAX 技术的重要性 …

2019年亚太杯APMCM数学建模大赛B题区域经济活力及其影响因素的分析与决策求解全过程文档及程序

2019年亚太杯APMCM数学建模大赛 B题 区域经济活力及其影响因素的分析与决策 原题再现 区域&#xff08;或城市或省级&#xff09;经济活力是区域综合竞争力的重要组成部分。近年来&#xff0c;为了提高经济活力&#xff0c;一些地区推出了许多刺激经济活力的优惠政策&#xf…

分布式锁的基本原理和实现以及synchronized底层原理

1.1Synchronized Synchronized的重点级锁&#xff0c;底层是基于锁监督器&#xff08;Monitor&#xff09;来实现&#xff0c;简单来说就是锁对象头会指向一个锁监督器&#xff0c;而在监督器中则会记录一些信息&#xff0c;比如&#xff1a; _owner:持有锁的线程_recursion…

自动驾驶之—车道线感知

零、前言 &#xff1a; 最近在学习自动驾驶方向的东西&#xff0c;简单整理一些学习笔记&#xff0c;学习过程中发现宝藏up 手写AI 一、视觉系统坐标系 视觉系统一共有四个坐标系&#xff1a;像素平面坐标系&#xff08;u,v&#xff09;、图像坐标系&#xff08;x,y&#xff09…

华泰证券:达达集团(DADA)3Q23业绩前瞻:短期业绩承压

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;考虑到宏观实物消费恢复相对较弱&#xff0c;华泰证券发布关于达达集团&#xff08;DADA&#xff09;达达集团&#xff08;DADA&#xff09;3Q23业绩前瞻:短期业绩承压的研报。 华泰证券在研报中预…

【Linux】【驱动】设备树中设备节点的挂载

【Linux】【驱动】设备树中设备节点的挂载 代码操作脚本Linux中的操作下位机中的操作指令 代码 设备树对应的文件是100ask_imx6ull_mini.dtb 所以需要在根节点上增加相关的测试代码 我们修改的就是hi如下的代码部分 增加测试节点 test1:test1{#addrsee-cells < 1 >;#s…

C算法:递归算法求a的n次方

需求&#xff1a; 用递归算法写一个函数&#xff0c;实现a的n次方。 代码实现&#xff1a; #include <stdio.h> #include <stdlib.h> int nndata(int a,int n) {if(n<1){printf("please input numdata(>1) !\n");exit(-1);}if(n1){return a;}els…

基于Java的校园办公室报修管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…