p align="left">Вычисление суммы взвешенных сигналов для скрытого и выходного слоев (методы run_hidden_layer и run_output_layer) производится аналогично. Каждый слой нейронов базируется на выходе предыдущего слоя (за исключением входного слоя, базирующегося непосредственно на предъявляемых сети входных данных (в коде - массив test_pat). Это значит, что значения входного слоя должны быть полностью рассчитаны до вычисления значений скрытого слоя, которые в свою очередь, должны быть рассчитаны до вычисления значений выходного слоя. Выходы нейронной сети - значения активностей (поле a) нейронов выходного слоя. Программа, симулирующая работу нейронной сети, в процессе обучения будет сравнивать их со значениями, которые должны быть на выходе сети. Полный алгоритм обучения НС с помощью процедуры обратного распространения строится так: 1. Инициализировать пороговые значения и весовые коэффициенты небольшими случайными величинами (не более 0.4). Инициализация весовых коэффициентов случайными вещественными значениями с помощью класса Random производится в функции random_weights. 2. Подать на входы сети один из возможных образов и в режиме обычного функционирования НС, когда сигналы распространяются от входов к выходам, рассчитать значения последних. Метод run_the_networ. 3. Вычислить ошибки для выходного слоя (calculate_output_layer_errors). При этом используем формулу (7) для каждого i-ого значения выходного слоя. Ниже представлена соответствующая функция: 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); } } Вычисление ошибки для скрытого и входного слоев производится методами calculate_input_layer_errors и calculate_hidden_layer_errors по формуле (8). Код соответствеющей функции для входного слоя предтсавлен ниже: 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; } } Используя формулы (9), (10), (11) получим функцию, обучающую весовые коэффициенты и пороговые уровни: private void weight_change() { //i обозначает нейрон скрытого слоя, j - выходного 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; // } //Модифицируем веса между входным слоем и скрытым слоем … //Модифицируем веса между входами и входным слоем … } } Далее объединим вышеуказанные функции в одном методе back_propogate(). В общем виде функция обучения сети будет выглядеть следующим образом: 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(); } Для очистки предыдущих значений используется функция blank_changes. Для упрощения временной сложности работы сети полученные весовые коэффициенты будем записывать в отдельные файлы (метод AddWeightsToFile()), имена которым даются программой автоматически Для считывания сохраненных параметров будет применяться метод ExtractWeights(). 2.2 Класс перевода текста в двоичный вид Данный класс предназначен для бинаризации исходных данных (слов), т.е. перевода слов с естественного языка в набор единиц и нулей. Данная процедура является необходимой, т.к. нейронная сеть обратного распространения ошибки работает только с двоичными данными. UML диаграмма класса Binarization представлена на рисунке 7. |
Класс Binarization | | Закрытые поля | | string[] sLetter; | | int iLengthPattern; | | Закрытые методы | | private string DecToBin(string value) | | Открытые методы | | public double[] GetBinarizeWord(string sWord) | | public double[,] GetBinarizeText(out double[,] OUT_PATTERNS, out int max_pat, out int iLengthPattern1) | | public Binarization(string[] sLetter1) | | |
Рисунок 7 -UML-диаграмма класса Binarization
Параметром конструктора является массив строк для перевода в двоичный вид. Алгоритм работы методов GetBinarizeWord и GetBinarizeText данного класса в общем состоит из следующих этапов: - кодировка слова: суммирование произведений ASCII-кодов букв на i+4, где i - номер буквы в слове; - перевод полученного десятичного числа в двоичный вид при помощи метода DecToBin; - обработка полученных данных.
2.3 Класс хеш-таблицы и методов работы с ней Некоторые слова невозможно четко классифицировать, т.к. они относятся либо к неизменяемым частям речи (наречия, деепричастия и.т.д), либо схожи по некоторым признакам со словами других частей речи. (существительное кровать оканчивается как глагол на ать). Слова определенных классов имеются в достаточно ограниченных количествах (союзы и.т.д) и создание для их распознавания нейросети является неоправданным. Для работы с такого рода словами и предназначен данный класс. UML диаграмма класса Hash представленна на рисунке 8. |
Класс Hash | | Закрытые поля | | Dictionary<int, string> predlog = new Dictionary<int, string>(); | | Dictionary<int, string> narechie = new Dictionary<int, string>(); | | Dictionary<int, string> deepr = new Dictionary<int, string>(); | | Dictionary<int, string> soyuz = new Dictionary<int, string>(); | | Dictionary<int, string> mest = new Dictionary<int, string>(); | | Dictionary<int, string> iskl = new Dictionary<int, string>(); | | string[] sConstant = { "predlog", "narechie", "deepr", "soyuz", "mest", "iskl" }; | | Закрытые методы | | private int HashFunction(string sInfo) | | Открытые методы | | public bool CheckHash(string sInfo, string sHash_name) | | public void AddLetterInHashAndFile(string sLetter, string sClass,bool Flag) | | public void AddToHash(string sInfo, string sHash_name) | | public void ReadFileInHash(string sNamefile) | | public void WriteWordInFile(string sInfo, string sNamefile) | | public Hash() | | |
Рисунок 8 - UML диаграмма класса Hash
Полями данного класса являются хеш-таблицы - predlog (содержит предлоги), narechie (наречия), deepr (деепричастия), soyuz (союзы), mest (местоимения), iskl (существительные, глаголы, прилагательные сложные для распознавания). Класс также содержит методы: - HashFunction - значение хеш-функции для текущего слова; - CheckHash - проверка наличия записи в хеш-таблице; - AddLetterInHashAndFile - классификация и добавление нового слова в хеш-таблицу, а также запись в файл; - AddToHash - добавление слова в хеш-таблицу; - ReadFileInHash и WriteWordInHash - чтение слов из файла и запись слова в файл соответственно.
2.4 Класс разбиения текста на лексемы и распознавания Данный класс является главным. Его задача - вычленение лексем из текста и их дальнейшее распознавание. В нем используются объекты всех вышеописанных классов. UML-диаграмма класса Analization представлена на рисунке 9. |
Класс Analization | | Закрытые поля | | List<Results> results = new List<Results>(); | | bool flag_oy = false; | | bool flag_om = false; | | bool flag_im = false; | | bool flag_em = false; | | Bool flag_ie=false; | | bool flag_mi=false; | | Закрытые методы | | private void AddEtalonLetter() | | private string GetNeuroResult(string sLetter, string sFileName, int N_HID, double beta, double m, int Epoch, bool flag) | | private string Scaning(string sLetter, int N_HID, double beta, double m, int Epoch, bool flag) | | Открытые методы | | public static void AddToFile(string sLetter, string sFile) | | public string BigToSmall(string letter) | | public Analization(string sText, int N_HID, double beta, double m, int Epoch, bool flag) | | public List<Results> GetResult() | | |
Рисунок 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)
Страницы: 1, 2, 3, 4, 5, 6, 7
|