精华内容
下载资源
问答
  • 官方文档:https://keras.io/layers/convolutional/#zeropadding2d ... 【搬运】conv卷积层: 1.相当于一个特征提取器来提取特征 2.提供了位置信息 3.减少了参数个数 https://blog.csdn.net/m0_37622530/articl...

    官方文档:https://keras.io/layers/convolutional/#zeropadding2d
    https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html VGG16架构

    https://www.cnblogs.com/ymjyqsx/p/9451739.html

    【搬运】conv卷积层
    1.相当于一个特征提取器(特征增强,消除噪声)
    2.提供了位置信息
    3.减少了参数个数

    https://blog.csdn.net/m0_37622530/article/details/82230368
    https://www.cnblogs.com/ymjyqsx/p/9451739.html

    【搬运】pooling池化层
    1.提取特征(减少之前的特征维数) 2.减少训练参数
    3.进而防止过拟合(泛化能力加强)。 激活函数:增加网络的非线性表达能力。

    1 过滤越来越多的卷积层,提取越来越高级的特征
    2 Max pooling和Global Average Pooling用来只保留这些特征中最强的,保证特征的位置与旋转不变性,减少模型参数数量,减少过拟合问题

    ————————————————————————————
    https://blog.csdn.net/qq_39521554/article/details/81385159
    【半搬运】对全连接层fully connected layer)的通俗理解:
    全连接层(fully connected layers,FC)(通过矩阵向量乘积)在整个卷积神经网络中起到“分类器”的作用。如果说卷积层、池化层和激活函数层等操作是将原始数据映射到隐层特征空间的话,全连接层则对前面的特征(通过“全局平均值global average pooling”的方法减少全连接的参数)做加权和,将学到的“分布式特征表示”(高度提纯的特征)映射到样本标记空间。

    https://blog.csdn.net/wangyuxi__/article/details/82714647
    全连接层:连接所有的特征,将输出值送给分类器(如softmax分类器)。
    在这里插入图片描述
    https://blog.csdn.net/m0_37407756/article/details/80904580
    卷积取的是局部特征,全连接就是把以前的局部特征重新通过权值矩阵组装成完整的图。因为用到了所有的局部特征,所以叫全连接。】

    分布式特征表示:XR理解:数据间如何相互关联的信息。参考:
    https://blog.csdn.net/zkh880loLh3h21AJTH/article/details/80326188
    样本空间:所有可能存在的、合理的、情况的集合。参考:
    https://blog.csdn.net/csucsgoat/article/details/79598803)】

    在实际使用中,全连接层可以转化为卷积核为1x1的卷积
    https://www.cnblogs.com/ymjyqsx/p/9451739.html
    卷积层本来就是全连接的一种简化形式:不全连接+参数共享,把局部视野之外的弱影响直接抹为零影响,同时还保留了空间位置信息(卷积层不同位置的权值共享)。这样大大减少了参数并且使得训练变得可控。

    【1x1卷积层的作用: https://blog.csdn.net/junmuzi/article/details/78219336
    https://blog.csdn.net/chaipp0607/article/details/60868689
    1、降维(dimension reductionality )。比如,一张500 x 500且厚度depth为100的图片在20个filter上做1x1的卷积,那么结果的大小为500x500x20。降低通道数(厚度)而不改变图片长宽。
    2、加入非线性。卷积层之后经过激励层,1x1的卷积在前一层的学习表示上添加了非线性激励( non-linear activation),提升网络的表达能力。】

    卷积层与全连接层之间的过渡层(将多维输入一维化Flatten)。
    model.add(Flatten())将最后一个池化层的长宽厚进行展平输出向量,不影响批量大小,方便将该结果接入全连接层。
    为了提升 CNN网络性能,全连接层每个神经元的激励函数一般采用ReLU函数。最后一层全连接层的输出值被softmax逻辑回归(softmax regression)分类,这层也被称作softmax层。
    https://www.cnblogs.com/lc1217/p/7324935.html
    【搬运】卷积神经网络结构图:
    在这里插入图片描述

    https://blog.csdn.net/blateyang/article/details/79101339
    【搬运】关于深度学习中的Batch normalization的理解:
    BN的原理:
    批规范化(Batch normalization)是深度学习中经常见到的一种训练trick,指在采用梯度下降法训练DNN时,对网络层中每个mini-batch的数据进行归一化,使其均值变为0,方差变为1,其主要作用是缓解DNN训练中的梯度消失/爆炸现象,加快模型的训练速度。
    BN的好处和原因:

    1. 允许较大的学习率,加快模型收敛速度
    2. 避免深层网络的梯度消失或爆炸问题
    3. 减少对参数初始化方法的依赖

    BN使用的注意点
    是沿着数据的batch size方向做规范化。对于二维张量形式的数据X(N,D),即沿着dim=0方向计算均值和方差;对于四维张量形式的图像数据X(N,C,H,W),把它reshape成X(NHW,C),再沿着dim=0方向计算均值和方差,计算完之后再reshape回去,此时叫做Spatial BN。
    测试阶段BN的均值和方差不再是基于batch计算的,而是使用固定的统计参数(根据训练阶段各mini-batch计算出的均值和方差得到,详见原论文(上面链接中))

    https://www.cnblogs.com/paulonetwo/p/10078961.html
    BatchNormalization使用:

    model.add(Conv2D(16, (3, 3), strides=(1, 1), padding='valid'))
    model.add(MaxPooling2D((2, 2)))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    

    https://www.cnblogs.com/skyfsm/p/8453498.html
    BN在深层神经网络的作用非常明显:若神经网络训练时遇到收敛速度较慢,或者“梯度爆炸”等无法训练的情况发生时都可以尝试用BN来解决。同时,常规使用情况下同样可以加入BN来加速模型训练,甚至提升模型精度。

    ——————————————————————————

    CNN 网络参数数量的计算:

    XR代码与运行结果:(#后面是注释)

    from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D
    from keras.layers import Dropout, Flatten, Dense
    from keras.models import Sequential
    
    model = Sequential()
    
    model.add(Conv2D(filters=16,#输出的维度Output Shape在这里插入代码片的最后一个维度的值
                     kernel_size=2, strides=1, padding='valid', #卷积核滤波器的高和宽的值均为2 #移动步幅为1 #valid 丢弃,same补零
                     activation='relu',#如果未指定任何值,则不应用任何激活函数
                     input_shape=(224, 224, 3))) #之前加载RGB图像过后缩放为 224×224 的图像,有3个通道(转化张量格式)    
                     #卷积层中的参数数量Param = (过滤器数量 * 过滤器高度 * 过滤器宽度 * 上一层深度即上一层过滤器数量)+ 过滤器数量
                     #      = (过滤器数量 * 每个过滤器的权重数量) + 过滤器数量
                     #      = (卷积层的权重总数) + 过滤器数量
                     #      = (卷积层的权重总数) + 每个过滤器有 1 个偏差项因此卷积层*共有过滤器数量个偏差
                     #      = (每个过滤器的偏差项 1+ 上一层过滤器的权重数量)* 这一层过滤器数量
                     #      = (16 * 2 * 2 * 3)+16 = 208
    model.add(MaxPooling2D(pool_size=2))
                     #池化层的输出: ((输入进的卷积层高度-池化窗口高度+1)/步幅长度) * ((输入进的卷积层宽度-池化窗口宽度+1)/步幅长度) ,输出的最后一个维度(厚度)等于经过上一层卷积滤波器后输入进池化层的数量
                     #如果padding='same',那时池化层的输出:((输入进的卷积层高度)/步幅长度) * ((输入进的卷积层宽度)/步幅长度) 
    model.add(Conv2D(filters=32,
                     kernel_size=2, strides=1, padding='valid',
                     activation='relu',
                    ) )
    model.add(MaxPooling2D(pool_size=2))
    model.add(Conv2D(filters=64,
                     kernel_size=2, strides=1, padding='valid',
                     activation='relu',
                    ) )
    model.add(MaxPooling2D(pool_size=2))
    model.add(GlobalAveragePooling2D(data_format='channels_last'))#缩小的因子(dim1,dim2)只有图像的长和宽,因此该空间数据的全局最大池操作是二维
    model.add(Dense(133, activation='softmax'))
    #Total params: 19,189 = 208+2080+8256+8645
    model.summary()
    

    在这里插入图片描述

    #卷积层中的参数数量Param = (过滤器数量 x 过滤器高度 x 过滤器宽度 x 上一层深度即上一层过滤器数量)+ 过滤器数量
    # = (过滤器数量 x 每个过滤器的权重数量) + 过滤器数量
    # = (卷积层的权重总数) + 过滤器数量
    # = (卷积层的权重总数) + 每个过滤器有 1 个偏差项因此卷积层 x 共有过滤器数量个偏差
    # = (每个过滤器的偏差项 1+ 上一层过滤器的权重数量) x(连接至) 这一层过滤器数量 【XR理解】

    不同基本CNN结构原理:http://cs231n.github.io/convolutional-networks/#architectures

    【搬运】
    最常见的ConvNet架构遵

    循以下模式:

    INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC

    其中,*表示重复,POOL?表示可选的池层。而且,N >= 0(通常N <= 3)M >= 0,K >= 0(和通常K < 3)。例如,以下是您可能会看到的一些常见的ConvNet架构,遵循以下模式:

    INPUT -> FC,实现线性分类器。在这里N = M = K = 0。
    INPUT -> CONV -> RELU -> FC
    INPUT -> [CONV -> RELU -> POOL]*2 -> FC -> RELU ->FC。
    在这里,我们看到每个POOL层之间都有一个CONV层。
    INPUT -> [CONV -> RELU -> CONV -> RELU -> POOL]*3 -> [FC -> RELU]*2 -> FC
    在这里,我们看到在每个POOL层之前堆叠了两个CONV层。对于更大更深的网络而言,这通常是一个好主意,因为多个堆叠的CONV层可以在破坏性池化操作之前开发输入卷的更复杂的特征。
    优选将一叠小滤波器CONV连接到一个大的感受野CONV层。

    改进点:1 Batch normalization layer用来解决Covariate Shift的问题
    2 Dropout layer用来降低模型复杂度,增强模型的泛化能力,防止过拟合,顺带降低了运算量

    展开全文
  • Pytorch深度学习(4) — BN层及ResNet + DenseNet实现1....1.批量归一化(BN) ...nn.BatchNorm1d(120) – 全连接层使用,超参数为输出单元个数 2.ResNet 2.1 残差块 输入为X + Y,因而X Y的输出通道要一致 可以用1*1
  • 1.批量归一化(BN)nn.BatchNorm2d(6) — 卷积层使用,超参数为输出通道数nn.BatchNorm1d(120) – 全连接使用,超参数为输出单元个数2.ResNet2.1 残差块输入为X + Y,因而X Y的输出通道要一致可以用1*1的卷积层来...

    1.批量归一化(BN)

    nn.BatchNorm2d(6) — 卷积层使用,超参数为输出通道数

    nn.BatchNorm1d(120) – 全连接层使用,超参数为输出单元个数

    2.ResNet

    2.1 残差块

    输入为X + Y,因而X Y的输出通道要一致

    可以用1*1的卷积层来调整通道的大小

    c4e2af1fad7baa821a902504e23cbb7e.png

    class Residual(nn.Module):

    #可以设定输出通道数、是否使用额外的1x1卷积层来修改通道数以及卷积层的步幅。

    def __init__(self, in_channels, out_channels, use_1x1conv=False, stride=1):

    super(Residual, self).__init__()

    self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1, stride=stride)

    self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1)

    if use_1x1conv:

    self.conv3 = nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride)

    else:

    self.conv3 = None

    self.bn1 = nn.BatchNorm2d(out_channels)

    self.bn2 = nn.BatchNorm2d(out_channels)

    def forward(self, X):

    Y = F.relu(self.bn1(self.conv1(X)))

    Y = self.bn2(self.conv2(Y))

    if self.conv3:

    X = self.conv3(X)

    return F.relu(Y + X)

    2.2 ResNet 模型实现

    结构:

    卷积(64,7x7,3)

    批量一体化

    最大池化(3x3,2)

    残差块x4 (通过步幅为2的残差块在每个模块之间减小高和宽)

    全局平均池化

    全连接

    net = nn.Sequential(

    nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),

    nn.BatchNorm2d(64),

    nn.ReLU(),

    nn.MaxPool2d(kernel_size=3, stride=2, padding=1))

    def resnet_block(in_channels, out_channels, num_residuals, first_block=False):

    if first_block:

    assert in_channels == out_channels # 第一个模块的通道数同输入通道数一致

    blk = []

    for i in range(num_residuals):

    if i == 0 and not first_block:

    blk.append(Residual(in_channels, out_channels, use_1x1conv=True, stride=2))

    else:

    blk.append(Residual(out_channels, out_channels))

    return nn.Sequential(*blk)

    net.add_module("resnet_block1", resnet_block(64, 64, 2, first_block=True))

    net.add_module("resnet_block2", resnet_block(64, 128, 2))

    net.add_module("resnet_block3", resnet_block(128, 256, 2))

    net.add_module("resnet_block4", resnet_block(256, 512, 2))

    net.add_module("global_avg_pool", d2l.GlobalAvgPool2d()) # GlobalAvgPool2d的输出: (Batch, 512, 1, 1)

    net.add_module("fc", nn.Sequential(d2l.FlattenLayer(), nn.Linear(512, 10)))

    输入结构:

    X = torch.rand((1, 1, 224, 224))

    for name, layer in net.named_children():

    X = layer(X)

    print(name, ' output shape:\t', X.shape)

    0 output shape: torch.Size([1, 64, 112, 112])

    1 output shape: torch.Size([1, 64, 112, 112])

    2 output shape: torch.Size([1, 64, 112, 112])

    3 output shape: torch.Size([1, 64, 56, 56])

    resnet_block1 output shape: torch.Size([1, 64, 56, 56])

    resnet_block2 output shape: torch.Size([1, 128, 28, 28])

    resnet_block3 output shape: torch.Size([1, 256, 14, 14])

    resnet_block4 output shape: torch.Size([1, 512, 7, 7])

    global_avg_pool output shape: torch.Size([1, 512, 1, 1])

    fc output shape: torch.Size([1, 10])

    3.DenseNet 稠密连接网络

    主要由稠密层和过滤层组成

    稠密层:使X Y不必相加(输出通道一样),直接cat即可

    过滤层:防止相加之后的输出通道数过大

    0e5828f91d686115f8d16bfe05b4b660.png

    3.1 稠密块(DenseBlock)

    def conv_block(in_channels, out_channels): # 卷积层一套

    blk = nn.Sequential(nn.BatchNorm2d(in_channels),

    nn.ReLU(),

    nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1))

    return blk

    class DenseBlock(nn.Module):

    def __init__(self, num_convs, in_channels, out_channels):

    super(DenseBlock, self).__init__()

    net = []

    for i in range(num_convs):

    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 + num_convs * out_channels # 计算输出通道数

    def forward(self, X):

    for blk in self.net:

    Y = blk(X)

    X = torch.cat((X, Y), dim=1) # 在通道维上将输入和输出连结

    return X

    3.3 过滤层(transition_block)

    1*1卷积层:来减小通道数

    步幅为2的平均池化层:减半高和宽

    # 使得23的输出通道数变为10

    def transition_block(in_channels, out_channels):

    blk = nn.Sequential(

    nn.BatchNorm2d(in_channels),

    nn.ReLU(),

    nn.Conv2d(in_channels, out_channels, kernel_size=1),

    nn.AvgPool2d(kernel_size=2, stride=2))

    return blk

    blk = transition_block(23, 10)

    blk(Y).shape # torch.Size([4, 10, 4, 4])

    3.4 DenseNet模型总实现

    net = nn.Sequential(

    nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),

    nn.BatchNorm2d(64),

    nn.ReLU(),

    nn.MaxPool2d(kernel_size=3, stride=2, padding=1))

    num_channels, growth_rate = 64, 32 # num_channels为当前的通道数

    num_convs_in_dense_blocks = [4, 4, 4, 4]

    for i, num_convs in enumerate(num_convs_in_dense_blocks):

    DB = DenseBlock(num_convs, num_channels, growth_rate)

    net.add_module("DenseBlosk_%d" % i, DB)

    # 上一个稠密块的输出通道数

    num_channels = DB.out_channels

    # 在稠密块之间加入通道数减半的过渡层

    if i != len(num_convs_in_dense_blocks) - 1:

    net.add_module("transition_block_%d" % i, transition_block(num_channels, num_channels // 2))

    num_channels = num_channels // 2

    net.add_module("BN", nn.BatchNorm2d(num_channels))

    net.add_module("relu", nn.ReLU())

    net.add_module("global_avg_pool", d2l.GlobalAvgPool2d()) # GlobalAvgPool2d的输出: (Batch, num_channels, 1, 1)

    net.add_module("fc", nn.Sequential(d2l.FlattenLayer(), nn.Linear(num_channels, 10)))

    输出结构:

    be58af75085e40744a64f76ac14402be.png

    X = torch.rand((1, 1, 96, 96))

    for name, layer in net.named_children():

    X = layer(X)

    print(name, ' output shape:\t', X.shape)

    0 output shape: torch.Size([1, 64, 48, 48])

    1 output shape: torch.Size([1, 64, 48, 48])

    2 output shape: torch.Size([1, 64, 48, 48])

    3 output shape: torch.Size([1, 64, 24, 24])

    DenseBlosk_0 output shape: torch.Size([1, 192, 24, 24])

    transition_block_0 output shape: torch.Size([1, 96, 12, 12])

    DenseBlosk_1 output shape: torch.Size([1, 224, 12, 12])

    transition_block_1 output shape: torch.Size([1, 112, 6, 6])

    DenseBlosk_2 output shape: torch.Size([1, 240, 6, 6])

    transition_block_2 output shape: torch.Size([1, 120, 3, 3])

    DenseBlosk_3 output shape: torch.Size([1, 248, 3, 3])

    BN output shape: torch.Size([1, 248, 3, 3])

    relu output shape: torch.Size([1, 248, 3, 3])

    global_avg_pool output shape: torch.Size([1, 248, 1, 1])

    fc output shape: torch.Size([1, 10])

    展开全文
  • 一、BN的作用   原因:当网络很深的时候,如果初始输入数据...注:不管有多少个样本,一个样本有多少个特征维度(特征图个数)。BN都是在相同的特征维度上进行计算均值、方差、γ和β。 四个重要参数: weigh

    一、BN的作用

      原因:当网络很深的时候,如果初始输入数据很小,比如介于[0, 1],前向传播时,会导致数据越来越小,最后导致数据趋向于0。导致反向传播时,梯度可能会消失,使模型无法训练。如果输入数据很大时,前向传播使数据越来越大,反向传播求梯度时,梯度可能会爆炸,同样不利于训练。

    二、BN优点

    在这里插入图片描述

    三、BN算法

    在这里插入图片描述

    四、PyTorch的BN

    在这里插入图片描述
    注:不管有多少个样本,一个样本有多少个特征维度(特征图个数)。BN都是在相同的特征维度上进行计算均值、方差、γ和β。
    在这里插入图片描述
    四个重要参数

    weight: 用于保存模型表达能力的γ
    bias:用于保存模型表达能力的β
    running_mean:特征维度对应的均值
    running_std:特征维度对应的方差
    

    五、验证代码

    # -*- coding: utf-8 -*-
    """
    @file name      : bn_in_123_dim.py
    @author         : QuZhang
    @date           : 2021-1-1 20:51
    @brief          : bn的三种维度函数
    """
    from tools.common_tools import set_seed
    import torch
    import torch.nn as nn
    
    
    set_seed(1)
    
    if __name__ == "__main__":
        # ---------------- nn.BatchNorm1d ------------
        # 一维的BN层:特征里最小的特征单元是1维
        # flag = True
        flag = False
        if flag:
            batch_size = 3  # 3个样本
            num_features = 5  # 5个特征维度
            momentum = 0.1  # 用于加权平均
    
            features_shape = (1)
    
            # 1D : 一个样本,一个特征维度
            feature_map = torch.ones(features_shape)  # 最小的特征单元
            # print("feature_map: ", feature_map.shape)
    
            # 2D : 一个样本,多个特征维度
            # 在第一个维度进行扩展
            feature_maps = torch.stack([feature_map*(i+1) for i in range(num_features)], dim=0)  # (扩展后的值,扩展的维度)
            # print("feature_maps: ", feature_maps)
    
            # 3D : 多个样本,多个特征维度
            feature_maps_bs = torch.stack([feature_maps for i in range(batch_size)], dim=0)  # 批量的数据
            print("input data:\n{} shape is: {}".format(feature_maps_bs, feature_maps_bs.shape))
    
            bn = nn.BatchNorm1d(num_features=num_features, momentum=momentum)
    
            running_mean, running_var = 0, 1  # 初始化上一次的均值和方差
    
            for i in range(2):
    
                outputs = bn(feature_maps_bs)
                # 使用BN计算所有特征维度的均值和方差
                print("\niteration: {}, running mean: {}".format(i, bn.running_mean))
                print("iteration: {}, running var: {}".format(i, bn.running_var))
    
                # 手动计算第二个特征维度的均值和方差
                mean_t, var_t = 2, 0  # 当前均值和方差
                # 用当前均值和方差与之前的均值和方差指数加权平均得到新的方差和均值
                running_mean = (1-momentum) * running_mean + momentum * mean_t
                running_var = (1-momentum) * running_var + momentum * var_t
                print("iteration:{}, 第二个特征的running mean: {} ".format(i, running_mean))
                print("iteration:{}, 第二个特征的running var:{}".format(i, running_var))
    
                print("outputs:\n", outputs.data)
    
        # ---------------- nn.BatchNorm2d --------------
        # 二维的BN层:特征里最小的特征单元是2维
        flag = True
        if flag:
            batch_size = 3
            num_features = 6  # 特征维度数
            momentum = 0.1
    
            features_shape = (2, 2)  # 一个特征维度里的数据是2D
            feature_map = torch.ones(features_shape)  # 最小的特征单元 2D
            feature_maps = torch.stack([feature_map*(i+1) for i in range(num_features)], dim=0)
            feature_maps_bs = torch.stack([feature_maps for i in range(batch_size)], dim=0)
    
            print("input data:\n{} shape is {}".format(feature_maps_bs, feature_maps_bs.shape))
    
            bn = nn.BatchNorm2d(num_features=num_features, momentum=momentum)
            running_mean, running_var = 0, 1
    
            for i in range(2):
                outputs = bn(feature_maps_bs)
    
                # 验证BN在同一维度上计算
                print("\niter:{}, running_mean.shape: {}".format(i, bn.running_mean.shape))
                print("iter:{}, running_var.shape: {}".format(i, bn.running_var.shape))
    
                print("\niter:{}, weight.shape: {}".format(i, bn.weight.shape))
                print("iter:{}, bias.shape: {}".format(i, bn.bias.shape))
    
    
    展开全文
  • 所以还想继续改进一下模型,一开始想的是使用修改超参数,以及加入随机失活,bn层,应用了数据增强。先说一下超参数的改变:更改过滤器的数量,更改batch_size,应用了学习率退火。更改过滤器的数量改动:应用了自己...

    一开始使用的是alexnet模型,最好达到了99.271的成绩。在成绩榜上大概应在20%左右。所以还想继续改进一下模型,一开始想的是使用修改超参数,以及加入随机失活,bn层,应用了数据增强。先说一下超参数的改变:更改过滤器的数量,更改batch_size,应用了学习率退火。

    更改过滤器的数量

    改动:应用了自己上一个笔记中讲的模型,更改了第一个第二个的卷积层的过滤器数量。
    结果:一个epoch的运行时间并没有太大的变化,最初的验证集的准确率有所升高,损失值有下降,但是最后提交的准确率也没有太大的变化。

    更改batch_size

    改动:将batch_size从200降到了100。
    结果:一个epoch的运行时间快了一点。验证集的准确率最后提升了一点,但提交后的成绩反而下降了,可能是减少的batch_size不能更好的模拟完整的训练集。

    使用学习率退火

    一开始的学习率可能在起始时表现的很好,但在训练一段时间过后,可能一直达不到最优值,这时候就可以减少学习率来慢慢达到最优值。
    改动:

    learning_rate_reduction = ReduceLROnPlateau(monitor='val_loss', 
                                                patience=3, 
                                                verbose=1, 
                                                factor=0.5, 
                                                min_lr=0.00001)

    监督的值,过几个回合,乘以0.5,最小的学习率(keras中文文档)

    model.fit(train_images, train_labels, validation_data=(validation_images,      validation_labels), epochs=60, batch_size=100, verbose=2,callbacks=[learning_rate_reduction])

    这里应用了回调函数来使用学习率退火。
    结果:同上述参数改动一样,结果并没有什么太大的改变,但是在最后几次epoch中,确实都更要接近最优值,更稳定。

    小结

    我们通过几次参数的改变还有数据增强都没有使得最终的成绩有所提高,有些改变还使得成绩下降。所以猜测可能是模型不够复杂,不能够表达更复杂的式子,模型本身的性能,容量限制了它的提升。所以后来采用了更深的类VGG模型。

    更改网络结构

    改动:

        model.add(Convolution2D(filters = 32, kernel_size = (5,5),padding = 'Same', 
                     activation ='relu', input_shape = (28,28,1)))
        model.add(Convolution2D(filters = 32, kernel_size = (5,5),padding = 'Same', 
                     activation ='relu'))
        model.add(MaxPooling2D(pool_size=(2,2)))
        model.add(Dropout(0.25))
    
    
        model.add(Convolution2D(filters = 64, kernel_size = (3,3),padding = 'Same', 
                     activation ='relu'))
        model.add(Convolution2D(filters = 64, kernel_size = (3,3),padding = 'Same', 
                     activation ='relu'))
        model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2)))
        model.add(Dropout(0.25))
    
    
        model.add(Flatten())
        model.add(Dense(256, activation = "relu"))
        model.add(Dropout(0.5))
        model.add(Dense(10, activation = "softmax"))

    结果:运行一次epoch时间增加很多,成绩提升到了99.5左右。

    使用BN层

    改动:在每个卷积层使用BN。
    结果:发现模型收敛的更快,使用更少的步骤就能达到一样的准确率。但是可能对准确率很高的模型并没有太大的提升。

    使用dropout

    改动:在每个fc层加入dropout
    结果:最后的准确率有所提升。看来dropout还是能控制过拟合。

    使用数据增强

    在keras文档中,有对图片预处理的函数。利用一个图片迭代器。各参数都有介绍。
    数据增强:通过改变灰度,旋转等方法来使图片稍有不同,保持标签不同,这能有效的控制过拟合,提升模型的泛化能力。

    datagen = ImageDataGenerator(
            featurewise_center=False,  # set input mean to 0 over the dataset
            samplewise_center=False,  # set each sample mean to 0
            featurewise_std_normalization=False,  # divide inputs by std of the dataset
            samplewise_std_normalization=False,  # divide each input by its std
            zca_whitening=False,  # apply ZCA whitening
            rotation_range=10,  # randomly rotate images in the range (degrees, 0 to 180)
            zoom_range = 0.1, # Randomly zoom image 
            width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)
            height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)
            horizontal_flip=False,  # randomly flip images
            vertical_flip=False)  # randomly flip images

    使用了图片生成器在fit中要使用fit_generator。.flow()接收numpy数组和标签为参数,生成经过数据提升或标准化后的batch数据,并在一个无限循环中不断的返回batch数据.

    history = model.fit_generator(datagen.flow(train_images, train_labels, batch_size=86),
                                  epochs = 30, validation_data = (validation_images,validation_labels),
                                  verbose = 2, steps_per_epoch=train_images.shape[0] // 86
                                  , callbacks=[learning_rate_reduction])

    这里要注意的是,fit与fit_generator的区别。fit_generator里的一个epoch里包含的是steps_per_epoch * batch_size。steps_per_epoch应该等于你数据集的数量除以batch_size。
    结果:发现成绩大有提升!提升到了99.678。

    小结

    我们在想要改变参数时,首先要考虑的是整个网络结构。整个网络是不是性能足够,容量足够来通过改变参数得到更好的结果。所以现在的网络都是想要做的更深,因为更深的网络能过表达更复杂的式子,模型的容量更大。
    BN层能够加速模型的训练,收敛速度。并且不需要很仔细参数的初始化,还能使用更高的学习率。
    dropout能够很好地控制过拟合。
    数据增强很强大,增大训练集数量,提升模型的泛化能力。
    batch_size应该有一个比较合理的范围,不能盲目地增大,缩小。
    学习率退火有利于找到一个最优值。

    展开全文
  • 2.4BN与神经网络调优

    2020-03-29 15:41:01
    2.4.1神经网络调优 我们经常会涉及到参数的调优,也称之为超参数调优。... hiddenunits:各隐藏神经元个数 layers:神经网络数 2.4.1.1调参技巧 对于调参,通常采用跟机器学习中网格搜索...
  • BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)1.num_features:通常输入参数为batch_sizenum_featuresheight*width,即为其中特征的数量,即为输入BN层的通道;2.eps:分母...
  • 1.num_features:一般输入参数为batch_sizenum_featuresheight*width,即为其中特征的数量,即为输入BN层的通道; 2.eps:分母中添加的一值,目的是为了计算的稳定性,默认为:1e-5,避免分母为0; 3.momentum:...
  • BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)1.num_features:一般输入参数为batch_sizenum_featuresheight*width,即为其中特征的数量,即为输入BN层的通道;2.eps:分母...
  • Batch Normalization Batch Normalization的均值和方差对谁求...同样的,为了减少参数量, 一channel(相当于一种卷积核提取的同一种特征)只对应一组可学习的参数γ、β, 所以对于一层BN层, 可学习的参数为2*c. ...
  • 《动手学深度学习》课后习题3

    千次阅读 2020-02-24 14:52:52
    《动手学深度学习》学习网址: 《动手学》:批量归一化和残差网络 nn.BatchNorm2d(6)的含义是 答案:全连接层的批量归一化,...2.关于BN层描述错误的是 A. 卷积层的BN位于卷积计算之后,激活函数之前。 B. 拉伸参...
  • 在批标准化(BN)操作中,如果batch size大小为32,特征图深度为16,那么该BN层的总参数以及可训练参数个数分别是多少?该怎么计算?
  • 第五章 卷积神经网络

    2020-08-25 16:32:52
    1单选(2分) 已知两层3×3的卷积核与一层5×5的卷积核具有相同的感受野,那么前者...在批标准化(BN)操作中,如果batch size大小为32,特征图深度为16,那么该BN层的总参数以及可训练参数个数分别为: A.256,128
  • 文章目录为什么要使用BNBN的工作原理BN的优点PyTorch中使用BN层BN的弊端 为什么要使用BN 在深度学习中,层很多,可能有几十层甚至上百层,每次训练激活的过程中,参数不断改变,导致后续每一层输入的分布也发生...
  • pytorch之BatchNorm2d

    2020-12-07 23:39:25
    1.num_features:一般输入参数为batch_sizenum_featuresheight*width,即为其中特征的数量,即为输入BN层的通道; 2.eps:分母中添加的一值,目的是为了计算的稳定性,默认为:1e-5,避免分母为0; 3.momentum:...
  • 问题:计算每网络结构和输入输出尺寸和参数个数。不加BN?更深?每的尺寸变化?更多结构? def convolutional_neural_network(img): print('输入的shape:', img.shape) conv_pool_1 = ...
  • 原因1:梯度爆炸 产生原因:学习率过大。 解决方法: 3. 数据归一化(减均值,除...加如BN层进行归一化。 修改网络结构(如增加网络宽度、增加网络层)。 改变层的学习率,每层都可以设置学习率,可以尝试减小后面
  • 感谢上述 假设在卷积层有如下参数: 卷积权重: W, 卷积偏置: B ...假设在BN层有如下参数: 均值: mul; 方差:delta; 缩放因子:gama; 偏移:beta;一较小的(防止分母为0):epsilon ...
  • 神经网络实例Python

    千次阅读 2019-05-13 14:32:40
    本文采用一模拟数据集进行神经网络的训练,相关知识点包括数据预处理、BN层、神经网络模型、梯度反向传播、梯度检查、监测训练过程、超参数随机搜索等,使读者掌握一完整的机器学习流程。 1、生成数据 生成一...
  • 训练网络—train loss、test loss,accuracy从一开始就不变 ...但遇到这样一问题:把vgg_16bn参数全部打印处理,它有很多的w权重为接近0的特别小的,导致数据变化的程度不足以影响得到的结果。 **train ...
  • 最近在做深度学习实验,跑一次实验轻则以小时计、重则以天计,实在...数、每一卷积核个数、卷积权重初始化方式、dropout ratio、BN、全连接神经元个数、Relu等网络结构参数应该如何选? 学习率、decay等solve...
  • 卷积神经网络经验

    2017-12-10 16:18:00
    20卷积+20卷积+30卷积+10全连接 参数个数,因为后面全连接是相乘的关系,前面是相加的关系 2. BN层在LOSS 不怎么下降时可以起到奇效 3. 随着网络的加深,会出现梯度消失的情况,这就是不一定越深越好,这个时候...
  • 【要背住的知识】:用ReLU代替Sigmoid,用BN层,用残差结构解决梯度消失问题。梯度爆炸问题的话,可以用正则化来限制。sigmoid的导数是【0,0.25】. 出现原因 两者出现原因都是因为链式法则。当模型的层过多的时候...
  • 【要背住的知识】:用ReLU代替Sigmoid,用BN层,用残差结构解决梯度消失问题。梯度爆炸问题的话,可以用正则化来限制。sigmoid的导数是【0,0.25】. 1 出现原因 两者出现原因都是因为链式法则。当模型的层过多的...
  • 训练深层的神经网络非常困难,因为在训练的过程中,随着前面层数参数的改变,每输入的分布也会随之改变。这需要我们设置较小的学习率并且谨慎地对参数进行初始化,因此训练过程比较缓慢。 作者将这种现象称之为 ...
  • Batch Normalization

    2020-07-13 19:02:54
    BN是为了解决深度学习中的 Internal Covariate Shift 问题及其影响,ICS产生的原因是由于参数更新带来的网络中每一输入值分布的改变,并且随着网络层数的加深而变得更加严重,这就使得高层需要不断去重新适应底层...
  • Batch Normalization细节

    2019-02-21 13:50:37
    假设某一卷积层的输入为(m,f,w,h),其中m为batch size,f为通道数,即特征图个数,w,h分别为特征图的宽度和高度,实现BN时,把每个特征图当做一个神经元处理,因此对于每一个特征图都需要学习对应的参数:γ和β...
  • YOLOV3剪枝方法汇总

    千次阅读 2020-07-02 20:53:00
    给大家介绍了一下利用BN层的γ\gammaγ参数对YOLOV3检测模型进行剪枝,最终获得了2倍的速度增加。但需要注意的是,这剪枝有一些缺点,例如剪枝剪得不够极限,可能还有一些冗余通道存在,另外shortcut这种层也是...
  • 每次经过池化后特征图的尺寸缩小一倍,而通道增加一倍(除最后一池化)。 VGG摒弃了55的卷积层,而是采用了两33的卷积层进行堆叠。在保证相同感受野的情况下,降低了参数量,并且提升了网络的学习能力(多...

空空如也

空空如也

1 2
收藏数 37
精华内容 14
关键字:

bn层参数个数