关于 Pytorch 的 nn.torch.Conv2d 的记录与理解.
CLASS torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
假设 Conv2d 的输入 input 尺寸为 (N,Cin,Hin,Win)
1. Demo
import torch
import torch.nn as nn
转载自:https://www.aiuai.cn/aifarm618.html
关于 Pytorch 的 nn.torch.Conv2d 的记录与理解.
CLASS torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
假设 Conv2d 的输入 input 尺寸为 (N,Cin,Hin,Win)
import torch
import torch.nn as nn
# With square kernels and equal stride
m = nn.Conv2d(16, 33, 3, stride=2)
# non-square kernels and unequal stride and with padding
m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2))
# non-square kernels and unequal stride and with padding and dilation
m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1))
input = torch.randn(20, 16, 50, 100)
output = m(input)
对于 groups 参数,用于分解 inputs 和 outputs 间的关系,分组进行卷积操作.
[1] - groups=1
,所有输入进行卷积操作,得到输出.
[2] - groups=2
,等价于有两个并列 conv 操作,每个的输入是一半的 input_channels,并输出一半 - 的 output_channels,然后再进行链接.
[3] - groups=in_channels
,每个 input channel 被其自己的 filters 进行卷积操作,尺寸为 CoutCin
import numpy as np
import cv2
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torchvision.transforms.functional as F
img = cv2.imread(‘test.jpg’)
img_224 = cv2.resize(img, (224, 224), cv2.INTER_LINEAR)
img_224 = cv2.cvtColor(img_224, cv2.COLOR_BGR2RGB)
img_tensor = torch.from_numpy(np.moveaxis(img_224 / (255. if img_224.dtype == np.uint8 else 1), -1, 0).astype(np.float32))
inputs = torch.unsqueeze(img_tensor, 0)
conv = nn.Conv2d(in_channels=3, out_channels=6, kernel_size=7, stride=2, padding=3, groups=3, bias=False)
nn.init.xavier_uniform_(conv.weight.data, gain=nn.init.calculate_gain(‘relu’))
print(conv.weight.data.size())
print(conv.weight.data)
output=conv(inputs)
print(output)
groups
决定了将原输入in_channels 分为几组,而每组channel
重用几次,由out_channels/groups
计算得到,这也说明了为什么需要groups
能供被out_channels
与in_channels
整除. - pyotrch_nn.Conv2d中groups参数的理解
卷积层是用一个固定大小的矩形区去席卷原始数据,将原始数据分成一个个和卷积核大小相同的小块,然后将这些小块和卷积核相乘输出一个卷积值(注意这里是一个单独的值,不再是矩阵了).
卷积的本质就是用卷积核的参数来提取原始数据的特征,通过矩阵点乘的运算,提取出和卷积核特征一致的值,如果卷积层有多个卷积核,则神经网络会自动学习卷积核的参数值,使得每个卷积核代表一个特征.
conv1d是一维卷积,它和conv2d的区别在于只对宽度进行卷积,对高度不卷积.
函数定义:
torch.nn.functional.conv1d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)
参数说明:
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
print(“conv1d sample”)
a=range(16)
x = Variable(torch.Tensor(a))
x=x.view(1,1,16)
print(“x variable:”, x)
b=torch.ones(3)
b[0]=0.1
b[1]=0.2
b[2]=0.3
weights = Variable(b) #torch.randn(1,1,2,2)) #out_channelin_channelH*W
weights=weights.view(1,1,3)
print (“weights:”,weights)
y=F.conv1d(x, weights, padding=0)
print (“y:”,y)
输出结果为:
conv1d sample
x variable: tensor([[[ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15.]]])
weights: tensor([[[ 0.1000, 0.2000, 0.3000]]])
y: tensor([[[ 0.8000, 1.4000, 2.0000, 2.6000, 3.2000, 3.8000, 4.4000, 5.0000, 5.6000, 6.2000, 6.8000, 7.4000, 8.0000, 8.6000]]])
它是怎么计算的:
(1) 原始数据大小是0-15的一共16个数字,卷积核宽度是3,向量是[0.1, 0.2, 0.3]. 第一个卷积是对 x[0:3] 共3个值 [0,1,2] 进行卷积,公式如下:
0x0.1+1x0.2+2x0.3=0.8
(2) 对第二个目标卷积,是 x[1:4 ]共3个值 [1,2,3] 进行卷积,公式如下:
1x0.1+2x0.2+3x0.3=1.4
看到和计算结果完全一致.
conv1d 示意图如下:
conv1d 和 conv2d 的区别就是只对宽度卷积,不对高度卷积. 最后的结果的宽度是原始数据的宽度减去卷积核的宽度再加上1,这里就是14.
Pytorch卷积层原理和示例