Pytorch官网教程:https://pytorch.org/tutorials/
中文版:pytorch官方教程中文版|PyTorch介绍 (cvtutorials.com)
主要内容:
搭建神经网络的基本框架
搭建神经网络的基本框架
搭建一个神经网络来对FashionMNIST数据集中的图像进行分类。
import torch
from torch import nn # torch.nn模块包含准备好的各种层,方便我们调用以构建网络。
1.获取训练的设备
#Get device for training
device= "cuda" if torch.cuda.is_available() else "cpu" # cuda是NVIDIA支持的GPU计算平台
print(f"Using {device} device")
可用的话,我们可以在GPU这样的硬件加速器上训练我们的模型。cuda是NVIDIA支持的GPU计算平台。torch.cuda.is_available()检查是否可用,不可用则使用CPU。
2.定义类
这一部分首先了解基本框架,不必深究。然后对照下一部分的分解再细细研究。
# define the class
class NeuralNetwork(nn.Module): # Pytorch中自定义操作基本继承nn.Module
def __init__(self): # 在__init__方法里初始化
super().__init__()
self.flatten=nn.Flatten() #初始化Flatten层,进行展平
self.linear_relu_stack=nn.Sequential( # nn.Sequential是有序模块容器,数据以定义的顺序通过所有模块
nn.Linear(28*28,512), # 线性层,存储的权重和偏置对输入进行线性变换
nn.ReLU(), # Relu层,非线性激活,构造输入到输出的复杂映射
nn.Linear(512,512),
nn.ReLU(),
nn.Linear(512,10),
)
def forward(self,x): # 在forward方法中实现数据操作
x=self.flatten(x)
logits=self.linear_relu_stack(x)
return logits
# 创建实例,移动设备上
model=NeuralNetwork().to(device)
# 打印结构
# print(model)
# 传入数据,调用模型
X=torch.rand(1,28,28,device=device) # 因为FashionMNIST图片大小1*28*28
# 直接model(X),就执行模型的forward函数以及一些后台操作,不要直接调用model.forward()
logits=model(X) # 返回10维的tensor,包括每个类别的原始预测值
pred_probab=nn.Softmax(dim=1)(logits) # 通过nn.Softmax的实例获得预测概率 [1,10]
y_pred=pred_probab.argmax(1) # 返回最大值索引 axis=1,行中比较选出值最大的列索引
print(f"Predicted class:{y_pred}")
- 定义了NeuralNetwork的类,继承自nn.Module。 Pytorch中自定义操作基本继承nn.Module
- 在__init__方法中进行初始化,主要对层进行初始化。在forward方法中实现对数据的操作,构建层间关系。
- 创建实例
- 传入数据,调用模型
- 对输出进行处理,得到最终分类结果
3.模型分解
分解一下模型中的各层。为了说明这一点,由3张大小为28x28的图像组成的小批样本,看看它通过网络时发生了什么。
- nn.Flatten() 主要工作为展平。
input_image = torch.rand(3,28,28) print(input_image.size()) # [3,28,28] flatten = nn.Flatten() flat_image = flatten(input_image) print(flat_image.size()) # [3,784]
nn.Flatten()从第一维度展平到最后一个维度,即将28*28展平成784
- nn.Linear() 线性层,使用其存储权重和偏置对输入进行线性变换
layer1 = nn.Linear(in_features=28*28, out_features=20) #输入是28*28=784,输出是20
hidden1 = layer1(flat_image)
print(hidden1.size()) # [3,20]
- nn.Relu() Relu层,非线性激活,在模型的输入和输出之间建立复杂的映射关系
不改变形状,仍是[3,20]
print(f"Before ReLU: {hidden1}\n\n")
hidden1 = nn.ReLU()(hidden1)
print(f"After ReLU: {hidden1}")
- 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) #[3,10]
- nn.Softmax() softmax 函数是一种常用的激活函数,它可以将一个向量转换成一个概率分布,使得每个元素都是非负数且和为 1
softmax = nn.Softmax(dim=1)
pred_probab = softmax(logits) #返回10维的tensor,包括每个类别的原始预测值
nn.Softmax中的dim=1,请详见:【基础知识】pytorch:nn.Softmax()
到此,再回头看我们在2中搭建的网络就很清晰了。最后通过argmax返回最大值索引,其中也牵扯到参数问题,详见:【numpy】argmax参数辨析(axis=0,axis=1,axis=-1)
4.模型参数
#打印模型结构
print(f"Model structure: {model}\n\n")
#模型参数 查看权重和偏置
for name, param in model.named_parameters():
print(f"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \n")