Эта статья переведена с:«Операции потока управления: условные операторы и циклы», Если есть какое-либо нарушение, пожалуйста, свяжитесь, чтобы удалить его, только для академических обменов, пожалуйста, не используйте его в коммерческих целях. Если есть какие-либо ошибки, пожалуйста, свяжитесь, чтобы указать.
Когда мы создаем сложную модель, такую как RNN (рекуррентная нейронная сеть), вам может понадобиться контролировать поток операций с помощью условий и циклов. В этом разделе мы представим некоторые часто используемые потоки управления в TensorFlow.
Предположим, теперь нам нужно вынести условное суждение, чтобы решить, можем ли мыдобавитьвсе ещеумножитьдве переменные. Это можно сделать, позвонивtf.cond()
Простая реализация, ведет себя как в питонеif...else...
аналогичная функция.
a = tf.constant(1)
b = tf.constant(2)
p = tf.constant(True)
x = tf.cond(p, lambda: a + b, lambda: a * b)
print(tf.Session().run(x))
Поскольку это условие считается истинным, выход должен быть выходом сложения, то есть выходом 3.
В процессе использования TensorFlow большую часть времени вы будете работать с большими тензорами и работать в пакетном режиме. Родственный условный операторtf.where()
, он должен предоставить условное суждение, иtf.cond()
то же самое, ноtf.where()
Выход будет выбираться пакетно на основе этого условия, например:
a = tf.constant([1, 1])
b = tf.constant([2, 2])
p = tf.constant([True, False])
x = tf.where(p, a + b, a * b)
print(tf.Session().run(x))
Возвращаемый результат[3, 2]
.
Другой широко используемой операцией потока управления являетсяtf.while_loop()
. Это позволяет создавать динамические циклы в TensorFlow, которые работают с последовательностью переменных. Посмотрим, как мы пройдемtf.while_loops
Функция генерирует последовательность Фибоначчи:
n = tf.constant(5)
def cond(i, a, b):
return i < n
def body(i, a, b):
return i + 1, b, a + b
i, a, b = tf.while_loop(cond, body, (2, 1, 1))
print(tf.Session().run(b))
Этот код вернет 5.tf.while_loop()
Требуется условная функция и функция тела цикла в дополнение к инициализации переменных цикла. Эти переменные цикла обновляются после каждого вызова функции тела цикла, пока условие не вернет False.
Теперь представьте, что мы хотим сохранить эту последовательность Фибоначчи, мы можем обновить нашу функцию тела цикла, чтобы сохранить историю текущего значения:
n = tf.constant(5)
def cond(i, a, b, c):
return i < n
def body(i, a, b, c):
return i + 1, b, a + b, tf.concat([c, [a + b]], 0)
i, a, b, c = tf.while_loop(cond, body, (2, 1, 1, tf.constant([1, 1])))
print(tf.Session().run(c))
Когда вы попытаетесь запустить эту программу, TensorFlow будет «жаловаться», говоря:Форма четвертой переменной цикла меняется. Таким образом, вы должны указать, что было преднамеренно после этого события:
i, a, b, c = tf.while_loop(
cond, body, (2, 1, 1, tf.constant([1, 1])),
shape_invariants=(tf.TensorShape([]),
tf.TensorShape([]),
tf.TensorShape([]),
tf.TensorShape([None])))
Это делает код уродливым и крайне неэффективным. Обратите внимание, что мы строим множество промежуточных тензоров, которые не используем. На самом деле у TensorFlow есть лучшее решение для этого растущего массива:tf.TensorArray
. Сделаем то же самое с массивом тензоров:
n = tf.constant(5)
c = tf.TensorArray(tf.int32, n)
c = c.write(0, 1)
c = c.write(1, 1)
def cond(i, a, b, c):
return i < n
def body(i, a, b, c):
c = c.write(i, a + b)
return i + 1, b, a + b, c
i, a, b, c = tf.while_loop(cond, body, (2, 1, 1, c))
c = c.stack()
print(tf.Session().run(c))
в ТензорФлоуwhile_loop
и массивы тензоров являются фундаментальными инструментами для построения сложных рекуррентных нейронных сетей (RNN). В качестве упражнения можно попробовать использоватьtf.while_loops
выполнитьbeam search. Не могли бы вы попробовать еще раз с массивом тензоров, чтобы быть более эффективным?