1. 1x1的卷积核的作用
2. GoogLeNet中Inception Module的实现
2.1 Inception块的代码实现
import torch
import torch.nn.functional as F
class InceptinA(torch.nn.Module):
def __init__(self,channels):
super(InceptinA, self).__init__()
self.branch_pool = torch.nn.Conv2d(channels,24,kernel_size=1)
self.branch1x1 = torch.nn.Conv2d(channels,16,kernel_size=1)
self.branch5x5_1 = torch.nn.Conv2d(channels,16,kernel_size=1)
self.branch5x5_2 = torch.nn.Conv2d(16,24,kernel_size=5,padding=2)#使用了5x5的卷积核,为保证w和h不变,使用padding=2
self.branch3x3_1 = torch.nn.Conv2d(channels,16,kernel_size=1)
self.branch3x3_2 = torch.nn.Conv2d(16,24,kernel_size=3,padding=1)
self.branch3x3_3 = torch.nn.Conv2d(24,24,kernel_size=3,padding=1)
def forward(self,x):
branch_pool = F.avg_pool2d(x,kernel_size=3,padding=1,stride=1) #本来默认stride就是1
branch_pool = self.branch_pool(branch_pool)
branch1x1 = self.branch1x1(x)
branch5x5 = self.branch5x5_2(self.branch5x5_1(x))
branch3x3 = self.branch3x3_3(self.branch3x3_2(self.branch3x3_1(x)))
outputs = [branch_pool,branch1x1,branch5x5,branch3x3]
return torch.cat(outputs,dim=1) #BxCxWxH,dim=1按照通道数进行拼接
2.2 使用模块构建卷积网络训练Minist数据集
2.3 整体代码实现
import torch
from Inception import InceptinA
import torch.nn.functional as F
from torch.utils.tensorboard import SummaryWriter
from torch.utils.data import DataLoader
from torchvision import datasets,transforms
#追踪日志
writer = SummaryWriter(log_dir='../LEDR')
#准备数据集
trans = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,),(0.3801,))])
train_set = datasets.MNIST(root='E:\learn_pytorch\LE',train=True,transform=trans,download=True)
test_set = datasets.MNIST(root='E:\learn_pytorch\LE',train=False,transform=trans,download=True)
#下载数据集
train_data = DataLoader(dataset=train_set,batch_size=64,shuffle=True)
test_data = DataLoader(dataset=test_set,batch_size=64,shuffle=False)
#构建模型
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv_1 = torch.nn.Conv2d(1,10,kernel_size=5)#输出变成 10x24x24
self.conv_2 = torch.nn.Conv2d(88,20,kernel_size=5)# 输出变成 20x12x12
self.mp = torch.nn.MaxPool2d(2)
self.incept1 = InceptinA(channels=10)
self.incept2 = InceptinA(channels=20)
self.fc = torch.nn.Linear(1408,10)
def forward(self,x):
x = F.relu(self.mp(self.conv_1(x)))# 输出为 10x12x12
x = self.incept1(x) #输出是88x12x12
x = F.relu(self.mp(self.conv_2(x)))# 输出是 20x4x4
x = self.incept2(x) #输出是 88x4x4
x = x.view(-1,1408)
x = self.fc(x)
return x
#实例化模型
huihui = Net()
#定义损失函数和优化函数
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(params=huihui.parameters(),lr=0.01,momentum=0.5)
#开始训练
def train(epoch):
run_loss = 0.0
for batch_id , data in enumerate(train_data,0):
inputs , targets = data
outputs = huihui(inputs)
loss = criterion(outputs, targets)
#归零,反馈,更新
optimizer.zero_grad()
loss.backward()
optimizer.step()
run_loss += loss.item()
if batch_id % 300 == 299:
print("[%d,%d] loss:%.3f" %(epoch+1,batch_id+1,run_loss/300))
run_loss = 0.0
def test():
total = 0
correct = 0
with torch.no_grad():
for data in test_data:
inputs , labels = data
outputs = huihui(inputs)
_,predict = torch.max(outputs,dim=1)
total += labels.size(0)
correct += (predict==labels).sum().item()
writer.add_scalar("The Accuracy1",correct/total,epoch)
print('[Accuracy] %d %%' % (100*correct/total))
if __name__ == '__main__':
for epoch in range(10):
train(epoch)
test()
writer.close()
2.4 结果展示(正确率还是98%)
2.5 图像展示