Рефераты
 

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

p align="left">Рисунок 9 - UML-диаграмма класса Analization

Параметрами конструктора являются:

- текст для анализа - sText;

- параметры нейросети N_HID, beta, m, Epoch;

- индикатор необходимости обучения нейросети - flag.

Из всех вышеперечисленных методов наиболее важными являются: конструктор, Scaning и GetNeuroResult.

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

private string Scaning(string sLetter, int N_HID, double beta, double m, int Epoch, bool flag)

{ Hash hash = new Hash();

string result = "существительное";//результат

string[] znaks = { "с", "п", "г" };

for (int i = 0; i < znaks.Length; i++)//поиск существительных, прилагательных и глаголов-исключений, сохраненных в хеш-таблице

{ if (hash.CheckHash(sLetter + znaks[i].ToString(), "iskl") == true)

{ switch (znaks[i])

{ case "с": result = "существительное";//если в конце слова буква с - возвращаем результат

return result;

case "п": result = "прилагательное";

return result;

case "г": result = "глагол";

return result; } } }

if (hash.CheckHash(sLetter, "predlog") == true)//проверяем, является ли слово предлогом (ищем в соответствующей хеш-таблице

{ result = "предлог";//если слово есть в хеш-таблице - возвращаем результат

return result; }

//Для местоимений, союзов, деепричастий и наречий аналогично

if (String.Compare(sLetter, "не") == 0 || String.Compare(sLetter, "бы") == 0)

{ result = "частица";

return result; }

if (sLetter.Length < 2)

{ return "предлог"; }

//--------------------------------------------------------------------

string[] pril = {"ий","ый","ая","яя","го","ую","ое","их","ых","ым"};//массив окончаний прилагательных

string[] glagol = {"ит","ат","ят","ут","ют","ул","ял","ал","ли","ла","ег","ел","сь","ыл","ил"};//глаголов

string[] prich = {"вший","шими","вшая","вшем","вшие","ящий","ящая","ящие","щими","ющий","ющая","ющие","ущий","ущая","ущие","ащий","ащая","ащие","шего","щего"};//окончаний и суффиксов причастий

string okonchanie= (sLetter[sLetter.Length - 2].ToString() + sLetter[sLetter.Length - 1].ToString());

if (Array.IndexOf(pril,okonchanie)!=-1)//если окончание слова содержится в массиве окончаний прилагательных переходим к проверке суффикса

{string ok_i_suff = sLetter[sLetter.Length - 4].ToString() + sLetter[sLetter.Length - 3].ToString() + okonchanie;

if (Array.IndexOf(prich,ok_i_suff)!= -1)//ищем в массиве суффиксов и окончаний причастий

{ return "причастие"; //если есть - результат причастие }

return "прилагательное"; //если нет - прилагательное }

else

if (String.Compare(okonchanie, "ом") == 0)//если окончание -ом

{ string res= GetNeuroResult(sLetter,"-ом",N_HID,beta,m,Epoch,flag_om);//распознаем слово нейросетью

flag_om = true;//при повторном поступлении слова на -ом нейросеть повторно обкчаться не будет

return res; }

else

//Аналогично для -ем, -им, -ой, -ие, -ми.

….}

Метод Scaning логически можно разделить на 3 блока:

- поиск слова в хеш-таблицах;

- идентификация слова по окончанию и определение его типа;

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

Во втором блоке подразумевается определение типа слова по окончанию (последние две буквы) при помощи условных операторов:

- при помощи метода IndexOf класса Array определяется наличие в соответствующем массиве (массиве окончаний глаголов - glagol, прилагательных - pril) данного окончания;

- если это окончание прилагательного или -ся то критерий поиска изменяется до идентификации по паре суффикс-окончание: определяется наличие данной пары в массиве prich (причастие);

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

- в случае, если окончание не найдено ни в одном из массивов, то тип лексемы определяется как существительное;

- если слово оканчивается на -ие, -ми, -ем, -им, -ом то переходим к третьему блоку.

В третьем блоке в зависимости от окончания слова производится вызов функции private string GetNeuroResult(string sLetter, string sFileName, int N_HID, double beta, double m, int Epoch, bool flag) параметрами:

- sLetter - лексема,

- sFileName - имя файла с обучающей выборкой,

- N_HID - количество скрытых нейронов,

- beta - коэффициент обучения,

- m - момент,

- Epoch - количество эпох обучения,

- flag - логическая переменная, в значении «истина» означающая, что анализ будет производиться без обучения;

Код данной функции представлен ниже:

private string GetNeuroResult(string sLetter, string sFileName, int N_HID, double beta, double m, int Epoch, bool flag)

{ string[] techears = File.ReadAllLines(sFileName+".txt");

Binarization binar = new Binarization(techears);//проводим бинаризацию

double[,] inp = new double[1, 1], outp = new double[1, 1]; double[] test = new double[1]; //обучающая выборка, выходы, тестовая выборка

int max_inp, max_pat;//кол-во нейронов и выборок

inp = binar.GetBinarizeText(out outp, out max_pat, out max_inp);//получаем обучающую выборкув закодированном виде

test = binar.GetBinarizeWord(sLetter);//получаем тестовую выборку в закодированном виде

NeuroNetwork neuro = new NeuroNetwork(inp, outp, max_inp, N_HID, max_pat, beta, m, Epoch, sFileName, flag);//создаем объект нейросеть

if (flag == false)//если она не обучена

{ neuro.random_weights();//инициализируем весовые коэффициенты случайными числами

neuro.train_the_network(); //обучаем нейросеть }

string[] m_resultat = neuro.test_the_network(test);

string res1="",res2="";

switch (sFileName)

{ //в зависимости от имени файла с обучающей выборкой возможны определенные комбинации возвращаемых результатов

case "-ой":

res1 = "существительное";

res2 = "прилагательное";

break;

… }

//анализируем полученные значения нейросети и возвращаем результат

if (double.Parse(m_resultat[0]) < 0.5 && double.Parse(m_resultat[1]) < 0.5 && double.Parse(m_resultat[2]) < 0.5)

{ return res1; }

if (double.Parse(m_resultat[0]) < 0.5 && double.Parse(m_resultat[1]) < 0.5 && double.Parse(m_resultat[2]) > 0.5)

{ return res2; }

return "неизвестно"; }

Алгоритм данной функции можно разделить на следующие этапы:

- извлечение обучающей выборки из файла,

- ее бинаризация при помощи класса Binarization,

- если flag==false - обучение нейронной сети,

- получение результата,

- определение по полученному результату типа лексемы.

2.5 Описание тестирующей программы

Программа выполнена в виде Windows-приложения в среде Microsoft Visual Studio и имеет оконный интерфейс.

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

Приложение состоит из трех окон:

- окно ввода текста для анализа (рисунок 13);

- окно анализа текста (рисунок 14);

- окно добавления лексемы в хеш-таблицу или в обучающую выборку (рисунок 15).

Текст для анализа загружается из файла или вводится с клавиатуры в richTextBox. Результат анализа (лексема и класс) выводится в dataGridView (рисунок 10)

Рисунок 10 - электронная таблица dataGridView

2.6 Результаты тестирования

Программа запускается из файла KursP.exe. В интерфейсе окна ввода текста (рисунок 11) присутствуют две кнопки: “Загрузить из файла” - загрузка текста для анализа, «Далее» - перейти к анализу. Текст для анализа можно вводить и вручную.

Рисунок 11 - Окно ввода текста

При нажатии кнопки «Далее» на экране появится окно анализа текста (рисунок 12). В окне анализа текста имеются кнопки «Анализ» и «Обучение». Первая используется для анализа текста без обучения нейросети, вторая - соответственно с обучение. Кнопка «Анализ» становится активной только при наличии файлов с весовыми коэффициентами для всех нейросетей. Результаты анализа выводятся в таблицу лексем.

Рисунок 12 - Окно анализа текста

При необходимости можно добавить слово в хеш-таблицу или в обучающую выборку при нажатии на кнопки “Добавить слово в хеш-таблицу” и «Добавить слово на -ой, -им, -ем». После нажатия данных кнопок перед пользователем появится окно добавления слова (рисунок 13). Далее пользователю необходимо ввести слово и класс и нажать кнопку «Добавить».

Рисунок 13 - Окно добавления лексемы в хеш-таблицу или в обучающую выборку

Для тестирования программы будем использовать отрывок из произведения Л.Н. Толстого «Война и мир»:

«В штабе Кутузова ожидали вестей от командующего австрийской армией Мака. В это время в штаб неожиданно прибыл незнакомый генерал, которого адъютанты не захотели пропустить к Кутузову. Главнокомандующий вышел в приемную и узнал в прибывшем генерала Мака, который подтвердил слухи о поражении австрийцев под Ульмом и о сдаче всей армии. Князь Андрей понимал, что русская армия оказалась в очень тяжелом положении, что ей предстоит трудное сражение с французами. С одной стороны, он был рад этому, так как представилась наконец возможность принять участие в бое, с другой стороны - опасался поражения русской армии, понимая, что в данной ситуации преимущество на стороне Бонапарта.»

При тестировании будем использовать нейросеть со следующими параметрами:

- эпох - 6000;

- нейронов в скрытом слое - 15;

- момент - 0,7

- коэффициент обучения - 0,7.

При анализе полученного результата была выявлена ошибка (рисунок 14).

Рисунок 14 - Окно программы с результатом анализа с ошибкой

Данной ошибки можно избежать, добавив слово «Французами» в файл с тестовой выборкой.

После внесения соответствующих изменений в нейросеть был получен следующий результат (рисунок 15):

Рисунок 15 - Окно программы с результатом анализа с без ошибки

3. Руководство программисту

Используемые в тестирующей программе классы содержатся в библиотеке классов NeuroLibrary. Соответствующий библиотечный файл NeuroLibrary.dll содержится в одной директории с исполняемым файлом программы (файл KursP.exe).

Рассмотрим процедуру создания библиотеки классов. Для этого необходимо создать в VisualStudio проект типа ClassLibrary (рисунок 16).

Рисунок 16 - Создание проекта «Библиотека классов» в VisualStudio

После создания всех необходимых классов в библиотеке, необхлодимо произвести компиляцию проекта. В случае отсутствия ошибок в коде в папке NeuroLibrary/Debug/bin будет создан библиотечный файл.

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

Рисунок 17 - Окно добавления ссылки

Далее необходимо подключить соответсвующее пространство имен NeuroLibrary с помощью директивы using и классы данной библиотеки станут доступны.

В тестирующей программе для получения результата достаточно создать объект класса Analization и вызвать свойство GetResult. Все необходимые действия будут произведены в конструкторе класса. GetResult необходим для получения результата в виде списка объектов типа string.

Для возможности влиять на работу анализатора понадобится использование класса Hash. С помощью методов данного класса можно добавить слово-исключение в хеш-таблицу. Содержимое хеш-таблиц хранится в папке с исполняемым файлом программы в текстовых файлах: narechie, predlog, soyuz, deepr, iskl, mest.

Для возможности добавления слова в обучающую выборку нейросети предусмотрен статический метод AddToFile класса Analization. Обучающие выборки нейросети хранятся в текстовых файлах: -ом, -ем, -им, -ми, -ие, -ой.

Как было сказано в подразделе 2.1, нейросеть производит запись весовых коэффициентов в текстовые файлы, хранящиеся в одном каталоге с исполняемым файлом программы. Их имена формируются по следующему принципу: имя файла с обучающей выборкой + наименование слоя сети (ip - входной, hl - скрытый, ol - выходной. Пример омip - весовые коэффициенты входного слоя сети для слов с окончанием ом.

Системные требования:

- Для корректной работы приложения необходимо наличие на компьютере программы Microsoft.NET Framework 2.0

- Операционные системы: Windows 2000 Service Pack 3; Windows 98; Windows 98 Second Edition; Windows ME; Windows Server 2003; Windows XP Service Pack 2

- Требуемое программное обеспечение: установщик Windows 3.0 (кроме ОС Windows 98/ME, для которых требуется Установщик Windows 2.0 или более поздней версии). Рекомендуется Установщик Windows 3.1 или более поздней версии. Обозреватель IE 5.01 или более поздней версии: Для установки.NET Framework требуется обозреватель Microsoft Internet Explorer 5.01 или более поздней версии.

Заключение

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

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

Данный программный продукт может быть использован специалистами в области филолигии.

Список используемой литературы

Комарцова Л.Г., Максимов А.В.. Нейрокомпьютеры Учебное пособие для вузов. - М.: Изд-во МГТУ им. Н.Э.Баумана,2002.

Осовский С. Нейронные сети для обработки информации.-М.:Финансы и статистика, 2004.

Уоссермен Ф. Нейрокомпьютерная техника: теория и практика. -- М.: Мир, 1992.

Ключко В.И., Ермоленко В.В. Нейрокомпьютерные системы. Базы знаний. Учеб. пособие Изд-во КубГТУ,1999.-100с.

Приложение А. Листинг класса NeuroNetwork

class NeuroNetwork

{

struct neuron_type

{

public double[] w;//=new double[MAX_INP]; // {весовые коэффициенты}

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

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

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

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

}

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 = 0.8; // {Коэффициент обучения}

double M = 0.8; //{момент}

int num_cycles = 1000;

string filename;

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)

{

filename = name;

num_cycles = Epoch;

// elemKolvo = elemKol;

BETA = beta; M = m;

MAX_INP = Max_inp; //{Количество нейронов в входном слое}

MAX_HID = N_HID; //{Количество нейронов в скрытом слое}

MAX_OUT = 3; //int IPi;

MAX_PAT = Max_pat;

INP_PATTERNS = INP_PATTERNS1;

OUT_PATTERNS = OUT_PATTERNS1;

test_pat = new double[MAX_INP];

desired = new double[MAX_OUT];

ipl = new neuron_type[MAX_INP]; // {Входной слой }

hl = new neuron_type[MAX_HID]; // {Скрытый слой }

ol = new neuron_type[MAX_OUT];

if (indicate == true)

{

try { ExtractWeights(); }

catch { }

}

}

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; }

}

}

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

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]; }

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

}

}

