Pytorch学习_Transforms & Build Model

主要是给自己用来复习的博客,同学们第一次学习的话可以去看官网的tutorials,那里有更详细的解释。
Pytorch官方Transforms的tutorials

Transforms

Dataset或者Dataloader里的数据,往往不能直接作为训练用的数据,它们还要经过一些处理,这个处理的过程就是Transforms。

所有TrochVision的数据集都有两个参数,transformtarget_transform

FashionMNIST的特征图时PIL Image 标签时integers型的,但对于训练来说,我们需要的特征图是正则化向量,标签是“one-hot encoded tensors"应该是一维编码后的向量。
为了完成这种transform,我们要使用ToTensor和Lambda这两个方法。

import torch
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda

ds = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
    target_transform=Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(0, torch.tensor(y), value=1))
)

ToTensor():
该方法可以讲PIL图像或者NumPy格式的数据转换成FloatTensor格式。
Lambda Transforms:
可以让任何人定义一个lambda方法,如代码中的

target_transform = Lambda(lambda y: torch.zeros(
    10, dtype=torch.float).scatter_(dim=0, index=torch.tensor(y), value=1))

这里的scatter函数是根据y的值,确定torch.zero(10)这个1*10向量中第y个值设为1,其他为0。
lambda这个表达式平时也不咋用,去搜了一下使用方法,感觉上里面这层lambda定义规则,外面这个lambda相当于就是一个传递吧。

Build Model

一个神经网络由很多的layers(层)/moduls组成。torch.nn提供了所有用来搭建神经网络的所有“积木”。一个神经网络模块往往由其他模块(像layers)构成的,这样的好处是它能允许我们搭建很多很复杂的模型。

需要用到的一些库:

import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

首先需要确定你的设备能否支持GPU运算,就是安装cuda,安装的方法可以去csdn上搜一下,很容易就能搜到。如果不支持GPU的话也没事,就是放在cpu上运算。

device = 'cuda' if torch.cuda.is_available() else 'cpu'
print('Using {} device'.format(device))

定义一个nn.Module的子类作为我们的神经网络,在__init__中初始化layer的信息。

class NeuralNetwork(nn.Module):
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
            nn.ReLU()
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

现在,我们实例化一个NeuralNetwork,再将它一如device中,打印出它的结构。

注意,在使用过程中不要直接调用
model.forward()

调用模型,让其返回一个是分类的结果。我们通过将数据传送到一个nn.Softmax的模块中进行预测。

X = torch.rand(1, 28, 28, device=device)
logits = model(X)
pred_probab = nn.Softmax(dim=1)(logits)
y_pred = pred_probab.argmax(1)
print(f"Predicted class: {y_pred}")

结果为:
Predicted class: tensor([6], device='cuda:0')

下面逐个介绍一下各个的作用,首先我们创造一个3张28*28的图像。

input_image = torch.rand(3,28,28)

nn.Flatten

nn.Flatten()是将28*28的图像转化成一个784长的像素值。

flatten = nn.Flatten()
flat_image = flatten(input_image)
print(flat_image.size())

结果为:
torch.Size([3, 784])

nn.Linear

linear layer是一个将输入数据进行线性变换后输出的层。

layer1 = nn.Linear(in_features=28*28, out_features=20)
hidden1 = layer1(flat_image)
print(hidden1.size())

结果为:
torch.Size([3, 20])

nn.ReLU

中间层,输出用的,主要作用是让模型能够收敛。(好像)

print(f"Before ReLU: {hidden1}\n\n")
hidden1 = nn.ReLU()(hidden1)
print(f"After ReLU: {hidden1}")

结果为:
Before ReLU: tensor([[-0.5671,  0.4327,  0.1864, -0.3505, -0.1365, -0.2820, -0.0483, -0.4473,
         -0.3046,  0.2645, -0.3248, -0.4859, -0.0381, -0.4285,  0.1732,  0.5823,
          0.0651, -0.2859, -0.0588,  0.0078],
        [-0.7329,  0.2745,  0.2050, -0.2773, -0.4696, -0.1483, -0.2550, -0.3837,
          0.0274,  0.4271, -0.4471, -0.1616,  0.1872, -0.4931,  0.1550,  0.4568,
         -0.1581, -0.2910,  0.1229,  0.3264],
        [-0.3201,  0.4171, -0.0490, -0.0270, -0.4398,  0.1092, -0.0165, -0.3366,
          0.1293,  0.6627,  0.1070, -0.2909,  0.2535, -0.2683,  0.0832,  0.2603,
         -0.1257, -0.4058,  0.0765,  0.2798]], grad_fn=<AddmmBackward>)


