当前位置: 首页 > wzjs >正文

哈尔滨旅游团购网站建设和城乡建设厅官方网站

哈尔滨旅游团购网站建设,和城乡建设厅官方网站,营销型网站规划,wordpress front-page.php基于书中第十章,本节中,我们将深入学习反向传播的原理,并通过MNIST手写数字识别任务,结合PyTorch代码实现,手动编写反向传播逻辑,从而加深对于反向传播内部机制的理解。 神经网络与反向传播的基本概念 神…

基于书中第十章,本节中,我们将深入学习反向传播的原理,并通过MNIST手写数字识别任务,结合PyTorch代码实现,手动编写反向传播逻辑,从而加深对于反向传播内部机制的理解。

神经网络与反向传播的基本概念

神经网络是一种由多层神经元组成的计算模型,每一层神经元通过权重和偏置连接起来。神经网络的学习过程可以分为两个阶段:前向传播和反向传播。

  • 前向传播:输入数据从输入层经过隐藏层,最终到达输出层,计算网络的预测结果。
  • 反向传播:根据预测结果与真实标签之间的误差,从输出层逐层向前计算梯度,并更新网络的权重和偏置。

反向传播的核心是链式法则,它通过将误差从输出层传递回输入层,计算每一层参数的梯度,从而指导参数的更新。

MNIST手写数字识别任务

MNIST是一个经典的手写数字识别数据集,包含60,000张训练图像和10,000张测试图像,每张图像是一个28x28的灰度图,标签为0到9的数字。我们的目标是构建一个神经网络,能够正确识别这些手写数字。

反向传播的数学原理

为了更好地理解反向传播,我们需要从数学角度分析它的工作原理。假设我们有一个简单的两层神经网络,输入层大小为784(28x28),隐藏层大小为128,输出层大小为10(对应10个数字类别)。

前向传播

前向传播的计算过程如下:

  1. 输入层到隐藏层:
    在这里插入图片描述
    其中,X是输入数据,W1是输入层到隐藏层的权重矩阵,b1是偏置,σ是激活函数(如ReLU)。
  2. 隐藏层到输出层:
    在这里插入图片描述
    其中,W2是隐藏层到输出层的权重矩阵,b2是偏置,softmax函数用于将输出转换为概率分布。

损失函数

我们使用交叉熵损失函数来衡量预测结果与真实标签之间的差异:
在这里插入图片描述
其中,yi是真实标签的one-hot编码,a2i是输出层的预测概率。

反向传播

反向传播的目标是计算损失函数对每一层参数的梯度,并更新参数。具体步骤如下:

  1. 计算输出层的误差:
    在这里插入图片描述

  2. 计算隐藏层的误差:
    在这里插入图片描述
    其中,σ′是激活函数的导数。

  3. 计算梯度并更新参数:
    在这里插入图片描述

  4. 使用梯度下降法更新参数:
    在这里插入图片描述
    其中,η是学习率。

代码实现

下面我们通过PyTorch实现一个简单的两层神经网络,并手动编写反向传播逻辑,同时利用CUDA加速训练过程。

import torch
from torch.utils.data import DataLoader
from torchvision import datasets, transforms# 检查CUDA是否可用
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f'Using device: {device}')# 定义数据预处理
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,), (0.5,))
])# 加载MNIST数据集
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)# 定义神经网络模型
class SimpleNN:def __init__(self, input_size, hidden_size, output_size):# 初始化参数self.W1 = torch.randn(input_size, hidden_size, device=device) * 0.01self.b1 = torch.zeros(1, hidden_size, device=device)self.W2 = torch.randn(hidden_size, output_size, device=device) * 0.01self.b2 = torch.zeros(1, output_size, device=device)def forward(self, X):# 前向传播self.z1 = torch.matmul(X, self.W1) + self.b1self.a1 = torch.relu(self.z1)self.z2 = torch.matmul(self.a1, self.W2) + self.b2self.a2 = torch.softmax(self.z2, dim=1)return self.a2def backward(self, X, y, output, learning_rate):# 反向传播m = X.shape[0]# 输出层误差dz2 = output - ydW2 = torch.matmul(self.a1.T, dz2) / mdb2 = torch.sum(dz2, dim=0, keepdim=True) / m# 隐藏层误差dz1 = torch.matmul(dz2, self.W2.T) * (self.a1 > 0).float()dW1 = torch.matmul(X.T, dz1) / mdb1 = torch.sum(dz1, dim=0, keepdim=True) / m# 更新参数self.W2 -= learning_rate * dW2self.b2 -= learning_rate * db2self.W1 -= learning_rate * dW1self.b1 -= learning_rate * db1def train(self, train_loader, epochs, learning_rate):for epoch in range(epochs):for images, labels in train_loader:# 将图像展平并移动到GPUimages = images.view(-1, 28*28).to(device)# 将标签转换为one-hot编码并移动到GPUy = torch.zeros(labels.size(0), 10, device=device)y[torch.arange(labels.size(0)), labels] = 1# 前向传播output = self.forward(images)# 反向传播self.backward(images, y, output, learning_rate)if (epoch+1) % 5 == 0:print(f'Epoch [{epoch+1}/{epochs}]')def evaluate(self, test_loader):correct = 0total = 0for images, labels in test_loader:images = images.view(-1, 28*28).to(device)outputs = self.forward(images)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted.cpu() == labels).sum().item()print(f'Test Accuracy: {100 * correct / total:.2f}%')# 初始化模型
input_size = 28 * 28
hidden_size = 128
output_size = 10
model = SimpleNN(input_size, hidden_size, output_size)# 训练模型
model.train(train_loader, epochs=20, learning_rate=0.1)# 测试模型
model.evaluate(test_loader)

