我有一个1D张量,我希望将其划分为重叠块。我想的是:
tensor = tf.constant([1, 2, 3, 4, 5, 6, 7])
overlapping_blocker(tensor,block_size=3,stride=2)
=> [[1 2 3], [3, 4, 5], [5, 6, 7]]
到目前为止,我只找到了将张量分割成非重叠块的方法。谁知道解决这个问题的方法?
这需要适用于任意输入维度(即我的输入类似于tf.placeholder([None])
答案 0 :(得分:8)
您可以使用tf.nn.conv2d来提供帮助。基本上,你在输入上使用block_size的滑动过滤器,按步幅步进。要使所有矩阵索引排成一行,您必须进行一些重塑。
import tensorflow as tf
def overlap(tensor, block_size=3, stride=2):
reshaped = tf.reshape(tensor, [1,1,-1,1])
# Construct diagonal identity matrix for conv2d filters.
ones = tf.ones(block_size, dtype=tf.float32)
ident = tf.diag(ones)
filter_dim = [1, block_size, block_size, 1]
filter_matrix = tf.reshape(ident, filter_dim)
stride_window = [1, 1, stride, 1]
# Save the output tensors of the convolutions
filtered_conv = []
for f in tf.unstack(filter_matrix, axis=1):
reshaped_filter = tf.reshape(f, [1, block_size, 1, 1])
c = tf.nn.conv2d(reshaped, reshaped_filter, stride_window, padding='VALID')
filtered_conv.append(c)
# Put the convolutions into a tensor and squeeze to get rid of extra dimensions.
t = tf.stack(filtered_conv, axis=3)
return tf.squeeze(t)
# Calculate the overlapping strided slice for the input tensor.
tensor = tf.constant([1, 2, 3, 4, 5, 6, 7], dtype=tf.float32)
overlap_tensor = overlap(tensor, block_size=3, stride=2)
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
in_t, overlap_t = sess.run([tensor, overlap_tensor])
print 'input tensor:'
print in_t
print 'overlapping strided slice:'
print overlap_t
应该给你输出:
input tensor:
[ 1. 2. 3. 4. 5. 6. 7.]
overlapping strided slice:
[[ 1. 2. 3.]
[ 3. 4. 5.]
[ 5. 6. 7.]]
这是我工作的初始版本,它不允许使用变量block_size,但我认为更容易看到卷积滤波器发生了什么 - 我们采用3个值的向量,每个步幅。
def overlap(tensor, stride=2):
# Reshape the tensor to allow it to be passed in to conv2d.
reshaped = tf.reshape(tensor, [1,1,-1,1])
# Construct the block_size filters.
filter_dim = [1, -1, 1, 1]
x_filt = tf.reshape(tf.constant([1., 0., 0.]), filter_dim)
y_filt = tf.reshape(tf.constant([0., 1., 0.]), filter_dim)
z_filt = tf.reshape(tf.constant([0., 0., 1.]), filter_dim)
# Stride along the tensor with the above filters.
stride_window = [1, 1, stride, 1]
x = tf.nn.conv2d(reshaped, x_filt, stride_window, padding='VALID')
y = tf.nn.conv2d(reshaped, y_filt, stride_window, padding='VALID')
z = tf.nn.conv2d(reshaped, z_filt, stride_window, padding='VALID')
# Pack the three tensors along 4th dimension.
result = tf.stack([x, y, z], axis=4)
# Squeeze to get rid of the extra dimensions.
result = tf.squeeze(result)
return result
答案 1 :(得分:3)
您可以使用tf.extract_image_patches
实现相同的目标。
tensor = tf.placeholder(tf.int32, [None])
def overlapping_blocker(tensor,block_size=3,stride=2):
return tf.squeeze(tf.extract_image_patches(tensor[None,...,None, None], ksizes=[1, block_size, 1, 1], strides=[1, stride, 1, 1], rates=[1, 1, 1, 1], padding='VALID'))
result = overlapping_blocker(tensor,block_size=3,stride=2)
sess = tf.InteractiveSession()
print(result.eval({tensor:np.array([1, 2, 3, 4, 5, 6, 7], np.int32)}))
#[[1 2 3]
#[3 4 5]
#[5 6 7]]
答案 2 :(得分:2)
以下是使用您的示例的相对简单的方法:
MODS: Durgal, Wolfy, Pat
输出:
def overlapping_blocker(tensor,block_size,stride):
blocks = []
n = tensor.get_shape().as_list()[0]
ilo = range(0, n, stride)
ihi = range(block_size, n+1, stride)
ilohi = zip(ilo, ihi).
for ilo, ihi in ilohi:
blocks.append(tensor[ilo:ihi])
return(tf.pack(blocks, 0))
with tf.Session() as sess:
tensor = tf.constant([1., 2., 3., 4., 5., 6., 7.])
block_tensor = overlapping_blocker(tensor, 3, 2)
print(sess.run(block_tensor))
答案 3 :(得分:0)
如果您正在寻找一种方法将每个滚动窗口作为单个张量(即每次调用tf.FIFOQueue
,您的窗口都会移动一个。您可以使用tf.train.range_input_producer
以及def window_input_producer(tensor, window_size, capacity=32, num_epochs=None):
num_windows = tf.shape(tensor)[0] - window_size
range_queue = tf.train.range_input_producer(
num_windows,
shuffle=False,
capacity=capacity,
num_epochs=num_epochs
)
index = range_queue.dequeue()
window = tensor[index:index + window_size]
queue = tf.FIFOQueue(capacity=capacity,
dtypes=[tensor.dtype.base_dtype],
shapes=[window_size])
enq = queue.enqueue(window)
tf.train.add_queue_runner(
tf.train.QueueRunner(queue, [enq])
)
return queue.dequeue()
创建一个执行此操作的队列:
编辑:根据原始答案中的要求更新以使用可变长度张量
final File test = new File("files/test.txt");
final File dest = new File("WebContent");
try {
FileUtils.copyFileToDirectory(test, dest);
} catch (final IOException e) {
e.printStackTrace();
}
答案 4 :(得分:0)
我不确定这个问题是否得到了充分的回答,但您可以使用python生成器函数来创建重叠的窗口:
def gen_batch():
# compute number of batches to emit
num_of_batches = round(((len(sequence) - batch_size) / stride))
# emit batches
for i in range(0, num_of_batches * stride, stride):
result = np.array(sequence[i:i + batch_size])
yield result
sequence = np.array[1,2,3,4,5,6,7,8,9]
batch_size = 3
stride = 2
gen = gen_batch()
print(next(gen))
[1,2,3]
print(next(gen))
[3,4,5]
...
print(next(gen))
[7,8,9]
一旦定义了生成器函数,就可以使用TensorFlow的数据集类来调用每个切片:
ds = tf.data.Dataset.from_generator(
gen_batch,
(tf.float64),
(tf.TensorShape([batch_size, dim_width])))
ds_out = ds.make_one_shot_iterator().get_next()
print(sess.run(ds_out)))
[1,2,3]
print(sess.run(ds_out)))
[3,4,5]
...
print(sess.run(ds_out)))
[7,8,9]
答案 5 :(得分:-1)
我认为该功能
tf.signal.overlap_and_add(
signal, frame_step, name=None
)
可能是您想要的。它解决了我的问题。已在
中回答