Распознавание слов естественного языка с использованием нейросетей

Автор работы: Пользователь скрыл имя, 12 Мая 2012 в 21:54, курсовая работа

Краткое описание

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

Содержание работы

Введение
1. Анализ нейронных сетей
1.1 Выбор разновидности сети
1.2 Модель многослойного персептрона с обучением по методу обратного распространения ошибки
1.3 Постановка задачи
2. Проектирование библиотеки классов для реализации нейросети и тестовой программы
2.1 Программная реализация нейросети обратного распространения ошибки
2.2 Класс перевода текста в двоичный вид
2.3 Класс хеш-таблицы и методов работы с ней
2.4 Класс разбиения текста на лексемы и распознавания
2.5 Описание тестирующей программы
2.6 Результаты тестирования
3. Руководство программисту
Заключение
Список используемой литературы
Приложения

Содержимое работы - 1 файл

ф1.docx

— 220.45 Кб (Скачать файл)

 


 

 


 

Рисунок 4 - Модифицирование весовых коэффициентов  выходного слоя (обратное распространение ошибки)

 

Затем таким  же образом модифицируются весовые  коэффициенты скрытого слоя, на этот раз сравниваются выходные сигналы нейронов скрытого слоя и входные сигналы нейронов выходного слоя (рисунок 5), целью данного сравнения является формирование вектора ошибки для скрытого слоя.

 


 

 

 


Рисунок 5 - Модифицирование весовых коэффициентов  скрытого слоя (обратное распространение ошибки)

 

Если  в сети существует входной слой (именно слой, а не ряд входных значений), то проводятся аналогичные действия и с ним.

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

Сеть  обучается путем предъявления каждого  входного набора данных и последующего распространения ошибки. Этот цикл повторяется много раз. Например, для распознавания цифры от 0 до 9, сначала обрабатывается символ "0", символ "1" и так далее до "9", затем весь цикл повторяется много раз. Не следует поступать иначе, а именно, обучать сеть по отдельности сначала символу "0" (n-ое количество раз), потом "1", потом "2" и т.д., т.к. сеть вырабатывает очень "четкие" весовые коэффициенты для последнего входного набора (то есть для "9"), "забывая" предыдущие. Например, к тысячному повтору обучения символу "1" теряются весовые коэффициенты для распознавания символа "0". Повторяя весь цикл для всего набора входных данных, мы предполагаем, что каждый символ оказывает равноправное влияние на значения весовых коэффициентов.

Таким образом, полный алгоритм обучения НС с помощью  процедуры обратного распространения строится так:

  1. Инициализировать пороговые значения и весовые коэффициенты небольшими случайными величинами (не более 0.4).
  2. Подать на входы сети один из возможных образов и в режиме обычного функционирования НС, когда сигналы распространяются от входов к выходам.
  3. Вычислить ошибки для выходного слоя. При этом используем следующую формулу для каждого i-ого значения выходного слоя:

 

Ei = (ti - ai).ai.(1 - ai)     (7)

 

Здесь Ei - ошибка для i-ого узла выходного слоя,

ai - активность данного узла,

ti - требуемая активность для него же (т.е. требуемое выходное значение).

Используем  значения ошибок выходного слоя для  определения ошибок в скрытом слое. Формула практически та же, но теперь не определены желаемые выходные значения. Вычислить взвешенную сумму значений ошибок выходного слоя по формуле:

 

Ei = ai. (1 - ai). Σj Ej.wij       (8)

 

Смысл переменных по сравнению с формулой (9) изменился незначительно. индекс i используется для нейронов скрытого слоя (а не выходного), Ei, следовательно, значение ошибки для нейрона скрытого слоя, и ai - сигнал на выходе нейрона. Индекс j относится к нейронам выходного слоя: wij - вес (весовой коэффициент) связи между i-ым скрытым нейроном и j-ым выходным нейроном, а Ej - значение ошибки для выходного нейрона j. Суммирование проводится для всех весов связей между отдельно взятым i-ым нейроном и всеми нейронами выходного слоя.

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

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

Применяем уравнение:

 

new wij = old wij + ηδj.xi     (9)

 

где wij - вес связи между нейроном i скрытого слоя и нейроном j выходного;

δj - приращение ошибки для выходного нейрона j;

xi - сигнал на выходе скрытого нейрона i;

η - константа.

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

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

 

new threshold = old threshold + ηδj.(-1)   (10)

 

или (в более удобном виде):

 

new threshold = old threshold - ηδj    (11)

 

1.3 Постановка задачи

 

Задачей данного курсового  проекта является создание программы распознавания слов естественного языка с использованием нейросетей. Для ее выполнения была выбрана нейронная сеть обратного распространения ошибки, которая будет реализована на языке программирования C# в виде класса. Класс будет содержать конструктор, на который будут подаваться значения следующих параметров:

  • обучающая выборка;
  • тестовая выборка;
  • количество нейронов скрытого слоя;
  • коэффициент обучения;
  • момент;
  • количество эпох обучения.

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

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

