深度学习基础2

目录

1.损失函数

1.1 线性回归损失函数

1.1.1 MAE损失

1.1.2 MSE损失

1.1.3 SmoothL1Loss

1.2 CrossEntropyLoss

1.3 BCELoss

1.4. 总结

2.BP算法

2.1 前向传播

2.2 反向传播

2.2.1 原理

2.2.2. 链式法则

2.4 重要性

2.5 案例

2.5.1 数据准备

2.5.2 神经元计算

2.5.3 损失计算

2.5.4 梯度计算

2.5.5 参数更新  


1.损失函数

1.1 线性回归损失函数

1.1.1 MAE损失

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

公式:

其中:

  • n 是样本的总数。

  • y_i 是第 i 个样本的真实值。

  • \hat{y}_i 是第 i 个样本的预测值。

  • \left| y_i - \hat{y}_i \right| 是真实值和预测值之间的绝对误差。

特点

  • 鲁棒性:与均方误差(MSE)相比,MAE对异常值(outliers)更为鲁棒,因为它不会像MSE那样对较大误差平方敏感。

  • 物理意义直观:MAE以与原始数据相同的单位度量误差,使其易于解释。

应用场景

MAE通常用于需要对误差进行线性度量的情况,尤其是当数据中可能存在异常值时,MAE可以避免对异常值的过度惩罚。

import torch
import torch.nn as nn

y_true = torch.tensor([1.0, 2.0, 3.0])
y_pred = torch.tensor([4.0, 5.0, 6.0])

mae = nn.L1Loss()

loss  = mae(y_true,y_pred)

print(loss)

1.1.2 MSE损失

均方差损失,也叫L2Loss

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

公式:

其中:

  • n 是样本的总数。

  • y_i 是第 i 个样本的真实值。

  • \hat{y}_i 是第 i 个样本的预测值。

  • \left( y_i - \hat{y}_i \right)^2 是真实值和预测值之间的误差平方。

 特点

  • 平方惩罚:因为误差平方,MSE 对较大误差施加更大惩罚,所以 MSE 对异常值更为敏感。

  • 凸性:MSE 是一个凸函数,这意味着它具有一个唯一的全局最小值,有助于优化问题的求解。

应用场景

MSE被广泛应用在神经网络中。

y_true = torch.tensor([1.0, 4.0, 5.0])
y_pred = torch.tensor([6.0, 3.0, 2.0])

mae = nn.MSELoss()

loss  = mae(y_true,y_pred)

print(loss)

1.1.3 SmoothL1Loss

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

公式:

其中,x 表示预测值和真实值之间的误差,即x = y_i - \hat{y}_i。

所有样本的平均损失为:

特点:

  • 平滑过渡:当误差较小时,损失函数表现为 L2 Loss(平方惩罚);当误差较大时,损失函数逐渐向 L1 Loss过渡。这种平滑过渡既能对大误差有所控制,又不会对异常值过度敏感。

  • 稳健性:对于异常值更加稳健,同时在小误差范围内提供了较好的优化效果。

应用场景:

常用于需要对大误差进行一定控制但又不希望完全忽略小误差的回归任务。特别适用于目标检测任务中的边界框回归,如 Faster R-CNN 等算法中。

predictions = torch.tensor([1.0, 2.0, 3.0, 4.0])
targets = torch.tensor([3.0, 2.5, 3.5, 4.5])

# 方式一:
smooth_loss = nn.SmoothL1Loss()
loss = smooth_loss(predictions,targets)
print(loss)

# 方式二:
loss1 = nn.functional.smooth_l1_loss(predictions,targets)
print(loss1)

1.2 CrossEntropyLoss

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

对于多分类问题,CrossEntropyLoss 公式如下:

其中:

  • C 是类别的总数。

  • y 是真实标签的one-hot编码向量,表示真实类别。

  • \hat{y} 是模型的输出(经过 softmax 后的概率分布)。

  • y_i 是真实类别的第 i 个元素(0 或 1)。

  • \hat{y}_i 是预测的类别概率分布中对应类别 i 的概率。

特点:

Softmax 就是将网络输出的 logits 通过 softmax 函数,就映射成为(0,1)的值,而这些值的累和为1(满足概率的性质),那么我们将它理解成概率,选取概率最大(也就是值对应最大的)节点,作为我们的预测目标类别。

