如何在Tensorflow中输入大小不一的输入

问题描述 投票:6回答:4

我想用平面曲线训练一个网络,我将其表示为形状为(L,2)的numpy数组。数字2代表x,y坐标,L是我的数据集中正在变化的点数。我将x,y视为2个不同的“通道”。

我实现了一个函数next_batch(batch_size),它提供下一批作为形状为(batch_size,)的1D numpy数组,包含具有形状的二维数组的元素:(L,2)。这些是我的曲线,如前所述,L在元素之间是不同的。 (我不想局限于曲线中的固定点数)。

我的问题:

我如何操纵next_batch()的输出,以便我能够使用类似于Tensorflow教程中显示的方案为输入曲线提供网络:https://www.tensorflow.org/get_started/mnist/pros

即使用feed_dict机制。在给定的turorial中,输入大小是固定的,在教程的代码行中:

train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

batch[0]有一个固定的形状:(50,784)(50 =#samples,784 = #pixels)

我不能将我的输入转换为形状为(batch_size,L,2)的numpy数组,因为数组在每个维度都应该有固定的大小。那我该怎么办?

我已经定义了一个占位符(可能有未知的大小):

#first dimension is the sample dim, second is curve length, third:x,y coordinates    
x = tf.placeholder(tf.float32, [None, None,2]) 

但我怎么能正确喂它?

非常感谢你

python python-3.x numpy tensorflow
4个回答
2
投票

您可能正在寻找的简短回答:您不能没有填充或按长度分组样本。

详细说明:在tensorflow中,必须在整个批处理中修复维度,并且本机不支持锯齿状数组。 维度可能是先验未知的(在这种情况下,您将占位符的维度设置为None)但仍在运行时推断,因此您的占位符解决方案:

x = tf.placeholder(tf.float32, [None, None, 2]) 

无法正常工作,因为它在语义上等同于“我不知道先前批处理中曲线的恒定长度,在运行时从数据中推断它”。

这并不是说您的模型通常不能接受不同维度的输入,如果您相应地构建它,但每次调用sess.run()时提供的数据必须具有固定的维度。

您的选择如下:

  1. 沿第二维填充批次。 假设您有2条形状(4, 2)(5, 2)的曲线,并且您知道数据集中的最大曲线长度为6,您可以使用np.pad,如下所示: In [1]: max_len = 6 ...: curve1 = np.random.rand(4, 2) ...: curve2 = np.random.rand(5, 2) ...: batch = [curve1, curve2] In [2]: for b in batch: ...: dim_difference = max_len - b.shape[0] ...: print np.pad(b, [(0, dim_difference), (0,0)], 'constant') ...: [[ 0.92870128 0.12910409] [ 0.41894655 0.59203704] [ 0.3007023 0.52024492] [ 0.47086336 0.72839691] [ 0. 0. ] [ 0. 0. ]] [[ 0.71349902 0.0967278 ] [ 0.5429274 0.19889411] [ 0.69114597 0.28624011] [ 0.43886002 0.54228625] [ 0.46894651 0.92786989] [ 0. 0. ]]
  2. 让你的next_batch()函数返回按长度分组的批次曲线。

这些是处理锯齿状数组时的标准处理方式。

如果您的任务允许,另一种可能性是将所有点连接在一个形状(None, 2)的张量中,并将您的模型更改为单点操作,就好像它们是批量样本一样。如果将原始样本长度保存在单独的阵列中,则可以通过正确切片来恢复模型输出。这是非常低效的,需要对您的问题进行各种假设,但这是可能的。

干杯,祝你好运!


7
投票

您可以在TF中使用不同大小的输入。只需以与您列出的教程相同的方式提供数据,但请确保将占位符中的更改维度定义为None。

这是一个为不同形状的占位符提供简单示例:

import tensorflow as tf
import numpy as np


array1 = np.arange(9).reshape((3,3))
array2 = np.arange(16).reshape((4,4))
array3 = np.arange(25).reshape((5,5))

model_input = tf.placeholder(dtype='float32', shape=[None, None])
sqrt_result = tf.sqrt(model_input)
with tf.Session() as sess:
    print sess.run(sqrt_result, feed_dict={model_input:array1})
    print sess.run(sqrt_result, feed_dict={model_input:array2})
    print sess.run(sqrt_result, feed_dict={model_input:array3})

1
投票

你可以使用占位符,初始变量为[None,...,None]。每个“无”表示编译器在该维度上有输入馈送数据。例如,[None,None]表示可以提供任何行和列长度的矩阵。但是,您应该注意您使用哪种NN。因为当您处理CNN时,在卷积层和池层,您必须确定“张量”的特定大小。


0
投票

你可能会对Tensorflow Fold 感兴趣。

来自Tensorflow折叠自述文件:

TensorFlow Fold是一个用于创建消耗结构化数据的TensorFlow模型的库,其中计算图的结构取决于输入数据的结构.Fold实现动态批处理。批量任意形状的计算图被转换以产生静态计算图。无论接收到什么输入,该图都具有相同的结构,并且可以通过TensorFlow有效地执行。

可以设置图形结构以便接受任意的L值,以便可以读入任何结构化输入。这在构建诸如递归神经网络的体系结构时尤其有用。整体结构与您习惯的非常相似(提供dicts等)。由于您需要一个适用于您的应用程序的动态计算图形,从长远来看,这可能是一个很好的举措。

© www.soinside.com 2019 - 2024. All rights reserved.