Соответственно, для решения  поставленной задачи необходимо создание четырех классов:

  • класс нейросети и средств ее обработки;
  • класс перевода текста в двоичный вид;
  • класс хеш-таблицы и методов работы с ней;
  • класс разбиения текста на лексемы и распознавания.

Созданные классы будут оформлены в виде библиотечного компонента.

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

 

2. Проектирование библиотеки классов для реализации нейросети и тестовой программы

 

2.1 Программная реализация нейросети обратного распространения ошибки

 

Алгоритм  был реализован в виде класса NeuroNetwork. UML диаграмма класса представленна на рисунке 6.

Класс NeuroNetwork

Закрытые поля

string filename;

double[,] INP_PATTERNS;

double[,] OUT_PATTERNS;

int MAX_INP;

int MAX_HID;

int MAX_OUT;

int MAX_PAT;

double[] test_pat;

double[] desired;

neuron_type[] ipl;

neuron_type[] hl;

neuron_type[] ol;

double BETA;

double M;

int num_cycles;

Закрытые методы

 private double sigmoid(double x)

private void run_input_layer()

private void run_hidden_layer()

private void run_output_layer()

private void run_the_network()

private void display_the_results(out string[] outp)

private void AddWeightsToFile()

private void blank_changes()

private void calculate_output_layer_errors()

private void calculate_hidden_layer_errors()

private void calculate_input_layer_errors()

private void weight_change()

private void back_propagate()

private void ExtractWeights()

Открытые методы

public void random_weights()

public void get_test_pattern(double[] tests)

public void train_the_network()

public string[] test_the_network(double[] test)

Public NeuroNetwork(double[,] INP_PATTERNS1, double[,] OUT_PATTERNS1, int Max_inp, int N_HID, int Max_pat, double beta, double m,int Epoch,string name,bool indicate)


Рисунок 6 – UML-диаграмма класса NeuroNetwork

 

Параметры конструктора:

  • обучающая выборка - INP_PATTERNS;
  • желаемый выход - OUT_PATTERNS;
  • момент - M;
  • коэффициент обучения - BETA;
  • количество нейронов скрытого слоя - N_HID;
  • количество нейронов входного слоя - Max_inp;
  • количество образцов, содержащихся в обучающей выборке - Max_par;
  • количество эпох обучения - Epoch;
  • имя файла с обучающей выборкой - name;
  • логическая пременная indicate, сигнализирующая о необходимости обучения сети.

Ввод  тестируемой выборки производится посредствам метода get_test_pattern(double[] tests).

Для описания нейрона была создана структура neuron_type, содержащая следующие поля:

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

Описание  нейрона привидено ниже:

 

struct neuron_type

{

public double[] w; //весовые коэффициенты

public double[] change;//модификация весовых коэффициентов используется в процессе обучения

public double threshold, a; //а-сигнал на выходе нейрона,threshold-значение порога

public double t_change; //модификация порога используется в процессе обучения

public double E; //значение ошибки

}

 

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

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

 

int MAX_INP; //Количество нейронов в входном слое

int MAX_HID; //Количество нейронов в скрытом слое

int MAX_OUT; //Количество нейронов в выходном слое

neuron_type[] ipl; //Входной слой

neuron_type[] hl; //Скрытый слой

neuron_type[] ol; //Выходной слой

 

Функция активации (2) была реализована  в открытом методе sigmoid. В данном метода используется формула (3). Код на С# для этого метода:

 

private double sigmoid(double x)

{ return 1 / (1 + Math.Exp(-x)); }

 

Однако  функция Exp приводит к ошибке в программе, если входное значение выходит из промежутка -39..38. К счастью, эти значения настолько далеко отстоят от начала координат, что мы можем считать: при аргументе < -39 значение функции равно 0, при аргументе > 38, - значение функции равно 1. Для предотвращения ошибки добавим несколько строчек:

 

private double sigmoid(double x)

{ if (Math.Abs(x) < 38) //проверка условия нахождения функции в интервале -39..38

{ return 1 / (1 + Math.Exp(-x)); }

else

{ if (x >= 38)

{ return 1; }

else { return 0; } } }

 

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

Каждая  активность нейрона предыдущего  слоя умножается на соответствующий  весовой коэффициент, результаты умножения суммируются (1), вычитается пороговое значение, вычисляется значение сигмоидной функции (5). Вот пример на С#:

Вычисление  суммы взвешенных сигналов для входного набора данных

 

private void run_input_layer()

{ double sum = 0;

for (int i = 0; i < MAX_INP; i++)

{ sum = 0;

for (int j = 0; j < MAX_INP; j++)

{ sum = sum + ipl[i].w[j] * test_pat[j];//(1) }

ipl[i].a = sigmoid(sum - ipl[i].threshold);//(5) } }

 

Вычисление  суммы взвешенных сигналов для скрытого и выходного слоев (методы run_hidden_layer и run_output_layer) производится аналогично.

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

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

Информация о работе Распознавание слов естественного языка с использованием нейросетей