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)

经过卷积计算的转化公式是下面所示, 这里是向下取整:
Torch.nn模块学习-卷积_卷积
代码展示:

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()

下面分别是原图、边缘化卷积核处理之后的图和随机处理之后的图

Torch.nn模块学习-卷积_卷积核_02

Torch.nn模块学习-卷积_卷积核_03

Torch.nn模块学习-卷积_卷积核_04