Skip to main content
 首页 » 编程设计

python之Tensorflow:切片数据并对每个切片应用卷积

2024年10月17日26lovecherry

我有一个 3D 体积的输入数据,想对每个切片应用一个 ConvNet。

这个问题重复了。遗憾的是没有答案: How to slice a batch and apply an operation on each slice in TensorFlow

在 Keras 中我会使用 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. 

这是正确的方法吗? 我应该自己处理吗?

请您参考如下方法:

如果 Keras TimeDistributed Layer 是您所需要的,让我们看看它是如何实现的:

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:]) 

基本思想是以第一维和第二维(批处理和切片维)合并为一个的方式 reshape 张量。换句话说,每个“切片”都可以视为批处理中的一个附加数据点。然后将任何计算应用于这个新的虚拟批处理,并在最后 reshape 回原始形状。 所有这些操作都可以在 Tensorflow 中轻松实现。