conv2d的任意过滤器(与矩形相对)

时间:2017-07-05 00:05:37

标签: tensorflow convolution

我在由2d图像组成的数据样本上使用卷积图层。滤波器形状的一个选项是1x2,它作用于两个相邻像素的1x2连续块。如果我想要一个也可以作用于2个像素的滤镜,但是它们之间的另一个像素被分开了怎么办?是否有可能在神经网络中对这样的滤波器进行编码?

4 个答案:

答案 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')
相关问题