深度学习—损失函数及BP算法初步学习Day36

损失函数

1.MAE

MAE(Mean Absolute Error,平均绝对误差)通常也被称为 L1-Loss,通过对预测值和真实值之间的绝对差取平均值来衡量他们之间的差异。。

MAE的公式如下:
MAE = 1 n ∑ i = 1 n ∣ y i − y ^ i ∣ \text{MAE} = \frac{1}{n} \sum_{i=1}^{n} \left| y_i - \hat{y}_i \right| MAE=n1i=1nyiy^i
其中:

  • n n n 是样本的总数。
  • $ y_i $是第 i i i 个样本的真实值。
  • $ \hat{y}_i$ 是第 i i i 个样本的预测值。
  • ∣ y i − y ^ i ∣ \left| y_i - \hat{y}_i \right| yiy^i 是真实值和预测值之间的绝对误差。
import torchdef test01():l1_loss_fn = torch.nn.L1Loss()y_true = torch.tensor([1,2,3,4,5,6],dtype=torch.float32)y_pred = torch.tensor([10,20,30,40,50,60],dtype=torch.float32)loss = l1_loss_fn(y_true,y_pred)print(loss)if __name__ == '__main__':test01()

2.MSE

均方差损失,也叫L2Loss。

MSE(Mean Squared Error,均方误差)通过对预测值和真实值之间的误差平方取平均值,来衡量预测值与真实值之间的差异。

MSE的公式如下:
MSE = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 \text{MSE} = \frac{1}{n} \sum_{i=1}^{n} \left( y_i - \hat{y}_i \right)^2 MSE=n1i=1n(yiy^i)2
其中:

  • n n n 是样本的总数。
  • $ y_i $ 是第 i i i 个样本的真实值。
  • $ \hat{y}_i $ 是第 i i i 个样本的预测值。
  • ( y i − y ^ i ) 2 \left( y_i - \hat{y}_i \right)^2 (yiy^i)2 是真实值和预测值之间的误差平方。
import torchdef test01():l1_loss_fn = torch.nn.MSELoss()y_true = torch.tensor([1,2,3,4,5,6],dtype=torch.float32)y_pred = torch.tensor([2,3,4,5,6,8],dtype=torch.float32)loss = l1_loss_fn(y_true,y_pred)print(loss)if __name__ == '__main__':test01()

3.SmoothL1Loss

SmoothL1Loss可以做到在损失较小时表现为 L2 损失,而在损失较大时表现为 L1 损失。

