Hi,
I am trying to implement 1d convolution using the unfold and matrix multiplication operations. Convolution is equivalent to the unfold, matrix multiplication, and fold (or view) operations, and a 2d convolutional layer can be implemented equivalently as follows:
inp = torch.randn(1, 3, 10, 12)
w = torch.randn(2, 3, 4, 5)
inp_unf = torch.nn.functional.unfold(inp, (4, 5)).squeeze()
mat_a = inp_unf.T
mat_b = w.view(w.size(0), -1)
mat_b = mat_b.t()
out_unf = torch.matmul(mat_a, mat_b).T
out = out_unf.view(1, 2, 7, 8)
print((torch.nn.functional.conv2d(inp, w) - out).abs().max())
Unfortunately, this does not appear to generalize to 1d convolutional layers:
inp = torch.randn(1, 5, 10)
w = torch.randn(8, 5, 2)
inp_unf = torch.nn.functional.unfold(inp.unsqueeze(0), 2).squeeze()
mat_a = inp_unf.T
mat_b = w.view(w.size(0), -1)
mat_b = mat_b.t()
out_unf = torch.matmul(mat_a, mat_b).T
out = out_unf.view(...) # Reshape out_unf
print((torch.nn.functional.conv1d(inp, w) - out).abs().max())
as mat_a and mat_b cannot be multiped (36x4 and 10x8). Currently torch.nn.functional.unfold only supports 4D tensors.
Any help is greatly appreciated!