卷积神经网络2

一、池化

池化是使用某一位置的相邻输出的总体统计特征代替网络在该位置的输出,其好处是当输入数据做出少量平移时,经过池化函数后的大多数输出还能保持不变。

 

  • 如图(a):平均池化。这里使用大小为2×22\times22×2的池化窗口,每次移动的步幅为2,对池化窗口覆盖区域内的像素取平均值,得到相应的输出特征图的像素值。
  • 如图(b):最大池化。对池化窗口覆盖区域内的像素取最大值,得到输出特征图的像素值。当池化窗口在图片上滑动时,会得到整张输出特征图。池化窗口的大小称为池化大小,用kh×kwk_h \times k_wkh​×kw​表示。在卷积神经网络中用的比较多的是窗口大小为2×22 \times 22×2,步幅为2的池化

二、ReLU激活函数

在神经网络发展的早期,Sigmoid函数用的比较多,而目前用的较多的激活函数是ReLU。这是因为Sigmoid函数在反向传播过程中,容易造成梯度的衰减。

sigmoid函数和relu函数的比较

#ReLU和sigmoid激活函数示意图
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
plt.figure(figsize=(10,5))

#创建数据x
x = np.arange(-10,10,0.1)

#计算sigmoid函数
s = 1.0/(1+np.exp(0. - x))

#计算ReLU函数
y = np.clip(x,a_min=0.,a_max=None)

#画图
f = plt.subplot(121)
plt.plot(x,s,color='r')
currentAxis=plt.gca()
plt.text(-9.0,0.9,r'$y=Sigmoid(x)$',fontsize=13)
currentAxis.xaxis.set_label_text('x',fontsize=15)
currentAxis.yaxis.set_label_text('y',fontsize=15)

f = plt.subplot(122)
plt.plot(x,y,color='r')
plt.text(-3.0,9,r'$y=ReLU(x)$',fontsize=13)
currentAxis=plt.gca()
currentAxis.xaxis.set_label_text('x',fontsize=15)
currentAxis.yaxis.set_label_text('y',fontsize=15)
plt.show()

 三、梯度消失现象

在神经网络里,将经过反向传播之后,梯度值衰减到接近于零的现象称作梯度消失现象。

由于最开始是将神经网络的参数随机初始化的,x的取值很有可能在很大或者很小的区域,这些地方都可能造成Sigmoid函数的导数接近于0,导致x的梯度接近于0;即使x取值在接近于0的地方,经过Sigmoid函数反向传播之后,x的梯度不超过y的梯度的1/4,如果有多层网络使用了Sigmoid激活函数,则比较靠后的那些层梯度将衰减到非常小的值。

ReLU函数则不同,虽然在x<0的地方,ReLU函数的导数为0。但是在x≥0的地方,ReLU函数的导数为1,能够将y的梯度完整的传递给x,而不会引起梯度消失。

四、批归一化(Batch Normalization)

BatchNorm主要思路是在训练时以mini-batch为单位,对神经元的数值进行归一化,使数据的分布满足均值为0,方差为1。

1、计算mini-batch内样本的均值                                                                                                     2、计算mini-batch内样本的方差                                                                                                        3、计算标准化之后的输出

案例1:

  • 当输入数据形状是[N,K][N, K][N,K]时,一般对应全连接层的输出,示例代码如下所示。

这种情况下会分别对K的每一个分量计算N个样本的均值和方差

# 输入数据形状是 [N, K]时的示例
import numpy as np
import paddle
from paddle.nn import BatchNorm1D
# 创建数据
data = np.array([[1,2,3],[4,5,6],[7,8,9]]).astype('float32')
# 使用BatchNorm1D计算归一化的输出
# 输入数据维度[N, K],num_features等于K
bn = BatchNorm1D(num_features=3)
x = paddle.to_tensor(data)
y = bn(x)
print(('output of BatchNorm1D Layer: \n {}'.format(y.numpy())))

