我要对3个5x5滤镜进行卷积处理,以处理灰度图像(形状[nx,ny,1])输入。我已经预先设置了每个5x5过滤器的硬编码值,我不希望我的模型“学习”它们,而只是不断进行操作。
我该如何实现?
我当时正在研究使用tf.nn.conv2d(),它说它的过滤器必须为[高度,宽度,输入,输出]形状,所以我尝试使用tf.constant()为我的张量创建张量形状为[5,5,1,3]的过滤器(因此将3个形状为5x5的过滤器应用于具有1个通道的输入),但tf.constant()的结果看起来不正确。结果是这样的:
[[[[ -5 7 -12]]
[[ 21 0 2]]
[[ -6 9 -6]]
[[ 2 -2 8]]
[[-6 4 -1]]]
[[[ 2 -6 8]]
[[ -6 2 -1]]
[[ 2 -2 2]]
[[ -1 1 5]]
[[ 4 3 2]]]
...etc
看起来不像3个5x5滤镜的形状。
如果使用形状为[1,3,5,5]的tf.constant(),我会得到:
[[[[ -5 7 -12 21 0]
[ 2 -6 9 -6 2]
[ -2 8 -6 4 -1]
[ 2 -6 8 -6 2]
[ -1 2 -2 2 -1]]
[[ 1 5 4 3 2]
[ 4 0 -2 0 4]
[ 2 -1 7 -3 5]
[ -1 0 -1 0 -1]
[ 5 0 9 0 5]]
...etc
确实是 的5x5滤镜,但它不是tf.nn.conv2d()所采用的正确形状
所以我对这种不匹配感到困惑,不知道该怎么做。
答案 0 :(得分:1)
最好不要担心过滤器的外观。只需跟踪形状以确保它们有意义即可。
以下是将2个Sobel滤镜应用于图像的示例:
from skimage import data
img = np.expand_dims(data.camera(), -1)
img = np.expand_dims(img, 0) # shape: (1, 512, 512, 1)
sobel_x = np.array([[-0.25, -0.2 , 0. , 0.2 , 0.25],
[-0.4 , -0.5 , 0. , 0.5 , 0.4 ],
[-0.5 , -1. , 0. , 1. , 0.5 ],
[-0.4 , -0.5 , 0. , 0.5 , 0.4 ],
[-0.25, -0.2 , 0. , 0.2 , 0.25]])
sobel_y = np.array([[-0.25, -0.4 , -0.5 , -0.4 , -0.25],
[-0.2 , -0.5 , -1. , -0.5 , -0.2 ],
[ 0. , 0. , 0. , 0. , 0. ],
[ 0.2 , 0.5 , 1. , 0.5 , 0.2 ],
[ 0.25, 0.4 , 0.5 , 0.4 , 0.25]])
filters = np.concatenate([[sobel_x], [sobel_y]]) # shape: (2, 5, 5)
filters = np.expand_dims(filters, -1) # shape: (2, 5, 5, 1)
filters = filters.transpose(1, 2, 3, 0) # shape: (5, 5, 1, 2)
# Convolve image
ans = tf.nn.conv2d((img / 255.0).astype('float32'),
filters,
strides=[1, 1, 1, 1],
padding='SAME')
with tf.Session() as sess:
ans_np = sess.run(ans) # shape: (1, 512, 512, 2)
filtered1 = ans_np[0, ..., 0]
filtered2 = ans_np[0, ..., 1]
使用2个滤镜对图像进行正确的卷积,结果图像如下所示:
plt.matshow(filtered1)
plt.show()
plt.matshow(filtered2)
plt.show()
答案 1 :(得分:0)
第一种情况似乎是正确显示形状为[5, 5, 1, 3]
的过滤器。看一下方括号的数量-张量流显示了每个小盒子的水平方向的第4维,垂直方向的第2维。 (第三个维度为1,因此没有必要显示)