Помощь новичку с линейной алгеброй в TensorFlow (Тензоры 3 ранга) - PullRequest
0 голосов
/ 23 мая 2018

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

У меня есть стандартная нейронная сеть с прямой связью в тензорном потоке, которая корректно работает с входным тензором ранга 2 размером [None, n_features], весами [n_features, n_neurons], в результате чего скрытый слой tf.matmul(inputs, weight) = [None, n_neurons].

Однако я хотел бы расширить свою размерность на одно измерение как на входе, так и на выходе.Например, я хочу иметь

inputs = tf.placeholder("float", shape=[None, n_type, n_features])
weight= tf.Variable(FNN_weight_initializer([n_type, n_features, n_neurons]))
Hidden1 = tf.matmul(inputs, weight)

И моей конечной целью здесь является Hidden1 = [None, n_type, n_neurons].

Однако вместо генерации желаемой тензорной формы я получаю тензор формы[n_type, n_type, n_neurons].Я не эксперт по линейной алгебре, и я пробовал несколько комбинаций порядка измерений без успеха.Можно ли даже умножить тензоры ранга 3 на tf.matmul?Должен ли я где-нибудь здесь делать операцию изменения формы или транспонирования?

1 Ответ

0 голосов
/ 23 мая 2018

РЕДАКТИРОВАТЬ в соответствии с комментарием ОП

Вы можете сгладить векторы входных объектов, чтобы придать им форму [-1, n_type * n_features], применить правильно выбранную матрицу умножения и изменить форму вывода с [-1, n_type * n_neurons] до [-1, n_type, n_neurons]

Тензор операции будет иметь диагональ блока [n_type * n_features, n_type * n_neurons] один, каждый блок является одним из n_type тензоров в weights.

Для построения диагональной матрицы блокаЯ использовал другой ответ (из здесь )

Это будет выглядеть так:

inputs = tf.placeholder("float", shape=[None, n_type, n_features])
inputs = tf.reshape(inputs, shape=[-1, n_type * n_features])

weights = tf.Variable(FNN_weight_initializer([n_type, n_features, n_neurons]))

split_weights = tf.split(weights, num_or_size_splits=n_type, axis=1)
# each element of split_weights is a tensor of shape : [1, n_features, n_neurons] -> need to squeeze
split_weights = tf.map_fn(lambda elt : tf.squeeze(elt, axis=0), split_weights)

block_matrix = block_diagonal(split_weights) # from the abovementioned reference

Hidden1 = tf.matmul(inputs, block_matrix)
# shape : [None, n_type * n_neurons]

Hidden1 = tf.reshape(Hidden1, [-1, n_type, n_neurons])
# shape : [None, n_type, n_neurons]

Оригинальный ответ

Согласно документации tf.matmul ( ссылка ), умножаемые вами тензоры должны иметь одинаковый ранг.

Если ранг равен >2, только два последнихизмерения должны быть совместимы с умножением матриц, первые другие измерения должны точно совпадать.

Итак, на вопрос «Можно ли даже умножить тензоры ранга 3 на tf.matmul?», ответ «Да, возможно, но концептуально, это еще мультипликат ранга 2ion ".

Следовательно, необходимо изменить форму:

inputs = tf.placeholder("float", shape=[None, n_type, n_features])

inputs = tf.reshape(inputs, shape=[-1, n_type, 1, n_features])

weights = tf.Variable(FNN_weight_initializer([n_type, n_features, n_neurons]))

weights = tf.expand_dims(weights, 0)
# shape : [1, n_type, n_features, n_neurons]

weights = tf.tile(weights, [tf.shape(inputs)[0], 1, 1, 1])
# shape : [None, n_type, n_features, n_neurons]

Hidden1 = tf.matmul(inputs, weights)
# shape : [None, n_type, 1, n_neurons]

Hidden1 = tf.reshape(Hidden1, [-1, n_type, n_neurons])
# shape : [None, n_type, n_neurons]
...