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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Selenium中implicitly_wait等待失效

    Selenium中implicitly_wait等待失效

    2021年5月23日
    217
  • Visual Studio 2010 旗舰版免序列号安装体验

    Visual Studio 2010 旗舰版免序列号安装体验VisualStudio2010E文版已经发布多时,由于工作原因没有及早的下载体验,直到前几天园子里的朋友放出了下载简体中文的种子ed2k://|file|cn_visual_studio_2010_ultimate_x86_dvd_532347.iso|2685982720|4AE6228933DDE49D9BFA4C3467C831C2|/于是决定下来体验一把,网速慢,2.5G下了2…

    2022年7月20日
    13
  • java 拉姆达表达式_Java8中foreach与拉姆达表达式的组合使用

    java 拉姆达表达式_Java8中foreach与拉姆达表达式的组合使用1.forEachandMap1.1通常这样遍历一个MapMapitems=newHashMap<>();items.put(“A”,10);items.put(“B”,20);items.put(“C”,30);items.put(“D”,40);items.put(“E”,50);items.put(“F”,60);for(Map.Entryent…

    2022年9月19日
    0
  • 【转载】视频跟踪的研究

    首先,什么是视频跟踪?基于视频的运动目标跟踪技术作为计算机视觉领域的核心研究课题之一, 主要目的是模仿生理视觉系统的运动感知功能,通过对摄像头捕捉到的图像序列进行分析,计算出运动目标在每一帧图像中的二维坐标位置;然后,根据运动目标相关的特征值,将图像序列中连续帧间的同一运动目标关联起来,得到每帧图像中目标的运动参数以及相邻帧图像间运动目标的对应关系,从而得到各个运动目标完整的运动轨迹,即在

    2022年4月10日
    39
  • c3p0连接池的配置方式

    c3p0连接池的配置方式c3p0的配置方式分为三种,分别是1.setters一个个地设置各个配置项2.类路径下提供一个c3p0.properties文件3.类路径下提供一个c3p0-config.xml文件1.setters一个个地设置各个配置项这种方式最繁琐,形式一般是这样:01Propertiesprops= new Properties();

    2022年6月2日
    43
  • java datagramsocket,Java DatagramSocket和DatagramPacket[通俗易懂]

    java datagramsocket,Java DatagramSocket和DatagramPacket[通俗易懂]JavaDatagramSocket和DatagramPacket1JavaDatagramSocket和DatagramPacketJavaDatagramSocket和DatagramPacket类用于无连接Socket编程。2JavaDatagramSocket类JavaDatagramSocket类表示用于发送和接收数据报包的无连接Socket。DatagramSocket基…

    2022年6月12日
    27

发表回复

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

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