//{Вычисление суммы взвешенных сигналов для скрытого слоя}

private void run_hidden_layer()

{

double sum;

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

{

sum = 0;

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

{ sum = sum + hl[i].w[j] * ipl[j].a; }

hl[i].a = sigmoid(sum - hl[i].threshold);

}

}

//{Вычисление суммы взвешенных сигналов для выходного слоя}

private void run_output_layer()

{

double sum;

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

{

sum = 0;

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

{ sum = sum + ol[i].w[j] * hl[j].a; }

ol[i].a = sigmoid(sum - ol[i].threshold);

}

}

private void run_the_network()

{

run_input_layer();

run_hidden_layer();

run_output_layer();

}

//{Процедура выводит на экран результаты теста}

private void display_the_results(out string[] outp)

{

outp = new string[ol.Length];

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

{ outp[i] = ol[i].a.ToString() + " "; }

}

// {Процедуры для тестирования сети до и после обучения}

public void get_test_pattern(double[] tests)

{

test_pat = tests;

}

public string[] test_the_network(double[] test)

{

test_pat = test;

Console.WriteLine();

Console.WriteLine("Процедура тестирования сети");

Console.WriteLine();

string[] str;

run_the_network();

display_the_results(out str);

return str;

}

// {Процедуры обучения сети}

