Как реализовать нейронную обрезку? - PullRequest
6 голосов
/ 24 мая 2019

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

Автор «Изучения весов и связей для эффективного Нейронные сети говорят, что они добавляют маску к пороговым весам слоя. Я могу попытаться сделать то же самое и точно настроить обученную модель. Но как это уменьшает размер модели и количество вычислений?

Ответы [ 2 ]

6 голосов
/ 05 июня 2019

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

def weight_pruning(w: tf.Variable, k: float) -> tf.Variable:
    """Performs pruning on a weight matrix w in the following way:

    - The absolute value of all elements in the weight matrix are computed.
    - The indices of the smallest k% elements based on their absolute values are selected.
    - All elements with the matching indices are set to 0.

    Args:
        w: The weight matrix.
        k: The percentage of values (units) that should be pruned from the matrix.

    Returns:
        The unit pruned weight matrix.

    """
    k = tf.cast(tf.round(tf.size(w, out_type=tf.float32) * tf.constant(k)), dtype=tf.int32)
    w_reshaped = tf.reshape(w, [-1])
    _, indices = tf.nn.top_k(tf.negative(tf.abs(w_reshaped)), k, sorted=True, name=None)
    mask = tf.scatter_nd_update(tf.Variable(tf.ones_like(w_reshaped, dtype=tf.float32), name="mask", trainable=False), tf.reshape(indices, [-1, 1]),tf.zeros([k], tf.float32))

    return w.assign(tf.reshape(w_reshaped * mask, tf.shape(w)))
4 голосов
/ 24 мая 2019

Если вы добавите маску, то только часть ваших весов будет участвовать в вычислениях, следовательно, ваша модель будет сокращена.Например, авторегрессионные модели используют маску для маскирования весов, которые относятся к будущим данным, так что вывод на шаге по времени t зависит только от шагов по времени 0, 1, ..., t-1.

В вашем случае, так как у вас естьпростой полностью связанный слой, лучше использовать dropout.Он случайным образом отключает некоторые нейроны на каждом шаге итерации, что снижает сложность вычислений.Тем не менее, основная причина, по которой был выброшен отсев, заключается в решении проблемы переоснащения: при случайном выключении некоторых нейронов вы уменьшаете взаимозависимость нейронов, т.е. вы избегаете зависимости одних нейронов от других.Более того, на каждой итерации ваша модель будет отличаться (разное количество активных нейронов и разные связи между ними), поэтому вашу окончательную модель можно интерпретировать как совокупность (набор) нескольких разных моделей, каждая из которых специализирована (мы надеемся) впонимание определенного подмножества пространства ввода.

...