Программа работает в диалоговом режиме с пользователем. Ее главное окно – это диалоговое окно, содержащее набор кнопок, поле ввода рисунка буквы и поля редактирования, куда выводится распознанная буква. Кнопки имеют интуитивно понятные названия, говорящие об их назначении и снабжены поясняющими значками. Описание действия по нажатию каждой кнопки можно прочитать в файле справки, который вызывается по нажатии кнопки «Справка». Поле ввода рисунка буквы представляет собой поле размером 20х20 клеток. Ввод в это поле, аналогичен вводу в графическом редакторе при увеличенном масштабе. Щелчок мыши по белой клетке изменяет ее цвет на черный; щелчок по черной изменяет ее цвет на белый. Такое сходство позволяет быстро освоиться с вводом рисунков букв. Таким образом дизайн программы полностью удовлетворяет ее функциональному назначению.
Из вышеизложенного видно, что все критерии качества в программе учтены.
3 ПРОГРАММНАЯ РЕАЛИЗАЦИЯ
Для написания программы был выбран язык программирования С++. Он является полностью объектно-ориентированным, мощным языком программирования, поддерживающим практически все виды абстракций объектно-ориентированного программирования. Была использована среда программирования Visual C++ 6.0. Эта среда является визуальной средой программирования, позволяющей перетаскивать стандартные компоненты непосредственно в окно будущей программы. Она позволяет автоматизировано создавать различные проекты с использованием «мастеров».
Структурно программа представляет собой набор классов, часть из которых была создана разработчиком, а часть – самой средой программирования. Классы созданные средой программирования унаследованы от классов библиотеки MFC. Экземпляры одних классов создаются другими классами, и там происходит работа с ними. Среда программирования сама генерирует код главной функции и программисту он не доступен. Программист может работать только либо со своими классами, либо с классами, описывающими интерфейс программы и ее свойства. Также в исходниках программы присутствуют ресурсы, которые представляют из себя внешния объекты, подключаемые к программе во время связывания. Этими ресурсами являются диалоговые окна, картинки, иконки и специальные таблицы, определяющие системные и интерфейсные свойства программы.
Ниже представлено описание классов, созданных разработчиком.
Класс CNeuronP. Этот класс определяет нейрон, который является базовым элементом нейронной сети. Его объявление:
class CNeuronP: public CNeuron
{
protected:
float axon; //выход
std::vector<float> inputs; //входы
std::vector<float> synapses; //весавходов
int rang; //числовходов
public:
CNeuronP(int rng=2,float por=2.0);
virtual void AddInput(void); //добавляетсинапс
virtual float GetAxon(void); //возвращаетвыходнейрона
virtual void func(void); //просчетнейрона
int SetInput(float inp,int number); //устанавливаетвходы
int SetSynaps(float sip, int num); //устанавливаетвеса
float GetInput(int number); //возвращаетвход
float GetSynaps(int number); //возвращаетвесвхода
int GetRang(void); //возвращает число синапсов
float GetPro(void); //возвращает производную от активационной функции
};
Как видно из этого объявления все поля-члены данного класса являются закрытыми, а все функции-члены – открытыми. Этот принцип реализован и в остальных классах, созданных разработчиком. Это сделано для обеспечения гибкости работы с экземплярами классов, без доступа к их внутренней структуре. Действия, выполняемые функциями-членами и назначение полей-членов описаны в комментариях к ним.
Опишем функцию func. Она выполняет просчет нейрона. Она берет каждый вход нейрона и умножает его на соответствующий вес. Затем это произведение прибавляется к сумме таких же произведений, и так для каждого входа. Затем от полученной суммы вычисляется функция, в данном случае сигмоид, сдвинутый на -1/2 по оси ординат. Результат вычисления этой функции присваивается выходу нейрона.
Класс CLayerP. Он представляет собой набор нейронов, входящих в один слой нейронной сети. Его объявление:
class CLayerP
{
protected:
std::vector<CNeuronP> neurons; //нейроныслоя
int number; //число нейронов в слое
public:
CLayerP(int num=2);
virtual void AddNeuron(CNeuronP neur); //добавляетнейронвслой
virtual int SetNeuron(CNeuronP neur, int num);
int GetNumber(void); //возвращает число нейронов в слое
CNeuronP& GetNeuron(int num); //возвращает нейрон по его номеру
};
Некоторые функции-члены класса сделаны виртуальными для обеспечения полиморфизма в случае расширения системы.
Класс CNNetworkP. Этот класс описывает многослойную нейронную сеть, применяемую в программе для распознавания букв. Егообъявление:
class CNNetworkP:public CNNetwork
{
protected:
CLayerP FirstLayer; //первыйслой
CLayerP LastLayer; //последнийслой
std::vector<CLayerP> layers; //скрытыеслои
int m_number; //число скрытых слоев
public:
CNNetworkP(int num1=2/*число нейронов во входном слое*/,
int num2=2/*число нейронов в выходном слое*/,
int num3=2,/*число нейронов в скрытом слое*/
int number=1/*число скрытых слоев*/);
virtual void Solve(void); //просчетсети
void SetInputs(std::vector<float> inp); //устанавливаетвходы
void SetNumFSynaps(int num); //устанавливает число синапсов в каждом нейроне первого слоя
int NumHLayers(void); //число скрытых слоев
virtual float GetOut(int number); //возвращаетвыход
virtual void Learn(int number, CString filename, int num);//обучаетсетьконкретнойпаре
void before(void); //начальная инициализация весов
void SaveToFile(CString filename);//запись обученных весов в файл
void LoadFromFile(CString filename);//загрузка обученных весов из файла
void SaveOuts(CString filename); //сохранить выходы в файл
};
Конструктор данного класса создает экземпляры всех нейронов, входящих в данную сеть, используя их конструкторы с параметрами по умолчанию.
Функция-член Solve осуществляет просчет сети. При этом сначала просчитываются все нейроны входного слоя, затем их выходы используются в качестве входов нейронов первого скрытого слоя, для их просчета и так далее вплоть до выходного слоя сети. Выход выходного слоя используется в качестве выхода сети.
Функция-член before осуществляет начальную инициализацию весов, проводимую перед обучением сети. Она с помощью генератора произвольных чисел присваивает всем весам сети значения в пределах от -0.5 до 0.5.
Функция-член Learn осуществляет обучение нейронной сети, обучающим парам, которые берутся из заданного файла. В ней реализован алгоритм обучения с обратным распространением ошибки. Число итераций этого алгоритма может определяться либо допустимой величиной погрешности, которая задана в виде константы, либо с помощью параметра, определяющего число итераций и передаваемого функции в качестве параметра. На каждой итерации на вход сети подается стандартный входной вектор из обучающей пары, и сеть просчитывается. Затем ее выход сравнивается с эталонным выходом данной обучающей пары и вычисляется ошибка для каждого элемента этого вектора. Веса выходного слоя модифицируются согласно этой ошибке. Затем вычисляется ошибка для каждого выхода последнего скрытого слоя нейронной сети. И его веса изменяются точно так же, как веса выходного слоя. И так далее вплоть до входного слоя. Затем этот процесс повторяется.
Программа была обучена буквам из специально подготовленного для программы шрифта и показала высокую степень распознавания, даже при наличии больших помех. Программа будет распознавать рисунок буквы до тех пор, пока он не станет похож на рисунок другой буквы, которому обучена нейронная сеть.
4 РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ
Программа вместе со своими исходниками поставляется на дискете. Для установки программы необходимо переписать ее исполняемый файл nNetwork.exe в отдельную папку. Туда же необходимо переписать файлы nNetwork.cnt и nNetwork.hlp, которые обеспечивают программе работу со справкой. Также на дискете находится RAR-архив mfc42.rar. Файл находящийся в нем необходимо распаковать в папку windows\system32, для обеспечения работы с программой.
Для запуска программы необходимо щелкнуть по ее иконке. Откроется главное диалоговое окно программы, содержащее набор кнопок для управления программой, поле ввода букв размером 20х20 клеток и поле редактирования, куда будет выводиться распознанная буква. Вместе с программой поставляется файл a.txt, содержащий двоичное представление рисунков букв. Этот файл сделан в качестве примера шрифта для распознавания программой. Веса нейронной сети, обученной на распознавание букв из этого файла, находятся в файле final.txt. Для загрузки этих весов необходимо щелкнуть по кнопке «загрузка» в главном окне программы и в появившемся диалоговом окне ввести путь к этому файлу и щелкнуть по кнопке ОК. Работа с программой подробно описана в справочной системе, которая вызывается щелчком по кнопке «Помощь». Там же приведено краткое описание нейронной сети, используемой в этой программе.
ЗАКЛЮЧЕНИЕ
В результате выполнения данного курсового проекта была разработана программа, содержащая модель искусственной нейронной сети, предназначенную для распознавания печатных букв, которым она обучена. При написании программы использовался объектный подход, что позволило снизить время разработки системы, упростить понимание программы, значительно уменьшить размер исходного кода программы.
Программу можно легко расширить, вставив дополнительные классы других моделей нейронных сетей для более качественного и быстрого распознавания букв или для выполнения других действий. Также если эту программу на протяжении порядка 1000 циклов обучать почерку какого либо человека, то она научиться распознавать его почерк, то есть она сможет распознавать рукописные буквы, без каких либо изменений в структуре нейронной сети или в процессе обучения.
ПЕРЕЧЕНЬ ССЫЛОК
Г. Буч «Объектно-ориентированный анализ и проектирование с примерами приложений на С++» // Буч Г. - СПб: «Невский Диалект», 1998 г. – 632с.
Б. Страуструп «Язык программирования С++, 3-е издание» // Страуструп Б. – М.: «Невский Диалект» - «Издательство БИНОМ», 1999 г. – 991 с.
Г. Кейт «Использование Visual C++ 6. Специальное издание.» // Кейт Г. – К.: Издательский дом «Вильямс», 1999 г. – 864 с.
Доронина Ю. В. «Конспект лекций по ООП»