private void calculate_output_layer_errors()

{

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

{ ol[j].E = (desired[j] - ol[j].a) * ol[j].a * (1 - ol[j].a); }

}

private void calculate_hidden_layer_errors()

{

double sum;

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

{

sum = 0; // {Сумма ошибок выходного слоя}

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

{ sum = sum + ol[j].E * ol[j].w[i]; }

hl[i].E = hl[i].a * (1 - hl[i].a) * sum;

}

}

private void calculate_input_layer_errors()

{

double sum;

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

{

sum = 0; // {Сумма ошибок скрытого слоя}

for (int j = 1; j < MAX_HID; j++)

{ sum = sum + hl[j].E * hl[j].w[i]; }

ipl[i].E = ipl[i].a * (1 - ipl[i].a) * sum;

}

}

private void weight_change()

{

for (int j = 0; j < MAX_OUT; j++) //{выходной слой}

{

for (int i = 0; i < MAX_HID; i++) //{Подстройка}

{

ol[j].change[i] = BETA * ol[j].E * hl[i].a + M * ol[j].change[i];

ol[j].w[i] = ol[j].w[i] + ol[j].change[i];

}

// {Подстройка значения порога}

ol[j].t_change = BETA * ol[j].E * 1 + M * ol[j].t_change;

//--------------------

ol[j].threshold = ol[j].threshold + ol[j].t_change;

//----------------------------

}

// {Модифицируем веса между входным слоем и скрытым слоем}

// {i -нейрон входного слоя, j -скрытого}

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

{

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

{

hl[j].change[i] = BETA * hl[j].E * ipl[i].a + M * hl[j].change[i];

hl[j].w[i] = hl[j].w[i] + hl[j].change[i];

}

hl[j].t_change = BETA * hl[j].E * 1 + M * hl[j].t_change;

//-------------------------------------

hl[j].threshold = hl[j].threshold + hl[j].t_change;

}

// {Модифицируем веса между входами и входным слоем }

// {i -входной образ, j - нейроны входного слоя}

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

{

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

{

ipl[j].change[i] = BETA * ipl[j].E * test_pat[i] + M * ipl[j].change[i];

ipl[j].w[i] = ipl[j].w[i] + ipl[j].change[i];

}

ipl[j].t_change = BETA * ipl[j].E * 1 + M * ipl[j].t_change;

ipl[j].threshold = ipl[j].threshold + ipl[j].t_change;

}

}

