我有一个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
- &gt; ConvNet - &gt; 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 :(得分:2)
如果您需要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:])
基本思想是以第一维和第二维(批量和切片维度)折叠成一个方式重新形成张量。换句话说,每个&#34;切片&#34;可以视为批处理中的附加数据点。然后将任何计算应用于此新虚拟批次,并在最后重新形成原始形状。 所有这些操作都可以在Tensorflow中轻松实现。