CNN

1,为什么要做卷积操作  

    参数少一点,效果也很好,速度快,容易收敛。像下面这个图按10*10卷积后大小变成100*100,需要100个达到1M隐层,只需10M

的parameters

7,卷积方法
def conv2d(input, filter, strides, padding, use_cudnn_on_gpu=True, data_format="NHWC", name=None):
    input:输入的tensor对象,会对该值进行卷积操作。默认形状为:[batch_size, height, width, channels], batch_size表示一个批次中的样本数目,height表示一个feature map的高度,width表示一个feature map的宽度,channels表示一个图像的feature map的数量。一般简写为NHWC。当data_format的格式为NHWC的时候,使用默认的形状,如果给给data_format给定位NCHW,那么input的格式为:[batch_size, channels, height, width]
    filter: 卷积核Tensor对象(w),格式要求是一个4维的Tensor对象(一般为变量), 格式为: [height, width, in_channels, out_channels],height和width表示窗口的高度宽度,in_channels就是输入对象的通道数目,out_channels给定当前卷积之后的通道数目,也就是我们理论中所说的卷积核的数目。
    strides: 给定卷积窗口的滑动步长,格式和data_format有关,是一个数组。格式: [batch, in_height, in_width, in_channels]或者[batch, in_channels, in_height, in_width], 其中batch和in_channels必须为1,in_height和in_width分别给定在高度和宽度上的滑动窗口大小。
    padding:是否进行数据的填充操作,可选值:SAME表示进行最小填充,VALID表示不进行填充,直接删除多余的像素值。TensorFlow中有一个特征的值,当步长为1,padding为SAME的时候,卷积是不改变的feature map大小的。
    data_format:给定数据格式是NHWC还是NCHW,默认是NHWC

2,卷积核

28*28大小的feature map 有1024个神经元。1个feature map,1024个神经元。 每个神经元提取一个高阶特征

卷积核有大小,输入通道(channel),和输出通道数目(输出channel)

一个卷积核对应一个输出通道。卷积可以增加输出层次,用多个卷积核即可得到多个输出,比如vgg。1*1的卷积相当于合并所有输出featuremap 通道上对应位置的特征值。卷积就是各个通道的信息融合,做的是区域级的特征融合。

3,局部感知

      基于人脑的图片识别过程,我们可以认为图像的空间联系也是局部的像素联系比较紧密,而较远的像素相关性比较弱。所以每个神经元没有必要对全局图像进行感知,只要对局部进行感知,而在更高层次对局部的信息进行综合操作得出全局信息

4,神经网络参数

a,一般设置为均值为0,方差为2/n,n为权重数量,的高斯分布随机数列

b,归一化

5,BN理解

求均值,方差,归一化,e(epushion)防止标准差为0的情况,做一个保护,最后阿尔法和beta做一个缩放和移位

6,BN算法

 

BN一种方法时用tf.layers包下面的方法。一种是用tf.nn包的方法,如下面代码所示

n1 = tf.layers.batch_normalization(n1, training=is_training)
def batch_normalization(net, shape, is_training, moving_decay=0.9, eps=1e-8):
    with tf.variable_scope("BN"):
        # 缩放参数、平移参数y=gamma * x + beta
        gamma = tf.get_variable('gamma', shape=shape[-1],
                                initializer=tf.constant_initializer(1))
        beta = tf.get_variable('beta', shape=shape[-1],
                               initializer=tf.constant_initializer(0))

        # 计算当前批次的均值和标准差
        batch_mean, batch_variance = tf.nn.moments(net, axes=(0, 1, 2), keep_dims=True)

        # 采用滑动平均计算训练阶段中各个批次的的均值和方差的累加值
        # vmean = mean * decay + (1-decay) * batch_mean
        # variance = variance * decay + (1-decay) * batch_ariance
        ema = tf.train.ExponentialMovingAverage(decay=moving_decay)

        # 获取均值和方差
        def mean_and_variance_update():
            # apply就是触发更新操作
            ema_apply_op = ema.apply([batch_mean, batch_variance])
            with tf.control_dependencies([ema_apply_op]):
                # copy一份返回
                return tf.identity(batch_mean), tf.identity(batch_variance)

        mean, variance = tf.cond(is_training, mean_and_variance_update,
                                 lambda: (ema.average(batch_mean), ema.average(batch_variance)))

        # 执行批归一化操作
        return tf.nn.batch_normalization(net, mean, variance,
                                         offset=beta, scale=gamma, variance_epsilon=eps)

