2017-11-24 203 views
6

Chcę trenować sieć z krzywymi płaskimi, które reprezentuję jako tablice numpy o kształcie (L,2). Liczba 2 oznacza współrzędne x, y, a L to liczba punktów, która zmienia się w moim zestawie danych. Traktuję x, y jako 2 różne "kanały".Jak wprowadzić dane wejściowe ze zmianą rozmiaru w Tensorflow

Zaimplementowałem funkcję, next_batch(batch_size), która zapewnia następną partię jako tablicę 1D numpy o kształcie (batch_size,), zawierającą elementy będące tablicami 2D o kształcie: (L,2). To są moje krzywe, i jak już wcześniej wspomniano, L jest różny pomiędzy żywiołami. (Nie chciałem ograniczać się do ustalonej liczby punktów na krzywej).

Moje pytanie:

Jak mogę manipulować wyjście z next_batch() więc będę w stanie zasilać sieć z krzywymi wejściowych, wykorzystując schemat podobny do tego, co pojawia się w Tensorflow tutorialu: https://www.tensorflow.org/get_started/mnist/pros

tj. przy użyciu mechanizmu feed_dict. w danym turorial wielkości wejściowej została ustalona w linii kodu samouczek za:

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

batch[0] ma stały kształt: (50,784) (50 = # próbek, 784 = #pixels)

Nie mogę przekształcić mój wprowadzanie do numpy array o kształcie (batch_size,L,2) , ponieważ tablica powinna mieć stały rozmiar w każdym wymiarze. Więc co mogę zrobić?

już zdefiniowany zastępczy (które mogą mieć nieznaną wielkość):

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

ale jak mogę karmić go właściwie?

Bardzo dziękuję

+0

Czy dopełnienie wejścia jest możliwym rozwiązaniem? –

+0

Niestety, nie, w moim problemie –

+0

@Day_Dreamer trzeba go podkładać w celu użycia batchowania. A co z tworzeniem zastępczego długości? – Maxim

Odpowiedz

1

Krótka odpowiedź, że jesteś prawdopodobnie szuka, nie możesz bez wyściółki lub grupowanie próbek o długości.

Aby opracować nieco: w tensorflow, wymiary muszą być stałe w całej partii, a postrzępione tablice nie są obsługiwane natywnie.
Wymiary mogą być znane a priori (w takim przypadku można ustawić wymiary zastępcze do None), ale nadal wywnioskować przy starcie, więc rozwiązanie posiadania zastępczy:

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

nie może pracować, bo to semantycznie równoważne powiedzenie "Nie wiem, stała długość linii w a priori, wywnioskować go w czasie wykonywania z danych".

Nie oznacza to, że model generalnie nie może przyjmować danych wejściowych o różnych wymiarach, jeśli odpowiednio je utworzysz, ale dane, które podajesz za każdym razem, gdy wywołujesz sess.run(), muszą mieć stałe wymiary.

opcjami, a następnie, są następujące:

  1. Pad wasze partie wzdłuż drugiego wymiaru.
    Załóżmy, że masz 2 krzywe kształtu (4, 2) i (5, 2) i wiesz maksymalną długość krzywej w ty zestaw danych jest 6, można użyć np.pad następująco:

    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. miec next_batch() funkcyjnych partii powrotów krzywych zgrupowane według długość.

Oto standardowe sposoby robienia rzeczy w przypadku postrzępionych tablic.

Inną możliwością, jeśli pozwala na to twoje zadanie, jest połączenie wszystkich punktów w jeden tensor o kształcie (None, 2) i zmiana modelu, aby działał w pojedynczych punktach tak, jakby były próbkami w partii. Jeśli zapiszesz oryginalne długości próbek w osobnej tablicy, możesz przywrócić wyniki modelu, krojąc je poprawnie. Jest to wysoce nieefektywne i wymaga różnego rodzaju założeń dotyczących problemu, ale jest to możliwe.

Pozdrowienia i powodzenia!

5

Możesz użyć danych wejściowych o różnych rozmiarach w TF. po prostu przesyłaj dane w taki sam sposób, jak w tutorialu, który wymieniłeś, ale pamiętaj, aby zdefiniować zmieniające się wymiary w symbolu zastępczym jako Brak.

Oto prosty przykład karmienie zastępczy z różnych kształtach:

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}) 
0

Tensorflow Fold może Cię zainteresować.

Z Tensorflow Fold README:

TensorFlow Fold jest biblioteką do tworzenia modeli TensorFlow które zużywają danych strukturalnych, gdzie struktura wykresu obliczeń zależy od struktury data.Fold wejściowego realizuje dynamiczny dozowania . Partie arbitralnie ukształtowanych wykresów obliczeniowych są przekształcane w celu wygenerowania statycznego wykresu obliczeniowego. Ten wykres ma taką samą strukturę niezależnie od tego, jakie wejście otrzymuje i może być efektywnie wykonany przez TensorFlow.

Struktura wykres można skonfigurować tak, aby przyjąć dowolną wartość L tak zorganizowany, że każde wejście może być odczytywany w. Jest to szczególnie przydatne przy budowaniu architektury takie jak rekurencyjnych sieci neuronowych. Ogólna struktura jest bardzo podobna do tego, do czego jesteś przyzwyczajony (feed dyktuje, itp.). Ponieważ potrzebujesz dynamicznego wykresu obliczeniowego dla swojej aplikacji, może to być dobry ruch w dłuższej perspektywie.

1

Możesz użyć elementu zastępczego z początkowym elementem var za pomocą [Brak, ..., Brak]. Każde "Brak" oznacza, że ​​dane wejściowe są podawane w tym wymiarze dla kompilatora. Na przykład [Brak, Brak] oznacza macierz z dowolnym wierszem i kolumną, którą można podać. Powinieneś jednak zadbać o to, jakiego rodzaju NN używasz. Ponieważ kiedy zajmujesz się CNN, w warstwie splotu i warstwie puli musisz określić konkretny rozmiar "tensora".