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

PyTorch 提示和技巧:从张量到神经网络

在这里插入图片描述

张量和梯度

我们将深入探讨使用 PyTorch 构建自己的神经网络必须了解的 2 个基本概念:张量和梯度。

张量

张量是 PyTorch 中的中央数据单元。它们是类似于数组的数据结构,在功能和属性方面与 Numpy 数组非常相似。它们之间最重要的区别是 PyTorch 张量可以在 GPU 的设备上运行以加速计算。
在这里插入图片描述

# 使用Tensor对象创建了一个 3x3 形状的未初始化张量。
import torch
tensor_uninitialized = torch.Tensor(3, 3)
tensor_uninitialized
"""
tensor([[1.7676e-35, 0.0000e+00, 3.9236e-44],[0.0000e+00,        nan, 0.0000e+00],[1.3733e-14, 1.2102e+25, 1.6992e-07]])
"""
# 我们还可以创建用零、一或随机值填充的张量。
tensor_rand = torch.rand(3, 3)
tensor_rand
"""
tensor([[0.6398, 0.3471, 0.6329],[0.4517, 0.2253, 0.8022],[0.9537, 0.1698, 0.5718]])
"""

就像 Numpy 数组一样,PyTorch 允许我们在张量之间执行数学运算,同样的 Numpy 数组中的其他常见操作,如索引和切片,也可以使用 PyTorch 中的张量来实现。

# 数学运算
x = torch.Tensor([[1, 2, 3],[4, 5, 6]])
tensor_add = torch.add(x, x)
"""
tensor([[ 2.,  4.,  6.],[ 8., 10., 12.]])
"""

梯度📉

假设有 2 个参数 a 和 b ,梯度是一个参数相对于另一个参数的偏导数。导数告诉你当你稍微改变其他一些量时,给定量会发生多少变化。在神经网络中,梯度是损失函数相对于模型权重的偏导数。我们只想找到带来损失函数梯度最低的权重。
在这里插入图片描述

PyTorch 使用torch库中的Autograd包来跟踪张量上的操作。

# 01. 默认情况下,张量没有关联的梯度。
tensor= torch.Tensor([[1, 2, 3],[4, 5, 6]])
tensor.requires_grad
"""
False
"""
# 02. 可以通过调用requires_grad_函数在张量上启用跟踪历史记录。
tensor.requires_grad_()
"""
tensor([[1., 2., 3.],[4., 5., 6.]], requires_grad=True)
"""
# 03. 但是目前该 Tensor 还没有梯度
print(tensor.grad)
"""
None
"""
# 04. 现在,让我们创建一个等于前一个张量中元素均值的新张量,以计算张量相对于新张量的梯度。
mean_tensor = tensor.mean()
mean_tensor
"""
tensor(3.5000, grad_fn=<MeanBackward0>)
"""
# 05. 要计算梯度,我们需要显式执行调用backward()函数的反向传播。
mean_tensor.backward()
print(tensor.grad)
"""
tensor([[0.1667, 0.1667, 0.1667],[0.1667, 0.1667, 0.1667]])
"""

使用 PyTorch 的神经网络

我们可以将神经网络定义为扩展 torch.nn.Module 类的 Python 类。在这个类中,我们必须定义 2 个基本方法:

init()是类的构造函数。在这里,我们必须定义构成我们网络的层。forward()是我们定义网络结构以及各层连接方式的地方。这个函数接受一个输入,代表模型将被训练的特征。我将向你展示如何构建可用于分类问题的简单卷积神经网络并在 MNIST 数据集上训练它。
在这里插入图片描述

首先,我们必须导入torch和我们需要的所有模块。可以创建我们的模型了

import torch
from torch import nn
import torch.nn.functional as F
import numpy as np# CNN 由 2 个卷积层组成,后面是一个全局平均池化层。最后,我们有 2 个全连接层和一个softmax来获得最终的输出概率。class My_CNN(nn.Module):def __init__(self):super(My_CNN, self).__init__()self.conv1 = nn.Conv2d(1, 64, kernel_size=(3, 3), padding=1)self.conv2 = nn.Conv2d(64, 64, kernel_size=(3, 3), padding=1)self.avg_pool = nn.AvgPool2d(28)self.fc1 = nn.Linear(64, 64)self.fc2 = nn.Linear(64, 10)def forward(self, x):x = F.relu(self.conv1(x))x = F.relu(self.conv2(x))x = self.avg_pool(x)x = x.view(-1, 64)x = F.relu(self.fc1(x))x = self.fc2(x)x = F.softmax(x)return x