//{Выполнение алгоритма back propagation }

private void back_propagate()

{

calculate_output_layer_errors();

calculate_hidden_layer_errors();

calculate_input_layer_errors();

weight_change();

}

//{Инициализация весовых коэффициентов и порогов}

public void random_weights()

{

Random rnd = new Random();

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

{

ipl[i].w = new double[MAX_INP]; // {весовые коэффициенты}

ipl[i].change = new double[MAX_INP];

}

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

{

hl[i].w = new double[MAX_INP]; // {весовые коэффициенты}

hl[i].change = new double[MAX_INP];

}

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

{

ol[i].w = new double[MAX_HID]; // {весовые коэффициенты}

ol[i].change = new double[MAX_HID];

}

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

{

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

{ ipl[i].w[j] = (double)rnd.Next(1000) / 1000; }

ipl[i].threshold = (double)rnd.Next(1000) / 1000;

}

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

{

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

{ hl[i].w[j] = (double)rnd.Next(1000) / 1000; }

hl[i].threshold = (double)rnd.Next(1000) / 1000;

}

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

{

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

{ ol[i].w[j] = (double)rnd.Next(1000) / 1000; }

ol[i].threshold = (double)rnd.Next(1000) / 1000;

}

}

private void ExtractWeights()

{

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

{

ipl[i].w = new double[MAX_INP]; // {весовые коэффициенты}

ipl[i].change = new double[MAX_INP];

}

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

{

hl[i].w = new double[MAX_INP]; // {весовые коэффициенты}

hl[i].change = new double[MAX_INP];

}

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

{

ol[i].w = new double[MAX_HID]; // {весовые коэффициенты}

ol[i].change = new double[MAX_HID];

}

if (File.Exists(filename + "ip.txt") == true && File.Exists(filename + "ol.txt") == true && File.Exists(filename + "hl.txt") == true)

{

StreamReader streamreader = new StreamReader(filename + "ip.txt");

for (int i = 0; i < ipl.Length; i++)

{

ipl[i].a = double.Parse(streamreader.ReadLine());

ipl[i].threshold = double.Parse(streamreader.ReadLine());

for (int j = 0; j < ipl[i].w.Length; j++)

{

ipl[i].w[j] = double.Parse(streamreader.ReadLine());

}

}

streamreader.Close();

streamreader = new StreamReader(filename + "ol.txt");

for (int i = 0; i < ol.Length; i++)

{

ol[i].a = double.Parse(streamreader.ReadLine());

ol[i].threshold = double.Parse(streamreader.ReadLine());

for (int j = 0; j < ol[i].w.Length; j++)

{

ol[i].w[j] = double.Parse(streamreader.ReadLine());

}

}

streamreader.Close();

streamreader = new StreamReader(filename + "hl.txt");

for (int i = 0; i < hl.Length; i++)

{

hl[i].a = double.Parse(streamreader.ReadLine());

hl[i].threshold = double.Parse(streamreader.ReadLine());

for (int j = 0; j < hl[i].w.Length; j++)

{

hl[i].w[j] = double.Parse(streamreader.ReadLine());

}

}

streamreader.Close();

}

else

{

File.Create(filename + "ip.txt");

File.Create(filename + "ol.txt");

File.Create(filename + "hl.txt");

}

}

//-------------------------------------------------------------

private void AddWeightsToFile()

