2016-04-07 10 views
3

2つのイメージが畳み込みレイヤーでウェイトを共有し、完全連結レイヤーを通過する前に連結されるサイアム畳み込みニューラルネットワークを実装したいと考えています。私は実装を試みましたが、むしろ「ハッキングされた」ソリューションのようです。特に、私はテンソルの演算を単純にPythonの関数として定義しましたが、これが許されるかどうかはわかりません。テンソルフローでサイアーズネットワークを実装する

images = tf.placeholder(tf.float32, shape=[None, 64 * 64]) 
# Convolutional layers 
# ... 
# ... 
# Results in pool3_flat, which is the flattened output of the third convolutional layer 
pool3_flat = tf.reshape(pool3, [-1, 8 * 8 * 128]) 

# Now, merge the image pairs, where each pair is composed of adjacent images in the batch, with a stride of 2 
def merge_pairs(): 
    # Create a tensor to store the merged image pairs 
    # The batch size is 128, therefore there will be 64 pairs (64 in the first dimension of this tensor) 
    merged_pairs = tf.Variable(tf.zeros([64, 8 * 8 * 128])) 
    # Split the images into 64 pairs 
    pairs = tf.split(0, 64, pool3_flat) 
    # For each pair, concatenate the two images across dimension 1, and set this tensor in the appropriate row of merged_pairs 
    for pair_num, pair in enumerate(pairs): 
     merged_pair = tf.concat(1, pair) 
     merged_pairs[pair_num] = merged_pair 
    return merged_pairs 


# Proceed with operations on the merged_pair tensor, as if the batch size is 64 
fc4 = tf.matmul(merge_pairs(), weights4) 
# ... 
# ... 

これは、コンパイルし、正常に動作すると思われる一方で、予想通り、結果は実際にはありません。ここで

私がしようとしたコードです。だから、TensorFlowのビルトインオペレーションを使ってSiameseネットワークを実装するより良い方法があるのだろうか?

答えて

5

あなたは多少のように、tf.packtf.unpackを利用することができます。これを行うには

pairs = tf.pack(tf.split(0, 64, pool3_flat)) 
left, right = tf.unpack(tf.transpose(pairs, perm=[1,0,2])) 
merged_pairs = tf.concat(1, [left, right]) 

きれいな方法は、あなたが2つのネットワークを定義し、使用できるように、最初から分離あなたのペアを維持することです各ネットワークで同じ学習可能な変数。

あなたは(畳み込み層のスキップ)のようなものを持っているでしょう:

image_left = tf.placeholder(tf.float32, shape=[None, 64, 64, 1]) 
image_right = tf.placeholder(tf.float32, shape=[None, 64, 64, 1]) 

pool_left = tf.nn.max_pool(image_left, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') 
pool_right = tf.nn.max_pool(image_left, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') 

pool_flat_left = tf.reshape(pool_left, [-1, 32*32]) 
pool_flat_right = tf.reshape(pool_right, [-1, 32*32]) 

そして、単に連結左右の寸法で1

concat_layer = tf.concat(1, [pool_flat_left, pool_flat_right]) 

あなたはまた後でバッチサイズを変更することができますこの方法。 各サイズ(左右)に同じウェイトとバイアスを使用してください。

+0

ああ、実際には、2つの画像に対して別々の操作を明示的に書くことが実際よりはるかに理にかなっています。これはもう少しコードですが、はるかに管理しやすくなります! – Karnivaurus

+0

あなたのimage_leftは正しいプールですか?'pool_right = tf.nn.max_pool(image_left、ksize = [1,2,2,1]、strides = [1,2,2,1]、パディング= 'SAME')' –

関連する問題