我有 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
因此我添加了 reshape 。这确实减少了维数。但显然它也削减了batch_size。与第一条错误信息相比,问号和前 40 都消失了。
ValueError: Shape (40, 40, 1) must have rank 4
看来我需要在 reshape 中保留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 中轻松实现。
关于python - Tensorflow:对数据进行切片并对每个切片应用卷积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40402050/