{

StreamWriter streamwriter = new StreamWriter(filename + "ip.txt");

for (int i = 0; i < ipl.Length; i++)

{

streamwriter.WriteLine(ipl[i].a.ToString());

streamwriter.WriteLine(ipl[i].threshold.ToString());

for (int j = 0; j < ipl[i].w.Length; j++)

{

streamwriter.WriteLine(ipl[i].w[j].ToString());

streamwriter.Flush();

}

streamwriter.Flush();

}

streamwriter.Close();

streamwriter = new StreamWriter(filename + "hl.txt");

for (int i = 0; i < hl.Length; i++)

{

streamwriter.WriteLine(hl[i].a.ToString());

streamwriter.WriteLine(hl[i].threshold.ToString());

for (int j = 0; j < hl[i].w.Length; j++)

{

streamwriter.WriteLine(hl[i].w[j].ToString());

streamwriter.Flush();

}

streamwriter.Flush();

}

streamwriter.Close();

streamwriter = new StreamWriter(filename + "ol.txt");

for (int i = 0; i < ol.Length; i++)

{

streamwriter.WriteLine(ol[i].a.ToString());

streamwriter.WriteLine(ol[i].threshold.ToString());

for (int j = 0; j < ol[i].w.Length; j++)

{

streamwriter.WriteLine(ol[i].w[j].ToString());

streamwriter.Flush();

}

streamwriter.Flush();

}

streamwriter.Close();

}

private void blank_changes()

{

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

{

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

{ ipl[j].change[i] = 0; }

ipl[j].t_change = 0;

}

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

{

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

{ hl[j].change[i] = 0; }

hl[j].t_change = 0;

}

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

{

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

{ ol[j].change[i] = 0; }

ol[j].t_change = 0;

}

}

public void train_the_network()

{

blank_changes(); // {Очистка предыдущих значений changes}

for (int loop = 0; loop < num_cycles; loop++)

{

for (int pat = 0; pat < MAX_PAT; pat++)

{

for (int i = 0; i < MAX_INP; i++) //{Копирование входного образа}

{ test_pat[i] = INP_PATTERNS[pat, i]; } //{в массив 'test_pat' }

for (int i = 0; i < MAX_OUT; i++) //{Копирование выходного образа}

{ desired[i] = OUT_PATTERNS[pat, i]; } //{ в массив'desired' }

run_the_network(); //{Определение выходов сети}

back_propagate();

}

}

AddWeightsToFile();

}

}

Приложение Б. Листинг класса Analization

public class Analization

