【论文阅读及复现】(2017)Densely Connected Convolutional Networks + Pytorch代码实现

您所在的位置:网站首页 运筹优化论文复现 【论文阅读及复现】(2017)Densely Connected Convolutional Networks + Pytorch代码实现

【论文阅读及复现】(2017)Densely Connected Convolutional Networks + Pytorch代码实现

2024-03-23 21:12| 来源: 网络整理| 查看: 265

文章目录 一、摘要二、Dense Net 网络结构三、Dense Block四、PyTorch-GPU代码实现

论文来源:(2017)Densely Connected Convolutional Networks 作者:Gao Huang 等人

一、摘要 最近的工作表明,如果卷积网络在靠近输入的层和靠近输出的层之间包含较短的连接,则它们可以更深、更准确和更有效地训练。在本文中,我们接受了这一观察并介绍了密集卷积网络(DenseNet),它以前馈方式将每一层连接到其他每一层。具有 L 层的传统卷积网络有 L 个连接——每层与其后续层之间有一个连接——我们的网络有 L*(L+1) /2 个直接连接。 F 或每一层,所有前面的层的特征图被用作输入,它自己的特征图被用作所有后续层的输入。DenseNets 有几个引人注目的优势:它们缓解了梯度消失问题,加强了特征传播,鼓励特征重用,并大大减少了参数的数量。我们在四个竞争激烈的对象识别基准任务(CIF AR-10、CIF AR-100、SVHN 和 ImageNet)上评估我们提出的架构。DenseNets 在大多数情况下都比最先进的技术获得了显着改进,同时需要更少的计算来实现高性能。 二、Dense Net 网络结构

在这里插入图片描述 在这里插入图片描述

三、Dense Block

在Dense Block中,每一层都与后面的层有跳连接

为了更好的保存低层网络的特征,DenseNet 使用的是将不同层的输出拼接在一起,而在残差网络中使用的是单位加操作。以上便是DenseNet算法的动机 在这里插入图片描述 在Dsense Block中的每一层,都有1×1和3×3两个卷积核

论文中指出:”虽然每一层只产生 k 个输出特征图,但它通常有更多的输入。可以在每个 3×3 卷积之前引入一个 1×1 卷积作为瓶颈层,以减少输入特征图的数量,从而提高计算效率。我们发现这种设计对 DenseNet 特别有效,我们将我们的网络称为具有这样一个瓶颈层的网络,即 H’ 的 BN-ReLU-Conv(1×1)-BN-ReLU-Conv(3×3) 版本“

四、PyTorch-GPU代码实现

MNIST手写数据集的图片大小为28×28,如果采用论文里的结构,在第四层pooling时会出现0×0尺寸的情况,为了避免这个情况,我在第四层前的1×1的conv层设置了padding=(1,1),故下面的代码结构不和论文里完全一致