# 假设有三个类别,模型输出是未经softmax的logits
logits = torch.tensor([[1.5, 2.0, 0.5], [0.5, 1.0, 1.5]])
labels = torch.tensor([1,2])

criterion = nn.CrossEntropyLoss()

loss = criterion(logits,labels)
print(loss)

1.3 BCELoss

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

公式:

log的底数一般默认为e,y是真实类别目标,根据公式可知L是一个分段函数 :

以上损失函数是一个样本的损失值,总样本的损失值是求损失均值即可。

# y 是模型的输出,已经被sigmoid处理过,确保其值域在(0,1)
y = torch.tensor([[0.7], [0.2], [0.9], [0.7]],dtype=torch.float32)
# targets 是真实的标签,0或1
t = torch.tensor([[1], [0], [1], [0]],dtype=torch.float32)

# 计算损失方式一:
bceloss = nn.BCELoss()
loss = bceloss(y,t)
print(loss)

#计算损失方式二: 
loss2 = nn.functional.binary_cross_entropy(y,t)
print(loss2)

1.4. 总结

(1)当输出层使用softmax多分类时,使用交叉熵损失函数;

(2)当输出层使用sigmoid二分类时,使用二分类交叉熵损失函数, 比如在逻辑回归中使用;

(3)当功能为线性回归时,使用smooth L1损失函数或均方差损失-L2 loss;

2.BP算法

多层神经网络的学习能力比单层网络强得多。想要训练多层网络,需要更强大的学习算法。误差反向传播算法(Back Propagation)是其中最杰出的代表,它是目前最成功的神经网络学习算法。BP 算法不仅可用于多层前馈神经网络,还可以用于其他类型的神经网络。通常说 BP 网络时,一般是指用 BP 算法训练的多层前馈神经网络。

误差反向传播算法(BP)的基本步骤:

(1)前向传播:正向计算得到预测值。

(2)计算损失:通过损失函数计算预测值和真实值的差距。

(3)梯度计算:反向传播的核心是计算损失函数 L 对每个权重和偏置的梯度。

(4)更新参数:一旦得到每层梯度,就可以使用梯度下降算法来更新每层的权重和偏置,使得损失逐渐减小。

(5)迭代训练:将前向传播、梯度计算、参数更新的步骤重复多次,直到损失函数收敛或达到预定的停止条件。

2.1 前向传播

前向传播(Forward Propagation)把输入数据经过各层神经元的运算并逐层向前传输,一直到输出层为止。

作用:

  • 计算神经网络的输出结果,用于预测或计算损失。

  • 在反向传播中使用,通过计算损失函数相对于每个参数的梯度来优化网络。

2.2 反向传播

反向传播(Back Propagation,简称BP)通过计算损失函数相对于每个参数的梯度来调整权重,使模型在训练数据上的表现逐渐优化。反向传播结合了链式求导法则和梯度下降算法,是神经网络模型训练过程中更新参数的关键步骤。

2.2.1 原理

利用链式求导法则对每一层进行求导,直到求出输入层x的导数,然后利用导数值进行梯度更新

2.2.2. 链式法则

链式求导法则(Chain Rule)是微积分中的一个重要法则,用于求复合函数的导数。在深度学习中,链式法则是反向传播算法的基础,这样就可以通过分层的计算求得损失函数相对于每个参数的梯度。以下面的复合函数为例:

 其中 x 是输入数据,w 是权重,b 是偏置。

函数分解:

可以将该复合函数分解为:

链式求导:

x = torch.tensor(1.0)
w = torch.tensor(0.0,requires_grad =True)
b = torch.tensor(0.0,requires_grad =True)

# 函数
y = (torch.exp(-(w*x+b)+1))**-1

# 自动微分
y.backward()

print(w.grad)

2.4 重要性

反向传播算法极大地提高了多层神经网络训练的效率,使得训练深度模型成为可能。通过链式法则逐层计算梯度,反向传播可以有效地处理复杂的网络结构,确保每一层的参数都能得到合理的调整。

2.5 案例

2.5.1 数据准备

整体网络结构及神经元数据和权重参数如下图所示:

2.5.2 神经元计算