在SimpleNN的init部分,W1 和 W2 分别是输入层到隐藏层和隐藏层到输出层的权重矩阵。我们使用 torch.randn 生成服从标准正态分布的随机数,并乘以 0.01 来缩小初始值的范围。b1 和 b2 是偏置,初始化为零。所有参数都被放置在指定的设备(如GPU)上。

在forward()中,实现了前向传播的过程。首先,输入数据 X 与权重矩阵 W1 进行矩阵乘法,再加上偏置 b1,得到隐藏层的加权输入 z1。然后,通过ReLU激活函数对 z1 进行非线性变换,得到隐藏层的激活值 a1。之后,隐藏层的激活值 a1 与权重矩阵 W2 进行矩阵乘法,再加上偏置 b2,得到输出层的加权输入 z2。最后,通过softmax函数将 z2 转换为概率分布 a2,表示每个类别的预测概率。

在反向传播中,通过链式法则,误差从输出层逐层向前传递,计算每一层的梯度。首先,计算输出层的误差 dz2,即预测值 output 与真实标签 y 的差值。然后,计算权重 W2 的梯度 dW2,通过将隐藏层的激活值 a1 的转置与误差 dz2 相乘,并除以样本数 m。偏置 b2 的梯度 db2 是误差 dz2 的均值。之后,计算隐藏层的误差 dz1,通过将输出层的误差 dz2 与权重矩阵 W2 的转置相乘,再乘以ReLU激活函数的导数(即 a1 > 0 的布尔值转换为浮点数)。然后,计算权重 W1 的梯度 dW1,通过将输入数据 X 的转置与误差 dz1 相乘,并除以样本数 m。偏置 b1 的梯度 db1 是误差 dz1 的均值。最后,使用梯度下降法更新参数。权重和偏置分别减去学习率与对应梯度的乘积。

运行结果如下,可以看到通过上述代码,我们能够得到较高的准确率。
在这里插入图片描述

深入思考

反向传播是神经网络训练的核心算法,但它并非完美无缺。在实际应用中,我们可能会遇到以下问题:

  1. 梯度消失:在深层网络中,梯度可能会逐渐变小,导致靠近输入层的参数几乎无法更新。使用ReLU激活函数和批量归一化可以有效缓解这一问题。
  2. 过拟合:神经网络容易过拟合训练数据。可以通过正则化(如L2正则化)和Dropout来减少过拟合。
  3. 计算效率:反向传播的计算复杂度较高,尤其是在大规模数据集和深层网络中。使用GPU加速和分布式计算可以显著提高训练速度。

总结

通过MNIST手写数字识别任务,我们从理论和代码两个层面深入探讨了反向传播的原理和实现。不仅学习了反向传播的数学原理,还通过手动编写反向传播逻辑,更好地理解了其内部机制。

http://www.dtcms.com/wzjs/800980.html

相关文章:

  • 如何上传到网站根目录网站营销外包哪家专业
  • 在哪些网站做收录比较快免费空间凡科
  • 下载 asp网站高端企业网站价位
  • 常用的seo网站优化排名缠绕机东莞网站建设技术支持
  • 怎样建设自己的视频网站阿里云nas做网站
  • 深圳网站建设 罗湖黄骅市属于哪个省
  • 常用的电子商务网站建设网络强国征文
  • ps怎么网站首页企业网站模块
  • 精美网站界面高明网站开发公司
  • 做网站运营需要有什么能力揭阳手机网站建设
  • 南头企业网站建设公司网站建设 类型
  • 校园文化建设网站素材餐厅网站模版
  • 网站建设 乐清网络公司百度百家自媒体平台注册
  • 手机网站适合分开做wordpress手机端主题插件下载失败
  • 嘉峪关市网站建设设计宣传册设计与制作免费
  • 山东网站建设最便宜试述企业网的定义和意义
  • 黄江网站设计楚天网站建设合同
  • 潍坊网站建设首荐创美网络jsp是否可以做网站
  • 石家庄公司建设网站工作总结开头和结束语
  • 建网站带宽多少合适黄石网站设计公司
  • 青海省住房和建设门户网站如何开网店卖自己的东西
  • 辽宁建设工程招标网站阿里巴巴的网站建设与维护
  • 如何制作手机版网站网站模块建设方案
  • 如何快速更新网站快照大良营销网站建设渠道
  • 上海做网站hlanggroup做网站需要融资
  • 旅游网官方网站网站建设建站基本流程介绍
  • 微信网站开发视频做网站每年要交不费用吗
  • 网站建设直通车关键词设置社交网站设计
  • 网站建设 版权归属哪个网站可以做微信推送
  • 鞍山外国网站制作欧派全屋定制多少钱一平米