我在由2d图像组成的数据样本上使用卷积图层。滤波器形状的一个选项是1x2,它作用于两个相邻像素的1x2连续块。如果我想要一个也可以作用于2个像素的滤镜,但是它们之间的另一个像素被分开了怎么办?是否有可能在神经网络中对这样的滤波器进行编码?
答案 0 :(得分:6)
下面是一些示例代码,它定义了Conv2d的内核和5x5掩码,只允许中心值和外部值通过。
import tensorflow as tf
import numpy as np
image = np.array( range(25) ).reshape([1,5,5,1] ).astype( float )
image = tf.stop_gradient( tf.constant( image , dtype=tf.float32 ) )
kern = tf.Variable( tf.ones( [5,5,1,1] , dtype=tf.float32) )
mask = np.array([[ 1., 1., 1., 1., 1.],
[ 1., 0., 0., 0., 1.],
[ 1., 0., 1., 0., 1.],
[ 1., 0., 0., 0., 1.],
[ 1., 1., 1., 1., 1.]]).reshape( [5,5,1,1] )
mask_variable = tf.Variable( mask , dtype=tf.float32 )
mask = tf.stop_gradient( mask_variable )
output = tf.nn.conv2d( image , kern , strides=[1,1,1,1] , padding="VALID" )
output_with_mask = tf.nn.conv2d( image , kern * mask , strides=[1,1,1,1] , padding="VALID" )
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print "Using whole kernal :",sess.run( output )
print "Using kernal with a mask :",sess.run( output_with_mask )
输出
Using whole kernal : [[[[ 300.]]]]
Using kernal with a mask : [[[[ 204.]]]]
此外,backprop不会更改掩码,因为掩码包含在tf.stop_gradient中。
欢呼声
答案 1 :(得分:1)
这并不是一个真正的答案,而是一个代码片段,展示了我如何使用Panchishin的答案来编写六角游戏代码(主持人:如果有更好的方法来扩展评论或向他人发送私人消息,请让我知道)
注意:我是深度学习的初学者。
该游戏是Blackhole,用于2018年CodeCup竞赛:http://archive.codecup.nl/2018/60/rules_blackhole.html 这是一个六角形的六角形游戏。下面的代码定义了卷积层和relu层。
def conv_weight_variable(w, h, in_ch, out_ch, learn):
d = 1.0 / np.sqrt(in_ch * w * h)
initial = tf.truncated_normal([w, h, in_ch, out_ch], stddev=d)
return tf.Variable(initial, trainable=learn), iEnd
def conv_bias_variable(w, h, in_ch, out_ch, learn):
d = 1.0 / np.sqrt(in_ch * w * h)
initial = tf.constant([0.1*d]*out_ch, dtype=tf.float32)
return tf.Variable(initial, trainable=learn), iEnd
def relu_conv_layer(input, in_ch, out_ch, learn):
W, iEnd = conv_weight_variable(3, 3, in_ch, out_ch, learn)
o = np.zeros((in_ch, out_ch), np.float32)
i = np.ones((in_ch, out_ch), np.float32)
maskW = np.array([[ o, i, i],
[ i, i, i],
[ i, i, o]])
maskW = tf.constant(maskW, dtype=tf.float32)
b, iEnd = conv_bias_variable(3, 3, in_ch, out_ch, learn)
conv = tf.nn.conv2d(input, W * maskW, strides=[1, 1, 1, 1], padding='SAME')
o = np.zeros(out_ch, np.float32)
i = np.ones(out_ch, np.float32)
maskO = np.array([[ i, i, i, i, i, i, i, i],
[ i, i, i, i, i, i, i, o],
[ i, i, i, i, i, i, o, o],
[ i, i, i, i, i, o, o, o],
[ i, i, i, i, o, o, o, o],
[ i, i, i, o, o, o, o, o],
[ i, i, o, o, o, o, o, o],
[ i, o, o, o, o, o, o, o]])
maskO = tf.constant(maskO, dtype=tf.float32)
return tf.nn.relu(conv + b)*maskO, W, b, iEnd
答案 2 :(得分:0)
不,不可能。 Convolution在n-dim超立方体上运行,所以你建议的不是卷积,而是某种pedro-ponte算子。您可以自由write it on your own(基于tf转换运算符),但这并不容易,并且很可能无法获得比卷积更好的结果。
答案 3 :(得分:0)
任意过滤器(权重放在任何地方)都不可用,但存在一个名为atrous convolution的有用版本,它将权重放在备用网格上,可以处理您的具体示例。
例如,在您的情况下,您可以尝试
W = tf.Variable(tf.random_uniform((1, 2, n_in, n_out))
tf.nn.atrous_conv2d(value, W, (1, 2), 'SAME')