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

Day*_*mer 7 python numpy python-3.x tensorflow

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

我实现了一个函数,next_batch(batch_size)它提供下一个批处理作为带有形状的1D numpy数组(batch_size,),包含具有shape:的2D数组元素(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})
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

但我怎么能正确喂它?

非常感谢你

Mat*_*ugi 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})
Run Code Online (Sandbox Code Playgroud)


Dan*_*ola 6

您可能正在寻找的简短答案:您不能不按长度对样本进行填充或分组。

详细说明一下:在 tensorflow 中,尺寸必须在整个批次中固定,并且锯齿状数组本身不支持。
维度可能是先验未知的(在这种情况下,您将占位符的维度设置为None),但仍会在运行时推断出来,因此您拥有占位符的解决方案:

x = tf.placeholder(tf.float32, [None, None, 2]) 
Run Code Online (Sandbox Code Playgroud)

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

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

那么,您的选择如下:

  1. 沿第二维填充批次。
    你说你有形状的两条曲线(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.        ]]
    
    Run Code Online (Sandbox Code Playgroud)
  2. 让您的next_batch()函数返回按长度分组的曲线批次。

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

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

干杯,祝你好运!