对于我的教育,我试图在卷积神经网络中实现一个 N 维卷积层。
我想实现一个反向传播功能。但是,我不确定这样做的最有效方法。
目前,我正在使用signal.fftconvolve:
在 forwards 步骤中,卷积过滤器和内核对所有过滤器进行转发;
在反向传播步骤中,将导数(使用 FlipAllAxes 函数在所有维度上反转)与数组 ( https://jefkine.com/general/2016/09/05/backpropagation-in-convolutional-neural-networks/ ) 进行卷积所有过滤器并将它们相加。我认为输出是每个图像与每个过滤器的每个导数卷积的总和。
我对如何对导数进行卷积感到特别困惑。使用下面的类进行反向传播会导致权重的大小爆炸。
用输出和滤波器对导数的卷积进行编程的正确方法是什么?
编辑:
根据这篇论文(通过 FFT 快速训练卷积网络),它试图做我想做的事情:
前一层的导数由当前层的导数与权重的卷积给出:
dL/dy_f = dL/dx * w_f^T
权重的导数是导数与原始输入的卷积的分段和:
dL/dy = dL/dx * x
尽我所知,我已经在下面实现了这一点。然而,这似乎并没有给出预期的结果,因为我使用这一层编写的网络在训练期间表现出剧烈的波动。
import numpy as np
from scipy import signal
class ConvNDLayer:
def __init__(self,channels, kernel_size, dim):
self.channels = channels
self.kernel_size = kernel_size;
self.dim = dim
self.last_input = None
self.filt_dims = np.ones(dim+1).astype(int)
self.filt_dims[1:] = self.filt_dims[1:]*kernel_size
self.filt_dims[0]= self.filt_dims[0]*channels
self.filters = np.random.randn(*self.filt_dims)/(kernel_size)**dim
def …Run Code Online (Sandbox Code Playgroud) 假设我有两个张量:
a = torch.randn(10, 1000, 1, 4)
b = torch.randn(10, 1000, 6, 4)
Run Code Online (Sandbox Code Playgroud)
其中第三个索引是向量的索引。
我想取每个向量之间的点积b相对于in中的向量a。
为了说明,这就是我的意思:
dots = torch.Tensor(10, 1000, 6, 1)
for b in range(10):
for c in range(1000):
for v in range(6):
dots[b,c,v] = torch.dot(b[b,c,v], a[b,c,0])
Run Code Online (Sandbox Code Playgroud)
我将如何使用火炬功能实现这一目标?
我有以下一段代码,目的是将 2D 列表的每个元素重复一定次数:
empty =[]
l = [[1,2,3], [4,5,6]]
n = [2,3]
for i, _as in enumerate(l):
for _a in _as:
for _n in range(n[i]):
empty.append(_a)
empty
> [1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6]
Run Code Online (Sandbox Code Playgroud)
我想尝试用单行列表理解格式来写这个。
我尝试使用以下方法:
empty = [
[
[_a]*n[i] for _a in _as
]
for i, _as in enumerate(l)
]
empty
> [[[1, 1], [2, 2], [3, 3]], [[4, 4, 4], [5, 5, 5], [6, 6, 6]]]
Run Code Online (Sandbox Code Playgroud)
如何更正上述代码以提供所需的结果?