Torch.nn模块学习-卷积
原创
©著作权归作者所有:来自51CTO博客作者肆十二X的原创作品,请联系作者获取转载授权,否则将追究法律责任
Torch.nn模块学习
卷积层
卷积操作不是矩阵乘法,是哈达玛乘积,即原始图像的区域和卷积进行按元素相乘然后再求和。
Pytorch的nn模块中有针对一维数据、二维数据和三维数据的卷积操作和转置卷积操作,转置卷积操作可以理解为上采样,不过本次学习的目的以学习基础为主,主要学习卷积,常用的卷积操作如下:
对应的类
| 功能作用
|
.Conv1d()
| 在输入信号上应用1D卷积
|
.Conv2d()
| 在输入信号上应用2D卷积
|
.Conv3d()
| 在输入信号上应用3D卷积
|
.ConvTranspose1d()
| 在输入信号上应用1D转置卷积
|
.ConvTranspose2d()
| 在输入信号上应用2D转置卷积
|
.ConvTranspose3d()
| 在输入信号上应用3D转置卷积
|
以torch.nn.Conv2d()为例,介绍卷积在图像上的使用方法,调用方式为:
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
参数说明如下:
in_channels: 整数,输入图像的通道数,比如说对于彩色图像而言通道数为3
out_channels: 整数,经过卷积运算之后,输出图像的通道数
kernel_size:整数或者数组,卷积核的大小
stride:整数或者数组,如果是数组表示横向和纵向的移动不同,卷积的步长,默认为1
padding: 整数或者数组,在输入的图像周围进行0填充的数量,主要是为了防止边缘信息的丢失
dilation: 整数,卷积核元素之间的步幅,这个参数可以用于设置空洞卷积,在小物体检测中有用到
groups: 整数,从输入通道到输出通道的阻塞连接数
bias: 布尔值,如果bias=True,则添加偏置,默认为True
输入: (N,C-in, H-in, W-in)
输出:(N,C-out,H-out,W-out)
经过卷积计算的转化公式是下面所示, 这里是向下取整:
代码展示:
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
# 读取图片转化为灰度图,并转化为numpy数组
img = Image.open("imgs/lufei.jpg")
img_gray = np.array(img.convert("L"), dtype=np.float32)
plt.figure(figsize=(6, 6))
plt.imshow(img_gray, cmap=plt.cm.gray)
plt.axis("off")
plt.show()
# 将数组转化为张量
imh, imw = img_gray.shape
img_tensor = torch.from_numpy(img_gray.reshape(1, 1, imh, imw))
# 使用5*5的随机数构成的卷积核进行卷积操作
# 这里的卷积核是个比较神奇的卷积核,中间的数值比较大,两边的数值比较小
kernel_size = 5
kernel = torch.ones(kernel_size, kernel_size, dtype=torch.float32) * -1
kernel[2, 2] = 24
kernel = kernel.reshape((1, 1, kernel_size, kernel_size))
# 进行卷积操作
conv2d = nn.Conv2d(1, 2, (kernel_size, kernel_size), bias=False)
conv2d.weight.data[0] = kernel
imgconv2dout = conv2d(img_tensor)
# 进行维度的压缩,这样图像才能展示出来
imgconv2dout_img = imgconv2dout.data.squeeze()
print("卷积之后的尺寸为:{}".format(imgconv2dout_img.shape))
# 这个卷积核用了weight来进行表示,说明模型训练的目的也在于此
# 如果没有进行指明的话,卷积核是会使用随机数的
# 展示这两张图片
plt.figure(figsize=(12, 6))
plt.subplot(1,2,1)
plt.imshow(imgconv2dout_img[0], cmap=plt.cm.gray)
plt.axis("off")
plt.figure(figsize=(12, 6))
plt.subplot(1,2,2)
plt.imshow(imgconv2dout_img[1], cmap=plt.cm.gray)
plt.axis("off")
plt.show()
下面分别是原图、边缘化卷积核处理之后的图和随机处理之后的图