mnist使用全连接网络和卷积网络差别不大,只有小幅度提升,训练17轮之后准确率最高达到98.74%
ps:昨天有同学汇报论文,使用遗忘分数处理mnist数据集,删除90%的训练集准确率只下降了0.5%
import torch
import matplotlib.pyplot as plt
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
batchsize=32
lr=0.01
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
mean,sqr=0.1307,0.3081 #minist数据集的均值和方差,transforms.ToTensor()会将数据转换至0-1,compose是将操作组合
transform=transforms.Compose([transforms.ToTensor(), transforms.Normalize((mean,), (sqr,))])
traindata=datasets.MNIST(root='./datasets/mnist',download=False,train=True,transform=transform)
testdata=datasets.MNIST(root='./datasets/mnist',download=False,train=False,transform=transform)
trainloard=DataLoader(dataset=traindata,batch_size=batchsize,shuffle=True,num_workers=0,drop_last=True)
testloard=DataLoader(dataset=testdata,batch_size=batchsize,shuffle=False,num_workers=0,drop_last=True)
class Model(torch.nn.Module):
def __init__(self):
super(Model,self).__init__()
self.c1=torch.nn.Conv2d(in_channels=1,out_channels=10,kernel_size=3)
self.c2=torch.nn.Conv2d(in_channels=10,out_channels=5,kernel_size=3)
self.mp=torch.nn.MaxPool2d(2)
self.l1=torch.nn.Linear(5*5*5,64)
self.l2=torch.nn.Linear(64,32)
self.l3=torch.nn.Linear(32,10)
self.relu=torch.nn.ReLU()
def forward(self,x):
x=self.mp(self.relu(self.c1(x)))
x=self.mp(self.relu(self.c2(x)))
x=x.view(-1,5*5*5)
x=self.relu(self.l1(x))
x=self.relu(self.l2(x))
x=self.l3(x)
return x
model=Model()
model.to(device)
criterion=torch.nn.CrossEntropyLoss()
optimizer=torch.optim.SGD(model.parameters(),lr=lr,momentum=0.5)
def train(allepoch):
lepoch=[]
llost=[]
lacc=[]
for epoch in range(allepoch):
lost=0
count=0
for num,(x,y) in enumerate(trainloard,1):
x,y=x.to(device),y.to(device)
y_h=model(x)
loss=criterion(y_h,y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
lost+=loss.item()
count+=batchsize
print('epoch:',epoch+1,'loss:',lost/count,end=' ')
lepoch.append(epoch+1)
llost.append(lost/count)
acc=test()
lacc.append(acc)
print('acc:',acc)
plt.plot(lepoch,llost,label='loss')
plt.plot(lepoch,lacc,label='acc')
plt.legend()
plt.show()
def test():
with torch.no_grad():
acc=0
count=0
for num, (x, y) in enumerate(testloard, 1):
x,y=x.to(device),y.to(device)
y_h = model(x)
_,y_h=torch.max(y_h.data,dim=1)
acc+= (y_h==y).sum().item()
count+=x.size(0)
return acc/count
if __name__=='__main__':
train(20)
使用卷积网络训练cifar10训练23轮时准确率达到最高(0.745),之后就有点过拟合了
import torch
import matplotlib.pyplot as plt
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
batchsize=32
lr=0.01
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
traindata=datasets.CIFAR10(root='./datasets/cifar10',download=False,train=True,transform=transform)
testdata=datasets.CIFAR10(root='./datasets/cifar10',download=False,train=False,transform=transform)
trainloard=DataLoader(dataset=traindata,batch_size=batchsize,shuffle=True,num_workers=0,drop_last=True)
testloard=DataLoader(dataset=testdata,batch_size=batchsize,shuffle=False,num_workers=0,drop_last=True)
class model(torch.nn.Module):
def __init__(self):
super(model,self).__init__()
self.c1=torch.nn.Conv2d(in_channels=3,out_channels=32,kernel_size=5,padding=2)
self.mp=torch.nn.MaxPool2d(2)
self.c2=torch.nn.Conv2d(in_channels=32,out_channels=32,kernel_size=5,padding=2)
self.c3=torch.nn.Conv2d(in_channels=32,out_channels=64,kernel_size=5,padding=2)
self.l1=torch.nn.Linear(64*4*4,64)
self.l2=torch.nn.Linear(64,10)
self.relu=torch.nn.ReLU()
self.sig=torch.nn.Sigmoid()
def forward(self,x):
x=self.relu(self.mp(self.c1(x)))
x=self.relu(self.mp(self.c2(x)))
x=self.relu(self.mp(self.c3(x)))
x=x.view(-1,64*4*4)
x=self.sig(self.l1(x))
x=self.l2(x)
return x
model=model()
model.to(device)
criterion=torch.nn.CrossEntropyLoss()
optimizer=torch.optim.SGD(model.parameters(),momentum=0.5,lr=lr)
def train(allepoch):
lepoch=[]
llost=[]
lacc=[]
for epoch in range(allepoch):
lost=0
count=0
for num,(x,y) in enumerate(trainloard,1):
x,y=x.to(device),y.to(device)
y_h=model(x)
loss=criterion(y_h,y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
lost+=loss.item()
count+=batchsize
print('epoch:',epoch+1,'loss:',lost/count,end=' ')
lepoch.append(epoch+1)
llost.append(lost/count)
acc=test()
lacc.append(acc)
print('acc:',acc)
plt.plot(lepoch,llost,label='loss')
plt.plot(lepoch,lacc,label='acc')
plt.legend()
plt.show()
def test():
with torch.no_grad():
acc=0
count=0
for num, (x, y) in enumerate(testloard, 1):
x,y=x.to(device),y.to(device)
y_h = model(x)
_,y_h=torch.max(y_h.data,dim=1)
acc+= (y_h==y).sum().item()
count+=x.size(0)
return acc/count
if __name__=='__main__':
train(50)
另外,之前代码一直不能在GPU运行,昨天终于解决了,之前是直接安装了pytorch的包,没有安装cuda和cudann,后来安装上之后重装了pytorch就可以用GPU运行了,运行时报错Hint: This means that multiple copies of the OpenMP runtime have been linked into the program.
参考博客https://zhuanlan.zhihu.com/p/371649016解决了问题(我没有直接删除那个文件,而是重命名加了个下划线)