pytorch实现卷积神经网络_pytorch项目

pytorch实现卷积神经网络_pytorch项目论文链接:https://arxiv.org/pdf/1608.06993.pdf顾名思义,DenseNet采用了高密度的跳连结构,对于每一层,使用先前所有层的输出作为输入,该层的输出将作为之后所有层的输入的一部分。因此对于一个dense模块,假设有LLL层,那么存在L(L+1)2\frac{L(L+1)}{2}2L(L+1)​直接的连接。dense模块之后会连接一个transition层,…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

论文链接:https://arxiv.org/pdf/1608.06993.pdf
顾名思义,DenseNet采用了高密度的跳连结构,对于每一层,使用先前所有层的输出作为输入,该层的输出将作为之后所有层的输入的一部分。因此对于一个dense模块,假设有 L L L层,那么存在 L ( L + 1 ) 2 \frac{L(L+1)}{2} 2L(L+1)直接的连接。
在这里插入图片描述
dense模块之后会连接一个transition层,由1×1卷积和平均池化构成。
作者认为有如下优点:
(1)由于存在很多跳连,减轻了空梯度问题,加强了梯度和信息流动,更容易训练。
(2)加强了特征的重用。
(3)DenseNet层的filter数量比较少,使得层比较狭窄。每层只生成了很小的特征图,成为共同知识中的一员。这样网络的参数更少,且更有效率。

DenseNet结构分析

在这里插入图片描述
定义混合函数 H l ( ⋅ ) H_{l}(\cdot) Hl(),由三个连接操作组成:批标准化(BN),ReLU和3×3卷积。
ResNet比较 :恒等函数和混合函数的加和为输出,这样的做法可能会阻止网络中的信息流动。
密度连接: 对于某层,前 l − 1 l-1 l1层的输出 x 0 , ⋯   , x l − 1 \bm{x}_{0},\cdots,\bm{x}_{l-1} x0,,xl1进行channel水平的连接,生成一个单一的特征图:
x l = H l ( [ x 0 , ⋯   , x l − 1 ] ) \bm{x}_{l}=H_{l}([\bm{x}_{0},\cdots,\bm{x}_{l-1}]) xl=Hl([x0,,xl1])
池化层:当特征图的尺寸改变时,就无法进行连接了,然后在设计网络时必须要求特征图的尺寸在往后时减少,所以将dense模块分为几个模块。在模块之间设计transition层进行如下:BN,1×1卷积和2×2平均池化。
增长率 k k k: 在一个dense模块中,初始输入的特征图模块是 k 0 k_{0} k0,若则每层的输出通道 k k k, H l H_{l} Hl的输入为 k 0 + k ( l − 1 ) k_{0}+k(l-1) k0+k(l1) k k k调整每层多少信息加入到全局信息。
瓶颈层: 虽然每层仅仅产生 k k k通道的输出特征图,但是具有很多的输入。使用预激活的瓶颈层,采用如下的处理顺序:BN-ReLU-Conv(1×1)-BN-ReLU-Conv(3×3),称为DenseNet-B。在实验中,每1×1卷积降维变成 4 k 4k 4k通道特征图。
压缩: 在transition层减少特征图数量,设置压缩因子 0 < θ ≤ 1 0<\theta \leq 1 0<θ1,通过transition层后,产生了 ⌊ θ m ⌋ \left \lfloor \theta m\right \rfloor θm个通道的输出特征图。当 θ < 1 \theta<1 θ<1,称为DenseNet-C。在实验中,作者设为 θ = 0.5 \theta=0.5 θ=0.5。在DenseNet-C上使用瓶颈层被称为DenseNet-BC。

特征重用分析

