Tensorflow:将张量切片成重叠块 [英] Tensorflow: Slicing a Tensor into overlapping blocks

查看:31
本文介绍了Tensorflow:将张量切片成重叠块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个一维张量,我希望将其划分为重叠块.我在想这样的事情:tensor = tf.constant([1, 2, 3, 4, 5, 6, 7])

I have a 1D tensor that I wish to partition into overlapping blocks. I'm thinking of something like: 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]]

到目前为止,我只找到了将张量划分为不重叠块的方法.有人知道解决这个问题的方法吗?

So far I've only found ways to partition a tensor into non-overlapping blocks. Anybody knows of a way to solve this?

这需要适用于任意输入维度(即我的输入就像一个 tf.placeholder([None])

This needs to work for arbitrary input dimension (i.e. my input is like a tf.placeholder([None])

推荐答案

您可以使用 tf.nn.conv2d 提供帮助.基本上,您在输入上使用一个块大小的滑动过滤器,逐步进行.要使所有矩阵索引对齐,您必须进行一些整形.

You can use tf.nn.conv2d to help. Basically, you take a sliding filter of block_size over the input, stepping by stride. To make all the matrix indexes line up, you have to do some reshaping.

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

这篇关于Tensorflow:将张量切片成重叠块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