简体   繁体   English

PyTorch 卷积 - 为什么是四个维度?

[英]PyTorch Convolution - Why four dimensions?

I am trying to create a PyTorch network like shown in the image below (see: this link for the arXiv paper).我正在尝试创建一个 PyTorch 网络,如下图所示(请参阅:arXiv 论文的此链接)。 The network aims to learn features for source code.该网络旨在学习源代码的特征。 Basically, it consists of an embedding lookup layer, followed by convolution, max-pooling and a dense layer.基本上,它由嵌入查找层、卷积、最大池和密集层组成。

在此处输入图像描述

My attempt to build this network looks like this:我建立这个网络的尝试如下所示:

import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
"""
Class Net.
This network is used to learn source code features in a
supervised manner.
"""

def __init__(self, n_vocab, n=512, k=13, m=10):
    """
    Constructor.

    :parm n_vocab:      size of the vocabulary
    :param n:           number of convolution filters
    :param k:           embedding size
    :param m:           kernel size
    """
    super(Net, self).__init__()

    # embedding layer
    self.emb = nn.Embedding(n_vocab, k)

    # convolution and pooling
    self.conv1 = nn.Conv2d(1, n, (m, k))
    self.pool = nn.AdaptiveMaxPool2d(1)

    # fully connected layers
    self.fc1 = nn.Linear(n, 100)
    self.fc2 = nn.Linear(100, 5)


def forward(self, input):
    """
    Performs a forward pass through the network.

    :param input:       input to network
    :return:            network output
    """
    x = self.emb(torch.LongTensor(input))
    x = x.view(1, 500, 13)
    x = self.pool(F.relu(self.conv1(x)))
    x = F.relu(self.fc1(x))
    x = self.fc2(x)

    return x

I cannot get the convolution to work.我无法让卷积工作。 I keep getting the error: *** RuntimeError: Expected 4-dimensional input for 4-dimensional weight 512 1 10 13, but got 3-dimensional input of size [1, 500, 13] instead .我不断收到错误消息: *** RuntimeError: Expected 4-dimensional input for 4-dimensional weight 512 1 10 13, but got 3-dimensional input of size [1, 500, 13] instead The input to my network consists of vocabulary indices which are fed into the embedding layer.我的网络的输入由输入嵌入层的词汇索引组成。 An example input looks like this:示例输入如下所示:

[55, 28, 14, 56, 20, 55, 70, 14, 56, 20, 55, ..., 31, 31, 31, 31, 31, 31, 31]

After feeding this example input into the network, I get the corresponding embeddings:将此示例输入输入网络后,我得到了相应的嵌入:

ensor([[[-0.5966, -1.4197,  0.9875,  ..., -0.0211, -2.3168,  0.3744],
        [-0.1759, -1.1841, -0.0564,  ..., -0.0804, -1.1820, -0.1344],
        [ 1.4525,  0.1342, -0.3820,  ..., -0.2679,  0.5997,  1.1058],
        ...,
        [ 1.2074,  0.4087, -0.3353,  ..., -0.1959,  0.5806, -1.4581],
        [ 1.2074,  0.4087, -0.3353,  ..., -0.1959,  0.5806, -1.4581],
        [ 1.2074,  0.4087, -0.3353,  ..., -0.1959,  0.5806, -1.4581]]],
      grad_fn=<ViewBackward>)

The output looks right for me. output 看起来很适合我。 Apparently, PyTorch needs 4 dimensions for the convolutions, but I only have three.显然,PyTorch 需要 4 个维度的卷积,但我只有 3 个。 What is the missing dimension?缺少的维度是什么?

My train function looks like this:我的火车 function 看起来像这样:

def train(X, y, n_vocab, epochs=5):
"""
Trains the network.

:param X:           network input (indices into vocabulary)
:param y:           gold labels
:param epochs:      number of epochs to train the network
                    (default = 5)
:return:            trained network
"""
# instantiate network model
net = Net(n_vocab)

# define training loss and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

# train several epochs
for epoch in range(epochs):

    running_loss = 0.0
    for i in range(len(X)):
        X_b, y_b = X[i], y[i]

        # zero the parameter gradients
        optimizer.zero_grad()

        # perform forward pass
        y_pred = net(X_b)
        # compute loss
        loss = criterion(y_pred, y_b)
        # perform backpropagation
        loss.backward()
        # optimize model parameters
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 0:
            print("[%d, %5d] loss: %.3f" %
                (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print("Finished training")
return net

Any help would be greatly appreciated!任何帮助将不胜感激!

Thank you in advance.先感谢您。

The first dimension of the data should be the batch, mentioned in the documentation :数据的第一个维度应该是批次,在文档中提到:

Applies a 2D convolution over an input signal composed of several input planes.在由多个输入平面组成的输入信号上应用 2D 卷积。

... the output value of the layer with input size (N, C, H, W) ... ... 具有输入大小(N, C, H, W)的层的 output 值 ...

... ...

N is a batch size, C denotes a number of channels, H is a height of input planes in pixels, and W is width in pixels. N 是批量大小,C 表示通道数,H 是以像素为单位的输入平面的高度,W 是以像素为单位的宽度。

So you should batch your data before passing it to the net, or at least reshape it to a shape of (1, 1, 500, 13) to use a batch size of 1.因此,您应该在将数据传递到网络之前对其进行批处理,或者至少将其重塑为(1, 1, 500, 13)的形状以使用批量大小为 1。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM