Pytorch Conv1d 处理简单的一维信号

Sae*_*eed 3 pytorch

手动完成一维卷积非常简单。然而,我想用它来实现这里nn.Conv1d所做的事情,这对我来说并不简单。在此示例中,h=[1,2,-1],x=[4,1,2,5],输出将为 y=[4,9,0,8,8,-5]。为了使用 Pytorch 做到这一点,我们需要定义h=nn.Conv1d(in, out, k)和 ,x=torch.tensor(*)并且y=h(x)应该是结果。

注意:请不要使用nn.Conv2d它来实现它。

jod*_*dag 5

首先,您应该意识到,基本上所有与卷积神经网络(CNN)相关的文献中使用的术语“卷积”实际上对应于相关运算不是卷积运算

相关和卷积之间的唯一区别(对于实值输入)是,在卷积中,内核在滑过信号之前会被翻转/镜像,而在相关中,不会发生这种翻转。

CNN 中的卷积层还执行一些不属于卷积定义的额外操作。它们应用偏移(也称为偏差),对小批量进行操作,并将多通道输入映射到多通道输出。

因此,为了使用卷积层重新创建卷积运算,我们应该(i)禁用偏差,(ii)翻转内核,以及(iii)将批量大小、输入通道和输出通道设置为 1。

例如,卷积运算的 PyTorch 实现nn.Conv1d如下所示:

import torch
from torch import nn

x = torch.tensor([4, 1, 2, 5], dtype=torch.float)
k = torch.tensor([1, 2, -1], dtype=torch.float)

# Define these constants to differentiate the various usages of "1".
BATCH_SIZE, IN_CH, OUT_CH = 1, 1, 1

# Pad with len(k)-1 zeros to ensure all non-zero outputs are computed.
h = nn.Conv1d(IN_CH, OUT_CH, kernel_size=len(k), padding=len(k) - 1, bias=False)

# Copy flipped k into h.weight.
# h.weight is shape (OUT_CH, IN_CH, kernel_size), reshape k accordingly.
# Perform copy inside no_grad context to avoid autograd issues.
with torch.no_grad():
    h.weight.copy_(torch.flip(k, dims=[0]).reshape(OUT_CH, IN_CH, -1))

# Input shape to h is assumed to be (BATCH_SIZE, IN_CH, SIGNAL_LENGTH), reshape x accordingly.
# Output shape of h is (BATCH_SIZE, OUT_CH, OUTPUT_LENGTH), reshape output to 1D signal.
y = h(x.reshape(BATCH_SIZE, IN_CH, -1)).reshape(-1)
Run Code Online (Sandbox Code Playgroud)

这导致

>>> print(y)
tensor([ 4.,  9.,  0.,  8.,  8., -5.], grad_fn=<ViewBackward>)
Run Code Online (Sandbox Code Playgroud)