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

问题描述 投票:2回答:4

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

tensorflow convolution
4个回答
6
投票

Code to make it work

下面是一些示例代码,它定义了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
投票

这不是一个真正的答案,而是一个代码片段,展示我如何使用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

0
投票

不,这是不可能的。 Convolution在n-dim超立方体上运行,所以你建议的不是卷积,而是某种pedro-ponte算子。您可以自由地使用write it on your own(基于tf转换运算符),但这并不容易,并且很可能不会取得比卷积更好的结果。


0
投票

任意过滤器(权重放在任何地方)都不可用,但存在一个有用的版本称为atrous卷积,它将权重放在备用网格上,可以处理您的具体示例。

例如,在您的情况下,您可以尝试

W = tf.Variable(tf.random_uniform((1, 2, n_in, n_out))
tf.nn.atrous_conv2d(value, W, (1, 2), 'SAME')
© www.soinside.com 2019 - 2024. All rights reserved.