文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
反卷积层实现
为了了解卷积操作,我们需要首先了解中间层的特征激活值。我们使用了一种新的方式将这些激活值映射回输入像素空间,表明了什么样的输入模式将会导致 feature map 中一个给定的激活值。我们使用反卷积网络来完成映射。一个反卷积网络可以被看成是一个卷积模型,这个模型使用和卷积同样的组件(过滤和池化),但是却是相反的过程,因此是将特征映射到像素。在中,反卷积网络被提出作为一种进行非监督学习的方法,但是在这里,它没有学习能力,仅仅用来探测一个已经训练好的卷积神经网络。
- 获取对应卷积层的参数(卷积核)shape 为(NCHW),并且将卷积核转置(NCHW-->NCWH),也就是高和宽互换,原理请参考神经网络的反向传播
- 使用
fluid.dygraph.Conv2DTranspose()
动态图 API 创建反卷积层,并且用获得参数初始 - 进行反卷积
特征图的可视化
一般的 RGB 图像像素取值范围为 0-255,但在网络中的数据不一定会在这个范围内,它可能更接近(-1, 1)、(-10, 10)…
所以我们需要编写一个函数,使其可以拉伸图像像素取值范围,尽可能接近 0-255 取值范围。 我们要处理一个取值在未知范围的数组,其 shape 为 C, H, W(一般 2D 卷积后的特征图像格式为 NCHW,N 代表 Batch Size,C 为通道数/卷积的 num_filters,H 和 W 则为长宽,这里我们取单批数据) 获取这个数组的取值范围并设计算法进行拉伸 假定取值范围在(-1, 4),我们要将其等比例变成(0, 255) 取值范围 算法部分可以用一张图来解释
这是单通道的像素拉伸,在“猫十二分类”中,这里的单通道特征图像可能会是一只猫耳朵、一个猫爪…
- 将 single_featuremap_display 设置为 True,则可以显示指定数目的单通道特征图
- 将 single_featuremap_display 设置为 False,则会将指定数目的特征图进行通道合并,显示的是一张融合特征图
实现代码如下:
#猫十二分类(动态图)
#导入需要的包
import os,sys,time
import paddle.fluid as fluid
import numpy as np
import cv2
import matplotlib.pylab as plt
from PIL import Image
#本次训练的参数
train_paramters={
'train_image_list':'train_list.txt', #训练数据的标注文件
'test_image_dir':'cat_12_test', #测试数据集
'batch_size':32, #批大小
'epoch_num':40,
'save_model_name':'Cat_2_classes12' #训练的轮数
}
#反卷积实现
class Reverse_Conv:
def __init__(self,layername,display_featuremaps_num,\
layer,num_channels,num_filters,filter_size,\
single_featuremap_display=False,stride=1,padding=1,act='relu'):
'''
layername:显示特征图时自定义的名称
display_featuremaps_num:要可视化的 featuremap 的数量
layer:卷积层对应的反卷积层
param:反卷积网络的参数
num_channels:通道数,比数据格式是 NCHW,那么 num_channels=C
filter_size,num_filters:反卷积 API 的参数
featuremaps:shape 为(featuremaps_num,H,W)
single_featuremap_display:是否显示每个 featuremap
'''
self.param = (np.transpose(layer.parameters()[0].numpy(),(0,1,3,2))) #获得对应层卷积参数,并且转置(NCHW-->NCWH)作为新参数
self.num_channels = num_channels
self.num_filters = num_filters
self.filter_size = filter_size
self.stride = stride
self.padding = padding
self.act = act
self.title = layername
self.featuremaps_num = display_featuremaps_num
self.single_featuremap_display = single_featuremap_display
def reverse_conv(self,rx):
'''
创建反卷积层
输入数据进行反卷积
rx:NCHW 格式的 featuremap
'''
reverse_conv = fluid.dygraph.Conv2DTranspose(num_channels=self.num_channels,num_filters=self.num_filters,\
filter_size=self.filter_size,stride=self.stride,padding=self.padding,act=self.act,\
param_attr=fluid.initializer.NumpyArrayInitializer(self.param))
rx=reverse_conv(rx)
if(self.featuremaps_num>0):
self.featuremaps = rx[0].numpy()
self.concat_featuremaps()
return rx
def fix_value(self,img_pixs):#像素拉伸
'''
img_pixs:featuremap 的像素矩阵
'''
pix_max=np.max(img_pixs)#取最大像素
pix_min=np.min(img_pixs)#取最小像素
pix_range=np.abs(pix_max)+np.abs(pix_min)#获取像素距离
if(pix_range==0): #如果所有值都是零则直接返回(下面不能除以零)
return img_pixs
pix_rate = 255/pix_range#获取像素缩放倍率
pix_left = pix_min*pix_rate#获取最小还原像素值
img_pixs = img_pixs*pix_rate-pix_left#整体像素值平移
img_pixs[np.where(img_pixs<0)]=0. #增加鲁棒性,检查超出区间的像素值,np.where(a<x) 与 a<x 等同
img_pixs[np.where(img_pixs>255)]=255.
return img_pixs
def concat_featuremaps(self):
'''
featuremaps 可视化
输入(CHW) 的特征图,使其显示
'''
count=0
for featuremap in self.featuremaps:
if count>self.featuremaps_num:#超过指定数量就结束
break
if count==0:
featuremap = self.fix_value(featuremap)#像素拉伸
total_featuremaps = featuremap
else:
featuremap = self.fix_value(featuremap)
total_featuremaps += featuremap #通道合并
count+=1
if(self.single_featuremap_display):#单独显示一张 featuremap
single_featuremap = Image.fromarray(np.asarray(featuremap).astype('uint8')).convert('RGB')
plt.imshow(single_featuremap)
plt.title('featuremap'+str(count)+' of '+self.title)
plt.show()
time.sleep(0.2)
total_featuremaps = self.fix_value(total_featuremaps) #再次矫正像素取值范围
total_featuremaps = Image.fromarray(np.asarray(total_featuremaps).astype('uint8')).convert('RGB')
plt.imshow(total_featuremaps)
plt.title('total_featuremap of '+self.title)
plt.show()
2020-07-28 11:12:35,653-INFO: font search path ['/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf', '/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/afm', '/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts']
2020-07-28 11:12:35,993-INFO: generated new fontManager
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论