2.5.3 损失计算

2.5.4 梯度计算

2.5.5 参数更新  

假设学习率是0.5

方式1:

import math

# 前向传播
i1 = 0.05
i2 = 0.10
b1 = 0.35

w1 = 0.15
w2 = 0.20

w3 = 0.25
w4 = 0.30

w5 = 0.40
w6 = 0.45

w7 = 0.50
w8 = 0.55

# 神经元h1
def h1():
    # 线性
    l1_1 = i1 * w1 + i2 * w2 + b1
    # 激活函数
    return 1 / (1 + math.exp(-l1_1))

# 神经元h2
def h2():
    # 线性
    l1_2 = i1 * w3 + i2 * w4 + b1
    # 激活函数
    return 1 / (1 + math.exp(-l1_2))

b2 = 0.60

# 神经元o1
def o1(h1_val, h2_val):
    # 线性
    l2_1 = h1_val * w5 + h2_val * w6 + b2
    # 激活函数
    return 1 / (1 + math.exp(-l2_1))

# 神经元o2
def o2(h1_val, h2_val):
    # 线性
    l2_2 = h1_val * w7 + h2_val * w8 + b2
    # 激活函数
    return 1 / (1 + math.exp(-l2_2))

# 计算前向传播的结果
h1_val = h1()
h2_val = h2()
o1_val = o1(h1_val, h2_val)
o2_val = o2(h1_val, h2_val)

print('h1:', h1_val)
print('h2:', h2_val)
print('o1:', o1_val)
print('o2:', o2_val)

# 计算MSE损失
def mse(o1_val, o2_val):
    return 0.5 * ((o1_val - 0.01) ** 2 + (o2_val - 0.99) ** 2)

print('MSE Loss:', mse(o1_val, o2_val))

# 求w5的梯度 = mse()对o1求导  *  o1对l2_1求导  *  l2_1对w5求导
# dw5 = (o1 - 0.01) * [o1 * (1 - o1)] * h1
dw5 = (o1_val - 0.01) * (o1_val * (1.0 - o1_val)) * h1_val
print('dw5:', dw5)

# 求w7的梯度 = mse()对o2求导  *  o2对l2_2求导  *  l2_2对w7求导
# dw7 = (o2 - 0.99) * [o2 * (1 - o2)] * h1
dw7 = (o2_val - 0.99) * (o2_val * (1.0 - o2_val)) * h1_val
print('dw7:', dw7)

# 求w1的梯度 = mse()对o1求导  *  o1对l2_1求导  *  l2_1对h1求导 * h1对l1_1求导 *l1_1对w1求导 + mse()对o2求导  *  o2对l2_2求导  *  l2_2对h1求导 * h1对l1_1求导 *l1_1对w1求导
# dw1 = (o1() - 0.01) * [o1() * (1 - o1())] * w5 * [h1() * (1 - h1())] * i1 + (o2 - 0.99) * [o2 * (1 - o2)] *w7 * [h1() * (1 - h1())] * i1
dw1 = (o1_val - 0.01) * (o1_val * (1.0 - o1_val)) * w5 * h1_val*(1.0-h1_val) * 0.05 + (o2_val - 0.99) * (o2_val * (1.0 - o2_val)) * w7 *h1_val*(1.0-h1_val) * 0.05
print('dw1:', dw1)

方式2:

# 前向传播
i1_i2 = torch.tensor([0.05,0.10])

model1 = nn.Linear(2,2)
model1.weight.data = torch.tensor([[0.15,0.20],[0.25,0.30]])
model1.bias.data = torch.tensor([0.35])
l11_l12 = model1(i1_i2)
h1_h2 =torch.sigmoid(l11_l12)

model2 = nn.Linear(2,2)
model2.weight.data = torch.tensor([[0.40,0.45],[0.50,0.55]])
model2.bias.data = torch.tensor([0.60])
l21_l22 = model2(h1_h2)
o1_o2 = torch.sigmoid(l21_l22)

# 反向传播
true_o1_o2 = torch.tensor([0.01,0.99])
mse = nn.MSELoss()
loss = mse(o1_o2,true_o1_o2)
print(loss)

loss.backward()
print(model1.weight.grad)
print(model2.weight.grad)

方式3:

