2016-11-03 46 views
2

我有一個3D卷的輸入數據,並且想要將ConvNet應用於每個切片。Tensorflow:切片數據並將卷積應用到每個切片

這是個重複的問題。可悲的是沒有回答: How to slice a batch and apply an operation on each slice in TensorFlow

在凱拉斯我會用TimeDistributed圖層。 在Tensorflow中我找不到直接的等價物。相反,它接合我,我不得不自己分割數據。

這是我到目前爲止的代碼:

x=tf.placeholder(tf.float32, shape=[None, 40, 40, 40, 1]) 
slices=tf.split(0,40, x) 

segmented_slices=[] 

for slice in slices: 
    # apply a ConvNet to each slice 
    reshaped=tf.reshape(slice, (40, 40, 1))   #<-------second error 
    # reshaped=tf.reshape(slice, (None, 40, 40, 1)) #<-------third error 

    # segmented_slice=conv2d(slice, 3,1,32)   #<-------first error 
    segmented_slice=conv2d(reshaped, 3,1,32) 
    segmented_slice=conv2d(segmented_slice, 3,32,32) 

    #... (more convolutions) 

    segmented_slices.append(segmented_slice) 

volume=tf.concat(0, segmented_slices) 

基本佈局是split - > ConvNet - >concat。 但split保持維度。如果我簡單地傳遞到slice卷積,它抱怨:

ValueError: Shape (?, 40, 40, 40, 1) must have rank 4 

所以我加了重塑。這確實減少了維度的數量。但顯然它也削減了batch_size。與第一個錯誤消息相比,問號和前40個都不見了。

ValueError: Shape (40, 40, 1) must have rank 4 

看來我需要保持batch_size在重塑。我試圖在元組中添加None。這產生了另一個錯誤信息:

TypeError: Expected int32, got None of type '_Message' instead. 

這是正確的方法嗎? 我應該自己處理這個嗎?

+0

代碼頂部的tf.split指定要分割的批次維度,但它看起來像要在大小爲40的一個維上進行分割。 'tf.split(1,40,x)]'''slice = [tf.squeeze(sliced,squeeze_dims = [1])''''''''''''''這給了我一個40(?,40,40,1)張量表的清單。順便說一句,你可以通過使用'tf.shape'將形狀作爲張量來重塑某些東西,但保留一個或多個未知維度。 –

回答

2

如果Keras TimeDistributed層是你所需要的,讓我們來看看它是如何實現的:

input_length = input_shape[1] # assume 2nd dim is the one to slice 
# ... 
# Shape: (num_samples * timesteps, ...) 
inputs = K.reshape(inputs, (-1,) + input_shape[2:]) 
y = self.layer.call(inputs) # (num_samples * timesteps, ...) 
# Shape: (num_samples, timesteps, ...) 
output_shape = self.compute_output_shape(input_shape) 
y = K.reshape(y, (-1, input_length) + output_shape[2:]) 

的基本思路是,以重塑張量以這樣的方式在第一和第二尺寸(批次和切片尺寸)摺疊成一個。換句話說,每個「切片」可以被認爲是該批次中的附加數據點。然後對這個新的虛擬批次應用任何計算並在最後重新恢復到原始形狀。 所有這些操作都可以在Tensorflow中輕鬆實現。