pytorch框架八股
pytorch是现在很火的深度学习框架,其容易上手性和便捷性不仅在于其有很多方便可以调用的API,而且代码格式是有章可循的,下面就是介绍一下自己总结的pytorch框架八股(主要还是针对利用pytorch进行图像分类问题吧),看了总结是一个好习惯。
1. pytorch常见模板
下面主要是个人(小白一只)通过几次的实战类代码,自己总结的一些,方便以后更快模式化编写代码。
1.1 torch.nn.Module
我们有时候不需要很复杂的网络或者想自己搭建一个网络,这时候我们就可以继承torch.nn.Module类,快速构建一个前向传播的网络结构,当然torch.nn.Module类还可以构建损失函数
import torch
class net_name(torch.nn.Module):
def __init__(self,other_arguments):
super(net_name,self).__init__()
self.conv1 = torch.nn.Conv2d(in_channels, out_channels, kernel_size)
# other network layer
# torch.nn.Linear()
# torch.nn.ReLU()
# torch.nn.MaxPool2d()
# torch.nn.Dropout()
# torch.nn.BatchNorm2d()
def forward(self, x):
x = self.conv1(x)
return x
torch.nn.Module也很容易构建损失函数,如多分类交叉熵,二分类交叉熵,均方误差等,以下列举几种:
import torch
loss_function = torch.nn.CrossEntropyLoss()
loss_function = torch.nn.BCELoss()
loss_function = torch.nn.MSELoss()
loss_function = torch.nn.L1Loss()
# 具体用时
loss = loss_function(output, target)
loss.backward()
1.2 torch.optim
torch.optim里面有很多的可以实现模型参数自动优化的类,我们可以很方便地调用,例如有随机梯度下降SGD(stochastic gradient descent),适应性矩估计Adam(adaptive moment estimation),适应性梯度算法(AdaGrad),均方根传播(RMSProp),下面来看具体调用语句:
import torch
optimizer = torch.optim.SGD(models.parameters,lr)
optimizer = torch.optim.Adam(models.parameters,lr)
optimizer = torch.optim.Adagrad(models.parameters,lr)
optimizer = torch.optim.RMSprop(models.parameters,lr)
# 训练时
optimizer.zero_grad()
1.3 torch.autograd & Variable
torch.autograd包主要的功能是完成神经网络后向传播中的链式求导,在前向传播的时候构建了一张计算图,在后向传播的时候完成对参数的更新。而我们必须用Variable对Tensor类型数据进行封装才能应用自动梯度(pytorch 0.4.0之后可以不用了,但用了也是可以的)
import torch
from torch.autograd import Variable
use_gpu = torch.cuda.is_available()
if use_gpu:
data,y = Variable(data.cuda()),Variable(y.cuda())
else:
data,y = Variable(data),Variable(y)
1.4 torchvision
在pytorch里面有两个核心的包,分别为torch和torchvision,torchvision包的主要功能是实现数据的处理,导入,里面也有预训练的常见模型,例如下面的datasets,transforms,models:
from torchvision import datasets,models,transforms
data = datasets.MNIST(root=save_path,train=True,transform=self_defined_transform)
model = models.vgg16(pretrained=False)
transform = transforms.Normalize(mean=mean,std=std)
1.5 torch.save & torch.load
训练模型完事之后肯定就是要保存模型了呀,之后调用就可以之间测试了呀,在pytorch里面模型的保存和加载都有两种方法:
import torch
#保存整个模型,包括结构信息和参数信息
torch.save(model_name,"model_saved_path/model_name.pth")
#只保存参数信息
torch.save(model_name.state_dict(),"model_saved_path/model_name.pth")
#对应第一种模型保存方法,加载完整整个模型
load_model = torch.load("model_saved_path/model_name.pth")
#对应第二种模型保存方法,只加载模型参数,结构需要在上面先定义或导入
model.load_state_dict(torch.load("model_saved_path/model_name.pth"))
2 整合成工程py文件
我们按照上面的八股就能构建整个项目工程文件(当然我这里只针对简单的分类问题,其他类似),主体包含model,train,test三个文件
2.1 models文件
models文件与2.1.1中描述差不多,这里不再赘述。可以参考我另外一篇博客的例子
2.2 train文件
在train里面主要进行模型的训练及参数的更新,下面是一个总结的模板,之后可以在模板下面更改成自己具体问题的代码:
# train文件主要是训练模型,主要步骤有:
# 1、导入必要的包
# 2、设置超参数
# 3、读入数据及预处理
# 4、开始训练,打印错误和准确率
# 5、保存模型,并给出提示
import torch
import pandas as pd
from torchvision import datasets
from torch.autograd import Variable
LOSS_TYPE = 'MSELoss'
METHOD = 'alex'
EPOCHS = 400
BATCH_SIZE = 50
LR = 0.001
use_gpu = torch.cuda.is_available()
# 这里读入数据只是做个例子
train = pd.read_csv('./data/train.csv')
test = pd.read_csv('./data/test.csv')
# 开始训练
for epoch in range(EPOCHS):
index = 0
if use_gpu:
data, y = Variable(data.cuda()), Variable(y.cuda())
else:
data, y = Variable(data), Variable(y)
prediction = model.forward(data)
loss = loss_function(prediction, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(loss)
torch.save(model.state_dict(),'./models/%s.pth' % METHOD)
print("save model successfully!")
2.3 test文件
在test里面主要加载模型,针对测试集做测试(其实在训练的时候也可以测试打印测试准确率,一般无特别需要到train文件也就可以了,但是一般情况下我们训练出模型会用各种方法测试一下,或者下次直接加载模型做一些可视化),如果需要提交一些结果的,还得做一些文件写入操作,也像train一样给出模板,之后可以在模板下面更改成自己具体问题的代码:
# test文件主要是训练模型,主要步骤有:
# 1、导入必要的包
# 2、设置超参数
# 3、读入测试数据及预处理
# 4、加载模型预测
# 5、保存提交文件
import os
import pandas as pd
import torch as t
import tqdm
from torch.autograd import Variable
from models import your_defined_network
METHOD = 'conv' # METHOD主要为选择models里面哪个网络
LOSS_TYPE = 'cla'
BATCH_SIZE = 50
use_gpu = t.cuda.is_available()
test = pd.read_csv('./data/test_july.csv')
test_data = test.drop('index', axis=1)
# 初始化模型,因为之前没有保存整个模型,只保存了参数,所以这里还要加载结构
if METHOD == 'conv':
pass
else:
raise Exception("Wrong Method!")
# print(net)
if os.path.exists('./models/%s.pth' % METHOD):
try:
model.load_state_dict(torch.load('./models/%s.pth' % METHOD))
except Exception as e:
print(e)
print("Parameters Error")
if use_gpu:
model= model.cuda()
# print(next(model.parameters()).is_cuda)
print('=======Predicting========\n')
submission = pd.read_csv("./data/sample_submission.csv")
# 切换成验证模式,验证模式下DROPOUT将不起作用
net.eval()
if use_gpu:
test_data = Variable(test_data.cuda())
else:
test_data = Variable(test_data)
result = t.Tensor().cuda()
# result = t.Tensor()
index = 0
# 分段进行预测,以下是生成提交文件(比如一些比赛需要),只是一个范例
for i in tqdm(range(int(test_data.shape[0] / BATCH_SIZE)), total=int(test_data.shape[0] / BATCH_SIZE)):
label_prediction = net(test_data[index:index + BATCH_SIZE])
index += BATCH_SIZE
result = t.cat((result, label_prediction), 0)
# 结果处理
if LOSS_TYPE == 'cla':
_, submission['label'] = t.max(result.data.cpu(), 1) # t.max返回一个元祖,第一个元素是最大元素值,第二个元素是最大元素位置
elif LOSS_TYPE == 'reg':
submission['label'] = submission['label'].astype('int')
submission['label'] = submission['label'].apply(lambda x: 9 if x >= 10 else x)
submission.to_csv("submission_conv.csv", index=False) # 不保存行索引
print("\ncreate submission csv file successfully!")
这是我第二次写。第一次写没保存,希望别人不要犯像我这样的低级错误,第二次写难免没有第一次写想得那么全,也浮躁一些(真滴难受啊),所以有什么可以改进的地方,大家可以评论,我可以修改呀!
写之不易,如果你能看到末尾,不妨点个喜欢,你的轻轻一个动作,是激励我写出更负责有效博客的动力,谢谢!
网友评论