import torch
import torch.nn as nn
import torch.optim as optim

class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.linear1 = nn.Linear(2,2)
        self.linear2 = nn.Linear(2,2)
        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], dtype=torch.float32)
        self.linear2.bias.data = torch.tensor([0.60], dtype=torch.float32)

    def forward(self,x):
        x = self.linear1(x)
        x = torch.sigmoid(x)
        x = self.linear2(x)
        x = torch.sigmoid(x)
        return x

input = torch.tensor([[0.05, 0.10]])
target = torch.tensor([[0.01, 0.99]])

model = Net()
output = model(input)

print(output)
mse = torch.sum((output-target)**2)/2
print(mse)

optimizer = optim.SGD(model.parameters(), lr=0.5)
# 梯度清零
optimizer.zero_grad()

mse .backward()

print(model.linear1.weight.grad)
print(model.linear2.weight.grad)

#更新梯度
optimizer.step()

# 打印更新后的网络参数
print(model.state_dict())

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32的CAN波特率计算

公式: CAN波特率 APB总线频率 / (BRP分频器 1)/ (SWJ BS1 BS2) SWJ一般为1。 例如STM32F407的,CAN1和CAN2都在在APB1下,频率是42000000 如果想配置成1M波特率,则计算公式为:

⭐ Unity 资源管理解决方案:Addressable_ Demo演示

一、使用Addressable插件的好处: 1.自动管理依赖关系 2.方便资源卸载 3.自带整合好的资源管理界面 4.支持远程资源加载和热更新 二、使用步骤 安装组件 1.创建资源分组 2.将资源加入资源组 3.打包资源 4.加载资源 三种方式可以加载 using System.Collections…

uniapp实现APP版本升级

