前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Conv1d原理解析

Conv1d原理解析

作者头像
千灵域
发布2022-06-17 12:56:06
1.1K0
发布2022-06-17 12:56:06
举报
文章被收录于专栏:challenge filterchallenge filter

今天碰上了需要使用Conv1d的场景,但是对于in_channel,out_channel和kernel_size所影响的Conv1d层而进行的操作还是十分的迷惑,因此写下此篇文章记录自己的学习过程。

公式

官方文档

![formula](/assets/20210927 conv1d/Conv1d_formula.png)

从公式可以看出,输入到Conv1d中的数据有三个维度,第一个维度N一般是batch_size,第二个维度一般为in_channel,第三个维度为序列的时间维度,在NLP中为词向量大小;输出维度基本相同,但是输出的第二个维度为out_channel。

公式限定了第i个bathc_size中输出的第j个channel。在计算过程中,bias自然不必多讲,求和内的k指遍历所有的in_channel,然后使用对应的权重和指定的输入向量进行卷积操作。

计算例子

如果懂的人已经可以看懂这条公式了,可是我不懂……所以还是用例子来说明一下

代码语言:javascript
复制
import torch
import torch.nn as nn
test_layer = nn.Conv1d(in_channels=3, out_channels=2, kernel_size=4)  # 设计一个测试层,不同数据不一样,方便后面查阅
print(test_layer.weight.shape)  #  [2,3,4],即公式中的weight。对于每一个out_channel和in_channel的对应,都有一个kernel_size大小的卷积核
test_data = torch.rand(1,3,10) # 输入测试数据,3个channel,时间维为10
# 概要测试
output = test_layer(test_data) 
print(output.shape)  # [1,2,7] 2为out_channel,7为L_out,具体计算公式可参见官方文档

# 具体计算,以out(0, 0, 0)为例,即Ni=0, Coutj=0的第一个元素
print(output[0,0])  # [0.2545, 0.3342, 0.3826, 0.1345, 0.0378, 0.2512, 0.2467]
print(test_data[0,0],test_data[0,1],test_data[0,2])
# tensor([0.4535, 0.6660, 0.1077, 0.7335, 0.8431, 0.2407, 0.2267, 0.1635, 0.8010, 0.5360]) 
# tensor([0.5334, 0.7020, 0.7540, 0.7194, 0.9105, 0.2495, 0.3046, 0.3894, 0.6813, 0.0660]) 
# tensor([0.5396, 0.6200, 0.7067, 0.9654, 0.8220, 0.8894, 0.5200, 0.9175, 0.6874, 0.8831])
print(test_layer.weight[0,0], test_layer.weight[0,1],test_layer.weight[0,2])
# tensor([-0.1468, -0.0057,  0.0926,  0.0263], grad_fn=<SelectBackward>) 
# tensor([ 0.1042,  0.0158,  0.2408, -0.0116], grad_fn=<SelectBackward>) 
# tensor([ 0.0223, -0.2104,  0.1971, -0.0318], grad_fn=<SelectBackward>
## 第0个元素的计算,即为所有的in_channel与weight上对应的kernel_size做卷积的结果
a1 = torch.sum(test_layer.weight[0,0]*test_data[0,0,0:4])
a2 = torch.sum(test_layer.weight[0,1]*test_data[0,1,0:4])
a3 = torch.sum(test_layer.weight[0,2]*test_data[0,2,0:4])
print(a1+a2+a3) # tensor(0.1890, grad_fn=<AddBackward0>)
## 但是第0个元素 output[0,0,0] = 0.2545,不对啊……这是因为少了bias。加上bias[0]就对了
print(test_layer.bias) # tensor([ 0.0655, -0.1095], requires_grad=True)

# 另外一个例子,output(0, 1, 2),即out_channel=1的第二个元素,值为0.3290
print(output[0,1])
print(test_data[0,0],test_data[0,1],test_data[0,2])
print(test_layer.weight[1,0], test_layer.weight[1,1],test_layer.weight[1,2])
a1 = torch.sum(test_layer.weight[1,0]*test_data[0,0,2:6])
a2 = torch.sum(test_layer.weight[1,1]*test_data[0,1,2:6])
a3 = torch.sum(test_layer.weight[1,2]*test_data[0,2,2:6])
print(a1+a2+a3)  # 0.4385,减去bias[1](-0.1095),结果正确
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-09-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 公式
  • 计算例子
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档