如何在具有三个(RGB)通道的图像上计算卷积?
How is a convolution calculated on an image with three (RGB) channels?
假设我们有一个单通道图像 (5x5)
A = [ 1 2 3 4 5
6 7 8 9 2
1 4 5 6 3
4 5 6 7 4
3 4 5 6 2 ]
还有一个过滤器 K (2x2)
K = [ 1 1
1 1 ]
一个应用卷积的例子(让我们从 A 中取出第一个 2x2)是
1*1 + 2*1 + 6*1 + 7*1 = 16
这很简单。但是让我们为矩阵 A 引入一个深度因子,即在深度网络中具有 3 个通道或什至 conv 层的 RGB 图像(深度可能 = 512)。如何使用相同的过滤器完成卷积运算? 类似的计算对于 RGB 情况将非常有帮助。
它们将与您处理单通道图像的方式相同,只是您将获得三个矩阵而不是一个。
This是一篇关于CNN基础知识的讲义,我想可能对你有帮助。
在卷积神经网络中,卷积运算的实现方式如下,(注意:模糊/滤波运算中的卷积是分开的)
对于类似 RGB 的输入,过滤器实际上是 223,每个过滤器对应一个颜色通道,从而产生三个过滤器响应。这三个加起来就是一个由偏置和激活引起的流动。最后,这是输出图中的一个像素。
假设我们有一个由某个矩阵 A 给出的 3 通道 (RGB) 图像
A = [[[198 218 227]
[196 216 225]
[196 214 224]
...
...
[185 201 217]
[176 192 208]
[162 178 194]]
和一个模糊内核为
K = [[0.1111, 0.1111, 0.1111],
[0.1111, 0.1111, 0.1111],
[0.1111, 0.1111, 0.1111]]
#which is actually 0.111 ~= 1/9
卷积可以表示如下图所示
正如您在图像中看到的那样,每个通道都单独进行卷积,然后组合形成一个像素。
如果你想在 RGB 图像上实现 Conv2d,那么这个在 pytorch 中的实现应该有所帮助。
抓取一张图像并将其设为 uint8 的 numpy ndarray (note that imshow needs uint8 to be values between 0-255 whilst floats should be between 0-1):
link = 'https://oldmooresalmanac.com/wp-content/uploads/2017/11/cow-2896329_960_720-Copy-476x459.jpg'
r = requests.get(link, timeout=7)
im = Image.open(BytesIO(r.content))
pic = np.array(im)
您可以通过
查看
f, axarr = plt.subplots()
axarr.imshow(pic)
plt.show()
创建你的卷积层(以随机权重启动)
conv_layer = nn.Conv2d(in_channels=3,
out_channels=3,kernel_size=3,
stride=1, bias=None)
将输入图像转换为浮动并添加一个空维度,因为这是 pytorch 期望的输入
pic_float = np.float32(pic)
pic_float = np.expand_dims(pic_float,axis=0)
运行 通过卷积层的图像(围绕维度位置排列变化,使它们与 pytorch 所期望的相匹配)
out = conv_layer(torch.tensor(pic_float).permute(0,3,1,2))
删除我们添加的额外第一个 dim(可视化不需要),从 GPU 分离并转换为 numpy ndarray
out = out.permute(0,2,3,1).detach().numpy()[0, :, :, :]
可视化输出(转换为 uint8,这是我们开始的地方)
f, axarr = plt.subplots()
axarr.imshow(np.uint8(out))
plt.show()
然后您可以通过访问过滤器来更改过滤器的权重。例如:
kernel = torch.Tensor([[[[0.01, 0.02, 0.01],
[0.02, 0.04, 0.02],
[0.01, 0.02, 0.01]]]])
kernel = kernel.repeat(3, 3, 1, 1)
conv_layer.weight.data = kernel
假设我们有一个单通道图像 (5x5)
A = [ 1 2 3 4 5
6 7 8 9 2
1 4 5 6 3
4 5 6 7 4
3 4 5 6 2 ]
还有一个过滤器 K (2x2)
K = [ 1 1
1 1 ]
一个应用卷积的例子(让我们从 A 中取出第一个 2x2)是
1*1 + 2*1 + 6*1 + 7*1 = 16
这很简单。但是让我们为矩阵 A 引入一个深度因子,即在深度网络中具有 3 个通道或什至 conv 层的 RGB 图像(深度可能 = 512)。如何使用相同的过滤器完成卷积运算? 类似的计算对于 RGB 情况将非常有帮助。
它们将与您处理单通道图像的方式相同,只是您将获得三个矩阵而不是一个。 This是一篇关于CNN基础知识的讲义,我想可能对你有帮助。
在卷积神经网络中,卷积运算的实现方式如下,(注意:模糊/滤波运算中的卷积是分开的)
对于类似 RGB 的输入,过滤器实际上是 223,每个过滤器对应一个颜色通道,从而产生三个过滤器响应。这三个加起来就是一个由偏置和激活引起的流动。最后,这是输出图中的一个像素。
假设我们有一个由某个矩阵 A 给出的 3 通道 (RGB) 图像
A = [[[198 218 227] [196 216 225] [196 214 224] ... ... [185 201 217] [176 192 208] [162 178 194]]
和一个模糊内核为
K = [[0.1111, 0.1111, 0.1111], [0.1111, 0.1111, 0.1111], [0.1111, 0.1111, 0.1111]] #which is actually 0.111 ~= 1/9
卷积可以表示如下图所示
正如您在图像中看到的那样,每个通道都单独进行卷积,然后组合形成一个像素。
如果你想在 RGB 图像上实现 Conv2d,那么这个在 pytorch 中的实现应该有所帮助。
抓取一张图像并将其设为 uint8 的 numpy ndarray (note that imshow needs uint8 to be values between 0-255 whilst floats should be between 0-1):
link = 'https://oldmooresalmanac.com/wp-content/uploads/2017/11/cow-2896329_960_720-Copy-476x459.jpg'
r = requests.get(link, timeout=7)
im = Image.open(BytesIO(r.content))
pic = np.array(im)
您可以通过
查看f, axarr = plt.subplots()
axarr.imshow(pic)
plt.show()
创建你的卷积层(以随机权重启动)
conv_layer = nn.Conv2d(in_channels=3,
out_channels=3,kernel_size=3,
stride=1, bias=None)
将输入图像转换为浮动并添加一个空维度,因为这是 pytorch 期望的输入
pic_float = np.float32(pic)
pic_float = np.expand_dims(pic_float,axis=0)
运行 通过卷积层的图像(围绕维度位置排列变化,使它们与 pytorch 所期望的相匹配)
out = conv_layer(torch.tensor(pic_float).permute(0,3,1,2))
删除我们添加的额外第一个 dim(可视化不需要),从 GPU 分离并转换为 numpy ndarray
out = out.permute(0,2,3,1).detach().numpy()[0, :, :, :]
可视化输出(转换为 uint8,这是我们开始的地方)
f, axarr = plt.subplots()
axarr.imshow(np.uint8(out))
plt.show()
然后您可以通过访问过滤器来更改过滤器的权重。例如:
kernel = torch.Tensor([[[[0.01, 0.02, 0.01],
[0.02, 0.04, 0.02],
[0.01, 0.02, 0.01]]]])
kernel = kernel.repeat(3, 3, 1, 1)
conv_layer.weight.data = kernel