池化对数据起到了浓缩的效果,通过池化可以减少数据量,降低内存压力,简单地理解,池化操作都是通过池化的kernel的选取一定的区域,通过某种计算将这个区域一系列数值转化为一个数值,需要注意的是:对于池化操作来说,池化的步长一般是卷积核大小。
该库提供了多种池化的类,最大池化、平均池化、最大自适应池化等操作。下面以二维数据处理为例子,列出常用的池化操作。
一个序列容器,用于搭建神经网络的模块,被按照被传入构造器的顺序添加到nn.Sequential()r容器中,除此之外,一个包含神经网络模块的OrderedDict也可以被传入nn.Sequential()容器中,利用nn.Sequential()搭建好的模型架构,模型前向传播时调用 f o r w a r d ( ) forward() forward()方法,模型接受的输入首先被传入的nn.Sequential()包含的第一个网络模块中,然后**,第一个网络模块输出传入到第二个网咯模块作为输入**。按照顺序依次计算并传播,直到nn.Sequential()里的最后一个模块输出结果。
按照上面说法,与一层一层的单独调用的模块组成的序列相比,
n n . S e q u e n t i a l ( ) nn.Sequential() nn.Sequential(),可以允许将整个容器视为单个模块,(相当于把多个模块封装成一个模块)forward()方法接收输入之后,
nn.Sequential(),按照内部模块的顺序自动依次计算并输出结果。
这意味着,我们可以利用其来自定义网络层。:
nn.Conv2d对有多个输入平面组成的输入信号进行二维卷积。
paddle.nn.BatchNorm2D(num_features, momentum=0.9, epsilon=1e-05, weight_attr=None, bias_attr=None, data_format='NCHW', name=None):
加速神经网络的收敛过程,以及提高训练过程中的稳定性。
通常用于解决多层神经网络中间层的协方差偏移问题。
使一批(Batch) feature map满足均值为0,方差为1的分布规律。这样不仅数据分布一致,而且避免发生梯度消失。
类似于网咯输入中进行零均值化和方差归一化操作。不过是在中间层输入中的操作而已。
作用:卷积之后会添加BatchNorm2d进行数据的归一化处理,着使得数据在进行Relu之前,不会因为数据过大而导致网络性能不稳定。
在mini-batch上计算维度,的均值和标准差,gamma和beta是可学习的参数向量,gamma默认设置为1,beta默认设置为0,其中,标准差是通过有偏估计来计算的。等同于:
torch.var(input,unbiased=False)
通常默认情况下,训练过程中的BatchNorm 层会保持对其计算的均值和方差的估计,然后再测试时候,使用这个均值和方差进行标准化。Running estimates保持默认动量为0.1 。
如果参数track_running_stats被设置为False,BatchNorm层将不会进行running estimates,Batch统计的均值和方差将会使用测试数据的均值和方差来代替。
BatchNorm中的momentum参数与优化器中的momentum和传统概念中的momentum不同。
在BatchNorm中,Running statistics的更新规则是:
R e L U ( x ) = m a x ( 0 , m a x ) ReLU(x)=max(0, max) ReLU(x)=max(0,max)
nn.ReLU()函数默认inplace 默认是False
# 这个类是是许多池化类的基类,这里有必要了解一下
class _MaxPoolNd(Module):
__constants__ = ['kernel_size', 'stride', 'padding', 'dilation',
'return_indices', 'ceil_mode']
return_indices: bool
ceil_mode: bool
# 构造函数,这里只需要了解这个初始化函数即可。
def __init__(self, kernel_size: _size_any_t, stride: Optional[_size_any_t] = None,
padding: _size_any_t = 0, dilation: _size_any_t = 1,
return_indices: bool = False, ceil_mode: bool = False) -> None:
super(_MaxPoolNd, self).__init__()
self.kernel_size = kernel_size
self.stride = stride if (stride is not None) else kernel_size
self.padding = padding
self.dilation = dilation
self.return_indices = return_indices
self.ceil_mode = ceil_mode
def extra_repr(self) -> str:
return 'kernel_size={kernel_size}, stride={stride}, padding={padding}' \
', dilation={dilation}, ceil_mode={ceil_mode}'.format(**self.__dict__)
class MaxPool2d(_MaxPoolNd):
kernel_size: _size_2_t
stride: _size_2_t
padding: _size_2_t
dilation: _size_2_t
def forward(self, input: Tensor) -> Tensor:
return F.max_pool2d(input, self.kernel_size, self.stride,
self.padding, self.dilation, self.ceil_mode,
self.return_indices)
先来看一下基本参数,一共六个:
这里的kernel_szie跟卷积核不是一个东西,kernel_size可以看作是一个滑动窗口,这个窗口的大小由自己定,如果输入的是单个值,例如3,那么窗口的大小都是 3 × 3 3 \times 3 3×3。还可以输入元组 ( 3 , 2 ) (3,2) (3,2),
那么窗口的大小都是 3 × 2 3 \times 2 3×2
最大池化的方法都是取这个窗口覆盖元素中的最大值。
上一个参数,我们确定了滑动窗口的大小,现在我们来确定这个窗口如何进行滑动的,如果不指定这个参数, 那么默认步长跟最大池化窗口一致,如果指定了参数,那么将按照我们指定的参数进行滑动。例如 s t r i d e = ( 2 , 3 ) stride =(2,3) stride=(2,3) 那么窗口将每次向右滑动3个窗口的位置**,或者向下滑动两个元素的位置,**。
这参数控制如何进行填充,填充值默认为0,如果是单个值,例如1,那么将在周围填充一圈0,还可以用元组指定如何填充,例如:
p a d d i n g = ( 2 , 1 ) padding = (2,1) padding=(2,1),表示再上下两个方向上填充两个0,在左右方向上各填充一个0.
这是个布尔类型值,表示返回值中是否包含最大值位置的索引。注意这个最大值指的是在所有窗口中产生的最大值,如果窗口产生的最大值总共有5个,就会有5个返回值。
这个也是布尔类型值,它决定的是在计算输出结果形状的时候,是使用向上取整还是向下取整。怎么计算输出形状,下面会讲到。一看就知道了。(向上取整,还是向下取整)
会自己根据项目进行各种参数的调节,会自己进行各种的调参以及计算都行啦的样子与打算,。