赞
踩
最近在自学深度学习,由于之前有一些不采用机器学习的图像处理经验,现在说说自己对深度学习的一点理解。
池化层分为平均池化和最大池化,意为当输入数据做出少量平移时,经过池化函数后的大多数输出还能保持不变。
个人认为所谓平均池化很类似图像处理中的均值滤波。都是取卷积核内部的平均值作为特征图的输出。而最大池化个人感觉类似中值滤波,只不过将滤波器的中值部分换为了最大值部分。
现在有疑问,如果我的上述感觉是正确的那为什么要区分卷积层与池化层呢?感觉池化层就是一个已经确定好权重的卷积操作。
在pytorch搭建起网络时,大家通常都使用已有的框架进行训练,在网络中使用最多就是卷积操作,最熟悉不过的就是:torch.nn.conv2Dpytorch封装在torch.nn里的Conv2d非常好用,然而其卷积核的权重都是需要学习的参数,如果想要自定义一个卷积核(比如高斯核)来提取图像特征,conv2d就不适用了。
而解决方案如下:
pytorch自带的卷积操作:torch.nn.functional.conv2d()
这个卷积核与nn.Conv2d不同,它的weight可以自己设定。好处是,你既可以把各项参数写死在里面,不让它求导,也可以当成可学习参数,反向传播有pytorch来自动实现;并且,由于这是pytorch自带的,在训练中也不需要我们去考虑batch维度,数据格式采用torch tensor,方便得很。还有一个好处是,它可以像普通cnn的卷积核一样操作,有4个维度,分别是输出通道,输入通道,卷积核高,卷积核宽,这样可以很方便地把自定义的卷积核写成一个卷积层。具体操作为:
nn.functinoal.conv2d(inputs, weight, bias, padding=1)
而PaddlePaddle没有类似功能,希望可以以后加入
class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() self.conv_1_weight = nn.Parameter(torch.randn(16, 1, 5, 5)) self.bias_1_weight = nn.Parameter(torch.randn(16)) self.conv_2_weight = nn.Parameter(torch.randn(32, 16, 5, 5)) self.bias_2_weight = nn.Parameter(torch.randn(32)) self.linear_weight = nn.Parameter(torch.randn(4 * 4 * 32, 10)) self.bias_weight = nn.Parameter(torch.randn(10)) def forward(self, x): x = x.view(x.size(0), -1) out = F.conv2d(x, self.conv_1_weight, self.bias_1_weight) out = F.conv2d(out, self.conv_2_weight, self.bias_2_weight) out = F.linear(out.view(x.size(0), -1), self.linear_weight, self.bias_weight
以上为自定义卷积核操作
虽然paddlepaddle没有相关功能,不过我们可以利用opencv和numpy来进行自定义卷积核功能。比如在对图像进行边缘提取时,可以利用opencv中的Canny算子和Sobel算子进行边缘提取,之后将处理过的Mat转换为numpy中的数组之后送入神经网络中
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。