# 使用Numpy计算均值、方差和归一化的输出
# 这里对第0个特征进行验证
a = np.array([1,4,7])
a_mean = a.mean()
a_std = a.std()
b = (a - a_mean) / a_std
print('std {}, \n output {}'.format(a_mean,a_std,b))

 案例二:

  • 当输入数据形状是[N,C,H,W][N, C, H, W][N,C,H,W]时, 一般对应卷积层的输出,这种情况下会沿着C这一维度进行展开,分别对每一个通道计算N个样本中总共N×H×W个像素点的均值和方差
  • # 输入数据形状是[N, C, H, W]时的batchnorm示例
    import numpy as np
    import paddle
    from paddle.nn import BatchNorm2D
    
    # 设置随机数种子,这样可以保证每次运行结果一致
    np.random.seed(100)
    # 创建数据
    data = np.random.rand(2,3,3,3).astype('float32')
    # 使用BatchNorm2D计算归一化的输出
    # 输入数据维度[N, C, H, W],num_features等于C
    bn = BatchNorm2D(num_features=3)
    x = paddle.to_tensor(data)
    y = bn(x)
    print('input of BatchNorm2D Layer: \n {}'.format(x.numpy()))
    print('output of BatchNorm2D Layer: \n {}'.format(y.numpy()))
    
    # 取出data中第0通道的数据,
    # 使用numpy计算均值、方差及归一化的输出
    a = data[:,0,:,:]
    a_mean = a.mean()
    a_std = a.std()
    b = (a - a_mean) / a_std
    print('channel 0 of input data: \n {}'.format(a))
    print('std {}, mean {}, \n output: \n {}'.format(a_mean,a_std,b))

 五、丢弃法

丢弃法(Dropout)是深度学习中一种常用的抑制过拟合的方法,其做法是在神经网络学习过程中,随机删除一部分神经元。训练时,随机选出一部分神经元,将其输出设置为0,这些神经元将不对外传递信号。

  • downscale_in_infer

训练时以比例rrr随机丢弃一部分神经元,不向后传递它们的信号;预测时向后传递所有神经元的信号,但是将每个神经元上的数值乘以 (1−r)。

  • upscale_in_train

训练时以比例rrr随机丢弃一部分神经元,不向后传递它们的信号,但是将那些被保留的神经元上的数值除以 (1−r);预测时向后传递所有神经元的信号,不做任何处理。

# dropout操作
import paddle
import numpy as np

np.random.seed(100)
data1 = np.random.rand(2,3,3,3).astype('float32')
data2 = np.arange(1,13).reshape([-1,3]).astype('float32')
x1 = paddle.to_tensor(data1)
# downgrade_in_infer模式下
drop11 = paddle.nn.Dropout(p = 0.5,mode='downscale_in_infer')
droped_train11 = drop11(x1)
# 切换到eval模式。在动态图模式下,使用eval()切换到求值模式,该模式禁用了dropout。
drop11.eval()
droped_eval11 = drop11(x1)
# upscale_in_train模式下
drop12 = paddle.nn.Dropout(p = 0.5,mode='upscale_in_train')
droped_train12 = drop12(x1)
# 切换到eval模式
drop12.eval()
droped_eval12 = drop12(x1)

x2 = paddle.to_tensor(data2)
drop21 = paddle.nn.Dropout(p = 0.5,mode='downscale_in_infer')
droped_train21 = drop21(x2)

drop21.eval()
droped_eval21 = drop21(x2)
drop22 = paddle.nn.Dropout(p = 0.5,mode='upscale_in_train')
droped_train22 = drop22(x2)

drop22.eval()
droped_eval22 = drop22(x2)

print('x1 {}, \n droped_train11 \n {}, \n droped_eval11 \n {}'.format(data1,droped_train11.numpy(),droped_eval11.numpy()))
print('x1 {}, \n droped_train12 \n {}, \n droped_eval12 \n {}'.format(data1,droped_train12.numpy(),droped_eval12.numpy()))
print('x2 {}, \n droped_train21 \n {}, \n droped_eval21 \n {}'.format(data2,droped_train21.numpy(),droped_eval21.numpy()))
print('x2 {}, \n droped_train22 \n {}, \n droped_eval22 \n {}'.format(data2,droped_train22.numpy(),droped_eval22.numpy()))

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值