DenseNet中由于使用该密度的跳连结构使得能够复用前面的feature-map,使用heap-map来分析前面层不同feature-map对当前层的重要程度。
在这里插入图片描述
上图展示了卷积层filter权重绝对值的平均值。坐标(s,l)表示在一个dense块中,由第s层传到l层的feature-map,l层权重的平均L1-norm(即权重绝对值的平均值)。我们知道,权重绝对值越大,表示对应的特征越重要,因此也反映了l层对s层的依赖性。红色部分表示强大的使用了s层的feature-map。
从图中作者得到如下4点结论:
1.在相同的块中,所有层的对于输入都具有权重。特征提取在早期层,直接使用在深度层。
2.transition层对于输入都具有权重。DenseNet从第一层到最后一层的信息流动仅通过很少的间接连接。
3.第二层和第三层的dense块一致的对transition层的输出赋予了很小的权重(第一层除外),表明了transition层的输出对第一层之后的层产生了冗余的特征。
4.最终的分类层更加关注最终的feature-maps,表明有一些高水平的特征产生在后面。

Pytorch实现DenseNet-BC

在论文中,作者公开了ImageNet的DenseNet结构。对于CIFAR,denseNet采用3个dense模块,每个dense模块采用相同数量的bottleneck。例如在DenseNet-BC(k=12) 100中,每个dense模块有16个bottleneck层,3 * (16 *2)=96层,剩下的4层分别为第一层卷积,中间的2层transition层,和最后的全连接层。

import torch
import torch.nn as nn
from collections import OrderedDict


class _DenseLayer(nn.Sequential):
    def __init__(self, in_channels, growth_rate, bn_size):
        super(_DenseLayer, self).__init__()
        self.add_module('norm1', nn.BatchNorm2d(in_channels))
        self.add_module('relu1', nn.ReLU(inplace=True))
        self.add_module('conv1', nn.Conv2d(in_channels, bn_size * growth_rate,
                                           kernel_size=1,
                                           stride=1, bias=False))
        self.add_module('norm2', nn.BatchNorm2d(bn_size*growth_rate))
        self.add_module('relu2', nn.ReLU(inplace=True))
        self.add_module('conv2', nn.Conv2d(bn_size*growth_rate, growth_rate,
                                           kernel_size=3,
                                           stride=1, padding=1, bias=False))

    # 重载forward函数
    def forward(self, x):
        new_features = super(_DenseLayer, self).forward(x)
        return torch.cat([x, new_features], 1)


class _DenseBlock(nn.Sequential):
    def __init__(self, num_layers, in_channels, bn_size, growth_rate):
        super(_DenseBlock, self).__init__()
        for i in range(num_layers):
            self.add_module('denselayer%d' % (i+1),
                            _DenseLayer(in_channels+growth_rate*i,
                                        growth_rate, bn_size))


class _Transition(nn.Sequential):
    def __init__(self, in_channels, out_channels):
        super(_Transition, self).__init__()
        self.add_module('norm', nn.BatchNorm2d(in_channels))
        self.add_module('relu', nn.ReLU(inplace=True))
        self.add_module('conv', nn.Conv2d(in_channels, out_channels,
                                          kernel_size=1,
                                          stride=1, bias=False))
        self.add_module('pool', nn.AvgPool2d(kernel_size=2, stride=2))