其次,加载数据集,直接从 PyTorch 检索 MNIST 数据集,并使用 PyTorch 实用程序将数据集拆分为训练集和验证集。

from torchvision.datasets import MNIST
from torch.utils.data import DataLoader
from torch.utils.data.sampler import SubsetRandomSampler
mnist = MNIST("data", download=True, train=True)
## create training and validation split
split = int(0.8 * len(mnist))
index_list = list(range(len(mnist)))
train_idx, valid_idx = index_list[:split], index_list[split:]
## create sampler objects using SubsetRandomSampler
train = SubsetRandomSampler(train_idx)
valid = SubsetRandomSampler(valid_idx)# 使用DataLoader创建迭代器对象,它提供了使用多处理 worker 并行批处理、随机播放和加载数据的能力。
train_loader = DataLoader(mnist, batch_size=256, sampler=train)
valid_loader = DataLoader(mnist, batch_size=256, sampler=valid)

现在我们拥有了开始训练模型的所有要素。然后再定义损失函数和优化器,Adam将用作优化器,交叉熵用作损失函数。

model = My_CNN()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
loss_function = nn.CrossEntropyLoss()

最后开始训练,所有 PyTorch 训练循环都将经过每个 epoch 和每个DataPoint(在训练DataLoader 对象中)。


epochs = 10
for epoch in range(epochs):train_loss, valid_loss = [], []for data, target in train_loader:# forward propagation  outputs = model(data)# loss calculationloss = loss_function(outputs, target)# backward propagationoptimizer.zero_grad()loss.backward()# weights optimizationoptimizer.step()train_loss.append(loss.item())for data, target in valid_loader:outputs = model(data)loss = los_function(outputs, target)valid_loss.append(loss.item())print('Epoch: {}, training loss: {}, validation loss: {}'.format(epoch, np.mean(train_loss), np.mean(valid_loss)))

在验证阶段,我们必须像在训练阶段所做的那样循环验证集中的数据。不同之处在于我们不需要对梯度进行反向传播。


with torch.no_grad():correct = 0total = 0for data, target in valid_loader:outputs = model(images)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()
print('Validation set Accuracy: {} %'.format(100 * correct / total))

就是这样!现在你已准备好构建自己的神经网络。你可以尝试通过增加模型复杂性向网络添加更多层来获得更好的性能。

请关注博主,一起玩转人工智能及深度学习。

http://www.lryc.cn/news/92190.html

相关文章:

  • 第五期:字符串的一些有意思的操作
  • 使用Anaconda3结合vscode来实现django项目的建立(绝好的介绍)20230608
  • 【软件测试】软件测试的基本概念和开发模型
  • 接口测试 —— 接口测试定义
  • 2015 年一月联考逻辑真题
  • 基于GD32的定时器不完全详解--定时、级联
  • Clion开发STM32之ESP8266系列(四)
  • 降本增效,StarRocks 在同程旅行的实践
  • INTP型人格适合选择哪些专业?
  • 【LeetCode热题100】打卡第16天:组合总和
  • tinkerCAD案例:1.戒子环
  • RPC接口测试技术-Tcp 协议的接口测试
  • MyBatis Plus基本用法-SpringBoot框架
  • 指针--指针变量的定义和初始化
  • Web基本概念
  • Niagara—— Texture Sample 与 Particle Subuv 区别
  • 如何在食品行业运用IPD?
  • 如何用pandas进行条件分组计算?
  • tomcat如何调优,涉及哪些参数?
  • java培训机构学校教学教务选课管理平台springboot+vue
  • 半导体(TSS)放电管的两大选购注意事项及选型小策略
  • 05-使用Vue3 + Vue CLI 实现前端模块的搭建
  • 3.1 增加多进程执行playwright
  • 关于单片机的时钟浅谈及STM32F103/F030单片机的内外时钟切换问题
  • centos6.10环境下安装php7.4(基于WLNMP包)
  • Qt使用第三方库openssl进行RSA加密解密操作详解
  • 激发数学思维:GPT-4实证研究探索挑战性数学问题
  • 如何配置IP地址
  • CentOS + Nginx 环境自动申请和部署Let‘s Encrypt免费SSL证书教程
  • 浅谈对BI工具价值的看法