Создание и обучение только указанных весов в TensorFlow или PyTorch - PullRequest
0 голосов
/ 18 октября 2018

Мне интересно, есть ли способ в TensorFlow, PyTorch или какой-либо другой библиотеке для выборочного подключения нейронов.Я хочу создать сеть с очень большим количеством нейронов в каждом слое, но у нее очень мало связей между слоями.

Обратите внимание, что я не думаю, что это дубликат этого ответа: Выборочно нулевые веса в TensorFlow? .Я реализовал пользовательский слой keras, используя, по сути, тот же метод, который появляется в этом вопросе - по сути, создав плотный слой, в котором все, кроме указанных весов, игнорируются при обучении и оценке.Это выполняет часть того, что я хочу сделать, не тренируя указанные веса и не используя их для прогнозирования.Но проблема в том, что я все еще трачу память на сохранение нетренированных весов и трачу время на вычисление градиентов обнуленных весов.Я хотел бы, чтобы при вычислении матриц градиента использовались только разреженные матрицы, чтобы я не тратил время и память.

Есть ли способ выборочно создавать и тренировать веса, не тратя память?Если мой вопрос неясен или есть дополнительная информация, которую мне было бы полезно предоставить, пожалуйста, дайте мне знать.Я хотел бы быть полезным в качестве вопросника.

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

И тензорный поток, и pytorch поддерживают разреженные тензоры ( torch.sparse , tf.sparse ).

Мое интуитивное понимание состоит в том, что, если вы захотите написать свою сеть, используя соответствующие API низкого уровня (например, на самом деле реализуя forward-pass самостоятельно), вы можете привести свои весовые матрицы в качестве разреженных тензоров.Это, в свою очередь, приведет к разреженной связности, так как весовая матрица слоя [L] определяет связь между нейронами предыдущего слоя [L-1] с нейронами слоя [L].

0 голосов
/ 19 октября 2018

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

Псевдокод:

# setup network
weights = sparse_init()  # only nonzero for existing connections
zero_mask = where(weights == 0)

# train
for e in range(num_epochs):
    train_operation()  # may lead to introduction of new connections
    weights[zero_mask] = 0  # so we set them to zero again
...