Изменения

Перейти к: навигация, поиск

Рекуррентные нейронные сети

4995 байт добавлено, 19:13, 4 сентября 2022
м
rollbackEdits.php mass rollback
[[File:'''Рекуррентная нейронная сеть''' (англ. ''recurrent neural network'', ''RNN.png|450px|thumb|[http://colah.github.io/posts/2015'') {{-08-Understanding-LSTMs/ RNN и ее развернутое представление]]]}} вид [[File:RNN_layer.pngНейронные_сети,_перцептрон|450px|thumb|[http://colah.github.io/posts/2015-08-Understanding-LSTMs/ Схема слоя рекуррентной сети]нейронных сетей]], где связи между элементами образуют направленную последовательность.
'''Рекуррентная нейронная сеть''' (англ== Описание ==[[File:RNN.png|450px|thumb|Рисунок 1. ''recurrent neural network'', ''RNN'') и ее развернутое представление <ref>[http://colah.github.io/posts/2015-08-Understanding-LSTMs Understanding LSTM Networks]</ref>]][[File:RNN_layer.png|450px|thumb|Рисунок 2. Схема слоя рекуррентной сети <ref>[http://colah.github.io/posts/2015-08-Understanding-LSTMs Understanding LSTM Networks]</ref>]]Рекуррентные нейронные сети {{---}} вид сети с циклами, которые хорошо подходят для обработки последовательностей (рис. 1).[[File:RNN_BP.jpg|450px|thumb|Рисунок 3. RNN с задержкой на скрытом слое]][[File:Нейронные RNN_BPTT.jpg|450px|thumb|Рисунок 4. Развертка RNN]]Обучение RNN аналогично обучению обычной нейронной сети. Мы также используем [[:Обратное_распространение_ошибки|нейронных сетейалгоритм обратного распространения ошибки]](англ. Backpropagation), но с небольшим изменением. Поскольку одни и те же параметры используются на всех временных этапах в сети, градиент на каждом выходе зависит не только от расчетов текущего шага, где связи между элементами образуют направленную последовательностьно и от предыдущих временных шагов (рис. 4).Например, чтобы вычислить градиент для четвертого элемента последовательности, нам нужно было бы «распространить ошибку» на 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_BPRNN_BPTT_GRAD.jpgpng|450px400px|thumb|RNN с задержкой на скрытом слое]][[File:RNN_BPTT.jpg|450px|thumb|Развертка RNN]]Обучение RNN аналогично обучению обычной нейронной сети. Мы также используем алгоритм обратного распространения ошибки (backpropagation), но с небольшим изменением. Поскольку одни и те же параметры используются на всех временных этапах в сети, градиент на каждом выходе зависит не только от расчетов текущего шага, но и от предыдущих временных шагов. Например, чтобы вычислить градиент при t = 4, нам нужно было бы «распространить ошибку» на 3 шага и суммировать градиенты. Этот алгоритм называется «алгоритмом обратного распространения ошибки сквозь время» (англ. Backpropagation Through Time, BPTT).<ref name=BPTT_1>[http://andrew.gibiansky.com/blog/machine-learning/recurrent-neural-networks/ Backpropagation Through Timeframeless]</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>
== Области и примеры применения ==
Используются, когда важно соблюдать последовательность, когда нужен важен порядок того, что у нас происходитпоступающих объектов.* Обработка текста на естественном языке:** Анализ текста;** Автоматический перевод;* Обработка аудио :** Автоматическое распознавание речи;* Обработка видео:** Прогнозирование следующего кадра на основе предыдущих;** Распознавание эмоций;* Обработка изображений:** Прогнозирование следующего пикселя на основе окружения;** Генерация описания изображений. == Виды 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]]|Такой вариант подойдет для определения для классификации каждого слова в предложении в зависимости от контекста.|}
== Архитектуры ==
=== Рекурсивная сеть ===
[[:Рекурсивные нейронные сети|Рекурсивные нейронные сети]] (англ. Recurrent neural networks) представляют собой более общий случай рекуррентных сетей, когда сигнал в сети проходит через структуру в виде дерева (обычно бинарные деревья). Те же самые матрицы весов используются рекурсивно по всему графу в соответствии с его топологией.
=== Нейронная сеть Хопфилда ===
=== Двунаправленная ассоциативная память (BAM) ===
Вариацией сети Хопфилда является двунаправленная ассоциативная память (BAM). BAM имеет два слоя, каждый из которых может выступать в качестве входного, находить (вспоминать) ассоциацию и генерировать результат для другого слоя.
[[File:Elman_RNN.jpg|450px|thumb|Рисунок 5. Сеть Элмана]]
=== Сеть Элмана ===
Нейронная сеть Элмана состоит из трёх слоев: <math>x</math>, <math>y</math>, <math>z (см рис. Сеть Элмана)</math>. Дополнительно к сети добавлен набор «контекстных блоков»: <math>u </math> (см рис. Сеть Элмана5). Средний (скрытый) слой соединён с контекстными блоками с фиксированным весом, равным единице. С каждым шагом времени на вход поступает информация, которая проходит прямой ход к выходному слою в соответствии с правилами обучения. Фиксированные обратные связи сохраняют предыдущие значения скрытого слоя в контекстных блоках (до того как скрытый слой поменяет значение в процессе обучения). Таким способом сеть сохраняет своё состояние, что может использоваться в предсказании последовательностей, выходя за пределы мощности многослойного перцептрона.
<math>h_t = \sigma_h(W_h x_t + U_h h_{t-1} + b_h)</math>,
<math>y_t = \sigma_y(W_y h_t + b_y)</math>,
Обозначения переменных и функций:
* <math>x_t</math>: вектор входного слоя;* <math>h_t</math>: вектор скрытого слоя;* <math>y_t</math>: вектор выходного слоя;* <math>W, U и , b</math>: матрица и вектор параметров;* <math>\sigma_h и , \sigma_y</math>: функция активации.
=== Сеть Джордана ===
Нейронная сеть Джордана подобна сети Элмана, но контекстные блоки связаны не со скрытым слоем, а с выходным слоем. Контекстные блоки таким образом сохраняют своё состояние. Они обладают рекуррентной связью с собой.
<math>h_t = \sigma_h(W_h x_t + U_h y_{t-1} + b_h)</math>,
<math>y_t = \sigma_y(W_y h_t + b_y)</math>,
=== Эхо-сети ===
=== Нейронный компрессор истории ===
Нейронный компрессор исторических данных {{---}} это блок, позволяющий в сжатом виде хранить существенные исторические особенности процесса, который является своего рода стеком рекуррентной нейронной сети, формируемым в процессе самообучения.
[[File:LSTM.png|450px|thumb|Рисунок 6. Схема слоев рекуррентной сети долго-краткосрочной памяти <ref>[http://colah.github.io/posts/2015-08-Understanding-LSTMsUnderstanding LSTM Networks]</ Схема слоев рекуррентной сети долго-краткосрочной памяти]ref>]]
=== Сети долго-краткосрочной памяти ===
[[:Долгая_краткосрочная_память|Сеть долго-краткосрочной памяти ]] (англ. Long short-term memory, LSTM) является самой популярная архитектура популярной архитектурой рекуррентной нейронной сети на данный текущий момент, данная такая архитектура способна запоминать данные на долгое время(рис. 6).<ref name=LSTM>[https://www.bioinf.jku.at/publications/older/2604.pdf Sepp Hochreiter, Jurgen Schmidhuber. Long short-term memory (1997). Neural Computation.]</ref> Разберем работу слоев подробнее<ref name=Understanding_LSTM>[http://colah.github.io/posts/2015-08-Understanding-LSTMs/ Understanding LSTM Networks]</ref>: Первый слой вычисляет, насколько на данном шаге ему нужно забыть предыдущую информацию {{---}} по сути множители к компонентам вектора памяти.[[File:LSTM_F1.png|none|250px]]<math>f_t = \sigma(W_f * [h_{t-1}, x_t] + b_f)</math> Второй слой вычисляет, насколько ему интересна новая информация, пришедшая с сигналом {{---}} такой же множитель, но уже для наблюдения.[[File:LSTM_F2.png|none|250px]]<math>i_t = \sigma(W_f * [h_{t-1}, x_t] + b_i)</math> <math>\tilde{C}_t = tanh(W_C * [h_{t-1}, x_t] + b_C)</math> На третьем слое вычисляется линейная комбинация памяти и наблюдения с только вычисленными весами для каждой из компонент. Так получается новое состояние памяти, которое в таком же виде передаётся далее.[[File:LSTM_F3.png|none|250px]]<math>C_t = f_t * C_{t-1} + i_t * \tilde{C}_t</math> Осталось вычислить output. Но поскольку часть входного сигнала уже в памяти, не нужно считать активацию по всему сигналу. Сначала сигнал проходит через сигмоиду, которая решает, какая его часть важна для дальнейших решений, затем гиперболический тангенс «размазывает» вектор памяти на отрезок от -1 до 1, и в конце эти два вектора перемножаются.[[File:LSTM_F4.png|none|250px]]<math>o_t = \sigma(W_o * [h_{t-1}, x_t] + b_o)</math> <math>h_t = o_t * tanh(C_t)</math> Полученные таким образом <math>h_t</math> и <math>C_t</math> передаются далее по цепочке.
=== Управляемые рекуррентные блоки ===
Управляемые рекуррентные блоки (англ. Gated Recurrent Units, GRU) {{---}} обладает меньшим количеством параметров, чем у LSTM, и в ней отсутствует выходное управление. При этом производительность в моделях речевого сигнала или полифонической музыки оказалась сопоставимой с LSTM.
== Пример кода = Двунаправленные рекуррентные сети ===Пример кода на Python с использованием библиотеки Keras[[File:biRNN.png|450px|thumb|Рисунок 7.Двунаправленная рекуррентная сеть <ref name=KerasRNN>[https://kerastowardsdatascience.iocom/layers/recurrent/ Keras understanding-bidirectional-rnn-in-pytorch-5bd25a5dd66 Understanding Bidirectional RNNin PyTorch]</ref>]]<pre># Импортыimport numpy as npfrom kerasДвунаправленная рекуррентная сеть (англ. Bidirectional Recurrent Neural Network, biRNN) представляет собой две однонаправленные рекуррентные сети, одна из которых обрабатывает входную последовательность в прямом порядке, а другая {{---}} в обратном (рис.preprocessing import sequencefrom keras7).models import Sequentialfrom kerasТаким образом, для каждого элемента входной последовательности считается два вектора скрытых состояний, на основе которых вычисляется выход сети.layers import DenseБлагодаря данной архитектуре сети доступна информация о контексте как из прошлого, Activationтак и из будущего, Embeddingfrom kerasчто решает проблему однонаправленных рекуррентных сетей.layers import LSTMfrom kerasДля обучения biRNN используются те же алгоритмы, что и для RNN.datasets import imdb
# Устанавливаем seed для обеспечения повторяемости результатовnp.random.seed<math>H_t^f = \sigma^f(42W_x^f X_t + W_h^f H_{t-1}^f + b^f)</math>,
# Указываем количество слов из частотного словаря, которое будет использоваться <math>H_t^b = \sigma^b(отсортированы по частоте использованияW_x^b X_t + W_h^b H_{t+1}^b + b^b)max_features = 5000</math>,
# Загружаем данные (датасет IMDB содержит 25000 рецензий на фильмы с правильным ответом для обучения и 25000 рецензий на фильмы с правильным ответом для тестирования)(X_train<math>O_t = W^q H_t + b^q</math>, y_train), (X_test, y_test) = imdb.load_data(nb_words = max_features)
# Устанавливаем максимальную длину рецензий в словахгде <math>W_x^f</math>, чтобы они все были одной длиныmaxlen = 80<math>W_x^b</math>, <math>W_h^f</math>, <math>W_h^b</math>, <math>W^q</math>, {{---}} матрицы весов, <math>b^f</math>, <math>b^b</math>, <math>b^q</math>, {{---}} байесы, <math>\sigma^f</math>, <math>\sigma^b</math>, {{---}} функции активаций, <math>H_t^f</math> и <math>H_t^b</math> {{---}} выходы однонаправленных рекуррентных сетей, <math>H_t</math> {{---}} их конкатенированный вектор, а <math>O_t</math> {{---}} выход сети на шаге <math>t</math>.
# Заполняем короткие рецензии пробелами, а длинные обрезаем=== Seq-2-seq сети ===X_train = sequence[[File:Seq2seq.png|450px|thumb|Рисунок 8. Seq-2-seq сеть <ref>[https://medium.pad_sequencescom/guan-hong/implement-of-seq2seq-model-117c32492e57 Implementation of seq2seq model]</ref>]]Seq-2-seq (X_trainSequence to sequence, maxlen = maxlenSeq2seq) сеть является базовой архитектурой many-to-many RNN и используется для трансляции одной последовательности в другую (рис. 8)X_test = sequence.pad_sequences(X_testОна состоит из двух рекуррентных сетей: кодировщика и декодировщика. Кодировщик вычисляет вектор, кодирующий входную последовательность. Далее данный вектор передается декодировщику, maxlen который в свою очередь по полученному скрытому представлению восстанавливает целевую последовательность. При этом каждый посчитанный выход используется для обновления скрытого представления. <br clear= maxlen)"both" />
# Создаем модель последовательной сети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Пример кода на Python с использованием библиотеки Keras.add(Dense(1, activation <ref name= "sigmoid")) # Компилируем модель нейронной сетиmodelKerasRNN>[https://keras.compile(loss io/layers/recurrent/ Keras RNN]</ref>= 'binary_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
<font color="green"># Импорты</font> '''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 <font color="green"># Устанавливаем seed для обеспечения повторяемости результатов</font> np.random.seed(<font color="blue">42</font>) <font color="green"># Указываем количество слов из частотного словаря, которое будет использоваться (отсортированы по частоте использования)</font> max_features = <font color="blue">5000</font> <font color="green"># Загружаем данные (датасет IMDB содержит 25000 рецензий на фильмы с правильным ответом для обучения и 25000 рецензий на фильмы с правильным ответом для тестирования)</font> (X_train, y_train), (X_test, y_test) = imdb.load_data(nb_words = max_features) <font color="green"># Устанавливаем максимальную длину рецензий в словах, чтобы они все были одной длины</font> maxlen = <font color="blue">80</font> <font color="green"># Заполняем короткие рецензии пробелами, а длинные обрезаем</font> X_train = sequence.pad_sequences(X_train, maxlen = maxlen) X_test = sequence.pad_sequences(X_test, maxlen = maxlen) <font color="green"># Создаем модель последовательной сети</font> model = Sequential() <font color="green"># Добавляем слой для векторного представления слов (5000 слов, каждое представлено вектором из 32 чисел, отключаем входной сигнал с вероятностью 20% для предотвращения переобучения)</font> model.add(Embedding(max_features, <font color="blue">32</font>, dropout = <font color="blue">0.2</font>)) <font color="green"># Добавляем слой долго-краткосрочной памяти (100 элементов для долговременного хранения информации, отключаем входной сигнал с вероятностью 20%, отключаем рекуррентный сигнал с вероятностью 20%)</font> model.add(LSTM(<font color="blue">100</font>, dropout_W = <font color="blue">0.2</font>, dropout_U = <font color="blue">0.2</font>)) <font color="green"># Добавляем полносвязный слой из 1 элемента для классификации, в качестве функции активации будем использовать сигмоидальную функцию</font> model.add(Dense(<font color="blue">1</font>, activation = <font color="red">'sigmoid'</font>)) <font color="green"># Компилируем модель нейронной сети</font> model.compile(loss = <font color="red">'binary_crossentropy'</font>, optimizer = <font color="red">'adam'</font>, metrics = [<font color="red">'accuracy'</font>]) <font color="green"># Обучаем нейронную сеть (данные для обучения, ответы к данным для обучения, количество рецензий после анализа которого будут изменены веса, число эпох обучения, тестовые данные, показывать progress bar или нет)</font> model.fit(X_train, y_train, batch_size = <font color="blue">64</font>, nb_epoch = <font color="blue">7</font>, validation_data = (X_test, y_test), verbose = <font color="blue">1</font>) <font color="green"># Проверяем качество обучения на тестовых данных (если есть данные, которые не участвовали в обучении, лучше использовать их, но в нашем случае таковых нет)</font> scores = model.evaluate(X_test, y_test, batch_size = <font color="blue">64</font>) print(<font color="red">'Точность на тестовых данных: %.2f%%'</font> % (scores[1] * <font color="blue">100</font>))
# Проверяем качество обучения ===Пример на тестовых данных (если есть данные, которые не участвовали в обучении, лучше использовать их, но в нашем случае таковых нет)scores языке Java== model.evaluate(X_test, y_test, batch_size = 64)print("Точность на тестовых данных[https: %//github.2f%%" % (scores[1com/deeplearning4j/dl4j-examples/blob/master/dl4j-examples/src/main/java/org/deeplearning4j/examples/recurrent/basic/BasicRNNExample.java Пример] * 100))простой рекуррентной нейронной сети, способной генерировать заданную строку по первому символу, с применением библиотеки <code>deeplearning4j</precode>.
==См. также==
==Примечания==
<references/>
 
[[Категория: Машинное обучение]]
[[Категория: Нейронные сети]]
[[Категория: Рекуррентные нейронные сети]]
1632
правки

Навигация