import torch
import torch.nn as nn
import torch.nn.functional as F
#输入图片的格式是32*32classNet(nn.Module):def__init__(self):#只是定义网络中需要用到的方法super(Net, self).__init__()# 1 input image channel, 6 output channels, 3x3 square convolution# 32*32的输入
self.conv1 = nn.Conv2d(1,6,3)#30*30*6的输出,卷积之后15*15*6
self.conv2 = nn.Conv2d(6,16,3)#13*13*16的输出,卷积之后6*6*16# an affine operation: y = Wx + b
self.fc1 = nn.Linear(16*6*6,120)# 6*6 from image dimension
self.fc2 = nn.Linear(120,84)
self.fc3 = nn.Linear(84,10)defforward(self, x):#这里是真正建立网络# Max pooling over a (2, 2) window
x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))# If the size is a square you can only specify a single number
x = F.max_pool2d(F.relu(self.conv2(x)),2)
x = x.view(-1, self.num_flat_features(x))#特征平展,num_flat_features函数计算出的数据的维度为16*6*6,对接下一层的输入
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)return x
defnum_flat_features(self, x):
size = x.size()[1:]# all dimensions except the batch dimension
num_features =1for s in size:
num_features *= s
return num_features
net = Net()print(net)
输出:
Net((conv1): Conv2d(1,6, kernel_size=(3,3), stride=(1,1))(conv2): Conv2d(6,16, kernel_size=(3,3), stride=(1,1))(fc1): Linear(in_features=576, out_features=120, bias=True)(fc2): Linear(in_features=120, out_features=84, bias=True)(fc3): Linear(in_features=84, out_features=10, bias=True))
关于卷积的参数在注释中说明
池化过程的参数计算是 取整,如上例:(13/2)=6,所以fc1层的参数 是1666
cifar分类器
import torch
import torchvision
import torchvision.transforms as transforms
import torch.nn as nn
import torch.nn.functional as F
classNet(nn.Module):def__init__(self):super(Net, self).__init__()
self.conv1 = nn.Conv2d(3,6,5)
self.pool = nn.MaxPool2d(2,2)
self.conv2 = nn.Conv2d(6,16,5)
self.fc1 = nn.Linear(16*5*5,120)
self.fc2 = nn.Linear(120,84)
self.fc3 = nn.Linear(84,10)defforward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1,16*5*5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)return x
net = Net()
for epoch inrange(2):# loop over the dataset multiple times
running_loss =0.0for i, data inenumerate(trainloader,0):# get the inputs; data is a list of [inputs, labels]
inputs, labels = data
# zero the parameter gradients,把梯度置零,也就是把loss关于weight的导数变成0.
optimizer.zero_grad()# forward + backward + optimize
outputs = net(inputs)#forward前向传播求出预测的值
loss = criterion(outputs, labels)#求los
loss.backward()#backward反向传播求梯度
optimizer.step()#optimize更新所有参数# print statistics
running_loss += loss.item()if i %2000==1999:# print every 2000 mini-batchesprint('[%d, %5d] loss: %.3f'%(epoch +1, i +1, running_loss /2000))
running_loss =0.0print('Finished Training')
统计正确率
correct =0
total =0with torch.no_grad():for data in testloader:
images, labels = data
outputs = net(images)#得到模型输出
_, predicted = torch.max(outputs.data,1)#通过模型输出获取识别标签
total += labels.size(0)#测试集图片总数
correct +=(predicted == labels).sum().item()print('Accuracy of the network on the 10000 test images: %d %%'%(100* correct / total))
输出:
Accuracy of the network on the 10000 test images:53%
class_correct =list(0.for i inrange(10))
class_total =list(0.for i inrange(10))with torch.no_grad():for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs,1)
c =(predicted == labels).squeeze()for i inrange(4):
label = labels[i]
class_correct[label]+= c[i].item()
class_total[label]+=1for i inrange(10):print('Accuracy of %5s : %2d %%'%(
classes[i],100* class_correct[i]/ class_total[i]))
输出:
Accuracy of plane :47%
Accuracy of car :73%
Accuracy of bird :35%
Accuracy of cat :15%
Accuracy of deer :28%
Accuracy of dog :66%
Accuracy of frog :75%
Accuracy of horse :67%
Accuracy of ship :80%
Accuracy of truck :40%