赞
踩
卷积神经网络可以说是图像处理的天花板,也是当下图像处理在深度学习方面最热门的研究。接下来,从卷积核、池化、全连接等方面介绍卷积神经网络中的关键操作。
该文章中下采样主要为卷积(普通卷积、空洞卷积、池化)而上采样主要为转置卷积。
卷积操作的作用是提取图像中的局部信息。卷积核的大小通常比输入数据小,因此每次卷积计算得到的是输入数据的一个小的局部区域的特征。通过不同大小的卷积核和不同的卷积核数量,可以提取出不同尺度和不同方向的特征。
import torch import torch.nn as nn # 定义输入 input_data = torch.tensor([[[ [0.1 ,0.2,0.3,0.1,0.1,0.5], [0.2,0.1,0.2,0.3,0.1,0.1], [0.2,0.1,0.2,0.3,0.1,0.1], [0.2,0.1,0.2,0.3,0.1,0.1], [0.2,0.1,0.2,0.3,0.1,0.1], [0.2,0.1,0.2,0.3,0.1,0.1] ]]]) print(input_data)# 查看自定义张量input_data # 定义标准卷积层 conv = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0) print(conv.state_dict())# 返回一个字典,其中包含了模型的所有参数 # 进行普通卷积操作 conv_result = conv(input_data) print('Convolution result shape:', conv_result.shape)# 查看卷积操作后的形态 print('Convolution result:', conv_result)# 查看卷积操作后的结果
输出结果
tensor([[[[0.1000, 0.2000, 0.3000, 0.1000, 0.1000, 0.5000],
[0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
[0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
[0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
[0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000],
[0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000]]]])
OrderedDict([('weight', tensor([[[[-0.3229, 0.2283, 0.2123],
[ 0.1449, -0.1590, 0.1524],
[-0.2071, -0.0818, 0.2543]]]])), ('bias', tensor([-0.1603]))])
Convolution result shape: torch.Size([1, 1, 4, 4])
Convolution result: tensor([[[[-0.0384, -0.0675, -0.2571, -0.0657],
[-0.1148, -0.0156, -0.1792, -0.2152],
[-0.1148, -0.0156, -0.1792, -0.2152],
[-0.1148, -0.0156, -0.1792, -0.2152]]]],
grad_fn=<ConvolutionBackward0>)
空洞卷积是卷积神经网络中的一种卷积方式,它的作用主要有以下几个方面:
import torch import torch.nn as nn # 定义输入 input_data = torch.tensor([[[ [0.1 ,0.2,0.3,0.1,0.1,0.5], [0.2,0.1,0.2,0.3,0.1,0.1], [0.2,0.1,0.2,0.3,0.1,0.1], [0.2,0.1,0.2,0.3,0.1,0.1], [0.2,0.1,0.2,0.3,0.1,0.1], [0.2,0.1,0.2,0.3,0.1,0.1] ]]]) print(input_data) # 定义标准卷积层和空洞卷积层 conv = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=0) print(conv.state_dict()) # 空洞卷积输出结果 dilated_conv = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, stride=1, padding=2, dilation=2) print(dilated_conv.state_dict())# 返回一个字典,其中包含了模型的所有参数 dilated_conv_result = dilated_conv(input_data) print('Dilated convolution result shape:', dilated_conv_result.shape)# 查看卷积操作后的形态 print('Dilated convolution result:', dilated_conv_result)
输出结果
tensor([[[[0.1000, 0.2000, 0.3000, 0.1000, 0.1000, 0.5000], [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000], [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000], [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000], [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000], [0.2000, 0.1000, 0.2000, 0.3000, 0.1000, 0.1000]]]]) OrderedDict([('weight', tensor([[[[ 0.0818, 0.1001, -0.1972], [-0.0940, -0.2605, 0.1210], [ 0.1136, 0.2079, 0.0602]]]])), ('bias', tensor([-0.0697]))]) OrderedDict([('weight', tensor([[[[-0.2004, -0.2327, -0.1165], [-0.0940, 0.0574, -0.0417], [-0.0378, -0.2901, 0.3276]]]])), ('bias', tensor([0.3039]))]) Dilated convolution result shape: torch.Size([1, 1, 6, 6]) Dilated convolution result: tensor([[[[0.3047, 0.3805, 0.2748, 0.2120, 0.2449, 0.2829], [0.3146, 0.3664, 0.2596, 0.2495, 0.2543, 0.2411], [0.2563, 0.3082, 0.1581, 0.1279, 0.1709, 0.1047], [0.2447, 0.3082, 0.1613, 0.1480, 0.1909, 0.1577], [0.2372, 0.2389, 0.1941, 0.2060, 0.2275, 0.1980], [0.2372, 0.2389, 0.1941, 0.2060, 0.2275, 0.1980]]]], grad_fn=<ConvolutionBackward0>)
反卷积(Deconvolution)操作是卷积神经网络(CNN)中的一种常见操作,也称为转置卷积[2](Transposed Convolution)或分数步长卷积(Fractionally Strided Convolution)。在CNN中,卷积操作常用于提取输入图像的特征,反卷积操作则用于将特征图还原为原始图像或进行像素级别的分割。
import torch
import torch.nn as nn
# 定义输入和卷积核
t = torch.tensor([[
[ 0.1 , 0.2 ],
[ 0.2 , 0.1 ]]
])
print(type(t),t)
# in_channels表示输入通道数,out_channels表示输出通道数,kernel_size表示卷积核大小
conv_transpose = nn.ConvTranspose2d(in_channels=1, out_channels=1, kernel_size=2, stride=1)
print(conv_transpose.state_dict())# 返回一个字典,其中包含了模型的所有参数
# 输出结果
conv_transpose_result = conv_transpose(t)
print('conv_transpose_result:', conv_transpose_result)
输出结果
<class 'torch.Tensor'> tensor([[[0.1000, 0.2000],
[0.2000, 0.1000]]])
OrderedDict([('weight', tensor([[[[ 0.1511, -0.4327],
[ 0.2216, 0.0240]]]])), ('bias', tensor([-0.4246]))])
tensor([[[-0.4095, -0.4377, -0.5112],
[-0.3722, -0.4493, -0.4631],
[-0.3803, -0.3976, -0.4222]]], grad_fn=<SqueezeBackward1>)
转置卷积和膨胀卷积是两个不同的概念,它们之间的作用和区别如下所述:
感受野:指卷积神经网络中每个输出特征图的每个像素点对应输入图像的区域大小。
池化操作(Pooling)其主要作用是在卷积层之间减少特征图的维度,从而减少模型的参数数量和计算量,避免过拟合。常见的池化操作有最大池化(Max Pooling)和平均池化(Average Pooling)两种。
最大池化计算简单而且能够更好的保留纹理特征,得到的图像颜色更亮。
import torch import torch.nn as nn # 创建一个最大池化层,池化窗口大小为3x3,步长为1 pool = nn.MaxPool2d(kernel_size=3, stride=1) print(pool) # 创建一个输入张量,大小为(1, 1, 4, 4) x = torch.Tensor([[[ [ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12], [13, 14, 15, 16] ]]]) # 将输入张量传递给池化层,并计算输出 output = pool(x) # 打印输出张量 print(output)
输出结果
MaxPool2d(kernel_size=3, stride=1, padding=0, dilation=1, ceil_mode=False)
tensor([[[[11., 12.],
[15., 16.]]]])
import torch import torch.nn as nn # 创建一个最大池化层,池化窗口大小为3x3,步长为1 pool = nn.AvgPool2d(kernel_size=3, stride=1) print(pool) # 创建一个输入张量,大小为(1, 1, 4, 4) x = torch.Tensor([[[ [ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12], [13, 14, 15, 16] ]]]) # 将输入张量传递给池化层,并计算输出 output = pool(x) # 打印输出张量 print(output)
输出结果
AvgPool2d(kernel_size=3, stride=1, padding=0)
tensor([[[[ 6., 7.],
[10., 11.]]]])
注:池化层是不可学习的,用stride为2的可学习卷积层来代替pooling可以得到更好的效果,当然同时也增加了一定的计算量。
全连接层(Fully Connected Layer)是卷积神经网络中的一种常用层,通常位于卷积层和输出层之间。全连接层的作用是将经过卷积层和池化层处理后的特征图进行展平(Flatten),然后连接一个或多个全连接层进行分类或回归。
import torch
import torch.nn as nn
# 创建一个全连接层,输入维度为4,输出维度为2
fc = nn.Linear(4, 2)
print(fc.state_dict())# 返回一个字典,其中包含了模型的所有参数
# 创建一个输入张量,大小为(1, 4)
x = torch.tensor([0.1,0.2,0.2,0.1])
# 将输入张量传递给全连接层,并计算输出
output = fc(x)
# 打印输出张量
print(output)# 第一个:-0.4654×0.1+0.0059 ×0.2+ 0.2813×0.2+0.1×(-0.2186)-0.3949 = -0.40586
输出结果
OrderedDict([('weight', tensor([[-0.4654, 0.0059, 0.2813, -0.2186],
[ 0.4194, 0.0747, 0.2652, 0.0923]])), ('bias', tensor([-0.3949, -0.1806]))])
tensor([-0.4059, -0.0615], grad_fn=<AddBackward0>)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。