pytorch之nn.Conv1d详解

pytorch之nn.Conv1d详解之前学习pytorch用于文本分类的时候,用到了一维卷积,花了点时间了解其中的原理,看网上也没有详细解释的博客,所以就记录一下。Conv1dclasstorch.nn.Conv1d(in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True)in_channe…

大家好,又见面了,我是你们的朋友全栈君。

博主欢迎转载,但请一定要给出原文链接,标注出处!!!谢谢~

pytorch之nn.Conv1d详解

(没想到当初整理这篇,竟然有那么多人看,而且还有不少人提问。由于CSDN不常登陆,所以评论不一定及时回复。大家如果用知乎的话,可以知乎私信我:Sunny.夏的知乎个人主页。我看到消息肯定会及时回复大家的。对于那些评论了几个月博主都没回的,实在抱歉,千万别拿大刀砍我。。。我是真的不常登,只有在写文章的时候才会登下博客)

之前学习pytorch用于文本分类的时候,用到了一维卷积,花了点时间了解其中的原理,看网上也没有详细解释的博客,所以就记录一下。

Conv1d

class torch.nn.Conv1d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)

  • in_channels(int) – 输入信号的通道。在文本分类中,即为词向量的维度
  • out_channels(int) – 卷积产生的通道。有多少个out_channels,就需要多少个1维卷积
  • kernel_size(int or tuple) – 卷积核的尺寸,卷积核的大小为(k,),第二个维度是由in_channels来决定的,所以实际上卷积大小为kernel_size*in_channels
  • stride(int or tupleoptional) – 卷积步长
  • padding (int or tupleoptional)- 输入的每一条边补充0的层数
  • dilation(int or tuple, `optional“) – 卷积核元素之间的间距
  • groups(intoptional) – 从输入通道到输出通道的阻塞连接数
  • bias(booloptional) – 如果bias=True,添加偏置

举个例子:

conv1 = nn.Conv1d(in_channels=256,out_channels=100,kernel_size=2)
input = torch.randn(32,35,256)
# batch_size x text_len x embedding_size -> batch_size x embedding_size x text_len
input = input.permute(0,2,1)
out = conv1(input)
print(out.size())

这里32为batch_size,35为句子最大长度,256为词向量

再输入一维卷积的时候,需要将32*35*256变换为32*256*35,因为一维卷积是在最后维度上扫的,最后out的大小即为:32*100*(35-2+1)=32*100*34

附上一张图,可以很直观的理解一维卷积是如何用的:

图片来源:Keras之文本分类实现

图中输入的词向量维度为5,输入大小为7*5,一维卷积核的大小为2、3、4,每个都有两个,总共6个特征。

对于k=4,见图中红色的大矩阵,卷积核大小为4*5,步长为1。这里是针对输入从上到下扫一遍,输出的向量大小为((7-4)/1+1)*1=4*1,最后经过一个卷积核大小为4的max_pooling,变成1个值。最后获得6个值,进行拼接,在经过一个全连接层,输出2个类别的概率。

pytorch之nn.Conv1d详解

附上一个代码来详解:

其中,embedding_size=256, feature_size=100, window_sizes=[3,4,5,6], max_text_len=35

class TextCNN(nn.Module):
    def __init__(self, config):
        super(TextCNN, self).__init__()
        self.is_training = True
        self.dropout_rate = config.dropout_rate
        self.num_class = config.num_class
        self.use_element = config.use_element
        self.config = config

        self.embedding = nn.Embedding(num_embeddings=config.vocab_size, 
                                embedding_dim=config.embedding_size)
        self.convs = nn.ModuleList([
                nn.Sequential(nn.Conv1d(in_channels=config.embedding_size, 
                                        out_channels=config.feature_size, 
                                        kernel_size=h),
#                              nn.BatchNorm1d(num_features=config.feature_size), 
                              nn.ReLU(),
                              nn.MaxPool1d(kernel_size=config.max_text_len-h+1))
                     for h in config.window_sizes
                    ])
        self.fc = nn.Linear(in_features=config.feature_size*len(config.window_sizes),
                            out_features=config.num_class)
        if os.path.exists(config.embedding_path) and config.is_training and config.is_pretrain:
            print("Loading pretrain embedding...")
            self.embedding.weight.data.copy_(torch.from_numpy(np.load(config.embedding_path)))    
    
    def forward(self, x):
        embed_x = self.embedding(x)
        
        #print('embed size 1',embed_x.size())  # 32*35*256
# batch_size x text_len x embedding_size  -> batch_size x embedding_size x text_len
        embed_x = embed_x.permute(0, 2, 1)
        #print('embed size 2',embed_x.size())  # 32*256*35
        out = [conv(embed_x) for conv in self.convs]  #out[i]:batch_size x feature_size*1
        #for o in out:
        #    print('o',o.size())  # 32*100*1
        out = torch.cat(out, dim=1)  # 对应第二个维度(行)拼接起来,比如说5*2*1,5*3*1的拼接变成5*5*1
        #print(out.size(1)) # 32*400*1
        out = out.view(-1, out.size(1)) 
        #print(out.size())  # 32*400 
        if not self.use_element:
            out = F.dropout(input=out, p=self.dropout_rate)
            out = self.fc(out)
        return out

embed_x一开始大小为32*35*256,32为batch_size。经过permute,变为32*256*35,输入到自定义的网络后,out中的每一个元素,大小为32*100*1,共有4个元素。在dim=1维度上进行拼接后,变为32*400*1,在经过view,变为32*400,最后通过400*num_class大小的全连接矩阵,变为32*2。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/131636.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月12日 上午6:46
下一篇 2022年6月12日 上午6:46


相关推荐

  • 局域网vlan配置步骤_局域网vlan划分案例

    局域网vlan配置步骤_局域网vlan划分案例计算机网络技术的发展犹如戏剧舞台,你方唱罢我登台。从传统的以太网(10Mb/s)发展到快速以太网(100Mb/s)和千兆以太网(1000Mb/s)也不过几年的时间,其迅猛的势头实在令人吃惊。而现在中大型规模网络建设中,以千兆三层交换机为核心的所谓“千兆主干跑、百兆到桌面”的主流网络模型已不胜枚举。现在,网络业界对“三层交换”和VLAN这两词已经不感到陌生了。一、什么是三…

    2026年1月21日
    2
  • QCustomPlot配置[通俗易懂]

    QCustomPlot配置[通俗易懂]安装在https://www.qcustomplot.com/index.php/download下载压缩包。qcustomplot.h和qcustomplot.cpp即为需要使用的文件。然后自己新建一个QWidget,要么继承自QCustomPlot这个类,要么做提升。备注笔者使用环境是Windows7.编译器是VistualStudio2015(构建套件是vs2013)部分类说明QCPGraph图表通过调用QCPGraph的setData设置绘图需要的数据添加一.

    2022年8月31日
    8
  • Xray扫描器[通俗易懂]

    Xray扫描器[通俗易懂]简介xray是一款可以使用HTTP/HTTPS代理进行被动扫描的安全工具,支持功能如下独立的URL扫描 基于HTTP的被动代理扫描,同时支持HTTPS SQL注入检测模块 命令注入检测模块 任意重定向检测模块 路径遍历模块Xray扫描器内置插件XSS漏洞检测(key:xss):利用语义分析的方式检测XSS漏洞 SQL注入检测(key:sqldet…

    2022年5月30日
    188
  • unity3d实战_unity3d游戏制作

    unity3d实战_unity3d游戏制作[Unity3D入门]分享一个自制的入门级游戏项目"坦克狙击手"我在学Unity3D,TankSniper(坦克狙击手)这个项目是用来练手的。游戏玩法来自这里(http://www.4399.com/flash/127672_3.htm),虽然抄袭了人家的创意,不过我只用来练习(目前还很不成熟,离人家的境界相差很大),坦克、导弹、建筑模型来自网络,应该不会有版权问题吧。由于模型和代码总共…

    2022年8月10日
    9
  • vscode前端常用插件

    vscode前端常用插件vscode前端差用插件

    2022年7月25日
    15
  • Kubernetes Pod Evicted[通俗易懂]

    Kubernetes Pod Evicted[通俗易懂]一、背景以及措施近日Kubernetes测试集群Pod状态出现Evicted现象,但是项目还是能正常提供服务,最先的解决办法是手动将Evicted状态的Pod删除。#查看Evicted状态的Pod[ops@dev-gate~]#kubectlgetpods-nstaging-services|grepEvictedeureka-server-02-7f658c4dfc-zwtqk0/1Evicted

    2022年5月17日
    73

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号