How to file a resizing input in Tensorflow

I want to train a network with planar curves, which I represent as numpy arrays with shape (L,2) . The number 2 indicates the x, y coordinates, and L is the number of points changing in my dataset. I consider x, y as two different "channels".

I implemented the next_batch(batch_size) function, which provides the next batch as a 1D numpy array with the form (batch_size,) containing elements that are 2D arrays with the form: (L,2) . These are my curves, and as mentioned earlier, L is different between the elements. (I did not want to be limited to a fixed number of points on the curve).

My question is:

How can I manipulate the next_batch() from next_batch() , so I can feed the network using input curves using a scheme similar to the one that appears in the Tensorflow tutorial: https://www.tensorflow.org/get_started/mnist/pros

ie using the feed_dict mechanism. In this tourial, the input size was fixed in the code line of the textbook:

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

batch[0] has a fixed form: (50,784) (50 = # samples, 784 = #pixels)

I cannot convert my input to a numpy array with the form (batch_size,L,2) since the array must have a fixed size in each dimension. So what can I do?

I already defined a placeholder (which may have an unknown size):

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

but how can I feed him properly?

Thank you very much

+5
source share
4 answers

The short answer that you are probably looking for: you cannot without filling out or grouping the samples in length.

To develop a little: in a tensor flow, the dimensions should be fixed throughout the batch, and arrays with teeth are not supported. The sizes may not be known a priori (in this case you set the dimensions of the placeholders to None ), but they are still displayed at run time, so your decision to have a placeholder:

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

cannot work, because it is semantically equivalent to the words "I don’t know the length of the curve constant in a batch a priori, deduce it at run time from the data."

This does not mean that your model cannot accept inputs of different dimensions at all if you structure it accordingly, but the data that you sess.run() it every time you call sess.run() should have fixed sizes.

So your options are as follows:

  • Place your parties in the second dimension.
    Let's say that you have 2 curve shapes (4, 2) and (5, 2) , and you know that the maximum curve length in your dataset is 6, you can use np.pad as follows:

     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. ]] 
  • Let your next_batch() function return a batch of curves grouped by length.

These are standard ways to do things when working with gear arrays.

Another possibility, if your task allows this, is to combine all your points in one form tensor (None, 2) and change your model to work in single points, as if they were samples in a batch. If you save the original sample lengths in a separate array, you can restore the model output by cutting it correctly. This is extremely inefficient and requires you to make any assumptions about your problem, but this is an opportunity.

Greetings and good luck!

+1
source

You can use input with different sizes in TF. just submit the data in the same way as in the tutorial below, but do not forget to define the changing sizes in the placeholder as β€œNo”.

Here is a simple filler filler example with various forms:

 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}) 
+5
source

You can use the placeholder with the initial var with [None, ..., None]. Each β€œNo” means that in this dimension there are input channel data for the compiler. For example, [No, No] means a matrix with any row and column lengths that you can feed. However, you must take care of what type of NN you are using. Because when you work with CNN, at the level of convolution and pool, you must determine the specific size of the "tensor".

+1
source

Tensorflow Fold may interest you.

From Tensorflow Fold README:

TensorFlow Fold is a library for creating TensorFlow models that consume structured data, where the structure of the calculation graph depends on the structure of the input data. Fold implements dynamic dosing. Batches of arbitrary calculation graphs are converted to create a static calculation graph. This graph has the same structure, no matter what input it receives, and TensorFlow can execute efficiently.

The structure of the graph can be adjusted to take an arbitrary value of L , so that any structured input can be read. This is especially useful when building architectures such as recursive neural networks. The overall structure is very similar to what you are used to (feed dicts, etc.). Since your application needs a dynamic computing graph, this can be a good step for you in the long run.

0
source

Source: https://habr.com/ru/post/1273638/


All Articles