{

List<Results> results = new List<Results>();

public static void AddToFile(string sLetter, string sFile)

{

FileStream filestream = File.Open(sFile + ".txt", FileMode.Append, FileAccess.Write);

StreamWriter streamwriter = new StreamWriter(filestream);

streamwriter.WriteLine(sLetter);

streamwriter.Close();

filestream.Close();

}

private void AddEtalonLetter()

{

string[] im = { "смотрим@", "носим@", "ходим@", "бродим@", "катим@", "синим#", "большим#", "тугим#", "крайним#" };

if (File.Exists("-им.txt") == false)

{

FileStream filestream = File.Open("-им.txt", FileMode.CreateNew, FileAccess.Write);

StreamWriter streamwriter = new StreamWriter(filestream);

for (int i = 0; i < im.Length; i++)

{

streamwriter.WriteLine(im[i]);

}

streamwriter.Close();

filestream.Close();

}

string[] om = { "столом@", "стулом@", "ковром@", "городом@", "селом@", "красном#", "туманном#", "тяжелом#", "легком#" };

if (File.Exists("-ом.txt") == false)

{

FileStream filestream = File.Open("-ом.txt", FileMode.CreateNew, FileAccess.Write);

StreamWriter streamwriter = new StreamWriter(filestream);

for (int i = 0; i < om.Length; i++)

{

streamwriter.WriteLine(om[i]);

}

streamwriter.Close();

filestream.Close();

}

string[] oy = { "ручкой@", "краской@", "бумагой@", "оградой@", "каймой@", "большой#", "небольшой#", "тугой#", "малой#" };

if (File.Exists("-ой.txt") == false)

{

FileStream filestream = File.Open("-ой.txt", FileMode.CreateNew, FileAccess.Write);

StreamWriter streamwriter = new StreamWriter(filestream);

for (int i = 0; i < oy.Length; i++)

{

streamwriter.WriteLine(oy[i]);

}

streamwriter.Close();

filestream.Close();

}

string[] em = { "кидаем@", "бросаем@", "стережем@", "бережем@", "блюдем@", "гребнем#", "камнем#", "ставнем#", "гравием#" };

if (File.Exists("-ем.txt") == false)

{

FileStream filestream = File.Open("-ем.txt", FileMode.CreateNew, FileAccess.Write);

StreamWriter streamwriter = new StreamWriter(filestream);

for (int i = 0; i < em.Length; i++)

{

streamwriter.WriteLine(em[i]);

}

streamwriter.Close();

filestream.Close();

}

string[] ie = { "большие@", "синие@", "маленькие@", "хорошие@", "плохие@", "хождение#", "мероприятие#", "становление#", "украшение#" };

if (File.Exists("-ие.txt") == false)

{

FileStream filestream = File.Open("-ие.txt", FileMode.CreateNew, FileAccess.Write);

StreamWriter streamwriter = new StreamWriter(filestream);

for (int i = 0; i < ie.Length; i++)

{

streamwriter.WriteLine(ie[i]);

}

streamwriter.Close();

filestream.Close();

}

string[] mi = { "красными@", "зелеными@", "хорошими@", "плохими@", "трудными@", "стульями#", "столами#", "ставнями#", "карандашами#" };

if (File.Exists("-ми.txt") == false)

{

FileStream filestream = File.Open("-ми.txt", FileMode.CreateNew, FileAccess.Write);

StreamWriter streamwriter = new StreamWriter(filestream);

for (int i = 0; i < mi.Length; i++)

{

streamwriter.WriteLine(mi[i]);

}

streamwriter.Close();

filestream.Close();

}

}

public string BigToSmall(string letter)

{

switch (letter)

{

case "А": return "а";

case "Б": return "б";

case "В": return "в";

case "Г": return "г";

case "Д": return "д";

case "Е": return "е";

case "Ё": return "ё";

case "Ж": return "ж";

case "З": return "з";

case "И": return "и";

case "Й": return "й";

case "К": return "к";

case "Л": return "л";

case "М": return "м";

case "Н": return "н";

case "О": return "о";

case "П": return "п";

case "Р": return "р";

case "С": return "с";

case "Т": return "т";

case "У": return "у";

case "Ф": return "ф";

case "Х": return "х";

case "Ц": return "ц";

case "Ч": return "ч";

case "Ш": return "ш";

case "Щ": return "щ";

case "Ъ": return "ъ";

case "Ы": return "ы";

case "Ь": return "ь";

case "Э": return "э";

case "Ю": return "ю";

case "Я": return "я";

}

return "ё";

}

public Analization(string sText, int N_HID, double beta, double m, int Epoch, bool flag)

{

AddEtalonLetter();

Results res;

string sLetter = "";

for (int i = 0; i < sText.Length; i++)

{

if (sText[i] == ' ' || sText[i] == '.' || sText[i] == ',' || sText[i] == '!' || sText[i] == '?' || sText[i] == '-' || sText[i] == ':' || sText[i] == ';')

{

if (sLetter == "")

{

goto k;

}

if ((Char.ConvertToUtf32(sLetter, 0) >= 1040 && Char.ConvertToUtf32(sLetter, 0) <= 1071))

{

if (i - sLetter.Length + 1 == 1)

{

string ch = BigToSmall(sLetter[0].ToString());

sLetter = ch + sLetter.Substring(1, sLetter.Length - 1);

goto m;

}

else

if (sText[i - sLetter.Length - 1] == ' ' && sText[i - sLetter.Length - 2] == '.')

{

string ch = BigToSmall(sLetter[0].ToString());

sLetter = ch + sLetter.Substring(1, sLetter.Length - 1);

goto m;

}

res.Class = "существительное";

res.letter = sLetter;

results.Add(res);

sLetter = "";

goto k;

}

m:

res.letter = sLetter;

res.Class = Scaning(sLetter, N_HID, beta, m, Epoch, flag);

results.Add(res);

if (sText[i] == '.')

{

res.Class = "точка";

res.letter = sText[i].ToString();

results.Add(res);

goto k;

}

if (sText[i] == ',')

{

res.Class = "запятая";

res.letter = sText[i].ToString();

results.Add(res);

goto k;

}

if (sText[i] == '!')

{

res.Class = "восклицательный знак";

res.letter = sText[i].ToString();

results.Add(res);

goto k;

}

if (sText[i] == '?')

{

res.Class = "вопросительный знак";

res.letter = sText[i].ToString();

results.Add(res);

goto k;

}

if (sText[i] == '-')

{

res.Class = "тире";

res.letter = sText[i].ToString();

results.Add(res);

goto k;

}

if (sText[i] == ':')

{

res.Class = "двоеточие";

res.letter = sText[i].ToString();

results.Add(res);

goto k;

}

if (sText[i] == ';')

{

res.Class = "точка с запятой";

res.letter = sText[i].ToString();

results.Add(res);

goto k;

}

k: sLetter = "";

}

else

{

sLetter = sLetter + sText[i].ToString();

}

}

}

public List<Results> GetResult()

{

return results;

}

bool flag_oy = false, flag_om = false, flag_im = false, flag_em = false, flag_ie = false, flag_mi = false;

private string GetNeuroResult(string sLetter, string sFileName, int N_HID, double beta, double m, int Epoch, bool flag)

{

string[] techears = File.ReadAllLines(sFileName + ".txt");

Binarization binar = new Binarization(techears);//проводим бинаризацию

double[,] inp = new double[1, 1], outp = new double[1, 1]; double[] test = new double[1]; //обучающая выборка, выходы, тестовая выборка

int max_inp, max_pat;//кол-во нейронов и выборок

inp = binar.GetBinarizeText(out outp, out max_pat, out max_inp);

test = binar.GetBinarizeWord(sLetter);

NeuroNetwork neuro = new NeuroNetwork(inp, outp, max_inp, N_HID, max_pat, beta, m, Epoch, sFileName, flag);//нейросеть

if (flag == false)

{

neuro.random_weights();

neuro.train_the_network();

}

string[] m_resultat = neuro.test_the_network(test);

string res1 = "", res2 = "";

switch (sFileName)

{

case "-ой":

res1 = "существительное";

res2 = "прилагательное";

break;

case "-им":

res1 = "глагол";

res2 = "прилагательное";

break;

case "-ем":

res1 = "глагол";

res2 = "существительное";

break;

case "-ом":

res1 = "существительное";

res2 = "прилагательное";

break;

case "-ие":

res1 = "прилагательное";

res2 = "существительное";

break;

case "-ми":

res1 = "прилагательное";

res2 = "существительное";

break;

}

if (double.Parse(m_resultat[0]) < 0.5 && double.Parse(m_resultat[1]) < 0.5 && double.Parse(m_resultat[2]) < 0.5)

{

return res1;

}

if (double.Parse(m_resultat[0]) < 0.5 && double.Parse(m_resultat[1]) < 0.5 && double.Parse(m_resultat[2]) > 0.5)

{

return res2;

}

return "неизвестно";

}

private string Scaning(string sLetter, int N_HID, double beta, double m, int Epoch, bool flag)

{

Hash hash = new Hash();

string result = "существительное";//результат

string[] znaks = { "с", "п", "г" };

for (int i = 0; i < znaks.Length; i++)

{

if (hash.CheckHash(sLetter + znaks[i].ToString(), "iskl") == true)

{

switch (znaks[i])

{

case "с": result = "существительное";

return result;

case "п": result = "прилагательное";

return result;

case "г": result = "глагол";

return result;

}

}

}

if (hash.CheckHash(sLetter, "predlog") == true)

{

result = "предлог";

return result;

}

if (hash.CheckHash(sLetter, "mest") == true)

{

result = "местоимение";

return result;

}

if (hash.CheckHash(sLetter, "narechie") == true)

{

result = "наречие";

return result;

}

if (hash.CheckHash(sLetter, "deepr") == true)

{

result = "деепричастие";

return result;

}

if (hash.CheckHash(sLetter, "soyuz") == true)

{

result = "союз";

return result;

}

if (String.Compare(sLetter, "не") == 0 || String.Compare(sLetter, "бы") == 0)

{

result = "частица";

return result;

}

if (sLetter.Length < 2)

{ return "предлог"; }

//--------------------------------------------------------------------

string[] pril = { "ий", "ый", "ая", "яя", "го", "ую", "ое", "их", "ых", "ым" };

string[] glagol = { "ит", "ат", "ят", "ут", "ют", "ул", "ял", "ал", "ли", "ла", "ег", "ел", "сь", "ыл", "ил" };

string[] prich = { "вший", "шими", "вшая", "вшем", "вшие", "ящий", "ящая", "ящие", "щими", "ющий", "ющая", "ющие", "ущий", "ущая", "ущие", "ащий", "ащая", "ащие", "шего", "щего" };

string okonchanie = (sLetter[sLetter.Length - 2].ToString() + sLetter[sLetter.Length - 1].ToString());

if (Array.IndexOf(pril, okonchanie)!= -1)

{

string ok_i_suff = sLetter[sLetter.Length - 4].ToString() + sLetter[sLetter.Length - 3].ToString() + okonchanie;

if (Array.IndexOf(prich, ok_i_suff)!= -1)

{

return "причастие";

}

return "прилагательное";

}

else

if (Array.IndexOf(glagol, okonchanie)!= -1)

{

return "глагол";

}

else

if (Array.IndexOf(glagol, okonchanie)!= -1)

{

return "глагол";

}

else

if (String.Compare(okonchanie, "ся") == 0)

{

string ok_i_suff = sLetter[sLetter.Length - 4].ToString() + sLetter[sLetter.Length - 3].ToString();

if (Array.IndexOf(pril, ok_i_suff)!= -1)

{

return "причастие";

}

else

{

return "глагол";

}

}

else

if (String.Compare(okonchanie, "ть") == 0)

{

char ok_i_suff = sLetter[sLetter.Length - 3];

if (ok_i_suff == 'а' || ok_i_suff == 'я' || ok_i_suff == 'ю' || ok_i_suff == 'у' || ok_i_suff == 'е' || ok_i_suff == 'и')

{

return "глагол";

}

else

{

return "существительное";

}

}

else

if (String.Compare(okonchanie, "ом") == 0)

{

string res = GetNeuroResult(sLetter, "-ом", N_HID, beta, m, Epoch, flag_om);

flag_om = true;

return res;

}

else

if (String.Compare(okonchanie, "ем") == 0)

{

string ok_i_suff = sLetter[sLetter.Length - 4].ToString() + sLetter[sLetter.Length - 3].ToString() + okonchanie;

if (Array.IndexOf(prich, ok_i_suff)!= -1)

{

return "причастие";

}

string res = GetNeuroResult(sLetter, "-ем", N_HID, beta, m, Epoch, flag_em);

flag_em = true;

return res;

}

else

if (String.Compare(okonchanie, "им") == 0)

{

string res = GetNeuroResult(sLetter, "-им", N_HID, beta, m, Epoch, flag_im);

flag_im = true;

return res;

}

else

if (String.Compare(okonchanie, "ой") == 0)

{

string res = GetNeuroResult(sLetter, "-ой", N_HID, beta, m, Epoch, flag_oy);

flag_oy = true;

return res;

}

else

if (String.Compare(okonchanie, "ие") == 0)

{

string ok_i_suff = sLetter[sLetter.Length - 4].ToString() + sLetter[sLetter.Length - 3].ToString() + okonchanie;

if (Array.IndexOf(prich, ok_i_suff)!= -1)

{

return "причастие";

}

string res = GetNeuroResult(sLetter, "-ие", N_HID, beta, m, Epoch, flag_ie);

flag_ie = true;

return res;

}

else

if (String.Compare(okonchanie, "ми") == 0)

{

string ok_i_suff = sLetter[sLetter.Length - 4].ToString() + sLetter[sLetter.Length - 3].ToString() + okonchanie;

if (Array.IndexOf(prich, ok_i_suff)!= -1)

{

return "причастие";

}

string res = GetNeuroResult(sLetter, "-ми", N_HID, beta, m, Epoch, flag_mi);

flag_mi = true;

return res;

}

else

{

return "существительное";

}

}

}

