import torch # torch是顶级的pytorch的包和张量库
import torch.nn as nn # 包含了用来搭建各个层的模块(Modules),比如全连接、二维卷积、池化
import torch.nn.functional as F # 包含了常用的激活函数,如不具有可学习的参数(relu、leaky_relu、prelu、sigmoid)等
import torchvision # torchvision是一个提供对流行的数据集、模型结构和计算机视觉的图像转换的访问的包
import torchvision.transforms as transforms # 这个接口是我们能够访问图像处理的通用转换,图像到tensor ,numpy 数组到tensor , tensor 到 图像等
import torch.optim as optim # 函数可以选择优化器
import numpy as np
train_set=torchvision.datasets.FashionMNIST( # 从torchvision.datasets中获取数据集FashionMNIST
root='./data/FashionMNIST' # 训练集下载路径
,train=True # 训练参数设为true,意思是数据用于训练集,在此数据集中,6万张用于训练数据,1万张用于测试数据
,download=False # download设为True表示,如果数据集不在硬盘上,就执行下载,如果已经下载可以设置为False
,transform=transforms.Compose([
transforms.ToTensor() # 把图像转换为张量,用内置的Totensor
]))
C:\Users\82325\anaconda3\envs\pytorch\lib\site-packages\torchvision\datasets\mnist.py:498: UserWarning: The given NumPy array is not writeable, and PyTorch does not support non-writeable tensors. This means you can write to the underlying (supposedly non-writeable) NumPy array using the tensor. You may want to copy the array to protect its data or make it writeable before converting it to a tensor. This type of warning will be suppressed for the rest of this program. (Triggered internally at ..\torch\csrc\utils\tensor_numpy.cpp:180.)
return torch.from_numpy(parsed.astype(m[2], copy=False)).view(*s)
这个警告是因为我已经下载过了,大家可以忽略
解释:
def get_num_correct(preds, labels):
return preds.argmax(dim=1).eq(labels).sum().item()
解释:
class Network(nn.Module):
def __init__(self):
super(Network,self).__init__() # 直白的说super().__init__(),就是继承父类的init方法
# 定义conv1、conv2函数的是图像卷积函数:括号内输入通道、输出通道、卷积核
self.conv1=nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5)
self.conv2=nn.Conv2d(in_channels=6,out_channels=12,kernel_size=5)
# 定义fc1、fc2函数是全连接层函数,括号内输入特征、输出特征
self.fc1=nn.Linear(in_features=12*4*4,out_features=120) # 括号内输入特征、输出特征
self.fc2=nn.Linear(in_features=120,out_features=60)
self.out=nn.Linear(in_features=60,out_features=10)
def forward(self,t):
# 输入t经过卷积conv1之后,经过激活函数relu,使用2x2的窗口进行最大池化Max pooling,步长为2,然后更新到t
t=F.max_pool2d(F.relu(self.conv1(t)),kernel_size=2,stride=2)
# 输入t经过卷积conv2之后,经过激活函数relu,使用2x2的窗口进行最大池化Max pooling,然后更新到t
t=F.max_pool2d(F.relu(self.conv2(t)),kernel_size=2,stride=2)
# reshape函数将张量t变形成一维的向量形式,总特征数并不改变,为接下来的全连接作准备
t=t.reshape(-1,12*4*4)
# 输入t经过全连接1,再经过relu激活函数,然后更新t
t=F.relu(self.fc1(t))
# 输入t经过全连接2,再经过relu激活函数,更新t
t=F.relu(self.fc2(t))
return t
解释:
batch_size=1000 # 一次训练所抓取的数据样本数量
lr=0.01 # 学习率
network=Network() # 实例化类
train_loader=torch.utils.data.DataLoader(train_set,batch_size=100)
optimizer=optim.Adam(network.parameters(),lr=0.01)
for epoch in range(5): # 五个周期
total_loss=0 # 为追踪损失,我们将追踪正确预测的数量,所以在循环的顶部创建俩个变量,初始化为0
total_correct=0
# batch=next(iter(train_loader)) # 从训练集中抽取样本,将训练加载实例传递给内部函数,使用next获得下一批
for batch in train_loader: # 使用遍历来处理所有的批次而不是一个
images,labels=batch # 将样本压缩到一个图像和标签中,因为处理的是一批所以对变量名使用复数形式
preds=network(images) # 把图像传递给网络,结果是预测张量
loss=F.cross_entropy(preds,labels) # 调用交叉熵损失函数,来源于nn.functional,通过预测和标签计算损失,并返回一个张量
optimizer.zero_grad() # 告诉优化器把梯度属性中权重的梯度归零,因为pytorch会积累梯度,所以计算梯度之前,必须确保现在没有任何梯度值
loss.backward() # 调用反向函数,计算梯度,backward是反向传播的简称
optimizer.step() # 更新权重
total_loss+=loss.item()
total_correct+=get_num_correct(preds,labels)
print("epoch:",epoch,"total_correct:",total_correct,"loss:",total_loss)
epoch: 0 total_correct: 47257 loss: 336.4210552871227
epoch: 1 total_correct: 51110 loss: 239.50188337266445
epoch: 2 total_correct: 51872 loss: 220.99213953316212
epoch: 3 total_correct: 52169 loss: 211.96785034239292
epoch: 4 total_correct: 52433 loss: 205.83596700429916
解释
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
import torch.optim as optim
import numpy as np
train_set=torchvision.datasets.FashionMNIST( # 从torchvision.datasets中获取数据集FashionMNIST
root='./data/FashionMNIST' # 训练集下载路径
,train=True # 训练参数设为true,意思是数据用于训练集,在此数据集中,6万张用于训练数据,1万张用于测试数据
,download=False # download设为True表示,如果数据集不在硬盘上,就执行下载,如果已经下载可以设置为False
,transform=transforms.Compose([
transforms.ToTensor() # 把图像转换为张量,用内置的Totensor
]))
def get_num_correct(preds, labels):
return preds.argmax(dim=1).eq(labels).sum().item()
class Network(nn.Module):
def __init__(self):
super(Network,self).__init__() # 直白的说super().__init__(),就是继承父类的init方法
# 定义conv1、conv2函数的是图像卷积函数:括号内输入通道、输出通道、卷积核
self.conv1=nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5)
self.conv2=nn.Conv2d(in_channels=6,out_channels=12,kernel_size=5)
# 定义fc1、fc2函数是全连接层函数,括号内输入特征、输出特征
self.fc1=nn.Linear(in_features=12*4*4,out_features=120) # 括号内输入特征、输出特征
self.fc2=nn.Linear(in_features=120,out_features=60)
self.out=nn.Linear(in_features=60,out_features=10)
def forward(self,t):
# 输入t经过卷积conv1之后,经过激活函数relu,使用2x2的窗口进行最大池化Max pooling,步长为2,然后更新到t
t=F.max_pool2d(F.relu(self.conv1(t)),kernel_size=2,stride=2)
# 输入t经过卷积conv2之后,经过激活函数relu,使用2x2的窗口进行最大池化Max pooling,然后更新到t
t=F.max_pool2d(F.relu(self.conv2(t)),kernel_size=2,stride=2)
# reshape函数将张量t变形成一维的向量形式,总特征数并不改变,为接下来的全连接作准备
t=t.reshape(-1,12*4*4)
# 输入t经过全连接1,再经过relu激活函数,然后更新t
t=F.relu(self.fc1(t))
# 输入t经过全连接2,再经过relu激活函数,更新t
t=F.relu(self.fc2(t))
return t
batch_size=1000 # 一次训练所抓取的数据样本数量
lr=0.01 # 学习率
network=Network() # 实例化类
train_loader=torch.utils.data.DataLoader(train_set,batch_size=100)
optimizer=optim.Adam(network.parameters(),lr=0.01)
for epoch in range(5): # 五个周期
total_loss=0 # 为追踪损失,我们将追踪正确预测的数量,所以在循环的顶部创建俩个变量,初始化为0
total_correct=0
# batch=next(iter(train_loader)) # 从训练集中抽取样本,将训练加载实例传递给内部函数,使用next获得下一批
for batch in train_loader: # 使用遍历来处理所有的批次而不是一个
images,labels=batch # 将样本压缩到一个图像和标签中,因为处理的是一批所以对变量名使用复数形式
preds=network(images) # 把图像传递给网络,结果是预测张量
loss=F.cross_entropy(preds,labels) # 调用交叉熵损失函数,来源于nn.functional,通过预测和标签计算损失,并返回一个张量
optimizer.zero_grad() # 告诉优化器把梯度属性中权重的梯度归零,因为pytorch会积累梯度,所以计算梯度之前,必须确保现在没有任何梯度值
loss.backward() # 调用反向函数,计算梯度,backward是反向传播的简称
optimizer.step() # 更新权重
total_loss+=loss.item()
total_correct+=get_num_correct(preds,labels)
print("epoch:",epoch,"total_correct:",total_correct,"loss:",total_loss)