我想用平面曲线训练一个网络,我将其表示为形状为(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])
但我怎么能正确喂它?
非常感谢你
您可能正在寻找的简短回答:您不能没有填充或按长度分组样本。
详细说明:在tensorflow中,必须在整个批处理中修复维度,并且本机不支持锯齿状数组。
维度可能是先验未知的(在这种情况下,您将占位符的维度设置为None
)但仍在运行时推断,因此您的占位符解决方案:
x = tf.placeholder(tf.float32, [None, None, 2])
无法正常工作,因为它在语义上等同于“我不知道先前批处理中曲线的恒定长度,在运行时从数据中推断它”。
这并不是说您的模型通常不能接受不同维度的输入,如果您相应地构建它,但每次调用sess.run()
时提供的数据必须具有固定的维度。
您的选择如下:
(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. ]]
next_batch()
函数返回按长度分组的批次曲线。这些是处理锯齿状数组时的标准处理方式。
如果您的任务允许,另一种可能性是将所有点连接在一个形状(None, 2)
的张量中,并将您的模型更改为单点操作,就好像它们是批量样本一样。如果将原始样本长度保存在单独的阵列中,则可以通过正确切片来恢复模型输出。这是非常低效的,需要对您的问题进行各种假设,但这是可能的。
干杯,祝你好运!
您可以在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})
你可以使用占位符,初始变量为[None,...,None]。每个“无”表示编译器在该维度上有输入馈送数据。例如,[None,None]表示可以提供任何行和列长度的矩阵。但是,您应该注意您使用哪种NN。因为当您处理CNN时,在卷积层和池层,您必须确定“张量”的特定大小。
你可能会对Tensorflow Fold 感兴趣。
来自Tensorflow折叠自述文件:
TensorFlow Fold是一个用于创建消耗结构化数据的TensorFlow模型的库,其中计算图的结构取决于输入数据的结构.Fold实现动态批处理。批量任意形状的计算图被转换以产生静态计算图。无论接收到什么输入,该图都具有相同的结构,并且可以通过TensorFlow有效地执行。
可以设置图形结构以便接受任意的L
值,以便可以读入任何结构化输入。这在构建诸如递归神经网络的体系结构时尤其有用。整体结构与您习惯的非常相似(提供dicts等)。由于您需要一个适用于您的应用程序的动态计算图形,从长远来看,这可能是一个很好的举措。