8,BN,LN,IN,GN

BN同一批次的所有样本拥有相同的方差和均值

LN 同层神经元输入拥有相同的均值和方差,针对一个样本计算均值和方差

IN 针对每个batch中的数据进行归一化操作。一个样本一个通道计算

GN 相较于BN,批次更小

在CNN中做BN的时候不是以神经元为单位,而是以feature map作为单位的。也就是针对一个批次中(一 个channel)的所有feature map计算一对参数γ、β。这样可以减 少模型参数的数目。

8,过拟合问题

通过加入L2正则和dropout

dropout加载FC1层和FC2层之间

l2_loss加在loss后面,重新赋值loss

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits))
# 获取所有参与模型训练的模型参数(也就是说这些参数会参与优化器的参数更新操作)
trainable_variables = tf.trainable_variables()
l2_loss = tf.constant(0.0, dtype=tf.float32, shape=[])
for variable in trainable_variables:
    l2_loss += tf.nn.l2_loss(variable)
    loss += regularization_rate * l2_loss

5,模型训练,构建优化器

Adam在深度学习模型中用来替代随机梯度下降

optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)  对应参数,自适应学习率

initializer=tf.random_normal_initializer(0, 0.001)会有比较好的收敛

admin算法:https://www.sohu.com/a/156495506_465975

6,学习率衰减

一种是使用tf.train里面的方法,有很多种类型的衰减

tf.train.polynomial_decay 多项式衰减