SmoothL1Loss 的公式如下:
SmoothL1Loss ( x ) = { 0.5 ⋅ x 2 , if  ∣ x ∣ < 1 ∣ x ∣ − 0.5 , otherwise \text{SmoothL1Loss}(x) = \begin{cases} 0.5 \cdot x^2, & \text{if } |x| < 1 \\ |x| - 0.5, & \text{otherwise} \end{cases} SmoothL1Loss(x)={0.5x2,x0.5,if x<1otherwise
其中, x x x 表示预测值和真实值之间的误差,即 x = y i − y ^ i x = y_i - \hat{y}_i x=yiy^i

所有样本的平均损失为:
L = 1 n ∑ i = 1 n L i \\L=\frac{1}{n} \sum_{i=1}^{n} L_{i} L=n1i=1nLi

import torchdef test01():l1_loss_fn = torch.nn.SmoothL1Loss()l1_loss_fn1 =torch.nn.functional.smooth_l1_lossy_true = torch.tensor([1,2,3,4],dtype=torch.float32)y_pred = torch.tensor([3,2.5,3.5,4.5],dtype=torch.float32)loss = l1_loss_fn(y_true,y_pred)print(loss)if __name__ == '__main__':test01()

4.CrossEntropyLoss

交叉熵损失函数,使用在输出层使用softmax激活函数进行多分类时,一般都采用交叉熵损失函数。

对于多分类问题,CrossEntropyLoss 公式如下:
CrossEntropyLoss ( y , y ^ ) = − ∑ i = 1 C y i log ⁡ ( y ^ i ) \text{CrossEntropyLoss}(y, \hat{y}) = - \sum_{i=1}^{C} y_i \log(\hat{y}_i) CrossEntropyLoss(y,y^)=i=1Cyilog(y^i)

其中:

  • C C C 是类别的总数。
  • $ y $$ 是真实标签的one-hot编码向量,表示真实类别。
  • y ^ \hat{y} y^ 是模型的输出(经过 softmax 后的概率分布)。
  • y i y_i yi 是真实类别的第 i i i 个元素(0 或 1)。
  • $ \hat{y}_i $ 是预测的类别概率分布中对应类别 i i i 的概率。
import torch
import torch.nn as nndef test01():l1_loss_fn = torch.nn.CrossEntropyLoss()one_hot = torch.tensor([[1.5,2.0,0.5],[0.5,1.0,1.5]])y_pred = torch.tensor([1,2])loss = l1_loss_fn(one_hot,y_pred)print(loss)if __name__ == '__main__':test01()

5.BCELoss

二分类交叉熵损失函数,使用在输出层使用sigmoid激活函数进行二分类时。

对于二分类问题,CrossEntropyLoss 的简化版本称为二元交叉熵(Binary Cross-Entropy Loss),公式为:
BinaryCrossEntropy ( y , y ^ ) = − [ y log ⁡ ( y ^ ) + ( 1 − y ) log ⁡ ( 1 − y ^ ) ] \text{BinaryCrossEntropy}(y, \hat{y}) = - \left[ y \log(\hat{y}) + (1 - y) \log(1 - \hat{y}) \right] BinaryCrossEntropy(y,y^)=[ylog(y^)+(1y)log(1y^)]
log的底数一般默认为e,y是真实类别目标,根据公式可知L是一个分段函数 :
L = − l o g ( s i g m o i d 激活值 ) , 当 y = 1 L = − l o g ( 1 − s i g m o i d 激活值 ) , 当 y = 0 L = -log(sigmoid激活值), 当y=1 \\ L = -log(1-sigmoid激活值), 当y=0 L=log(sigmoid激活值),y=1L=log(1sigmoid激活值),y=0

import torchdef test01():#样本x = torch.tensor([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.41,0.52,0.63],[0.41,0.51,0.61]])#权重w = torch.tensor([[0.11,0.22,0.33],[0.44,0.55,0.66],[0.41,0.53,0.63],[0.4,0.1,0.6]])#偏置b = 0.1#预测y = w*x +b#激活y_pred = torch.nn.functional.sigmoid(y)print(y_pred)y_true = torch.tensor([[1,0,0],[1,0,0],[0,0,1],[0,0,1]],dtype=torch.float32)loss_fn = torch.nn.BCELoss()loss_fn1 = torch.nn.functional.binary_cross_entropyloss = loss_fn1(y_pred,y_true)print(loss)if __name__ == '__main__':test01()

BP算法

在这里插入图片描述
误差反向传播算法(BP)的基本步骤:

  1. 前向传播:正向计算得到预测值。
  2. 计算损失:通过损失函数 L ( y pred , y true ) L(y_{\text{pred}}, y_{\text{true}}) L(ypred,ytrue) 计算预测值和真实值的差距。
  3. 梯度计算:反向传播的核心是计算损失函数 L L L 对每个权重和偏置的梯度。
  4. 更新参数:一旦得到每层梯度,就可以使用梯度下降算法来更新每层的权重和偏置,使得损失逐渐减小。
  5. 迭代训练:将前向传播、梯度计算、参数更新的步骤重复多次,直到损失函数收敛或达到预定的停止条件。

1.前向传播

既把数据按照输入层→神经元→输出层逐级传递
1.输入层到隐藏层
z ( 1 ) = W 1 ⋅ x + b 1 z^{(1)} = W_1 \cdot x + b_1 z(1)=W1x+b1
a ( 1 ) = σ ( z ( 1 ) ) a^{(1)} = \sigma(z^{(1)}) a(1)=σ(z(1))
2.隐藏层到输出层
z ( 2 ) = W 2 ⋅ a ( 1 ) + b 2 z^{(2)} = W_2 \cdot a^{(1)} + b_2 z(2)=W2a(1)+b2
y pred = a ( 2 ) = σ ( z ( 2 ) ) y_{\text{pred}} = a^{(2)} = \sigma(z^{(2)}) ypred=a(2)=σ(z(2))

2.反向传播

反向传播是训练神经网络时常用的一种算法,用于高效地计算损失函数关于网络权重的梯度。通过这些梯度,可以使用梯度下降等优化算法来更新网络的权重,从而最小化损失函数。反向传播的核心思想是利用链式法则来逐层传递误差信息,从输出层向输入层反向传播。
在这里插入图片描述

'''
手动实现反向传播
'''
import torchi1 = 0.05
i2 = 0.10
b1 = 0.35
def h1():w1 = torch.tensor(0.15)w2 = torch.tensor(0.20)l1 = i1*w1 + i2*w2 +b1return torch.sigmoid(l1)#1+torch.e**(-l1))**-1
print('h1神经元的输入结果:',h1())def h2():w3 = torch.tensor(0.25)w4 = torch.tensor(0.30)l2 = i1*w3 + i2*w4 +b1return torch.sigmoid(l2)#(1+torch.e**(-l2))**(-1)
print('h2神经元的输入结果:',h2())b2 = 0.60
def o1():w5 = torch.tensor(0.4)w6 = torch.tensor(0.45)l3 = h1()*w5 + h2()*w6 + b2print('l3',l3)m1 = torch.sigmoid(l3)#(1+torch.e**(-l3))**(-1)return m1
print('o1神经元的输入结果:',o1())def o2():w7 = torch.tensor(0.5)w8 = torch.tensor(0.55)l4 = h1()*w7 + h2()*w8 + b2print('l4',l4)m2 = torch.sigmoid(l4)#(1+torch.e**(-l4))**(-1)return m2
print('o2神经元的输入结果:',o2())def mse():o1_target = 0.01o2_target = 0.99return 0.5*((o1()-0.01)**2+(o2()-0.99)**2)
loss = mse()#loss是一个具体值#目标是求loss对w5求导
#求w5的梯度 ==> loss对o1()求导 ==> o1()对l3求导 ==> l3对w5再求导
#(m1-o1_target) * (sigmoid(l3)*(1-sigmoid(l3) * h1
#(0.7513650695523157-0.01) * (sigmoid(1.1059)*(1-sigmoid(1.1059) * 0.5933
dw5 = (0.7513650695523157-0.01) * (0.7513650695523157*(1-0.7513650695523157)) * 0.5933
print('dw5',dw5)#0.08217119661422286#目标是求loss对w5求导
#求w7的梯度 ==> loss对o2()求导 ==> o2()对l4求导 ==> l4对w7再求导
#(m2-o2_target) * (sigmoid(l4)*(1-sigmoid(l4) * h1
#(0.7729-0.99) * (sigmoid(1.2249)*(1-sigmoid(1.2249) * 0.5933
dw7 = (0.7729-0.99) * (0.7729*(1-0.7729)) * 0.5933
print('dw7',dw7)#0.08217119661422286#目标是求loss对w1求导
#求w1的梯度 ==> loss对o1()求导 ==> o1()对l3求导 ==> l3对h1()求导 ==> h1()对l1求导 ==> l1对w1求导
#(m1-o1_target) * (sigmoid(l3)*(1-sigmoid(l3) * w5 * sigmoid(l1)*(1-sigmoid(l1)) * i1
dw1 = (0.7513650695523157-0.01) * (0.7513650695523157*(1-0.7513650695523157)) * 0.4 * 0.5933*(1-0.5933) * 0.05
print('dw1',dw1)
dw1 = 0.0004
lr = 0.5
w1 = 0.15 - lr*dw1
w5 = 0.40 - lr*dw5
w7 = 0.5 -lr*dw7
print('w1_new',w1)
print('w5_new',w5)
print('w7_new',w7)```python
'''
标准反向传播方式1
'''
import torchclass mynet(torch.nn.Module):def __init__(self):super(mynet, self).__init__()# 定义网络结构self.linear1 = torch.nn.Linear(2, 2)self.linear2 = torch.nn.Linear(2, 2)self.activation = torch.nn.Sigmoid()# 初始化参数self.linear1.weight.data = torch.tensor([[0.15, 0.20],[0.25, 0.30]])self.linear2.weight.data = torch.tensor([[0.40, 0.45],[0.50, 0.55]])self.linear1.bias.data = torch.tensor([0.35, 0.35])self.linear2.bias.data = torch.tensor([0.60, 0.60])def forward(self, x):x = self.linear1(x)x = self.activation(x)x = self.linear2(x)x = self.activation(x)return xdef train():model = mynet()optimizer = torch.optim.SGD(model.parameters(), lr=0.1)input = torch.tensor([[0.05, 0.1]])target = torch.tensor([[0.01, 0.99]])pred = model(input)  # torch.nn.Module父系已经实现了调用forward前向传播函数mes = torch.nn.MSELoss()loss = mes(pred, target)loss.backward()print(model.linear1.weight.grad)print(model.linear2.weight.grad)optimizer.step()# model.linear1.weight.data -= 0.1*model.linear1.weight.grad# model.linear2.weight.data -= 0.1 * model.linear2.weight.gradtrain()
'''
标准反向传播方式2
'''
import torchclass mynet(torch.nn.Module):def __init__(self):super(mynet, self).__init__()# 定义网络结构self.hide1 = torch.nn.Sequential(torch.nn.Linear(2,2),torch.nn.Sigmoid())self.out = torch.nn.Sequential(torch.nn.Linear(2, 2), torch.nn.Sigmoid())# self.linear1 = torch.nn.Linear(2, 2)# self.linear2 = torch.nn.Linear(2, 2)# self.activation = torch.nn.Sigmoid()# 初始化参数self.hide1[0].weight.data = torch.tensor([[0.15, 0.20],[0.25, 0.30]])self.out[0].weight.data = torch.tensor([[0.40, 0.45],[0.50, 0.55]])self.hide1[0].bias.data = torch.tensor([0.35, 0.35])self.out[0].bias.data = torch.tensor([0.60, 0.60])def forward(self, x):x = self.hide1(x)x = self.out(x)return xdef train():model = mynet()optimizer = torch.optim.SGD(model.parameters(), lr=0.1)input = torch.tensor([[0.05, 0.1]])target = torch.tensor([[0.01, 0.99]])pred = model(input)  # torch.nn.Module父系已经实现了调用forward前向传播函数mes = torch.nn.MSELoss()loss = mes(pred, target)loss.backward()print(model.hide1[0].weight.grad)print(model.out[0].weight.grad)optimizer.step()# model.linear1.weight.data -= 0.1*model.linear1.weight.grad# model.linear2.weight.data -= 0.1 * model.linear2.weight.gradtrain()

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[UUCTF 2022 新生赛]ez_rce

[UUCTF 2022 新生赛]ez_rce 我们来分析一下这个代码&#xff1a; 首先是isset看我们有没有传一个为空的值&#xff0c;如果为空就输出居然都不输入参数&#xff0c;可恶!!!!!!!!!不为空就GET传参赋值给$code &#xff0c;接着 如果 $code 中不包含这些模式中的任何一个&#x…

Flutter:启动屏逻辑处理02:启动页

启动屏启动之后&#xff0c;制作一个启动页面 新建splash&#xff1a;view 视图中只有一张图片sliding.png就是我们的启动图 import package:flutter/material.dart; import package:get/get.dart; import index.dart; class SplashPage extends GetView<SplashController…

系统思考—共同看见

在一家零售企业的项目中&#xff0c;团队频繁讨论客户流失的严重性&#xff0c;但每次讨论的结果都无法明确找出问题的根源。大家都知道客户流失了&#xff0c;但究竟是什么原因导致的&#xff0c;始终没有一致的答案。市场部认为是客户体验差&#xff0c;客服部门觉得是响应慢…

数据结构(Java版)第四期:ArrayLIst和顺序表(上)

目录 一、顺序表 1.1. 接口的实现 二、ArrayList简介 2.1. ArrayList的构造 2.2. ArrayList的常见操作 2.3. ArrayList的扩容机制 三、ArrayList的具体使用 3.1. 洗牌算法 3.2. 杨辉三角 一、顺序表 上一期我们讲到过&#xff0c;顺序表本质上和数组是差不多的&#…

Python编程语言中的优雅艺术:数值分隔符的巧妙运用

在Python编程的世界里&#xff0c;有许多精巧的设计让代码更优雅、更易读。今天要分享的是一个看似简单却能大幅提升代码可读性的特性 —— 数值分隔符。这个特性从Python 3.6版本开始引入&#xff0c;它用一种极其优雅的方式解决了大数值表示的难题。 数值分隔符的本质与应用…

心情追忆:构建支付模块的五个基本接口设计

之前&#xff0c;我独自一人开发了一个名为“心情追忆”的小程序&#xff0c;旨在帮助用户记录日常的心情变化及重要时刻。我从项目的构思、设计、前端&#xff08;小程序&#xff09;开发、后端搭建到最终部署。经过一个月的努力&#xff0c;通过群聊分享等方式&#xff0c;用…

实验三 z变换及离散时间LTI系统的z域分析

实验原理 有理函数z 变换的部分分式展开 【实例2-1】试用Matlab 命令对函数 X ( z ) 18 18 3 − 1 − 4 z − 2 − z − 3 X\left(z\right)\frac{18}{183^{-1} -4z^{-2} -z^{-3} } X(z)183−1−4z−2−z−318​ 进行部分分式展开&#xff0c;并求出其z 反变换。 B[18]; A…

Web登录页面设计

记录第一个前端界面&#xff0c;暑假期间写的&#xff0c;用了Lottie动画和canvas标签做动画&#xff0c;登录和注册也连接了数据库。 图片是从网上找的&#xff0c;如有侵权私信我删除&#xff0c;谢谢啦~

【es6】原生js在页面上画矩形及删除的实现方法

画一个矩形&#xff0c;可以选中高亮&#xff0c;删除自己效果的实现&#xff0c;后期会丰富下细节&#xff0c;拖动及拖动调整矩形大小 实现效果 代码实现 class Draw {constructor() {this.x 0this.y 0this.disX 0this.disY 0this.startX 0this.startY 0this.mouseDo…

高级 K8s 面试题(Advanced K8S Interview Questions)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

HiISP(一)

系列文章目录 文章目录 系列文章目录前言一、Hi3518EV200 芯片架构1.1. ARM子系统1.2. 图像子系统&#xff08;Image Subsystem&#xff09;1.3. 视频子系统&#xff08;Video Subsystem&#xff09;1.4. 存储与接口模块1.5. 通用功能模块1.6. DDR与总线1.7. 数据流1.7.1. 数据…

京东物流与亿纬锂能达成战略合作,双方跨界意义何在?

首先&#xff0c;这一合作有助于双方实现资源共享和优势互补。京东物流作为国内领先的物流服务商&#xff0c;拥有先进的物流技术和丰富的运营经验&#xff0c;能够为亿纬锂能提供高效、安全、可靠的物流服务。而亿纬锂能作为新能源领域的佼佼者&#xff0c;拥有先进的电池技术…

103.【C语言】数据结构之二叉树的三种递归遍历方式

目录 1.知识回顾 2.分析二叉树的三种遍历方式 1.总览 2.前序遍历 3.中序遍历 4.后序遍历 5.层序遍历 3.代码实现 1.准备工作 2.前序遍历函数PreOrder 测试结果 3.中序遍历函数InOrder 测试结果 4.后序遍历函数PostOrder 测试结果 4.底层分析 1.知识回顾 在99.…

【kafka03】消息队列与微服务之Kafka 读写数据

Kafka 读写数据 参考文档 Apache Kafka 常见命令 kafka-topics.sh #消息的管理命令 kafka-console-producer.sh #生产者的模拟命令 kafka-console-consumer.sh #消费者的模拟命令 创建 Topic 创建topic名为 chen&#xff0c;partitions(分区)为3&#xff0…

SAP开发语言ABAP开发入门

1. 了解ABAP开发环境和基础知识 - ABAP简介 - ABAP&#xff08;Advanced Business Application Programming&#xff09;是SAP系统中的编程语言&#xff0c;主要用于开发企业级的业务应用程序&#xff0c;如财务、物流、人力资源等模块的定制开发。 - 开发环境搭建 - 首先需…

[护网杯 2018]easy_tornado

这里有一个hint点进去看看&#xff0c;他说md5(cookie_secretmd5(filename))&#xff0c;所以我们需要获得cookie_secret的value 根据题目tornado,它可能是tornado的SSTI 这里吧filehash改为NULL. 是tornado的SSTI 输入{{handler.settings}} (settings 属性是一个字典&am…

【k8s深入学习之 Scheme】全面理解 Scheme 的注册机制、内外部版本、自动转换函数、默认填充函数、Options等机制

参考 【k8s基础篇】k8s scheme3 之序列化_基于schema进行序列化-CSDN博客【k8s基础篇】k8s scheme4 之资源数据结构与资源注册_kubernetes 的scheam-CSDN博客 Scheme的字段总览 type Scheme struct {// gvkToType 允许通过给定的版本和名称来推断对象的 Go 类型。// map 键是…

PySide6 QSS(Qt Style Sheets) Reference: PySide6 QSS参考指南

Qt官网参考资料&#xff1a; QSS介绍&#xff1a; Styling the Widgets Application - Qt for Pythonhttps://doc.qt.io/qtforpython-6/tutorials/basictutorial/widgetstyling.html#tutorial-widgetstyling QSS 参考手册&#xff1a; Qt Style Sheets Reference | Qt Widge…

python控制鼠标,键盘,adb

python控制鼠标&#xff0c;键盘&#xff0c;adb 听说某系因为奖学金互相举报&#xff0c;好像拿不到要命一样。不禁想到几天前老墨偷走丁胖子的狗&#xff0c;被丁胖子逮到。他面对警察的问询面不改色坚持自我&#xff0c;反而是怒气冲冲的丁胖子被警察认为是偷狗贼。我觉得这…

前端Vue项目整合nginx部署到docker容器

一、通过Dockerfile整合nginx方法&#xff1a; 1&#xff0c;使用Vue CLI或npm脚本构建生产环境下的Vue项目。 npm run build or yarn build2&#xff0c;构建完成后&#xff0c;项目目录中会生成一个dist文件夹&#xff0c;里面包含了所有静态资源文件&#xff08;HTML、CSS…