Python 如何使用自定义过滤器将彩色图像通过Pytorch卷积层?

Python 如何使用自定义过滤器将彩色图像通过Pytorch卷积层?,python,conv-neural-network,pytorch,rgb,Python,Conv Neural Network,Pytorch,Rgb,我试图将彩色图像通过卷积层时发生的情况可视化。为此,我使用0和1设置自定义权重我面临的问题是,我丢失了3D通道,在将数据传递到图层后,我得到了一个1D通道。 import requests from io import BytesIO from PIL import Image import torch import torch.nn as nn import matplotlib.pyplot as plt import numpy as np link = 'https://audimed

我试图将彩色图像通过卷积层时发生的情况可视化。为此,我使用0和1设置自定义权重我面临的问题是,我丢失了3D通道,在将数据传递到图层后,我得到了一个1D通道。

import requests
from io import BytesIO
from PIL import Image
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import numpy as np

link = 'https://audimediacenter-a.akamaihd.net/system/production/media/85094/images' \
       '/2a4e98976b1f9088fe6ae883f2f29e4d8f3ed473/A1912967_x500.jpg?1575885688'

r = requests.get(link, timeout=10)
im = Image.open(BytesIO(r.content))

pic = np.array(im)

horizontal_filter = torch.zeros(5, 5)
horizontal_filter[2, :] = 1

print(horizontal_filter)
这是我的自定义过滤器:

tensor([[0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.],
        [1., 1., 1., 1., 1.],
        [0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.]])
现在我正在使用自定义过滤器,并重复它以适合3个通道

hz = nn.Conv2d(in_channels=3,
               out_channels=3,
               kernel_size=5,
               stride=1,
               bias=None)

hz.weight.data =  horizontal_filter.type('torch.FloatTensor').repeat(1, 3, 1, 1)

print(hz.weight.data.shape)
这是过滤器的形状:

torch.Size([1, 3, 5, 5])
我通过卷积滤波器,我失去了3个通道:

zz = hz(torch.tensor(pic[None, ...]).permute(0, 3, 1, 2).type('torch.FloatTensor'))

print(np.transpose(zz.detach().numpy(), (0, 2, 3, 1)).shape)
如果我画出来,我就没有颜色了

z = np.transpose(zz.detach().numpy(), (0, 2, 3, 1))[0, :, :, 0]

f, axarr = plt.subplots()
axarr.imshow(z)
plt.show()


tl;dr:如何通过卷积层传递3D图片并返回具有3个通道的图像

问题在于你没有充分重复这些频道。由于您有3个输入和输出通道,Conv权重矩阵应为
3x5x5
。由于您已将其设置为
1x3x5x5
,因此它只能输出1个通道

您需要进行以下更改

hz.weight.data =  horizontal_filter.type('torch.FloatTensor').repeat(3, 3, 1, 1)

由于您的过滤器,您的输出将具有~3700的最大值。所以要查看,请使用
z=z/np.max(z)
除以max,然后得到

问题在于你没有充分重复这些频道。由于您有3个输入和输出通道,Conv权重矩阵应为
3x5x5
。由于您已将其设置为
1x3x5x5
,因此它只能输出1个通道

您需要进行以下更改

hz.weight.data =  horizontal_filter.type('torch.FloatTensor').repeat(3, 3, 1, 1)

由于您的过滤器,您的输出将具有~3700的最大值。所以要查看,请使用
z=z/np.max(z)
除以max,然后得到

输出通道的数量等于过滤器的数量,每个过滤器的深度(内核的数量)应与输入图像的深度相匹配。 例如,请参见下图(来源:)。在那里,我们有一个7x7形状的输入图像,有3个通道和2个滤波器,W0和W1形状为3x3x3。第i个输入通道与滤波器W0(W1)的第i个内核进行卷积,然后将它们相加,得到输出的第一个(第二个)通道

在您的示例中,只有一个带有三个5x5内核(1x3x5x5)的过滤器,因此输出有一个通道。要获得3个通道的输出,您需要三个这样的过滤器,即一个形状阵列(3x5x5)


输出通道的数量等于过滤器的数量,每个过滤器的深度(内核的数量)应与输入图像的深度相匹配。 例如,请参见下图(来源:)。在那里,我们有一个7x7形状的输入图像,有3个通道和2个滤波器,W0和W1形状为3x3x3。第i个输入通道与滤波器W0(W1)的第i个内核进行卷积,然后将它们相加,得到输出的第一个(第二个)通道

在您的示例中,只有一个带有三个5x5内核(1x3x5x5)的过滤器,因此输出有一个通道。要获得3个通道的输出,您需要三个这样的过滤器,即一个形状阵列(3x5x5)