class DenseNet_BC(nn.Module):
    def __init__(self, growth_rate=12, block_config=(6,12,24,16),
                 bn_size=4, theta=0.5, num_classes=10):
        super(DenseNet_BC, self).__init__()

        # 初始的卷积为filter:2倍的growth_rate
        num_init_feature = 2 * growth_rate

        # 表示cifar-10
        if num_classes == 10:
            self.features = nn.Sequential(OrderedDict([
                ('conv0', nn.Conv2d(3, num_init_feature,
                                    kernel_size=3, stride=1,
                                    padding=1, bias=False)),
            ]))
        else:
            self.features = nn.Sequential(OrderedDict([
                ('conv0', nn.Conv2d(3, num_init_feature,
                                    kernel_size=7, stride=2,
                                    padding=3, bias=False)),
                ('norm0', nn.BatchNorm2d(num_init_feature)),
                ('relu0', nn.ReLU(inplace=True)),
                ('pool0', nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
            ]))



        num_feature = num_init_feature
        for i, num_layers in enumerate(block_config):
            self.features.add_module('denseblock%d' % (i+1),
                                     _DenseBlock(num_layers, num_feature,
                                                 bn_size, growth_rate))
            num_feature = num_feature + growth_rate * num_layers
            if i != len(block_config)-1:
                self.features.add_module('transition%d' % (i + 1),
                                         _Transition(num_feature,
                                                     int(num_feature * theta)))
                num_feature = int(num_feature * theta)

        self.features.add_module('norm5', nn.BatchNorm2d(num_feature))
        self.features.add_module('relu5', nn.ReLU(inplace=True))
        self.features.add_module('avg_pool', nn.AdaptiveAvgPool2d((1, 1)))

        self.classifier = nn.Linear(num_feature, num_classes)

        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                nn.init.constant_(m.bias, 0)

    def forward(self, x):
        features = self.features(x)
        out = features.view(features.size(0), -1)
        out = self.classifier(out)
        return out


# DenseNet_BC for ImageNet
def DenseNet121():
    return DenseNet_BC(growth_rate=32, block_config=(6, 12, 24, 16), num_classes=1000)

def DenseNet169():
    return DenseNet_BC(growth_rate=32, block_config=(6, 12, 32, 32), num_classes=1000)

def DenseNet201():
    return DenseNet_BC(growth_rate=32, block_config=(6, 12, 48, 32), num_classes=1000)

def DenseNet161():
    return DenseNet_BC(growth_rate=48, block_config=(6, 12, 36, 24), num_classes=1000,)

# DenseNet_BC for cifar
def densenet_BC_100():
    return DenseNet_BC(growth_rate=12, block_config=(16, 16, 16))


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/187978.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • CUDA是什么-CUDA简介「建议收藏」

    CUDA是什么-CUDA简介「建议收藏」在大家开始深度学习时,几乎所有的入门教程都会提到CUDA这个词。那么什么是CUDA?她和我们进行深度学习的环境部署等有什么关系?通过查阅资料,我整理了这份简洁版CUDA入门文档,希望能帮助大家用最快的时间尽可能清晰的了解这个深度学习赖以实现的基础概念。本文在以下资料的基础上整理完成,感谢以下前辈提供的资料:CUDA——“从入门到放弃”我的CUDA学习之旅——启程介绍一篇不错的CUDA入门博…

    2022年5月29日
    34
  • 麦肯锡:芯片业界整合即将完成

    麦肯锡:芯片业界整合即将完成

    2022年3月6日
    60
  • UNIX网络编程卷1 时间获取程序server UDP 协议无关[通俗易懂]

    UNIX网络编程卷1 时间获取程序server UDP 协议无关

    2022年1月28日
    32
  • idea修改properties文件编码_idea使用maven

    idea修改properties文件编码_idea使用maven结果图:

    2022年9月21日
    1
  • mount 命令介绍

    mount 命令介绍磁盘挂载可以有效解决数据同步与磁盘空间浪费的问题 而且支持不同操作系统之间挂载操作 核心命令为 mount 本文介绍该命令 挂载挂载常用的命令为 mount 其命令格式为 mount args devicedirarg 表示配置参数 其中最常用的为 t 和 o 参数 t 指定文件系统的类型 通常不必指定 mount 会自动选择正确的类型 常用类型有 iso9660 光盘或光盘镜像 msdos DOSfat16 文件系统 vfat Windows9xfat 文件系统 n

    2025年7月11日
    3
  • git使用步骤_小猪酸奶的使用步骤

    git使用步骤_小猪酸奶的使用步骤厉害了!小猪用Git一年多后的精华总结标签:Git描述性文字:不要问我为什么用这种骚猪风格的标题,现在写博文,标题不骚,人家都不乐意看~接触Git到现在有一年多了,对Git使用也是日渐精进,虽说不上很熟络,但也算入门,决定年前总结下,所以有了此文。Git博大精深,还有很多的东西需要学习,比如自己搭建啊,一些便利工具的使用啊,一些疑难杂症解决方案啊等等,当然这就是下一话的事了。本文讲述的

    2022年9月22日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号