PyTorch是一个用于深度学习的开源机器学习库,它提供了灵活的张量计算和建立神经网络模型的丰富功能。敲黑板:建立的是神经网络!!!
一、导入需要的包
import torch
import torch.nn.functional as F
from torch import nn
from torch.nn import Conv2d,MaxPool2d,Flatten,Linear
from keras.models import Sequential
二、重写基类
按理说第二步是需要先处理数据,因为神经网络的结构是根据数据而变动的。这里做流程示例,就直接到这一步吧。
pytorch官网给出的描述是:这是所有神经网络模块的基类,你的模型也应该继承这个类,模块也可以包含其他模块,允许在树形结构中嵌套它们,你可以将子模块指定为常规属性:
class Model(nn.Module):
def __init__(self):
super().__init__()
# 第一层卷积层,输入通道数为1,输出通道数为20,卷积核大小为5x5
self.conv1 = nn.Conv2d(1, 20, 5)
# 第二层卷积层,输入通道数为20(前一层的输出通道数),输出通道数为20,卷积核大小为5x5
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
# 使用ReLU激活函数进行第一层卷积操作
x = F.relu(self.conv1(x))
# 使用ReLU激活函数进行第二层卷积操作,并返回输出
return F.relu(self.conv2(x))
上面的代码是最简单的卷积神经网络。稍微普遍一点的用法是:
class Vida(nn.Module):
def __init__(self):
super(Vida, self).__init__()
self.conv1 = Conv2d(3, 32, 5, padding=2)
self.maxpool1 = MaxPool2d(2)
self.conv2 = Conv2d(32, 32, 5, padding=2)
self.maxpool2 = MaxPool2d(2)
self.conv3 = Conv2d(32, 64, 5, padding=2)
self.maxpool3 = MaxPool2d(2)
self.flatten = Flatten
self.linear1 = Linear(1024, 64)
self.linear2 = Linear(64, 10)
def forward(self, x):
× = self.conv1(x)
× = self.maxpool1(x)
x = self.conv2(x)
x = self.maxpool2(x)
x = self.conv3(x)
x = self.maxpool3(x)
× = self.flatten(x)
x = self.linear1(x)
× = self.linear2(x)
return x
这里用到了最大池化层,池化的作用可以参考这篇文章:池化层详细介绍。这个网络在控制台输出:
这就是大名鼎鼎的cifar10模型,模型图如下
但是这样写会显得代码非常冗长,所以torch官方推出了Sequential(),不过多解释,直接上代码:
class Vida(nn.Module):
def __init__(self):
super (Vida, self).__init__()
self.model1 = nn.Sequential(
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPoo12d(2),
Conv2d(32, 64, 5, padding=2),
MaxPoo12d(2),
Flatten(),
Linear (1024, 64),
Linear (64, 10)
)
def forward(self, x):
x = self.model1(x)
return x
vida = Vida()
print(vida)
input = torch.ones((64, 3, 32, 32))
output = vida(input)
print(output.shape)
如果你的模型有嵌套网络,那么使用Sequential()将会是你的代码简洁许多。输出结果如下:
三、添加优化器
优化器(Optimizer)是一种用于更新和优化模型参数以最小化(或最大化)损失函数的算法。它通过调整模型的权重和偏差(参数)来最小化训练数据上的损失函数,从而使模型更好地拟合训练数据,提高模型的性能和泛化能力。
优化器使用不同的算法(例如随机梯度下降、Adam、Adagrad、RMSProp等)来更新模型参数。这些算法通过计算损失函数的梯度并按照一定的规则更新参数。每种优化器都有其独特的优缺点,适合不同类型的问题和数据。
在PyTorch中,优化器是作为一个类提供的,您可以选择不同的优化器,并根据需要设置不同的超参数。例如,学习率(learning rate)、动量(momentum)、权重衰减(weight decay)等参数可以调整优化器的行为,以获得更好的训练结果。
优化器的选择和调整对于训练模型的成功至关重要。不同的优化器可能会对模型的收敛速度、稳定性和性能产生影响。
lr = 0.01 #学习率,一般都设置为0.01,跟风就对了。
optimizer = tf.keras.optimizers.SGD(#随机梯度下降
learning_rate=lr,
decay=lr / comms_round,
momentum=0.9
)
四、完整流程
在完整的训练流程中,一般会根据需要添加或使用不同的激活函数和损失函数。
torch完整使用:
# 导入必要的包
import torch
import torch.nn.functional as F
import tensorflow as tf
import torchvision
from torch import nn
from torch.nn import Conv2d,MaxPool2d,Flatten,Linear
from keras.models import Sequential
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
#导入、处理数据
#===============
#***your data***
#===============
#trans_cifar = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
#datasets_train = datasets.CIFAR10('../data/cifar', train=True, download=True, transform=trans_cifar)
#datasets_test = datasets.CIFAR10('../data/cifar', train=False, download=True, transform=trans_cifar)
train_data = torchvision.datasets.CIFAR10('../data', train=True, download=True, transform=torchvision.transforms.ToTensor())
test_data = torchvision.datasets.CIFAR10('../data', train=False, download=True, transform=torchvision.transforms.ToTensor())
#加载数据集(将数据加载到模型中)
train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)
#cpu/cuda
# device=torch.device("cuda")#需要检查cuda是否可用
#定义网络
class Vida(nn.Module):
def __init__(self):
super (Vida, self).__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, 1, 2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear (64*4*4, 64),
nn.Linear (64, 10)
)
def forward(self, x):
x = self.model(x)
return x
vida = Vida()
# vida = vida.to(device)
#定义损失函数
loss_fn=nn.CrossEntropyLoss()
# loss = loss.to(device)
#定义优化器
learning_rate = 0.01
optimizer = torch.optim.SGD(vida.parameters(),lr=learning_rate)
#记录训练次数
train_step=0
test_step=0
#训练轮数
epoch=10
#模型训练
for i in range(epoch):
vida.train()
for data in train_dataloader:
imgs, targets = data
# imgs = imgs.to(device)
# targets = targets.to(device)
outputs = vida(imgs)
loss = loss_fn(outputs, targets)
#优化器优化模型
optimizer.zero_grad()
loss.backward ()
optimizer.step()
train_step = train_step + 1
if train_step % 100 == 0:
print("训练次数:{},Loss: {}".format(train_step, loss.item()))
# 模型测试
vida.eval()
total_test_loss = 0
with torch.no_grad(): #不更改模型的梯度
for data in test_dataloader:
imgs, targets = data
# imgs = imgs.to(device)
# targets = targets.to(device)
outputs = vida(imgs)
loss = loss_fn(outputs, targets)
total_test_loss = total_test_loss + loss.item()
print("整体测试集上的Loss:{}".format(total_test_loss))
total_test_step = test_step + 1