App.vue 直接上代码 <script>export default {methods: {//APP 版本升级Urlupload() {// #ifdef APP-PLUSplus.runtime.getProperty(plus.runtime.appid, (info) > {// 版本号变量持久化存储getApp().globalData.version info.version;this.ToLoadUpdate(info.versi…

spark 写入mysql 中文数据 显示?? 或者 乱码

目录 前言 Spark报错&#xff1a; 解决办法&#xff1a; 总结一下&#xff1a; 报错&#xff1a; 解决&#xff1a; 前言 用spark写入mysql中&#xff0c;查看中文数据 显示?? 或者 乱码 Spark报错&#xff1a; Sat Nov 23 19:15:59 CST 2024 WARN: Establishing SSL…

欧科云链研究院:比特币还能“燃”多久?

出品&#xff5c; OKG Research 作者&#xff5c;Hedy Bi 本周二&#xff0c;隔夜“特朗普交易” 的逆转趋势波及到比特币市场。比特币价格一度冲高至约99,000美元后迅速回落至93,000美元以下&#xff0c;最大跌幅超6%。这是由于有关以色列和黎巴嫩有望达成停火协议的传闻引发…

27加餐篇:gRPC框架的优势与不足之处

gRPC作为一个现代的、开源的远程过程调用(RPC)框架,在多个方面都展现了其优雅之处,同时也存在一些不足之处。这篇文章我们就相对全面的分析一下gRPC框架那些优雅的地方和不足的地方。 优雅的地方 gRPC作为一个RPC框架,在编码、传输协议已经支持多语言方面都比较高效,下…

Spring MVC练习(前后端分离开发实例)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f439;今日诗词:二十五弦弹夜月&#xff0c;不胜清怨却飞来&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4…

重构项目架构

前言 我们上篇文章对整个项目进行一个整体的规划&#xff0c;其中对于APP类规划了类&#xff0c;本篇文章我们就来实现这个规划&#xff1b; class App {//加载页面constructor() {}//获取位置_getPosition() {}//接受位置_loadMap() {}//在地图上点击展现表单_showForm() {}/…

哈希C++

文章目录 一.哈希的概念1.直接定址法2.负载因子 二.哈希函数1.除法散列法 / 除留余数法2.乘法散列法3.全域散列法&#xff08;了解&#xff09; 三.处理哈希冲突哈希冲突&#xff1a;1.开放定址法&#xff08;1&#xff09;线性探测&#xff1a;&#xff08;2&#xff09;二次探…

转录组数据挖掘(生物技能树)(第11节)下游分析

转录组数据挖掘&#xff08;生物技能树&#xff09;&#xff08;第11节&#xff09; 文章目录 R语言复习转录组数据差异分析差异分析的输入数据操作过程示例一&#xff1a;示例二&#xff1a;示例三&#xff1a;此代码只适用于人的样本 R语言复习 #### 读取 ####dat read.deli…

Diving into the STM32 HAL-----Cyclic Redundancy Check笔记

在数字系统中&#xff0c;数据完全有可能被损坏&#xff0c;特别是当它流经通信介质时。在数字电子学中&#xff0c;消息是等于 0 或 1 的比特流&#xff0c;当这些比特中的一个或多个在传输过程中意外更改时&#xff0c;它就会损坏。因此&#xff0c;消息中始终有一些额外的数…

Swift——类与结构体

一.结构体 在swift的标准库中&#xff0c;大部分的类型都是结构体&#xff0c;比如&#xff1a;Int&#xff0c;Double&#xff0c;String&#xff0c;Array&#xff0c;Dictionary等等&#xff0c;它们都是结构体。 结构体定义如下&#xff1a; struct Person {var name:St…

反射泛型

反射 class 包含哪些内容&#xff1f; 当使用new 对象时需要构造函数是public 的&#xff0c;而当变成私有时再new则会报错 反射通过私有构造方法创建对象&#xff0c;破环单例模式 Clazz.getDeclared(构造函数&#xff0c;方法属性等)和直接get构造函数&#xff0c;方法属性等…

RHCE——SELinux

SELinux 什么是SELinux呢&#xff1f;其实它是【Security-Enhanced Linux】的英文缩写&#xff0c;字母上的意思就是安全强化Linux的意思。 SELinux是由美国国家安全局(NSA)开发的&#xff0c;当初开发的原因是很多企业发现&#xff0c;系统出现问题的原因大部分都在于【内部…

etcd、kube-apiserver、kube-controller-manager和kube-scheduler有什么区别

在我们部署K8S集群的时候 初始化master节点之后&#xff08;在master上面执行这条初始化命令&#xff09; kubeadm init --apiserver-advertise-address10.0.1.176 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.16.0 --service…

uniapp定义new plus.nativeObj.View实现APP端全局弹窗

为什么要用new plus.nativeObj.View在APP端实现弹窗&#xff1f;因为uni.showModal在APP端太难看了。 AppPopupView弹窗函数参数定义 参数一:弹窗信息(所有属性可不填&#xff0c;会有默认值) 1.title:"", //标题 2.content:"", //内容 3.confirmBoxCo…

一文学习开源框架OkHttp

OkHttp 是一个开源项目。它由 Square 开发并维护&#xff0c;是一个现代化、功能强大的网络请求库&#xff0c;主要用于与 RESTful API 交互或执行网络通信操作。它是 Android 和 Java 开发中非常流行的 HTTP 客户端&#xff0c;具有高效、可靠、可扩展的特点。 核心特点 高效…

DRM(数字权限管理技术)防截屏录屏----视频转hls流加密、web解密播放

提示&#xff1a;视频转hls流加密、web解密播放 需求&#xff1a;研究视频截屏时&#xff0c;播放器变黑&#xff0c;所以先研究的视频转hls流加密 文章目录 [TOC](文章目录) 前言一、工具ffmpeg、openssl二、后端nodeexpress三、web播放四、文档总结 前言 ‌HLS流媒体协议‌&a…

Rk3588 onnx转rknn,出现 No module named ‘rknn‘

一、操作步骤&#xff1a; rk3588 需要将yolo11 的模型onnx转rknn。 https://github.com/airockchip/rknn_model_zoo/tree/main/examples/yolo11 这个是用yolo11训练的模型&#xff0c;有80种类型。 完整下载下来后&#xff0c;在按文档描述下载模型下来&#xff1a; 然后进…

IDEA 解决Python项目import导入报错、引用不到的问题

使用Idea 23.1 专业版编写Python项目时&#xff0c;import 导入爆红&#xff0c;无法引入其他package的代码&#xff0c;现象如&#xff1a; 解决方案&#xff1a;Idea表头打开 File -> Project Settring 解决效果&#xff1a;