卷积操作: # 1. 卷积核的输入通道数与输入数据的通道数保持一致,所以卷积核的对应通道与输入数据的对应通道进行卷积操作,以卷积核conv_i为例: # 2. 卷积核conv_i的对应通道与输入数据对应通道 进行 对应位置元素 的乘法,即用乘法操作“*”,得到一个与卷积核形状一样的矩阵M # 3. 将第2步中卷积结果矩阵M中的所有元素相加,得到卷积核conv_i在当前通道的卷积结果:标量su_i # 4. 卷积核conv_i的所有通道的卷积结果su_i相加之后得到该卷积核conv_i对输入数据的最终卷积结果。
pytorch中定义的卷积核形状:
conv = nn.Conv2d(in_channels=3,out_channels=2,kernel_size=(2,2))
print(conv.weight.size()) #torch.Size([2, 3, 2, 2])
#-*- coding:utf-8 -*-
#Author LJB Create on 2021/8/27
import torch
import torch.nn as nn
import numpy as np
class Test(nn.Module):
def __init__(self):
super(Test,self).__init__()
self.conv = nn.Conv2d(in_channels=3,out_channels=2,kernel_size=(2,2),padding=0,bias=False)
conv_w = self.conv.weight
print(conv_w.size()) #torch.Size([2, 3, 2, 2])
def forward(self,data):
return self.conv(data)
#自定义的“卷积”:不是真正的卷积,因为此函数的卷积操作中卷积核的大小与输入数据的H,W完全一样
#此函数为了证明一个卷积核的运算过程:
# 1. 卷积核的输入通道数与输入数据的通道数保持一致,所以卷积核的对应通道与输入数据的对应通道进行卷积操作,以卷积核conv_i为例:
# 2. 卷积核conv_i的对应通道与输入数据对应通道 进行 对应位置元素 的乘法,即用乘法操作“*”,得到一个与卷积核形状一样的矩阵M
# 3. 将第2步中卷积结果矩阵M中的所有元素相加,得到卷积核conv_i在当前通道的卷积结果:标量su_i
# 4. 卷积核conv_i的所有通道的卷积结果su_i相加之后得到该卷积核conv_i对输入数据的最终卷积结果。
def conv(data,weight):
'''
卷积核大小与输入数据的H,W完全一样
:param data: 形状[batchsize,channels,H,W]
:param weight: 形状[out_channels,in_channels,H,W],其中in_channels与data的channels保持一致进行卷积操作
:return:
'''
out_channels,in_channels,H,W = weight.size()
conv_result = []
for d in data:
conv_channel = []
for out_c in range(out_channels):
r = 0.
for in_c in range(in_channels):
w = weight[out_c][in_c]
d_c = d[in_c]
su = d_c*w #两个形状相同的矩阵对应元素相乘,得到一个形状也完全一样的矩阵
r += torch.sum(su) #矩阵所有元素之和,是标量
conv_channel.append([[r.data.item()]])
conv_result.append(conv_channel)
return np.array(conv_result)
if __name__=='__main__':
#模拟输入数据 batchsize=8,channel=3,H=2,W=2
test_data = torch.randint(0,9,(8,3,2,2)).float()
T = Test()
T.eval()
with torch.no_grad():
init_weight = torch.Tensor([[[[.1,.2],[.3,.4]],[[.5,.6],[.7,.8]],[[.9,.1],[.2,.3]]],
[[[.2,.1],[.4,.3]],[[.6,.5],[.8,.7]],[[.6,.5],[.7,.8]]]])
T.conv.weight = nn.Parameter(init_weight) #手动初始卷积核的权重
r = T(test_data)
conv_res = conv(test_data,init_weight)
print('+++ my conv:',conv_res.tolist())
print('normal conv:',r.tolist())
print(np.shape(conv_res))
print(r.size())