After ReLU: tensor([[0.0000, 0.4327, 0.1864, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000,
         0.2645, 0.0000, 0.0000, 0.0000, 0.0000, 0.1732, 0.5823, 0.0651, 0.0000,
         0.0000, 0.0078],
        [0.0000, 0.2745, 0.2050, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0274,
         0.4271, 0.0000, 0.0000, 0.1872, 0.0000, 0.1550, 0.4568, 0.0000, 0.0000,
         0.1229, 0.3264],
        [0.0000, 0.4171, 0.0000, 0.0000, 0.0000, 0.1092, 0.0000, 0.0000, 0.1293,
         0.6627, 0.1070, 0.0000, 0.2535, 0.0000, 0.0832, 0.2603, 0.0000, 0.0000,
         0.0765, 0.2798]], grad_fn=<ReluBackward0>)

nn.Sequential

一个容器,容器里的东西是有顺序放置的,可以用该容器来定义一个简单的模型。

seq_modules = nn.Sequential(
    flatten,
    layer1,
    nn.ReLU(),
    nn.Linear(20, 10)
)
input_image = torch.rand(3,28,28)
logits = seq_modules(input_image)

nn.Softmax

最后一层线性层返回的值没有上下限,softmax模块能把数值压缩到[0,1]的范围,对应的是每个预测结果的可能性。其中,参数dim代表着哪一个维度的总和必须是1。

softmax = nn.Softmax(dim=1)
pred_probab = softmax(logits)

另外,在模型中的每一层,都包含着很多参数,这些参数是可以被查看的。

print("Model structure: ", model, "\n\n")

for name, param in model.named_parameters():
    print(f"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \n")


Model structure:  NeuralNetwork(
  (flatten): Flatten(start_dim=1, end_dim=-1)
  (linear_relu_stack): Sequential(
    (0): Linear(in_features=784, out_features=512, bias=True)
    (1): ReLU()
    (2): Linear(in_features=512, out_features=512, bias=True)
    (3): ReLU()
    (4): Linear(in_features=512, out_features=10, bias=True)
    (5): ReLU()
  )
)


Layer: linear_relu_stack.0.weight | Size: torch.Size([512, 784]) | Values : tensor([[ 0.0033,  0.0199, -0.0016,  ..., -0.0347,  0.0318, -0.0163],
        [ 0.0250,  0.0342, -0.0142,  ...,  0.0054, -0.0062, -0.0338]],
       device='cuda:0', grad_fn=<SliceBackward>)

Layer: linear_relu_stack.0.bias | Size: torch.Size([512]) | Values : tensor([0.0205, 0.0168], device='cuda:0', grad_fn=<SliceBackward>)

Layer: linear_relu_stack.2.weight | Size: torch.Size([512, 512]) | Values : tensor([[ 0.0089,  0.0016, -0.0141,  ..., -0.0031,  0.0040, -0.0112],
        [-0.0306, -0.0074, -0.0249,  ...,  0.0336, -0.0215,  0.0391]],
       device='cuda:0', grad_fn=<SliceBackward>)

Layer: linear_relu_stack.2.bias | Size: torch.Size([512]) | Values : tensor([-0.0376,  0.0233], device='cuda:0', grad_fn=<SliceBackward>)

Layer: linear_relu_stack.4.weight | Size: torch.Size([10, 512]) | Values : tensor([[ 0.0155, -0.0111,  0.0200,  ..., -0.0142, -0.0163, -0.0036],
        [-0.0163, -0.0383,  0.0412,  ..., -0.0419,  0.0184, -0.0137]],
       device='cuda:0', grad_fn=<SliceBackward>)

Layer: linear_relu_stack.4.bias | Size: torch.Size([10]) | Values : tensor([0.0078, 0.0371], device='cuda:0', grad_fn=<SliceBackward>)

这里有更多关于torch.nn的API的信息

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值