NOTE_北大Tensorflow_Chapter5

0.Attention

上一章用的 mnist 数据集是二值数据集。
本章用的 cifar10 数据集是彩色数据集。

1.知识点

1.1卷积神经网络

卷积神经网络
卷积就是特征提取,就是CBAPD。

from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout

为何使用卷积神经网络:为了减少待训练参数,先对原始图像进行特征提取,再把提取到的特征送入全连接网络。
步骤

1.1.1卷积核

1.1.1.1 感受野(receptive field)

定义:卷积神经网络各输出层每个像素点在原始图像上的映射区域大小。
使用:当我们采用尺寸不同的卷积核时,最大的区别就是感受野的大小不同,所以经常会采用多层小卷积核来替换一层大卷积核,在保持感受野相同的情况下减少参数量和计算量。
例如:十分常见的用 2 层 3 × \times × 3 卷积核来替换 1 层 5 × \times × 5 卷积核的方法。
receptive_field

1.1.1.2 Dropout

定义:在神经网络训练时,将一部分神经元按照一定概率从神经网络中暂时舍弃,从而减小对W权重的依赖,以达到减小过拟合的效果。神经网络使用时,被舍弃的神经元恢复链接。
注意:dropout只能用在训练中,测试的时候不能dropout,要用完整的网络测试。
大佬链接

1.1.1.3 全零填充(padding)

作用:为了保持输出图像尺寸与输入图像一致,经常会在输入图像周围进行全零填充,在 5 × \times × 5 的输入图像周围填 0,则输出特征尺寸同为 5 × \times × 5。

1.1.1.4 池化(Pooling)

作用:减少特征数据量(降维),减少计算量。

  1. 最大值池化可提取图片纹理。
  2. 均值池化可保留背景特征。
1.1.1.5 批标准化(BatchNormalization)

作用:

  1. 标准化:使数据符合0均值,1为标准差的分布。
  2. 批标准化:对一小批数据(batch),做标准化处理 。

使用位置:在卷积操作和激活操作之间。

1.1.1.6 激活(Activation)

作用:激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。
如果不用激活函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合,这种情况就是最原始的感知机(Perceptron)。

1.1.2 卷积核计算量

设:输入特征图的宽、高均为 x,卷积计算的步长为 1。

Kernel图像经卷积核后输出尺寸输出特征图像计算量卷积核参数计算量
2 个
3 × \times × 3
第一个 3 × \times × 3 卷积核输出特征图共有 ( x − 3 + 1 ) 2 (x-3+1)^2 (x3+1)2 个像素点,每个像素点需要进行 3 × \times × 3 = 9 次乘加运算,第二个 3 × \times × 3卷积核输出特征图共有 ( x − 3 + 1 − 3 + 1 ) 2 (x-3+1-3+1)^2 (x3+13+1)2 个像素点,每个像素点同样需要进行 9 次乘加运算。则总计算量为 9 × ( x – 3 + 1 ) 2 + 9 × ( x – 3 + 1 – 3 + 1 ) 2 9\times(x – 3 + 1)^2 + 9 \times(x – 3 + 1 – 3 + 1)^2 9×(x3+1)2+9×(x3+13+1)2 = 18 x 2 – 108 x + 180 18 x^2 – 108x + 180 18x2108x+1809 + 9 = 18
5 × \times × 5输出特征图共有 ( x − 5 + 1 ) 2 (x-5+1)^2 (x5+1)2 个像素点每个像素点需要进行 5 × \times × 5 = 25 次乘加运算,则总计算量为:25 × ( x − 5 + 1 ) 2 \times(x-5+1)^2 ×(x5+1)2 = 25 x 2 – 200 x + 400 25x^2 – 200x + 400 25x2200x+40025,上面的参数量更少。

1.2卷积核的理解

1 × \times × 1卷积操作可通过步长改变特征图尺寸,通过卷积核个数改特征图深度。


2.其他知识点

2.1 python类的使用

python类的使用

2.2 python len()

返回对象(字符, 列表, 元组)长度和项目个数。

2.3 ∗ * arg和 ∗ ∗ ** kwarg

∗ * arg和 ∗ ∗ ** kwarg的用法
∗ ∗ ** kwarg的用法
这只是编程人员约定的变量名字,args 是 arguments 的缩写,表示位置参数;kwargs 是 keyword arguments 的缩写,表示关键字参数。这其实就是 Python 中可变参数的两种形式,并且 ∗ * args 必须放在 ∗ ∗ ** kwargs 的前面,因为位置参数在关键字参数的前面。

2.4 python 括号作用

2.5 sigmoid和softmax

sigmoid和softmax的差别:
softmax函数:Normalized exponential function 归一化指数函数(归一化用),对于多分类任务时,只有一个正确答案。
sigmoid函数:sigmoid function s型函数(激活用),对于多分类任务时,有多个正确答案。
差别1
差别2

2.6 tensorflow使用GPU

首先确保已安装 TensorFlow GPU 版本。
tensorflow使用

控制gpu代码:

gpus = tf.config.experimental.list_physical_devices('GPU')
tf.config.experimental.set_virtual_device_configuration(
    gpus[0],
    [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=1024)])

