2017-02-03 15 views
0

У меня есть обычная сеть прямой передачи, которая создает вектор v. Затем элементы v используются как ненулевые записи разреженной матрицы M (предположим, что координаты предопределены). Затем разреженная матрица умножается на плотный вектор и на полученном скаляре определяется потеря. Я хочу вернуть распространение w.r.t. веса сети, что влечет за собой переход через разреженную матрицу.Обратные градиенты через разреженный тензор?

Это кажется вполне разумным прецедентом для разреженной матрицы, но, похоже, такая функциональность не поддерживается. В самом деле, даже называя tf.gradients (M, [v]) выдает ошибку:

AttributeError: 'SparseTensor' object has no attribute 'value_index'

я делаю что-то не так или я правильно в предполагая, что эта функция не (пока?) Существуют? Если последнее, то есть ли обход для этого конкретного случая использования, чтобы не переписать все разреженные тензорные операции с определенными градиентами?

ответ

0

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

Tensor Класс создатель:

def __init__(self, op, value_index, dtype): 
    # value_index: An `int`. Index of the operation's endpoint that produces this tensor. 

value_index используется для создания имени Tensor.

SparseTensor один не

def __init__(self, indices, values, dense_shape): 

Нигде в файле это определение tensorflow/tensorflow/python/framework/sparse_tensor.py ссылается value_index.

Его аргументы - тензоры, предположительно каждый со своим value_index.

Другое, где оказывается, что SparseTensor является альтернативой IndexedSlices, который также содержит тензоры.

Входы tf.gradients все

A `Tensor` or list of tensors 

Файл определения gradients имеет _IndexedSlicesToTensor метод, но ничего эквивалентного для SparseTensor. Таким образом, в случае IndexedSlices (с предупреждением, если результат слишком большой), кажется, что-то вроде автоматического преобразования в плотное, но не для SparseTensors. Я не знаю, является ли это случай неполного развития или несовместимость, что делает невозможным.

1

Небольшое изменение на это делает работу, принимая градиент values из SparseTensor непосредственно:

import tensorflow as tf 
sparse_values = tf.identity(tf.Variable(tf.constant([1., 2., 3.]))) 
sparse_indices = tf.constant([[0, 0], [1, 1], [2, 2]], dtype=tf.int64) 
sparse_matrix = tf.SparseTensor(sparse_indices, sparse_values, [3, 3]) 
multiplied = tf.sparse_tensor_dense_matmul(sparse_matrix, tf.eye(3)) 
loss = tf.reduce_sum(multiplied) 
gradients = tf.gradients(loss, [sparse_values]) 
with tf.Session() as session: 
    tf.global_variables_initializer().run() 
    print(session.run(gradients)) 

распечаток (на TensorFlow 0.12.1):

[array([ 1., 1., 1.], dtype=float32)] 

Почему в tf.identity ор необходимо для определения градиента. Я не совсем понял (возможно, что-то делать с ref-типами).