Приложение В. Листинг класса Binaryzation

class Binarization

{

string[] sLetter;

int iLengthPattern;

public Binarization(string[] sLetter1)

{

sLetter = sLetter1;

}

private string DecToBin(string value)

{

value.Trim(); // очищаем строку от пробелов

char[] array = null; /* массив для хранения двоичных чисел ввиде символов */

int degree = Convert.ToInt32(value) / 255; /* получаем степень возведения для отображения количества 0 в массиве */

if (degree <= 255 && Convert.ToInt32(value) <= 255) /* если степень входит в стандартный диапазон 8 цифр */

array = new char[8];

else /* иначе вычисляем наш диапазон цифр */

{

if (degree == 1) /* если оставить 1, то получится первое условие, а нам надо чтобы выполнилось второе */

degree++;

array = new char[8 * degree];

}

int position = array.Length - 1; /* двоичные цифры считаются с конца в начало, соответственно писать мы их будем, тоже с конца в начало */

int nextValue = Convert.ToInt32(value); /* здесь будет хранится наше значение, которое мы будем делить на 2 и проверять есть ли остаток от деления */

for (int i = 0; i < array.Length; i++) /* в этом цикле мы будем заполнять наш массив значениями */

{

if ((Convert.ToInt32(nextValue) % 2)!= 0) /* проверяем есть ли остаток от деления */

{

nextValue /= 2; /* в любом случае записываем результат, для дальнейших расчетов */

array[position] = '1'; /* устанавливаем 1 если остаток есть */

}

else

{

nextValue /= 2; /* в любом случае записываем результат, для дальнейших расчетов */

array[position] = '0'; /* устанавливаем 0 если остатка нет */

}

position--; /* уменьшаем итератор */

}

string ret = ""; // пустая строка для хранения результата

for (int i = 0; i < array.Length; i++) /* в этом цикле уже записываем в нашу строку, наше двоичное число, с начала и до конца */

ret += array[i].ToString();

return ret;

}

public double[] GetBinarizeWord(string sWord)

{

int iSum = 0; string sBuf = ""; int k = 0;

for (int j = 0; j < sWord.Length; j++)

{

iSum = iSum + (j + 5) * Char.ConvertToUtf32(sWord[j].ToString(), 0);

}

sBuf = DecToBin(iSum.ToString());

k = 0;

while (sBuf[k]!= '1')

{

k++;

}

sBuf = sBuf.Substring(k, sBuf.Length - 1 - k);

double[] test = new double[iLengthPattern];

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

{

if (sBuf.Length <= j)

{

test[j] = 0;

}

else

if (sBuf[j] == '1')

{

test[j] = 1;

}

}

return test;

}

public double[,] GetBinarizeText(out double[,] OUT_PATTERNS, out int max_pat, out int iLengthPattern1)

{

max_pat = sLetter.Length;

OUT_PATTERNS = new double[sLetter.Length, 3];

int iSum = 0; string sBuf; int k = 0; iLengthPattern1 = 0; string[] sBigBuf = new string[sLetter.Length];

for (int i = 0; i < sLetter.Length; i++)

{

iSum = 0;

for (int j = 0; j < sLetter[i].Length - 1; j++)

{

iSum = iSum + (j + 5) * Char.ConvertToUtf32(sLetter[i][j].ToString(), 0);

}

switch (sLetter[i][sLetter[i].Length - 1])

{

case '@': OUT_PATTERNS[i, 0] = 0; OUT_PATTERNS[i, 1] = 0;

OUT_PATTERNS[i, 2] = 0;

break;

case '#': OUT_PATTERNS[i, 0] = 0; OUT_PATTERNS[i, 1] = 0;

OUT_PATTERNS[i, 2] = 1;

break;

case '*': OUT_PATTERNS[i, 0] = 0; OUT_PATTERNS[i, 1] = 1;

OUT_PATTERNS[i, 2] = 0;

break;

case '(': OUT_PATTERNS[i, 0] = 0; OUT_PATTERNS[i, 1] = 1;

OUT_PATTERNS[i, 2] = 1;

break;

case '-': OUT_PATTERNS[i, 0] = 1; OUT_PATTERNS[i, 1] = 0;

OUT_PATTERNS[i, 2] = 0;

break;

case '/': OUT_PATTERNS[i, 0] = 1; OUT_PATTERNS[i, 1] = 0;

OUT_PATTERNS[i, 2] = 1;

break;

case '+': OUT_PATTERNS[i, 0] = 1; OUT_PATTERNS[i, 1] = 1;

OUT_PATTERNS[i, 2] = 0;

break;

}

sBuf = DecToBin(iSum.ToString());

k = 0;

while (sBuf[k]!= '1')

{

k++;

}

sBuf = sBuf.Substring(k, sBuf.Length - 1 - k);

if (sBuf.Length > iLengthPattern1)

{

iLengthPattern1 = sBuf.Length;

}

sBigBuf[i] = sBuf;

}

double[,] inp = new double[sLetter.Length, iLengthPattern1];

for (int i = 0; i < sLetter.Length; i++)

{

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

{

if (sBigBuf[i].Length <= j)

{

inp[i, j] = 0;

}

else

if (sBigBuf[i][j] == '1')

{

inp[i, j] = 1;

}

}

}

iLengthPattern = iLengthPattern1;

return inp;

}

}

Страницы: 1, 2


© 2010 BANKS OF РЕФЕРАТ