2016-01-23 8 views
11

Jak utworzyć instrukcję if za pomocą tensora boolowskiego? Mówiąc dokładniej, próbuję porównać tensor wielkości 1 ze stałą, sprawdzając, czy wartość w tensorze jest mniejsza od stałej. Stwierdziłem, że muszę ustawić stałą wielkość 1 tensora i użyć metody this, aby sprawdzić, czy pierwszy tensor jest mniejszy niż drugi tensor, ale nie jestem pewien, jak sprawić, by wynikowy tensor boolowski zmieścił się poprawnie w instrukcji if . Umieszczenie go jako zapytania dla instrukcji if sprawia, że ​​instrukcja zawsze zwraca wartość true.Jak utworzyć instrukcję if za pomocą boolowskiego tensora

EDYCJA: Jest to mniej więcej taki sam kod. Jednak otrzymuję błąd 'bool' object has no attribute 'name', niezależnie od tego, czy ma on parametry, czy nie, co powoduje, że myślę, że problem polega na tym, że nie zwraca on obiektu TensorFlow.

pred = tf.placeholder(tf.bool) 

def if_true(x, y, z): 
    #act on x, y, and z 
    return True 

def if_false(): 
    return False 

# Will be `tf.cond()` in the next release. 
from tensorflow.python.ops import control_flow_ops 
from functools import partial 
x = ... 
y = ... 
z = ... 

result = control_flow_ops.cond(pred, partial(if_true, x, y, z), if_false) 
+1

myślę, że trzeba wrócić 'obiektów Tensor' z' if_true' i ' funkcje if_false'. Mogą to być po prostu odpowiednio 'tf.constant (True)' i 'tf.constant (False)'.Jeśli twoje działania na 'x',' y' i 'z' wywołują efekty uboczne, pamiętaj, aby dodać zależność kontroli od nich do zwróconego tensora lub nie mogą one być wykonywane. – mrry

+0

To pokonuje cel pierwotnego warunku. Być może znalazłem obejście dla moich konkretnych zmiennych. – Beez

+0

Hmm, jeśli otrzymanie wyniku jako 'Tensor' nie spełnia twoich potrzeb, to zakładam, że nie podajesz wyniku do kolejnego submenu TensorFlow. W takim przypadku najprościej byłoby użyć 'sess.run()' i prostej instrukcji 'if'. – mrry

Odpowiedz

22

TL; DR: Trzeba użyć Session.run() aby uzyskać wartość logiczną Pythona, ale istnieją inne sposoby, aby osiągnąć taki sam wynik, który może być bardziej wydajny.

Wygląda na to, że już zorientowali się, jak uzyskać logiczną tensor ze swojej wartości, ale z korzyścią dla innych czytelników, będzie to wyglądać mniej więcej tak:

computed_val = ... 
constant_val = tf.constant(37.0) 
pred = tf.less(computed_val, constant_val) # N.B. Types of the two args must match 

Kolejna część jest jak używać go jako warunkowego. Najprostszym rozwiązaniem jest użycie Pythona if oświadczenie, ale aby to zrobić trzeba ocenić tensor pred użyciu Session.run():

sess = tf.Session() 

if sess.run(pred): 
    # Do something. 
else: 
    # Do something else. 

Jedno zastrzeżenie o użyciu Python if oświadczenie, że trzeba ocenić całe wyrażenie do pred, co utrudnia ponowne wykorzystanie wartości pośrednich, które zostały już obliczone. Chciałbym zwrócić uwagę na dwa inne sposoby obliczania wyrażeń warunkowych za pomocą TensorFlow, które nie wymagają oceny predykatu i odzyskania wartości Pythona.

Pierwszy sposób wykorzystuje tf.select() op warunkowo przejść przez wartości z dwóch tensorów przekazywane jako argumenty

pred = tf.placeholder(tf.bool) # Can be any computed boolean expression. 
val_if_true = tf.constant(28.0) 
val_if_false = tf.constant(12.0) 
result = tf.select(pred, val_if_true, val_if_false) 

sess = tf.Session() 
sess.run(result, feed_dict={pred: True}) # ==> 28.0 
sess.run(result, feed_dict={pred: False}) # ==> 12.0 

tf.select() op elementem mądry na wszystkich swoich argumentów, co pozwala na łączenie wartości z prac dwa tensory wejściowe. Aby uzyskać więcej informacji, patrz its documentation. Wadą modelu tf.select() jest to, że przed obliczeniem wyniku oblicza on zarówno val_if_true i val_if_false, co może być kosztowne, jeśli są to skomplikowane wyrażenia.

Drugi sposób wykorzystuje opcję tf.cond() op, która warunkowo ocenia jedno z dwóch wyrażeń. Jest to szczególnie przydatne, jeśli wyrażenia są kosztowne i konieczne jest, aby były one have side effects. Podstawowy wzór jest określenie dwie funkcje Pythona (lub wyrażeń lambda), które budują subgraphs które będą uruchamiane na prawdziwych lub fałszywych oddziałów:

# Define some large matrices 
a = ... 
b = ... 
c = ... 

pred = tf.placeholder(tf.bool) 

def if_true(): 
    return tf.matmul(a, b) 

def if_false(): 
    return tf.matmul(b, c) 

# Will be `tf.cond()` in the next release. 
from tensorflow.python.ops import control_flow_ops 

result = tf.cond(pred, if_true, if_false) 

sess = tf.Session() 
sess.run(result, feed_dict={pred: True}) # ==> executes only (a x b) 
sess.run(result, feed_dict={pred: False}) # ==> executes only (b x c) 
+0

Czy istnieje sposób, aby jedną z tych funkcji w parametrze .cond mieć? Chcę, aby if_true miał 3 parametry, ale nie mogę wymyślić, jak przejść przez nie. Jeśli użyję częściowego lub lambda, to powie mi, że obiekt bool nie ma nazwy atrybutu, który podejrzewam, że jest z Tensorflow próbującego utworzyć wykres. Och, a moje if_true i if_false zwracają wartość logiczną, dlatego jest to obiekt typu bool. – Beez

+0

Funkcje 'if_true' /' if_false' nie powinny mieć parametrów, ale można przechwytywać wartości z otaczającego zakresu. Nie jestem pewien, czy mam dobry obraz twojego kodu z twojego komentarza, więc może lepiej byłoby zaktualizować twoje pytanie do aktualnej wersji. – mrry

+0

Edytowane za pomocą nowego kodu. Próbowałem przesuwać informacje dotyczące parametrów z funkcji oraz w normalnych instrukcjach if i otrzymuję ten sam błąd, więc problem musi być spowodowany tym, że nie zwracam obiektu TensorFlow. Problem polega na tym, że informacje zależne od tej wartości boolowskiej nie znajdują się w obiekcie TensorFlow. – Beez

1

użycie reshape(t, []) aby uzyskać wartość i wykorzystać, że w if-oświadczenie