import torch import torch.nn as nn from torchvision import transforms from torchvision import datasets from torch.utils.data import DataLoader import torch.optim as optim import torch.nn.functional as F def conv_block(in_channels, out_channels): block = nn.Sequential(nn.BatchNorm2d(in_channels), nn.ReLU(), nn.Conv2d(in_channels, out_channels, kernel_size=(3, 3), padding=(1, 1))) return block class DenseBlock(nn.Module): def __init__(self, in_channels, out_channels, cnt): super(DenseBlock, self).__init__() net = [] for i in range(cnt): in_c = in_channels + i * out_channels net.append(conv_block(in_c, out_channels)) self.net = nn.ModuleList(net) self.out_channels = in_channels + cnt * out_channels # 计算输出通道数 def forward(self, x): for blk in self.net: y = blk(x) x = torch.cat((x, y), dim=1) # 在通道维上将输入和输出拼接 return x class DenselyNet(torch.nn.Module): def __init__(self): super(DenselyNet, self).__init__() self.conv7x7 = nn.Conv2d(1, 16, kernel_size=(7, 7), padding=(3, 3), stride=(2, 2)) self.conv1x1_1 = nn.Conv2d(112, 16, kernel_size=(1, 1)) self.conv1x1_2 = nn.Conv2d(208, 16, kernel_size=(1, 1)) self.conv1x1_3 = nn.Conv2d(400, 16, kernel_size=(1, 1),padding=(1,1)) self.max_pooling3x3 = nn.MaxPool2d(kernel_size=(3, 3), stride=(2, 2)) self.avg_pooling2x2 = nn.AvgPool2d(kernel_size=(2, 2), stride=(2, 2)) self.dense_block1 = DenseBlock(16, 16, 6) self.dense_block2 = DenseBlock(16, 16, 12) self.dense_block3 = DenseBlock(16, 16, 24) self.dense_block4 = DenseBlock(16, 16, 16) self.fc = nn.Linear(272, 10) def forward(self, x): in_size = x.size(0) x = torch.relu(self.conv7x7(x)) x = torch.relu(self.max_pooling3x3(x)) x = self.dense_block1(x) x = torch.relu(self.conv1x1_1(x)) x = torch.relu(self.avg_pooling2x2(x)) x = self.dense_block2(x) x = torch.relu(self.conv1x1_2(x)) x = torch.relu(self.avg_pooling2x2(x)) x = self.dense_block3(x) x = torch.relu(self.conv1x1_3(x)) x = torch.relu(self.avg_pooling2x2(x)) x = self.dense_block4(x) x = torch.relu(F.adaptive_avg_pool2d(x, output_size=(1, 1))) x = x.view(in_size, -1) x = self.fc(x) return x # 单次训练函数 def train(epoch, criterion): running_loss = 0.0 for batch_idx, data in enumerate(train_loader, 0): inputs, target = data # 将inputs, target转移到Gpu或者Cpu上 inputs, target = inputs.to(device), target.to(device) optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, target) loss.backward() optimizer.step() running_loss += loss.item() if batch_idx % 300 == 299: print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300)) running_loss = 0.0 # 单次测试函数 def ttt(): correct = 0.0 total = 0.0 with torch.no_grad(): for data in test_loader: images, labels = data # 将images, labels转移到Gpu或者Cpu上 images, labels = images.to(device), labels.to(device) outputs = model(images) _, predicted = torch.max(outputs.data, dim=1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy on test set: %d %% [%d/%d]' % (100 * correct / total, correct, total)) if __name__ == '__main__': batch_size = 64 transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]) train_dataset = datasets.MNIST(root='../dataset/', train=True, download=True, transform=transform) train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size) test_dataset = datasets.MNIST(root='../dataset/', train=False, download=True, transform=transform) test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # 声明模型 model = DenselyNet() # 将模型转移道Gpu或者Cpu上 model.to(device) # 定义损失函数 criterion = torch.nn.CrossEntropyLoss() # 定义优化器 optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5) for epoch in range(10): train(epoch, criterion) ttt()

输出:

[1, 300] loss: 1.274 [1, 600] loss: 0.321 [1, 900] loss: 0.179 Accuracy on test set: 96 % [9699/10000] [2, 300] loss: 0.114 [2, 600] loss: 0.115 [2, 900] loss: 0.099 Accuracy on test set: 98 % [9813/10000] [3, 300] loss: 0.080 [3, 600] loss: 0.068 [3, 900] loss: 0.069 Accuracy on test set: 98 % [9864/10000] [4, 300] loss: 0.053 [4, 600] loss: 0.056 [4, 900] loss: 0.056 Accuracy on test set: 98 % [9873/10000] [5, 300] loss: 0.041 [5, 600] loss: 0.044 [5, 900] loss: 0.041 Accuracy on test set: 98 % [9882/10000] [6, 300] loss: 0.033 [6, 600] loss: 0.035 [6, 900] loss: 0.034 Accuracy on test set: 98 % [9864/10000] [7, 300] loss: 0.033 [7, 600] loss: 0.028 [7, 900] loss: 0.033 Accuracy on test set: 99 % [9903/10000] [8, 300] loss: 0.024 [8, 600] loss: 0.027 [8, 900] loss: 0.031 Accuracy on test set: 98 % [9883/10000] [9, 300] loss: 0.020 [9, 600] loss: 0.022 [9, 900] loss: 0.027 Accuracy on test set: 99 % [9901/10000] [10, 300] loss: 0.019 [10, 600] loss: 0.022 [10, 900] loss: 0.021 Accuracy on test set: 98 % [9883/10000]


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3