Подтвердить что ты не робот

В TensorFlow для чего используется tf.identity?

Я видел tf.identity, используемый в нескольких местах, например, официальный учебник CIFAR-10 и реализацию пакетной нормализации в stackoverflow, но я не понимаю, почему это необходимо.

Для чего он используется? Может ли кто-нибудь использовать прецедент или два?

Один из предложенных ответов заключается в том, что он может использоваться для передачи между CPU и GPU. Это мне непонятно. Расширение вопроса, основанное на this: loss = tower_loss(scope) находится под блоком графического процессора, что говорит мне, что все операторы, определенные в tower_loss, являются сопоставляемый с графическим процессором. Затем, в конце tower_loss, мы видим total_loss = tf.identity(total_loss) до его возврата. Зачем? Каким будет недостаток, не используя tf.identity здесь?

4b9b3361

Ответ 1

После некоторого спотыкания я думаю, что заметил один случай, который подходит ко всем примерам, которые я видел. Если есть другие варианты использования, пожалуйста, уточните пример.

Случай использования:

Предположим, вы хотите запускать оператор каждый раз, когда вычисляется конкретная переменная. Например, предположим, что вы хотите добавить один из x каждый раз, когда оценивается переменная y. Может показаться, что это сработает:

x = tf.Variable(0.0)
x_plus_1 = tf.assign_add(x, 1)

with tf.control_dependencies([x_plus_1]):
    y = x
init = tf.initialize_all_variables()

with tf.Session() as session:
    init.run()
    for i in xrange(5):
        print(y.eval())

Это не так: он будет печатать 0, 0, 0, 0, 0. Вместо этого нам кажется, что нам нужно добавить новый node к графу в блоке control_dependencies. Поэтому мы используем этот трюк:

x = tf.Variable(0.0)
x_plus_1 = tf.assign_add(x, 1)

with tf.control_dependencies([x_plus_1]):
    y = tf.identity(x)
init = tf.initialize_all_variables()

with tf.Session() as session:
    init.run()
    for i in xrange(5):
        print(y.eval())

Это работает: он печатает 1, 2, 3, 4, 5.

Если в учебнике CIFAR-10 мы сбросили tf.identity, то loss_averages_op никогда не запустится.

Ответ 2

tf.identity полезен, когда вы хотите явно переносить тензор между устройствами (например, с GPU на CPU). Оператор добавляет узлы send/recv к графику, которые делают копию, когда устройства ввода и вывода отличаются.

Поведение по умолчанию заключается в том, что узлы send/recv неявно добавляются, когда операция происходит на другом устройстве, но вы можете представить некоторые ситуации (особенно в многопоточных/распределенных настройках), когда было бы полезно получить значение переменной несколько раз в течение одного выполнения session.run. tf.identity позволяет больше контролировать, когда значение должно считываться с исходного устройства. Возможно, более подходящее имя для этого op будет read.

Также обратите внимание, что в реализации tf.Variable

Ответ 3

В дополнение к вышесказанному, я просто использую его, когда мне нужно назначить имя для ops, у которых нет аргумента name, точно так же, как при инициализации состояния в RNN:

rnn_cell = tf.contrib.rnn.MultiRNNCell([cells])
# no name arg
initial_state = rnn_cell.zero_state(batch_size,tf.float32)
# give it a name with tf.identity()
initial_state = tf.identity(input=initial_state,name="initial_state")

Ответ 4

Я столкнулся с другим вариантом использования, который не полностью покрыт другими ответами.

def conv_layer(input_tensor, kernel_shape, output_dim, layer_name, decay=None, act=tf.nn.relu):
    """Reusable code for making a simple convolutional layer.
    """
    # Adding a name scope ensures logical grouping of the layers in the graph.
    with tf.name_scope(layer_name):
        # This Variable will hold the state of the weights for the layer
        with tf.name_scope('weights'):
            weights = weight_variable(kernel_shape, decay)
            variable_summaries(weights, layer_name + '/weights')
        with tf.name_scope('biases'):
            biases = bias_variable([output_dim])
            variable_summaries(biases, layer_name + '/biases')
        with tf.name_scope('convolution'):
            preactivate = tf.nn.conv2d(input_tensor, weights, strides=[1, 1, 1, 1], padding='SAME')
            biased = tf.nn.bias_add(preactivate, biases)
            tf.histogram_summary(layer_name + '/pre_activations', biased)
        activations = act(biased, 'activation')
        tf.histogram_summary(layer_name + '/activations', activations)
        return activations

В большинстве случаев, когда вы создаете сверточный слой, вы просто хотите, чтобы активации были возвращены, чтобы вы могли передать их на следующий уровень. Иногда, однако, например, при создании автокодера - вы хотите значения предварительной активации.

В этой ситуации изящное решение состоит в том, чтобы передать tf.identity в качестве функции активации, эффективно не активируя слой.

Ответ 5

Я нашел другое приложение tf.identity в Tensorboard. Если вы используете tf.shuffle_batch, он сразу возвращает сразу несколько тензоров, поэтому при визуализации графика вы видите беспорядочную картину, вы не можете разделить контур создания тензора от действующих тензоров входного сигнала: неаккуратно

Но с tf.identity вы можете создавать повторяющиеся узлы, которые не влияют на поток вычислений: nice

Ответ 6

Когда наши входные данные сериализуются в байтах, и мы хотим извлечь объекты из этого набора данных. Мы можем сделать это в формате ключ-значение, а затем получить заполнитель для него. Его преимущества более понятны, когда есть несколько функций, и каждая функция должна быть прочитана в различном формате.

  #read the entire file in this placeholder      
  serialized_tf_example = tf.placeholder(tf.string, name='tf_example')

  #Create a pattern in which data is to be extracted from input files
  feature_configs = {'image': tf.FixedLenFeature(shape=[256], dtype=tf.float32),/
                     'text': tf.FixedLenFeature(shape=[128], dtype=tf.string),/
                     'label': tf.FixedLenFeature(shape=[128], dtype=tf.string),}

  #parse the example in key: tensor dictionary
  tf_example = tf.parse_example(serialized_tf_example, feature_configs)

  #Create seperate placeholders operation and tensor for each feature
  image = tf.identity(tf_example['image'], name='image')
  text  = tf.identity(tf_example['text'], name='text')
  label = tf.identity(tf_example['text'], name='label')

Ответ 7

В тренинге распределения мы должны использовать tf.identity, или рабочие будут висеть в ожидании инициализации главного работника:

vec = tf.identity(tf.nn.embedding_lookup(embedding_tbl, id)) * mask
with tf.variable_scope("BiRNN", reuse=None):
    out, _ = tf.nn.bidirectional_dynamic_rnn(fw, bw, vec, sequence_length=id_sz, dtype=tf.float32)

Для получения дополнительной информации, без идентификации, главный работник будет обрабатывать некоторые переменные как локальные переменные ненадлежащим образом, а другие рабочие ждут операции инициализации, которая не может закончиться

Ответ 8

Я вижу этот вид взлома, чтобы проверить утверждают:

assertion = tf.assert_equal(tf.shape(image)[-1], 3, message="image must have 3 color channels")
with tf.control_dependencies([assertion]):
    image = tf.identity(image)

Также он используется только для того, чтобы дать имя:

image = tf.identity(image, name='my_image')

Ответ 9

Другой случай использования, который я обнаружил, - это использование тензоров Кераса с функциями тензорного потока. Мне удалось решить, что объект не имеет атрибута outbound_nodes ошибка.