Environment
- OS: macOS Mojave
- Python version: 3.7
- PyTorch version: 1.4.0
- IDE: PyCharm
文章目录
0. 写在前面
PyTorch 主要是用 torch.nn
模块来构建神经网络,该模块包含以下几个内容
- 基本网络层,卷积、池化等,如
Conv2d
、ReLU
; functional
模块,函数的具体实现,如卷积、池化、激活函数等,Conv2d、ReLU 等类均为调用这里的函数;Container
类,模型容器,用于组装和管理网络的属性;Parameter
类,Tensor 的子类,用于表示可学习的参数;init
模块,一些初始化的方法。
搞一下 torch.nn
中提供的各种层,包括卷积层(卷积、转置卷积)、池化层(平均池化、最大池化、反池化)、全连接层、激活函数层。
这里主要记录对于二维的情况,以经典的 Lenna 图为例,尺寸 299 x 299 ,观察
- 卷积的输出
- 转置卷积的输出
- 最大池化的输出
- 平均池化的输出
- 去池化的输出
1. 卷积与转置卷积
1.1 卷积层
torch.nn.Conv2d
类,该类的实例对象能够对一个 batch 的二维 Tensor 进行卷积,要求输入的格式为 (B, C, H, W)。
卷积层输出与输入的尺寸关系,以高为例,宽同理
H o u t = ⌊ H i n + 2 × p a d d i n g [ 0 ] − d i l a t i o n [ 0 ] × ( k e r n e l _ s i z e [ 0 ] − 1 ) − 1 s t r i d e [ 0 ] + 1 ⌋ H_{out} = \lfloor \frac{H_{in} + 2 \times padding[0] - dilation[0] \times (kernel\_size[0] - 1) - 1}{stride[0]} + 1 \rfloor Hout=⌊stride[0]Hin+2×padding[0]−dilation[0]×(kernel_size[0]−1)−1+1⌋
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import torch
from torch.nn import Conv2d
from torchvision.transforms import ToTensor, ToPILImage
img_pil = Image.open('Lenna.jpg')
img_tensor = ToTensor()(img_pil) # (299, 299, 3) -> (3, 299, 299)
x = torch.unsqueeze(img_tensor, dim=0) # (3, 299, 299) -> (1, 3, 299, 299)
# 定义卷积层
conv_layer = Conv2d(
in_channels=3, # 输入通道数
out_channels=1, # 输出通道数,即卷积核的个数
kernel_size=3, # 卷积核的尺寸,传入整数表示高宽相同;若要不同可传入元组,表示卷积核的 (高, 宽)
stride=1, # 步长。同样可传入元组,表示高和宽方向上的分别步长
padding=0, # 边缘填充。同样可传入元组,表示高宽方向上分别填充的大小
dilation=1, # 空洞卷积大小,增大可以扩大感受野,常在图像分割任务中使用
groups=1, # 分组卷积
bias=True, # 是否设置偏置
padding_mode='zeros' # 填充的模式
)
# forward and visualization
sns.set_style('white')
plt.figure(figsize=(15, 15))
for i in range(4):
# 对图像执行卷积操作
torch.manual_seed(i)
torch.nn.init.xavier_normal_(conv_layer.weight.data) # 参数初始化
out = conv_layer(x) # 对图像进行卷积操作 size: (1, 1, 297, 297)
# 将 torch tensor 转换为 PIL Image 再转换为 numpy array
out_pil = ToPILImage()(out[0]) # (1, 297, 297) -> (297, 297, 1)
out_array = np.asarray(out_pil)
# visualization
plt.subplot(10, 10, i + 1)
plt.xticks([])
plt.yticks([])
plt.imshow(out_array, cmap='gray')
plt.show()
1.2 转置卷积层
torch.nn.ConvTranspose2d
类,该类的实例对象能够对一个 batch 的二维 Tensor 进行卷积,同样,要求输入的格式为 (B, C, H, W)。
转置卷积(Transposed Convolution),又称为反卷积(Deconvolution)或部分跨越卷积(Fractionally-strided Convolution),对图像进行上采样(upsampling)。为避免与信号处理中反卷积的概念混淆,深度学习中一般不建议称作"反卷积",而称为"转置卷积"。
转置卷积层输出与输入的尺寸关系,以高为例,宽同理
H o u t = ( H i n − 1 ) × s t r i d e [ 0 ] − 2 × p a d d i n g [ 0 ] + d i l a t i o n [ 0 ] × ( k e r n e l _ s i z e [ 0 ] − 1 ) + o u t p u t _ p a d d i n g [ 0 ] + 1 H_{out} = (H_{in} - 1) \times stride[0] - 2 \times padding[0] + dilation[0] \times (kernel\_size[0] - 1) + output\_padding[0] + 1 Hout=(Hin