PyTorch

PyTorch

详情请看Pytorch 最全入门介绍,Pytorch入门看这一篇就够了-腾讯云开发者社区-腾讯云 (tencent.com)

1.PyTorch

1.1简介

Pytorch是torch的python版本,是由Facebook开源的神经网络框架,专门针对 GPU 加速的深度神经网络(DNN)编程。Torch 是一个经典的对多维矩阵数据进行操作的张量(tensor )库,在机器学习和其他数学密集型应用有广泛应用。与Tensorflow的静态计算图不同,pytorch的计算图是动态的,可以根据计算需要实时改变计算图。但由于Torch语言采用 Lua,导致在国内一直很小众,并逐渐被支持 Python 的 Tensorflow 抢走用户。作为经典机器学习库 Torch 的端口,PyTorch 为 Python 语言使用者提供了舒适的写代码选择。

至于为什么推荐使用Pytorch,我想最主要的原因就是它非常的简洁,非常符合Python的风格。

Pytorch中一共有5个不同的层次结构,分别为硬件层、内核层、低阶API、中阶API和高阶API。

1.2安装

PyTorch

  • 如果安装速度慢,可选择换源

测试安装是否成功

import torch
print(torch.__version__) # pytorch版本
print(torch.version.cuda) # cuda版本
print(torch.cuda.is_available()) # 查看cuda是否可用

2.Pytorch基础

2.1Tensor操作

Tensor是PyTorch中最基本的数据结构,你可以将其视为多维数组或者矩阵。PyTorch tensor和NumPy array非常相似,但是tensor还可以在GPU上运算,而NumPy array则只能在CPU上运算。

import torch

# 创建一个未初始化的5x3矩阵
x = torch.empty(5, 3)
print(x)

# 创建一个随机初始化的5x3矩阵
x = torch.rand(5, 3)
print(x)

# 创建一个5x3的零矩阵,类型为long
x = torch.zeros(5, 3, dtype=torch.long)
print(x)

# 直接从数据创建tensor
x = torch.tensor([5.5, 3])
print(x)

# 创建一个tensor,并设置requires_grad=True以跟踪计算历史
x = torch.ones(2, 2, requires_grad=True)
print(x)

# 对tensor进行操作
y = x + 2
print(y)

# y是操作的结果,所以它有grad_fn属性
print(y.grad_fn)

# 对y进行更多操作
z = y * y * 3
out = z.mean()
print(z, out)

在PyTorch中,可以使用.backward()来计算梯度

# 因为out包含一个标量,out.backward()等价于out.backward(torch.tensor(1.))
out.backward()

# 打印梯度 d(out)/dx
print(x.grad)

2.2GPU加速

检查是否存在可用的GPU

import torch
print(torch.cuda.is_available())

如果返回True,则存在可用GPU,使用.to()将tensor移动到GPU上:

# 创建一个tensor
x = torch.tensor([1.0, 2.0])
# 移动tensor到GPU上
if torch.cuda.is_available():
    x = x.to('cuda')
    
 #也可以直接在创建tensor的时候就指定其设备:
 if torch.cuda.is_available():
    x = torch.tensor([1.0, 2.0], device='cuda')

将模型和数据移动到GPU上:

# 创建一个简单的模型
model = torch.nn.Linear(10, 1)

# 创建一些数据
data = torch.randn(100, 10)

# 移动模型和数据到GPU
if torch.cuda.is_available():
    model = model.to('cuda')
    data = data.to('cuda')
    
    
#Tensor在CPU和GPU之间转移
# 判断是否支持CUDA
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 创建一个Tensor
x = torch.rand(3, 3)

# 将Tensor转移到GPU上
x_gpu = x.to(device)

# 或者
x_gpu = x.cuda()

# 将Tensor转移到CPU上
x_cpu = x_gpu.cpu()

#将模型转移到GPU上
model = Model()
model.to(device)

2.3自动求导

在深度学习中,我们经常需要进行梯度下降优化。这就需要我们计算梯度,也就是函数的导数。在PyTorch中,我们可以使用自动求导机制(autograd)来自动计算梯度。

在PyTorch中,我们可以设置tensor.requires_grad=True来追踪其上的所有操作。完成计算后,我们可以调用.backward()方法,PyTorch会自动计算和存储梯度。这个梯度可以通过.grad属性进行访问。

import torch

# 创建一个tensor并设置requires_grad=True来追踪其计算历史
x = torch.ones(2, 2, requires_grad=True)

# 对这个tensor做一次运算:
y = x + 2

# y是计算的结果,所以它有grad_fn属性
print(y.grad_fn)

# 对y进行更多的操作
z = y * y * 3
out = z.mean()

print(z, out)

# 使用.backward()来进行反向传播,计算梯度
out.backward()

