Добавление узлов смещения в нейронную сеть

Добавлено 15 февраля 2020 в 17:41
Нейронные сети перцептрон для начинающих  (содержание)

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

Добро пожаловать в серию статей о нейронных сетях. Прежде чем вы перейдете к этой статье об узлах смещения, попробуйте наверстать упущенное в остальных статьях, которые можно увидеть выше, в меню с содержанием.

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

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

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

Включение смещения через электронную таблицу

Следующая диаграмма изображает нейросеть, у которой узел смещения находится во входном слое, а не в скрытом слое.

Рисунок 1 Узел смещения во входном слое многослойного перцептрона
Рисунок 1 – Узел смещения во входном слое многослойного перцептрона

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

Преимущество этого метода состоит в том, что не требуется никаких существенных изменений кода. Первым шагом является вставка столбца в таблицу и заполнение его значением смещения:

Рисунок 2 Столбец смещения
Рисунок 2 – Столбец смещения

Теперь всё, что вам нужно сделать, – это увеличить размерность входного слоя на единицу:

LR = 0.1

#I_dim = 4  # без смещения
I_dim = 5   # со смещением
H_dim = 7

epoch_count = 1

#np.random.seed(1)

Интеграция смещения в код

Если вам нужен узел смещения в скрытом слое или вам не нравится работать с электронными таблицами, вам понадобится другое решение.

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

Я сделаю это следующим образом:

LR = 0.1

input_bias = 1   # 0 - если нет смещения, 1 - смещение включено
hidden_bias = 1  # 0 - если нет смещения, 1 - смещение включено

I_dim = 4
H_dim = 7

epoch_count = 1

Создание узла смещения во входном слое

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

training_data = pandas.read_excel('MLP_Tdata4.xlsx')
target_output = training_data.output
training_data = training_data.drop(['output'], axis=1)
training_data = np.asarray(training_data)
training_count = len(training_data[:,0])

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

Следующий код показывает, как это можно сделать.

validation_count = len(validation_data[:,0])

if input_bias:
    new_column = np.ones((training_count, 1))
    training_data = np.hstack((training_data, new_column))
    
    new_column = np.ones((validation_count, 1))
    validation_data = np.hstack((validation_data, new_column))

Функция np.ones() создает массив из одного столбца, число строк которого равно training_count, и присваивает значение +1 каждому элементу в этом массиве. Затем мы используем функцию np.hstack(), чтобы добавить этот массив из одного столбца справа к исходному массиву training_data.

Обратите внимание, что я выполнил эту процедуру как для данных обучения, так и для данных проверки. Важно помнить, что цель на самом деле состоит не в том, чтобы изменить данные обучения или проверки; скорее, мы модифицируем данные как средство реализации необходимой конфигурации сети.

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

Создание узла смещения в скрытом слое

Мы можем добавить смещение в обработку прямого распространения, изменив цикл for, который вычисляет значения постактивации скрытого слоя, а затем вручную вставить значение смещения для последнего скрытого узла (который на самом деле является узлом смещения).

Первая модификация показана ниже:

    for sample in range(training_count):
        for node in range(H_dim - hidden_bias):
            preActivation_H[node] = np.dot(training_data[sample,:], weights_ItoH[:, node])
            postActivation_H[node] = logistic(preActivation_H[node])

Если нейросеть настроена на отсутствие узла смещения в скрытом слое, hidden_bias равно 0, выполнение цикла for не изменяется.

Если, наоборот, мы решили включить узел смещения в скрытый слой, цикл for не будет вычислять значение постактивации для последнего узла в слое (то есть узла смещения).

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

            postActivation_H[node] = logistic(preActivation_H[node])
        
        if hidden_bias:
            node += 1
            postActivation_H[node] = 1
        
        preActivation_O = np.dot(postActivation_H, weights_HtoO)

Обратите внимание, что эти изменения должны быть применены и к проверочной части кода.

Значения смещения, отличающиеся от +1

По моему опыту, +1 – это стандартное значение смещения, и я не знаю, есть ли какое-либо веское обоснование для использования других чисел. Смещение изменяется весами, поэтому выбор +1 не накладывает жестких ограничений на то, как смещение взаимодействует с общим функционалом нейросети.

Однако, если вы хотите поэкспериментировать с другими значениями смещения, вы можете легко это сделать. Для смещения в скрытом слое вы просто меняете число, присвоенное postActivation_H[node]. Для смещения во входном слое вы можете умножить массив new_column (каждый элемент которого изначально равен +1) на необходимое значение смещения.

Тестирование влияния смещения

Если вы читали 16-ую статью, вы знаете, что моему перцептрону было трудно классифицировать выборки в эксперименте № 3, который был задачей «высокой сложности».

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

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

Результаты:

Результаты эксперимента 3. Влияние смещения
 Средняя точностьМинимальная точностьМаксимальная точность
без смещения92,45%89,42%94,18%
смещение только во входном слое92,25%89,48%96,02%
смещение только в скрытом слое92,05%89,50%93,32%
смещение и во входном, и в скрытом слоях92,19%89,28%95,70%

Заключение

Как видите, узлы смещения не привели к каким-либо значительным изменениям в эффективности классификации.

Это на самом деле меня не удивляет – я думаю, что узлы смещения иногда немного переоцениваются, и, учитывая природу входных данных, которые я использовал в этом эксперименте, я не вижу причин, почему узлы смещения могли бы помочь.

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

Теги

MLP, Multilayer Perceptron / Многослойный перцептронPythonМашинное обучение / Machine LearningНейросеть / Нейронная сетьПерцептрон / PerceptronПрограммированиеТестированиеТочность нейронной сетиУзлы смещения

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.