Рекуррентные нейронные сети — различия между версиями
Adel (обсуждение | вклад)  | 
				Adel (обсуждение | вклад)   | 
				||
| Строка 7: | Строка 7: | ||
[[File:RNN_BP.jpg|450px|thumb|RNN с задержкой на скрытом слое]]  | [[File:RNN_BP.jpg|450px|thumb|RNN с задержкой на скрытом слое]]  | ||
[[File:RNN_BPTT.jpg|450px|thumb|Развертка RNN]]  | [[File:RNN_BPTT.jpg|450px|thumb|Развертка RNN]]  | ||
| − | Обучение RNN аналогично обучению обычной нейронной сети. Мы также используем [[:Обратное_распространение_ошибки|алгоритм обратного распространения ошибки (backpropagation)]], но с небольшим изменением. Поскольку одни и те же параметры используются на всех временных этапах в сети, градиент на каждом выходе зависит не только от расчетов текущего шага, но и от предыдущих временных шагов. Например, чтобы вычислить градиент   | + | Обучение RNN аналогично обучению обычной нейронной сети. Мы также используем [[:Обратное_распространение_ошибки|алгоритм обратного распространения ошибки (backpropagation)]], но с небольшим изменением. Поскольку одни и те же параметры используются на всех временных этапах в сети, градиент на каждом выходе зависит не только от расчетов текущего шага, но и от предыдущих временных шагов. Например, чтобы вычислить градиент для четвертого элемента последовательности, нам нужно было бы «распространить ошибку» на 3 шага и суммировать градиенты. Этот алгоритм называется «алгоритмом обратного распространения ошибки сквозь время» (англ. Backpropagation Through Time, BPTT).<ref name=BPTT_1>[http://andrew.gibiansky.com/blog/machine-learning/recurrent-neural-networks/ Backpropagation Through Time]</ref><ref name=BPTT_2>[http://www.wildml.com/2015/10/recurrent-neural-networks-tutorial-part-3-backpropagation-through-time-and-vanishing-gradients/ Backpropagation Through Time]</ref>  | 
| + | |||
| + | Алгоритм обратного распространения ошибки сквозь время:  | ||
| + | |||
| + | [[File:RNN_BPTT_GRAD.png|400px|frameless]]  | ||
== Области и примеры применения ==  | == Области и примеры применения ==  | ||
| Строка 22: | Строка 26: | ||
** Прогнозирование следующего пикселя на основе окружения  | ** Прогнозирование следующего пикселя на основе окружения  | ||
** Генерация описания изображений  | ** Генерация описания изображений  | ||
| + | |||
| + | == Виды RNN ==  | ||
| + | === Один к одному ===  | ||
| + | {|  | ||
| + | |-  | ||
| + | |[[File:RNN_OTO.jpg|100px|left]]  | ||
| + | |Архитектура по сути является обычной нейронной сетью.  | ||
| + | |}  | ||
| + | |||
| + | === Один ко многим ===  | ||
| + | {|  | ||
| + | |-  | ||
| + | |[[File:RNN_OTM.jpg|100px|left]]  | ||
| + | |Один вход ко многим выходам может применяться, например, для генерации аудиозаписи. На вход подаем жанр музыки, который хотим получить, на выходе получаем последовательность аудиозаписи.  | ||
| + | |}  | ||
| + | |||
| + | === Многие к одному ===  | ||
| + | {|  | ||
| + | |-  | ||
| + | |[[File:RNN_MTO.jpg|100px|left]]  | ||
| + | |Много входов и один выход может применяться, если мы хотим оценить тональность рецензии. На вход подаем слова рецензии, на выходе получаем оценку ее тональности: позитивная рецензия или негативная.  | ||
| + | |}  | ||
| + | |||
| + | === Многие ко многим ===  | ||
| + | {|  | ||
| + | |-  | ||
| + | |[[File:RNN_MTM1.jpg|100px|left]]  | ||
| + | |Данную архитектуру можно использовать для перевода текста с одного языка на другой.  | ||
| + | |-  | ||
| + | |[[File:RNN_MTM2.jpg|100px|left]]  | ||
| + | |Такой вариант подойдет для определения для классификации каждого слова в предложении в зависимости от контекста.  | ||
| + | |}  | ||
== Архитектуры ==  | == Архитектуры ==  | ||
Версия 20:54, 26 января 2019
Рекуррентная нейронная сеть (англ. recurrent neural network, RNN) — вид нейронных сетей, где связи между элементами образуют направленную последовательность.
Содержание
Описание
Рекуррентные нейронные сети — сети с циклами, которые хорошо подходят для обработки последовательностей.
Обучение RNN аналогично обучению обычной нейронной сети. Мы также используем алгоритм обратного распространения ошибки (backpropagation), но с небольшим изменением. Поскольку одни и те же параметры используются на всех временных этапах в сети, градиент на каждом выходе зависит не только от расчетов текущего шага, но и от предыдущих временных шагов. Например, чтобы вычислить градиент для четвертого элемента последовательности, нам нужно было бы «распространить ошибку» на 3 шага и суммировать градиенты. Этот алгоритм называется «алгоритмом обратного распространения ошибки сквозь время» (англ. Backpropagation Through Time, BPTT).[1][2]
Алгоритм обратного распространения ошибки сквозь время:
Области и примеры применения
Используются, когда важно соблюдать последовательность, когда важен порядок поступающих объектов.
-  Обработка текста на естественном языке
- Анализ текста
 - Автоматический перевод
 
 -  Обработка аудио 
- Автоматическое распознавание речи
 
 -  Обработка видео
- Прогнозирование следующего кадра на основе предыдущих
 - Распознавание эмоций
 
 -  Обработка изображений
- Прогнозирование следующего пикселя на основе окружения
 - Генерация описания изображений
 
 
Виды RNN
Один к одному
| Архитектура по сути является обычной нейронной сетью. | 
Один ко многим
| Один вход ко многим выходам может применяться, например, для генерации аудиозаписи. На вход подаем жанр музыки, который хотим получить, на выходе получаем последовательность аудиозаписи. | 
Многие к одному
| Много входов и один выход может применяться, если мы хотим оценить тональность рецензии. На вход подаем слова рецензии, на выходе получаем оценку ее тональности: позитивная рецензия или негативная. | 
Многие ко многим
| Данную архитектуру можно использовать для перевода текста с одного языка на другой. | |
| Такой вариант подойдет для определения для классификации каждого слова в предложении в зависимости от контекста. | 
Архитектуры
Полностью рекуррентная сеть
Это базовая архитектура, разработанная в 1980-х. Сеть строится из узлов, каждый из которых соединён со всеми другими узлами. У каждого нейрона порог активации меняется со временем и является вещественным числом. Каждое соединение имеет переменный вещественный вес. Узлы разделяются на входные, выходные и скрытые.
Рекурсивная сеть
Рекурсивные нейронные сети представляют собой более общий случай рекуррентных сетей, когда сигнал в сети проходит через структуру в виде дерева (обычно бинарные деревья). Те же самые матрицы весов используются рекурсивно по всему графу в соответствии с его топологией.
Нейронная сеть Хопфилда
Тип рекуррентной сети, когда все соединения симметричны. Изобретена Джоном Хопфилдом в 1982 году и гарантируется, что динамика такой сети сходится к одному из положений равновесия.
Двунаправленная ассоциативная память (BAM)
Вариацией сети Хопфилда является двунаправленная ассоциативная память (BAM). BAM имеет два слоя, каждый из которых может выступать в качестве входного, находить (вспоминать) ассоциацию и генерировать результат для другого слоя.
Сеть Элмана
Нейронная сеть Элмана состоит из трёх слоев: x, y, z (см рис. Сеть Элмана). Дополнительно к сети добавлен набор «контекстных блоков»: u (см рис. Сеть Элмана). Средний (скрытый) слой соединён с контекстными блоками с фиксированным весом, равным единице. С каждым шагом времени на вход поступает информация, которая проходит прямой ход к выходному слою в соответствии с правилами обучения. Фиксированные обратные связи сохраняют предыдущие значения скрытого слоя в контекстных блоках (до того как скрытый слой поменяет значение в процессе обучения). Таким способом сеть сохраняет своё состояние, что может использоваться в предсказании последовательностей, выходя за пределы мощности многослойного перцептрона.
Обозначения переменных и функций:
- : вектор входного слоя
 - : вектор скрытого слоя
 - : вектор выходного слоя
 - : матрица и вектор параметров
 - : функция активации
 
Сеть Джордана
Нейронная сеть Джордана подобна сети Элмана, но контекстные блоки связаны не со скрытым слоем, а с выходным слоем. Контекстные блоки таким образом сохраняют своё состояние. Они обладают рекуррентной связью с собой.
Эхо-сети
Эхо-сеть (англ. Echo State Network, ESN) характеризуется одним скрытым слоем (который называется резервуаром) со случайными редкими связями между нейронами. При этом связи внутри резервуара фиксированы, но связи с выходным слоем подлежат обучению. Состояние резервуара (state) вычисляется через предыдущие состояния резервуара, а также предыдущие состояния входного и выходного сигналов. Так как эхо-сети обладают только одним скрытым слоем, они обладают достаточно низкой вычислительной сложностью.
Нейронный компрессор истории
Нейронный компрессор исторических данных — это блок, позволяющий в сжатом виде хранить существенные исторические особенности процесса, который является своего рода стеком рекуррентной нейронной сети, формируемым в процессе самообучения.
Сети долго-краткосрочной памяти
Сеть долго-краткосрочной памяти (англ. Long short-term memory, LSTM) является самой популярной архитектурой рекуррентной нейронной сети на данный момент, данная архитектура способна запоминать данные на долгое время.[3]
Управляемые рекуррентные блоки
Управляемые рекуррентные блоки (англ. Gated Recurrent Units, GRU) — обладает меньшим количеством параметров, чем у LSTM, и в ней отсутствует выходное управление. При этом производительность в моделях речевого сигнала или полифонической музыки оказалась сопоставимой с LSTM.
Пример кода
Пример кода на Python с использованием библиотеки Keras.[4]
 # Импорты
 import numpy as np
 from keras.preprocessing import sequence
 from keras.models import Sequential
 from keras.layers import Dense, Activation, Embedding
 from keras.layers import LSTM
 from keras.datasets import imdb
 
 # Устанавливаем seed для обеспечения повторяемости результатов
 np.random.seed(42)
 
 # Указываем количество слов из частотного словаря, которое будет использоваться (отсортированы по частоте использования)
 max_features = 5000
 
 # Загружаем данные (датасет IMDB содержит 25000 рецензий на фильмы с правильным ответом для обучения и 25000 рецензий на фильмы с правильным ответом для тестирования)
 (X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words = max_features)
 
 # Устанавливаем максимальную длину рецензий в словах, чтобы они все были одной длины
 maxlen = 80
 
 # Заполняем короткие рецензии пробелами, а длинные обрезаем
 X_train = sequence.pad_sequences(X_train, maxlen = maxlen)
 X_test = sequence.pad_sequences(X_test, maxlen = maxlen)
 
 # Создаем модель последовательной сети
 model = Sequential()
 # Добавляем слой для векторного представления слов (5000 слов, каждое представлено вектором из 32 чисел, отключаем входной сигнал с вероятностью 20% для предотвращения переобучения)
 model.add(Embedding(max_features, 32, dropout = 0.2))
 # Добавляем слой долго-краткосрочной памяти (100 элементов для долговременного хранения информации, отключаем входной сигнал с вероятностью 20%, отключаем рекуррентный сигнал с вероятностью 20%)
 model.add(LSTM(100, dropout_W = 0.2, dropout_U = 0.2))
 # Добавляем полносвязный слой из 1 элемента для классификации, в качестве функции активации будем использовать сигмоидальную функцию
 model.add(Dense(1, activation = 'sigmoid'))
 
 # Компилируем модель нейронной сети
 model.compile(loss = 'binary_crossentropy',
               optimizer = 'adam',
               metrics = ['accuracy'])
 
 # Обучаем нейронную сеть (данные для обучения, ответы к данным для обучения, количество рецензий после анализа которого будут изменены веса, число эпох обучения, тестовые данные, показывать progress bar или нет)
 model.fit(X_train, y_train, 
           batch_size = 64,
           nb_epoch = 7,
           validation_data = (X_test, y_test),
           verbose = 1)
 
 # Проверяем качество обучения на тестовых данных (если есть данные, которые не участвовали в обучении, лучше использовать их, но в нашем случае таковых нет)
 scores = model.evaluate(X_test, y_test, batch_size = 64)
 print('Точность на тестовых данных: %.2f%%' % (scores[1] * 100))