2.7 经验

2.7.1

https://blog.csdn.net/weixin_43584807/article/details/103093874

# 控制输出的值的个数,np.inf只是为了保证这个阈值足够大,以至于所有长度的数组都能完整打印
np.set_printoptions(threshold=np.inf)

2.7.2

有时batch设置的过大(1024)可能会导致数据收敛的不好,相对batch=32就会大大改善情况,缺点是训练时间长一些。

3.顶会 Paper

neuron networkfeature
LeNet开篇之作,共享卷积核,减少网路参数。
AlexNet1.用 relu 激活函数,提升训练速度;
2.使用 Dropout 缓解过拟合。
VGGNet小尺寸卷积核减少参数,网络结构规整,适合并行加速。
Inception 10一层内使用不同尺寸卷积核,提升感知力使用批标准化防止梯度消失
ResNet层间残差跳连,引入前方信息,缓解模型退化,使模型网络层数加深成为可能

3.1 LeNet

CAP -> CAP -> FDDD

3.2 AlexNet

CBAP -> CBAP -> CA -> CA -> CAP -> FDDD

3.3 VGGNet

CBA -> CBAPD -> CBA -> CBAPD -> CBA -> CBA -> CBAPD -> CBA -> CBA -> CBAPD -> CBA -> CBA -> CBAPD -> FDDD

3.4 Inception 10:

3个class:
1.将C、B、 A 这3个操作在Sequential中合并简化后续步骤。
2.每个Inception Block组成一个class
3.将其合并成为真正的Inception10 class

class employee:
    perc_raise =1.05
    def __init__(self, first, last, sal):
    ##############################################################
    #注意:外部变量传入内部时,在内部创建相应的变量,方便后边相关函数调用
    ##############################################################
        self.fname=first
        self.lname=last
        self.sal=sal
        self.email=first + '.' + last + '@company.com'
 
    def fullname(self):
            return '{}{}'.format(self.fname,self.lname)
    def apply_raise(self):
        self.sal=int(self.sal*1.05)

3.5 ResNet

neuron networkValue
Inception struct block“+”是沿深度方向叠加(千层蛋糕层数叠加),四个并行子块的叠加。
ResNet struct block“+”是特征图对应元素值相加(矩阵值相加),卷积块和原始块对应数字相加。

双方加法位置及函数:

# 在倒数第二行
class InceptionBlk(Model):
    def __init__(self, ch, strides=1):
        super(InceptionBlk, self).__init__()
        self.ch = ch
        self.strides = strides
        self.c1 = ConvBNRelu(ch, kernelsz=1, strides=strides)
        self.c2_1 = ConvBNRelu(ch, kernelsz=1, strides=strides)
        self.c2_2 = ConvBNRelu(ch, kernelsz=3, strides=1)
        self.c3_1 = ConvBNRelu(ch, kernelsz=1, strides=strides)
        self.c3_2 = ConvBNRelu(ch, kernelsz=5, strides=1)
        self.p4_1 = MaxPool2D(3, strides=1, padding='same')
        self.c4_2 = ConvBNRelu(ch, kernelsz=1, strides=strides)

    def call(self, x):
        x1 = self.c1(x)
        x2_1 = self.c2_1(x)
        x2_2 = self.c2_2(x2_1)
        x3_1 = self.c3_1(x)
        x3_2 = self.c3_2(x3_1)
        x4_1 = self.p4_1(x)
        x4_2 = self.c4_2(x4_1)
        # concat along axis=channel
        x = tf.concat([x1, x2_2, x3_2, x4_2], axis=3)
        return x

# 在倒数第2行
class ResnetBlock(Model):

    def __init__(self, filters, strides=1, residual_path=False):
        super(ResnetBlock, self).__init__()
        self.filters = filters
        self.strides = strides
        self.residual_path = residual_path

        self.c1 = Conv2D(filters, (3, 3), strides=strides, padding='same', use_bias=False)
        self.b1 = BatchNormalization()
        self.a1 = Activation('relu')

        self.c2 = Conv2D(filters, (3, 3), strides=1, padding='same', use_bias=False)
        self.b2 = BatchNormalization()

        # residual_path为True时,对输入进行下采样,即用1x1的卷积核做卷积操作,保证x能和F(x)维度相同,顺利相加
        if residual_path:
            self.down_c1 = Conv2D(filters, (1, 1), strides=strides, padding='same', use_bias=False)
            self.down_b1 = BatchNormalization()
        
        self.a2 = Activation('relu')

    def call(self, inputs):
        residual = inputs  # residual等于输入值本身,即residual=x
        # 将输入通过卷积、BN层、激活层,计算F(x)
        x = self.c1(inputs)
        x = self.b1(x)
        x = self.a1(x)

        x = self.c2(x)
        y = self.b2(x)

        if self.residual_path:
            residual = self.down_c1(inputs)
            residual = self.down_b1(residual)

        out = self.a2(y + residual)  # 最后输出的是两部分的和,即F(x)+x或F(x)+Wx,再过激活函数
        return out

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值