def fetch_learning_rate(base_learning_rate, step, step_size=100, gamma=0.9):
    """
    做一个学习率的衰减
    :param base_learning_rate:
    :param step:
    :param step_size:
    :param gamma:
    :return:
    """
    return base_learning_rate * gamma ** np.floor(step // step_size)
def f3():
    num_epoch = tf.Variable(0, name='epoch', trainable=False)
    assign_op = tf.assign_add(num_epoch, 1)
    base_learning_rate = 0.1
    decay_steps = 10
    with tf.control_dependencies([assign_op]):
        # decayed_learning_rate = learning_rate * exp(-decay_rate * global_step / decay_steps)
        # learning_rate:初始学习率
        # global_step:当前的训练批次
        # decay_steps:衰减周期(每隔多少批次衰减一次)
        # decay_rate: 衰减率系数
        # staircase:是否做阶梯型的衰减还是连续衰减,默认False为连续衰减
        learning_rate1 = tf.train.natural_exp_decay(
            learning_rate=base_learning_rate,
            global_step=num_epoch,
            decay_steps=decay_steps,
            decay_rate=0.9,
            staircase=False
        )
        learning_rate2 = tf.train.natural_exp_decay(
            learning_rate=base_learning_rate,
            global_step=num_epoch,
            decay_steps=decay_steps,
            decay_rate=0.9,
            staircase=True
        )

    N = 100
    y1 = []
    y2 = []
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        for epoch in range(N):
            lr1, lr2 = sess.run([learning_rate1, learning_rate2])
            y1.append(lr1)
            y2.append(lr2)

    plt.plot(y1, 'r-')
    plt.plot(y2, 'g-')
    plt.show()

7,数据增强的集中方式

水平翻转;随机裁剪;fancy PCA ;增加小众数据;其他平移,旋转,模糊处理,颜色饱和度亮度等处理

8,几种经典卷积神经网络

LeNet-5:

关键学习点,C3层卷积的变种

最终输出的16个fetaure map中,对应的前六个卷积核是和s2中输出的六个feature map中的任意3个feature map做卷积, 中间九个卷积核是和s2中输出的六个feature map中的任意4个feature map做卷积,最后一个卷积核是和六个feature map做卷积

AlexNet

引入局部相应归一化(通过公式可得出,抑制反馈较小的神经元)

对局部神经元的活动创建了竞争机制,使得其中响应比较大的值变得相对更大, 并抑制其它反馈较小的神经元,增强了模型的泛化能力。本质上,LRN是仿造生物学上活跃 的神经元对于相邻神经元的抑制现象(侧抑制)。

ZFNet

基于AlexNet,修改窗口大小,使用Relu激活函数和交叉熵损失函数

VGGNet

引入重复卷积

GoogleNet

引入NIN思想,Network-in-Network,用全连接的多层感知机去代替传统的卷积过程。

引入Inception结构,改变CNN串行结构,改成并行。使用平均池化代替FC层,参数量仅为AlexNet的1/12,用softmax获取平均结果,性能比AlexNet好

而1*1是做的像素级的特征融合,1*1不改变featruemap 大小的,改变通道数的数目,升维或降维。3*3步长为1的卷积也可不改变大小,填充即可

ResNet

引入残差结构,使用shortcut connection,保留了原始数据的特征。resnet主要缓解vgg模型退化问题,vgg在很深的模型上学到的东西太抽象,

DenseNet

在ResNet的基础上,连接更加密集。能缓解梯度消失问题,极大的减少参数量

SeNet

特征压缩。两个fc层,一个降维,一个升维。全连接降维,x=n*c  w=c*c/r  ,相乘及得到n*c/r,实现了降维,

Residual Attention Networks

基于下采样-上采样的机制, 将特征权重加入到特征图中。

MobileNet

引入depthwise separable convolutions(纵向可分离卷积),分解为深度卷积和点卷积。主要降低参数量和计算量。

relu6的理解。relu是在(x,0)之间取最大值max(x,0),relu6是在max(x,0)和6之间取最小值 min(max(x,0),6)

左边传统卷积;右边深度卷积,再做点卷积,用来做通道间的信息融合。

ShuffleNet

在做group convolution之前,先做一个channel的shuffle操作,以保障信息的表达能力

9,为什么输入数据需要归一化(Normalized Data)?

   归一化后有什么好处呢?原因在于神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对数据都要做一个归一化预处理的原因。

   对于深度网络的训练是一个复杂的过程,只要网络的前面几层发生微小的改变,那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变,那么这一层网络就需要去适应学习这个新的数据分布,所以如果训练过程中,训练数据的分布一直在发生变化,那么将会影响网络的训练速度。

10,rbf

from scipy.linalg import norm, pinv

def _basisfunc(self, c, d):
   return np.exp(-self.beta * norm(c - d) ** 2)

# 计算权重(pinv API:计算矩阵的逆) ==> Y=GW ==> W = G^-1Y
self.W = np.dot(pinv(G), Y)



centers = tf.get_variable(name='centers', shape=[rbf_hidden_units, 784], dtype=tf.float32)
gamma = tf.get_variable(name='gamma', shape=[rbf_hidden_units], dtype=tf.float32)

# 进行运行
# 0. RBF系数计算
gamma2 = 2.0 * tf.square(gamma)
# a. 将input_x转换为[None,1,784]的形状,数据不变
x = tf.expand_dims(input_x, axis=1)
# b. 将x进行数据的重复操作,因为每个样本都需要计算到所有中心点的距离
x = tf.tile(x, [1, rbf_hidden_units, 1])
# c. 计算所有样本到所有中心点的距离
dist = tf.reduce_sum(tf.square(x - centers), axis=2)
# d. 做一个sigma的转换
dist = -dist / gamma2
# c. 做一个exp指数转换,得到rbf的输出
rbf_output = tf.exp(dist)

10,初始化器

with tf.variable_scope('net', initializer=tf.random_normal_initializer(0.0, 0.001)):
    # 在variable_scope中如果给定了initializer初始化器,那么在使用tf.get_variable来构建变量的时        候,如果没有给定初始化器,那么使用variable_scope中定义的初始化器
   

11,训练好的模型mat下载

https://www.vlfeat.org/matconvnet/pretrained/

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值