当前位置:   article > 正文

【戴口罩高精度识别项目】神经网络搭建_pytorch 四层神经网络

pytorch 四层神经网络

 1.Pytorch搭建4层Resnet神经网络,基本参数如下:

1)一开始的输入大小设置为:(224,224,3)

2)layer0层有1层卷积、BN、激活、池化两个部分,卷积核大小为7X7,通道为64,步长为2,池化层大小为   3x3,步长为2;

3)layer1-layer4每层都有ResBlock1、ResBlock2,每个模块都经过两次2维卷积,每个模块可能会经历下采样与尺寸通道的变化,具体见layer1-layer4架构细节图ResBlock1、ResBlock2每个模块都会经历卷积、BN算法(解决层数多了后收敛慢的问题)、激活的过程,具体见各层关系对应图

各层对应关系:

  1. import torch
  2. import torch.nn as nn
  3. from torchsummary import summary
  4. import torchvision
  5. import torchvision.transforms as transforms
  6. """目的:搭建一个4层残差网络:输入:224x224x3 RGB彩图,输出:1000类"""
  7. class Resnet18(nn.Module):
  8. #每个神经网络的构成
  9. def __init__(self,num_classes):
  10. super().__init__()#继承父类的方法,即使定义了def __init__(self,num_classes):也不会覆盖父类的def __init__(self,num_classes)函数
  11. channels_list = [64,128,256,512]#为方便预先定义每层通道数量
  12. #layer 0
  13. self.layer_0 = nn.Sequential(
  14. nn.Conv2d(in_channels=3,out_channels=64,kernel_size=7,stride=2,padding=3),
  15. nn.BatchNorm2d(64),
  16. nn.ReLU(),
  17. nn.MaxPool2d(kernel_size=3,stride=2,padding=1),
  18. )
  19. # layer 1
  20. self.layer_1 = nn.Sequential(
  21. ResBlock(False,channels_list[0],channels_list[0]),#不做下采样
  22. ResBlock(False,channels_list[0],channels_list[0]),#不做下采样
  23. )
  24. # layer 2
  25. self.layer_2 = nn.Sequential(
  26. ResBlock(True,channels_list[0],channels_list[1]),#做下采样
  27. ResBlock(False,channels_list[1],channels_list[1]),#不做下采样
  28. )
  29. # layer 3
  30. self.layer_3 = nn.Sequential(
  31. ResBlock(True,channels_list[1],channels_list[2]),#做下采样
  32. ResBlock(False,channels_list[2],channels_list[2]), #不做下采样
  33. )
  34. # layer 4
  35. self.layer_4 = nn.Sequential(
  36. ResBlock(True,channels_list[2],channels_list[3]),#做下采样
  37. ResBlock(False,channels_list[3],channels_list[3]),#不做下采样
  38. )
  39. #layer 5
  40. self.aap = nn.AdaptiveAvgPool2d((1, 1))# 平均池化
  41. self.flatten = nn.Flatten(start_dim=1)# 拉直
  42. self.fc = nn.Linear(channels_list[3],num_classes)# 全连接层
  43. #每层神经网络之间的链接
  44. def forward(self,x):
  45. x = self.layer_0(x)
  46. x = self.layer_1(x)
  47. x = self.layer_2(x)
  48. x = self.layer_3(x)
  49. x = self.layer_4(x)
  50. x = self.aap(x)
  51. x = self.flatten(x)
  52. x = self.fc(x)
  53. return x
  54. class ResBlock(nn.Module):
  55. def __init__(self,down_sample,in_channels,out_channels):
  56. super().__init__()
  57. if down_sample:
  58. self.conv1 = nn.Conv2d(in_channels,out_channels,3,2,1)
  59. self.bn1 = nn.BatchNorm2d(out_channels)
  60. self.relu1 = nn.ReLU()
  61. self.conv2 = nn.Conv2d(out_channels,out_channels,3,1,1)
  62. self.bn2 = nn.BatchNorm2d(out_channels)
  63. self.relu2 = nn.ReLU()
  64. self.shortcut = nn.Sequential(
  65. nn.Conv2d(in_channels,out_channels,1,2,0),
  66. nn.BatchNorm2d(out_channels))#Sequential不是一个空壳,加了nn.Conv2d、nn.BatchNorm2d规则,所以shortcut接收任何数都是先卷积再BN算法
  67. self.relu3 = nn.ReLU()#一个模块的最终结果也是需要被激活一下的
  68. else:
  69. self.conv1 = nn.Conv2d(in_channels,out_channels,3,1,1)
  70. self.bn1 = nn.BatchNorm2d(out_channels)
  71. self.relu1 = nn.ReLU()
  72. self.conv2 = nn.Conv2d(out_channels,out_channels,3,1,1)
  73. self.bn2 = nn.BatchNorm2d(out_channels)
  74. self.relu2 = nn.ReLU()
  75. self.shortcut = nn.Sequential()#Sequential是一个空壳,没有规则,所以shortcut接收任何数都是没有规则的出去
  76. self.relu3 = nn.ReLU()#一个模块的最终结果也是需要被激活一下的
  77. def forward(self,x):
  78. shortcut = self.shortcut(x)#注意这里做下采样和不做下采样的self.shortcut对x的处理结果是不一样的
  79. #ResBlock的两次卷积
  80. x= self.conv1(x)
  81. x = self.bn1(x)
  82. x = self.relu1(x)
  83. x= self.conv2(x)
  84. x = self.bn2(x)
  85. x = self.relu2(x)
  86. #残差连接
  87. x = x + shortcut
  88. x = self.relu3(x)
  89. return x
  90. resnet18 =Resnet18(10)
  91. #resnet18 =Resnet18(10).to('cuda:0')
  92. """加载模型"""
  93. transform = transforms.Compose(
  94. [transforms.ToTensor(),
  95. transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
  96. batch_size = 4
  97. trainset = torchvision.datasets.CIFAR10(root='./1', train=True,
  98. download=True, transform=transform)
  99. trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,
  100. shuffle=True, num_workers=2)
  101. testset = torchvision.datasets.CIFAR10(root='./1', train=False,
  102. download=True, transform=transform)
  103. testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size,
  104. shuffle=False, num_workers=2)
  105. optimizer = torch.optim.SGD(resnet18.parameters(),lr=0.01)# 加载res18模型及res18模型的优化器
  106. criterion = nn.CrossEntropyLoss()#加载res18模型LOSS函数
  107. for epoch in range(2): # loop over the dataset multiple times
  108. running_loss = 0.0
  109. for i, data in enumerate(trainloader, 0):
  110. # get the inputs; data is a list of [inputs, labels]
  111. inputs, labels = data
  112. #inputs.to('cuda:0')
  113. # zero the parameter gradients
  114. optimizer.zero_grad()
  115. # forward + backward + optimize
  116. outputs = resnet18(inputs)
  117. loss = criterion(outputs, labels)
  118. loss.backward()
  119. optimizer.step()
  120. # print statistics
  121. running_loss += loss.item()
  122. print(loss.item())
  123. if i % 2000 == 1999: # print every 2000 mini-batches
  124. print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 2000:.3f}')
  125. running_loss = 0.0
  126. print('Finished Training')

Gitee链接:✉ 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/691151
推荐阅读
相关标签
  

闽ICP备14008679号