假设我们有一个单一频道图像(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个通道或甚至转换层的RGB图像(可能深度= 512)。如何使用相同的滤波器完成卷积运算? 类似的工作对RGB案例非常有帮助。
答案 0 :(得分:6)
它们与您对单个通道图像的处理方式相同,只是您将获得三个矩阵而不是一个。 This是关于CNN基础知识的讲义,我认为这可能对您有所帮助。
答案 1 :(得分:5)
对于类似RGB的输入,滤波器实际上是2 * 2 * 3,每个滤波器对应一个颜色通道,产生三个滤波器响应。这三个加起来就是偏向和激活。最后,这是输出图中的一个像素。
答案 2 :(得分:3)
假设我们有一个矩阵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
如您在图像中所见,每个通道分别进行卷积,然后合并形成一个像素。
答案 3 :(得分:0)
如果您要在RGB图像上实现Conv2d,则在pytorch中的实现应该会有所帮助。
获取图像并将其设为uint8(note that imshow needs uint8 to be values between 0-255 whilst floats should be between 0-1)的numpy ndarray:
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