pytorch训练过程acc_pytorch⼊门练⼿:⼀个简单的CNN模型
由于新型冠状肺炎疫情⼀直没能开学,在家⾃⼰学习了⼀下pytorch,本来说按着官⽹的60分钟教程过⼀遍的,但是CIFAR-10数据库的下载速度太慢了……
这台电脑⾥也没有现成的数据库,想起之前画了⼀些粒⼦的动量分量分布图,⼲脆拿来⽤了,也没期待它能表现得多好,主要图⼀个练⼿。(事实证明它表现相当差,不过这也在意料之中)
关于创新的议论文那么开始。
import torch
import torchvision
ansforms as transforms
import matplotlib.pyplot as plt
import numpy as np
我终于战胜了粗心from PIL import Image
as nn
functional as F
import torch.optim as optim
接下来定义读取和处理图⽚的函数,图⽚尺⼨是432x288,把它切成中间的288x288,再缩⼩成32x32。这样的处理单纯是为了让模型
不是训练⼀个⾼精度的模型,⽽是训练⼀个模型
训练⼀个模型。(⽽且话说回来这电脑也莫得英伟达⾼性能图训练得快⼀点,毕竟这次练⼿本⾝的⽬的不是训练⼀个⾼精度的模型
形处理器,(笑))
这⾥其实两个函数写成⼀个就⾏,但是我懒得改了。
PATH = '/Urs/huangyige/Downloads/fig/'
def load_img(imgname):
#here, only consider pion at 7.7 and 14.5 GeV, px.
img = Image.open(imgname).convert('RGB')
return img
def process_img(img):
img = p((72,0,360,288))
img = size((32,32))
return img
然后随意拉张图进来看看。
img = load_img(PATH+'Pion-7.7GeV-7-P1.png')
img = process_img(img)
plt.imshow(img)
只能隐约能看出来有两个峰2333333,这样的数据集能训练出来个⿁咯~
然后⽣成两个数据集的⽂件名列表(附带标签)的⽂档。
def generate_file(name,num_range):
with open('./'+name+'.txt','w') as f:
for energy in ['7.7','14.5']:
for _ in num_range:
imgname = PATH + 'Pion-' + energy + 'GeV-' + str(_+1) + '-P1.png'
f.write(imgname+' '+energy+'n')
return
generate_file('train',range(0,70))
generate_file('test',range(70,90))
就别问我为什么训练集就70张图,测试集就20张图了,只有这么点数据……可以打开⽂档看看效果。
差不多就这样,没什么问题。接下来定义⾃定义Datat类。
class ts(torch.utils.data.Datat):
def __init__(lf,datatxt,transform=None):
super(ts,lf).__init__()
imgs = []
with open(datatxt,'r') as f:
for line in f:
line = line.rstrip('n')
words = line.split(' ')
imgs.append((words[0],words[1]))
lf.imgs = imgs
return
def __getitem__(lf,index):
imgname,label_o = lf.imgs[index]
img = load_img(imgname)
img = process_img(img)
if label_o == '7.7':
label = 0
el:
label = 1
ansform is not None:
img = lf.transform(img)
return img,label
def __len__(lf):
电脑蓝屏修理>甲的成语
return len(lf.imgs)
以及DataLoader。
train_t = ts('./',transforms.ToTensor())
test_t = ts('./',transforms.ToTensor())
train_loader = torch.utils.data.DataLoader(datat=train_t,batch_size=1,shuffle=True)
test_loader = torch.utils.data.DataLoader(datat=test_t,batch_size=1)
batch_size选1是不是很扯,哈哈哈我也这么觉得。如果需要做数据增强,在初始化ts时,transform参数⽤transforms.Compo[transforms.ToTensor(),...]这样多填⼏个就⾏了。
然后是模型的结构。
class Net(nn.Module):
def __init__(lf):
super(Net,lf).__init__()
lf.pool = nn.MaxPool2d(2,2)
lf.fc1 = nn.Linear(16*5*5,120)
lf.fc2 = nn.Linear(120,84)
#lf.fc3 = nn.Linear(84,10)
lf.fc3 = nn.Linear(84,2)
return
def forward(lf,x):
x = lf.v1(x)))
x = lf.v2(x)))
x = x.view(-1,16*5*5)
注塑车间管理x = F.relu(lf.fc1(x))
x = F.relu(lf.fc2(x))
x = lf.fc3(x)
return x
net = Net()
用word做表格直接把pytorch官⽹的tutorial⾥CIFAR-10的模型拉出来⽤了,正好我已经把数据变成了32x32,参数都不⽤改。(修改:最后⼀个全链接层的神经元数应该是2⽽不是10,还是得改⼀下的)
选损失函数和优化器。
黔娄criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(),lr=0.001,momentum=0.9)
pytorch没有现成的算accuracy的函数所以⾃⼰写⼀个。
def accuracy(net,test_loder):
correct = 0
total = 0
_grad():
for data in test_loader:
inputs,labels = data
outputs = net(inputs)
_,pred = torch.max(outputs.data,1)
total += labels.size(0)
correct += (pred==labels).sum().item()
acc = 100.0*correct/total
return acc
然后就可以开始训练了,本来也只是个玩具模型,所以2代就够了。不得不插⼀嘴,keras⽤起来确实要⽅便⼀点。
for epoch in range(2):
running_loss = 0.0
for i,data in enumerate(train_loader,0):
inputs,labels = data
<_grad()
leapt
outputs = net(inputs)
loss = criterion(outputs,labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
acc = accuracy(net,test_loader)
print('r[epoch %d >%3.d<] loss:%.3f,acc:%.1f%%'%(epoch+1,i+1,loss,acc),end='')
print('')
print('Done!')
看看效果:
精度精准地锁定在50%,也就是说这模型在纯猜~whatever,这次练⼿主要是熟悉pytorch怎么⽤,模型本⾝的质量不重要。最后保存⼀下模型:
torch.save(net.state_dict(),'./model.pth')
想开学啊啊啊啊啊……