# 输出梯度d(out)/dx
print(x.grad)
#输出结果
<AddBackward0 object at 0x000001444CBCBFA0>
tensor([[27., 27.],
        [27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>)
tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])

以上示例中,out.backward()等同于out.backward(torch.tensor(1.))。如果out不是一个标量,因为tensor是矩阵,那么在调用.backward()时需要传入一个与out同形的权重向量进行相乘。

x = torch.randn(3, requires_grad=True)

y = x * 2
while y.data.norm() < 1000:
    y = y * 2

print(y)

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)

print(x.grad)

2.4求最小值

使用自动微分机制配套使用SGD随机梯度下降来求最小值

import numpy as np
import torch
 
# f(x) = a*x**2 + b*x + c的最小值
x = torch.tensor(0.0, requires_grad=True)  # x需要被求导
a = torch.tensor(1.0)
b = torch.tensor(-2.0)
c = torch.tensor(1.0)
optimizer = torch.optim.SGD(params=[x], lr=0.01)  #SGD为随机梯度下降
print(optimizer)
 
def f(x):
    result = a * torch.pow(x, 2) + b * x + c
    return (result)
 
for i in range(500):
    optimizer.zero_grad()  #将模型的参数初始化为0
    y = f(x)
    y.backward()  #反向传播计算梯度
    optimizer.step()  #更新所有的参数
print("y=", y.data, ";", "x=", x.data)

2.5数据

Pytorch主要通过Dataset和DataLoader进行构建数据管道。

  • Dataset:一个数据集抽象类,所有自定义的Dataset都需要继承它,并且重写_getitem_()或_ get_sample_()这个类方法.
  • DataLoader:一个可迭代的数据装载器。在训练的时候,每一个for循环迭代,就从DataLoader中获取一个batch_sieze大小的数据。
DataLoader(
 dataset,
 batch_size=1,
 shuffle=False,
 sampler=None,
 batch_sampler=None,
 num_workers=0,
 collate_fn=None,
 pin_memory=False,
 drop_last=False,
 timeout=0,
 worker_init_fn=None,
 multiprocessing_context=None,
)

Epoch 所有的样本数据都输入到模型中,称为一个epoch
Iteration 一个Batch的样本输入到模型中,称为一个Iteration
Batchsize 一个批次的大小,一个Epoch=Batchsize*Iteration
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

# 数据转换
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

# 下载并加载训练集
trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2)

# 下载并加载测试集
testset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = DataLoader(testset, batch_size=4, shuffle=False, num_workers=2)

自定义数据集

from torch.utils.data import Dataset, DataLoader

class MyDataset(Dataset):
    def __init__(self, x_tensor, y_tensor):
        self.x = x_tensor
        self.y = y_tensor

    def __getitem__(self, index):
        return (self.x[index], self.y[index])

    def __len__(self):
        return len(self.x)

x = torch.arange(10)
y = torch.arange(10) + 1

my_dataset = MyDataset(x, y)
loader = DataLoader(my_dataset, batch_size=4, shuffle=True, num_workers=0)

for x, y in loader:
    print("x:", x, "y:", y)

3.神经网络框架

3.1构建神经网络

PyTorch提供了torch.nn库,它是用于构建神经网络的工具库。torch.nn库依赖于autograd库来定义和计算梯度。nn.Module包含了神经网络的层以及返回输出的forward(input)方法。

import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):	#定义一个Net类,继承自nn.Module
    def __init__(self):
        super(Net, self).__init__()

        # 输入图像channel:1,输出channel:6,5x5卷积核
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)

        # 全连接层
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

#定义数据的流向
    def forward(self, x):
        # 使用2x2窗口进行最大池化
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        # 如果窗口是方的,只需要指定一个维度
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)

        x = x.view(-1, self.num_flat_features(x))

        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)

        return x

    def num_flat_features(self, x):
        size = x.size()[1:]  # 获取除了batch维度之外的其他维度
        num_features = 1
        for s in size:
            num_features *= s
        return num_features

net = Net()
print(net)

3.2模型的加载和保存

# 保存
torch.save(model, PATH)

# 加载
model = torch.load(PATH)
model.eval()

3.3训练网络

for epoch in range(2):  # 在数据集上训练两遍

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # 获取输入数据
        inputs, labels = data

        # 梯度清零
        optimizer.zero_grad()

        # 前向传播
        outputs = net(inputs)

        # 计算损失
        loss = criterion(outputs, labels)

        # 反向传播
        loss.backward()

        # 更新参数
        optimizer.step()

        # 打印统计信息
        running_loss += loss.item()
        if i % 2000 == 1999:  # 每2000个批次打印一次
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')
posted @   洞爷湖kagura  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示