Pytorch-Tensor基础以及简单的神经网络实现

PyTorch是一个基于Python的科学计算库,是一个用于深度学习的计算机视觉库。它的底层实现是由C/C++语言编写的,同时也兼容其他语言(如Python、C++等)。PyTorch中的Tensor是其最基本的数据类型之一,本篇博客将主要介绍PyTorch中的Tensor,包括Tensor数据类型的介绍和Tensor的运算。同时也会通过实现Python和PyTorch代码的方式,让读者更加深入地了解PyTorch中的Tensor。

1. Tensor数据类型介绍

在PyTorch中,Tensor是最基本的数据类型之一,可以看作是一个n维的数组。与NumPy中的ndarray类似,Tensor也支持大量的数学运算操作,例如加、减、乘、除、矩阵乘法、转置、索引等等,而在PyTorch中却比较方便实用,也更为高效。

下面我们通过实例的方式来看一下PyTorch中的Tensor数据类型。

import torch

# 创建一个5x3的随机Tensor
x = torch.rand(5, 3)
print(x)

上述代码中,首先引入了PyTorch库,然后使用rand函数创建了一个形状为5x3的随机元素值的Tensor,并将其打印出来:

tensor([[0.3764, 0.0654, 0.4382],
        [0.0903, 0.5140, 0.6225],
        [0.9246, 0.3911, 0.5736],
        [0.7845, 0.4795, 0.2405],
        [0.6178, 0.9304, 0.2541]])

在PyTorch中,Tensor可以像标准的Python数组一样进行索引,并使用多种数学运算操作。例如:

import torch

# 创建两个形状为3x3的Tensor
x = torch.rand(3, 3)
y = torch.rand(3, 3)

# Tensor加法
z = x + y
print(z)

# Tensor乘法
z = torch.mm(x, y)
print(z)

# Tensor转置
z = x.t()
print(z)

# Tensor索引
z = x[1, :]
print(z)

上述代码中,我们创建了两个形状为3x3的Tensor,并实现了Tensor的加法、乘法、转置和索引操作。其中,Tensor加法、乘法和转置的语法与NumPy类似。而Tensor的索引操作可以看作是在获取Tensor中某个特定位置上的值,x[1,:]的语法表示获取在第二行所有列上的值。

2. Tensor运算

PyTorch中的Tensor不仅支持基本的数学运算操作,还支持大量的高级运算操作。例如,向Tensor中的每一个元素添加一个常数、矩阵乘法、拼接(Concatenation)以及Tensor形状改变等等。

在本节中,我们将介绍一些Tensor的高级运算操作。

2.1 向Tensor中的每一个元素添加一个常数

import torch

# 创建一个形状为3x3的Tensor,并每一个元素加上常数10
x = torch.ones(3, 3)
y = x + 10
print(y)

上述代码中,我们定义了一个形状为3x3的Tensor x,这个Tensor每个元素的值为1。接着,我们向这个Tensor中的每一个元素加上了一个常数10,并将结果打印出来:

tensor([[11., 11., 11.],
        [11., 11., 11.],
        [11., 11., 11.]])

2.2 矩阵乘法

import torch

# 创建两个形状为3x3的Tensor,并实现矩阵乘法
x = torch.randn(3, 3)
y = torch.randn(3, 3)
z = torch.mm(x, y)
print(z)

上述代码中,我们创建了两个形状为3x3的Tensor,并对它们进行矩阵乘法运算,结果如下:

tensor([[-0.7018, -0.9357, -1.0921],
        [-2.0233,  3.3809,  2.5824],
        [ 0.0214, -1.5318, -1.1426]])

2.3 拼接(Concatenation)

import torch

# 创建两个形状为3x3的Tensor,然后对这两个Tensor进行拼接(Concatenation)
x = torch.randn(3, 3)
y = torch.randn(3, 3)
z = torch.cat([x, y], dim=1)
print(z)

上述代码中,我们创建了两个形状为3x3的Tensor x 和 y。然后我们对这两个Tensor进行了拼接(Concatenation),指定拼接方向为列方向(即dim=1),结果如下:

tensor([[ 0.2775, -1.1655, -1.5055, -0.0827,  0.1648,  1.2135],
        [ 0.1548,  1.4414,  0.6044, -1.2424, -0.2577, -0.8128],
        [-0.1800, -1.0362,  0.5983,  1.0433, -1.3550, -0.7059]])

2.4 Tensor形状改变

import torch

# 创建一个4x4的Tensor,并修改形状为8x2
x = torch.randn(4, 4)
print(x.shape)
y = x.view(8, 2)
print(y.shape)

上述代码中,我们创建了一个形状为4x4的Tensor x,并使用view函数将其形状修改为8x2,结果如下:

torch.Size([4, 4])
torch.Size([8, 2])

3. 实战案例

我们使用PyTorch中的Tensor对手写数字进行分类。首先,我们需要准备一些数据,这里我们使用MNIST数据集。MNIST数据集包含了很多手写数字的图像,每张图像的尺寸为28x28。每一个图像都有一个标签,标记了该图像所代表的数字。首先我们需要将这些数据读取到内存中。

import torch
from torchvision import datasets, transforms

transform = transforms.Compose([transforms.ToTensor(),
                                transforms.Normalize((0.1307,), (0.3081,))])
train_data = datasets.MNIST('data', train=True, download=True, transform=transform)
test_data = datasets.MNIST('data', train=False, download=True, transform=transform)

train_loader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_data, batch_size=64, shuffle=True)

上述代码中,我们使用transforms模块对数据集进行了预处理,其中transforms.ToTensor()将图像转换为Tensor格式,transforms.Normalize((0.1307,), (0.3081,))用来对图像进行归一化处理。接着,我们使用datasets模块将数据集下载到了本地,并创建了一个train_loader和test_loader来分别加载训练数据和测试数据。

我们使用PyTorch的神经网络中的两种层来创建这个手写数字分类的模型,分别是全连接层和Dropout层。

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

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(28 * 28, 512)
        self.fc2 = nn.Linear(512, 256)
        self.fc3 = nn.Linear(256, 10)
        self.dropout = nn.Dropout(0.2)

    def forward(self, x):
        x = x.view(-1, 28 * 28)
        x = F.relu(self.fc1(x))
        x = self.dropout(x)
        x = F.relu(self.fc2(x))
        x = self.dropout(x)
        x = self.fc3(x)
        return F.log_softmax(x, dim=1)

上述代码中,我们定义了一个Net类,继承了nn.Module。Net类包含了三个全连接层,其中第一个全连接层的输入维度为28x28,输出维度为512,第二个全连接层的输入维度为512,输出维度为256,第三个全连接层的输入维度为256,输出维度为10。同时,我们还定义了两个Dropout层,用于降低模型的过拟合程度。在Net中,我们首先将输入的Tensor形状转换为(-1, 28 * 28),然后将其经过多个全连接层和Dropout层的处理,最终通过log_softmax进行分类。

我们使用nn.CrossEntropyLoss()来计算loss,并使用torch.optim.Adam()作为优化算法。

import torch.optim as optim
from tqdm import tqdm

net = Net()
loss_fn = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)

def train(epoch):
    net.train()
    train_loss = 0
    correct = 0
    for batch_idx, (data, target) in enumerate(train_loader):
        optimizer.zero_grad()
        output = net(data)
        loss = loss_fn(output, target)
        loss.backward()
        optimizer.step()
        train_loss += loss.item()
        pred = output.argmax(dim=1, keepdim=True)
        correct += pred.eq(target.view_as(pred)).sum().item()
        if batch_idx % 100 == 0:
            tqdm.write('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
            epoch, batch_idx * len(data), len(train_loader.dataset),
            100. * batch_idx / len(train_loader), loss.item()))

    tqdm.write('Train Epoch: {} [Accuracy]: {}/{} ({:.0f}%)\n'.format(epoch, correct, len(train_loader.dataset),
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZATuTu丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值