Автор: Пользователь скрыл имя, 07 Марта 2013 в 09:14, доклад
Идея, что мир можно рассматривать как в терминах объектов, так и событий, была известна еще в древности. По словам Декарта, люди имеют обектно-ориентированный взгляд на мир. Объектный подход является одним из современных методов реализации программных систем. Он позволяет применять объектную ориентацию для решения всего круга проблем, связанных со сложными системами. Объектный подход является концептуальной основой объектно-ориентированного проектирования, которое использует в качестве метода объектно-ориентированный анализ, а в качестве инструмента для реализации объектно-ориентированное программирование.
Введение
1 Постановка задачи
2 Описание проектного решения
2.1 Объектно-ориентированный анализ
2.1.1 Описание предметной области
2.1.2 Информационная модель системы
2.1.3 Модель состояний
2.1.4 Модель процессов
2.2 Объектно-ориентированное проектирование
2.3 Реализация критериев качества
3 Программная реализация
4 Руководство пользователя
Заключение
Для описания моделей используются 6 видов диаграмм. Логическая структура описывается диаграммой классов и диаграммой объектов. Физическая – диаграммой модулей и диаграммой процессов. Статический аспект модели определяет диаграмму переходов состояний, динамический аспект – временная диаграмма.
В ОО-анализе системы были выделены 4 абстракции системы, и связи между ними. Эти абстракции представляют из себя Элемент ввода, Нейрон, Слой нейронов и Нейронную сеть. Здесь мы на основании этих абстракций построим классы и объекты и их структуры.
Диаграмма классов определяет существующие классы и их связь в логическом проекте системы. Диаграмма классов данной системы представлена на рисунке 2.2.2.
использует 1
атрибут m
1
Рисунок 2.2.2 – Диаграмма классов системы
На этой диаграмме класс CLImage представляет собой абстракцию Элемент ввода. Класс CNNetworkP (нейронная сеть) использует его атрибут Выходной вектор. Каждый экземпляр класса CNNetworkP использует m экземпляров класса CLayer (слой нейронов). Каждый экземпляр класса CLayer использует n экземпляров класса CNeuronP (нейрон).
Диаграмма объектов показывает существующие объекты и их взаимосвязи. Она используется для того, чтобы показать динамическую семантику проекта. Каждый объект диаграммы объектов представляет собой экземпляр некоторого класса; операции на диаграмме объектов соответствуют операциям класса. На рисунке 2.2.3 представлена часть диаграммы структуры объектов системы.
запрос выходного
вектора
Рисунок 2.2.3 –
Часть диаграммы структуры
Здесь F – это поле Выходной вектор объекта Ввод (экземпляр класса CLImage). Объект Распознаватель (экземпляр класса CNNetworkP) посылает сообщение объекту Ввод на запрос выходного вектора.
Диаграмма переходов
определяет пространство состояний
экземпляров конкретного
Рисунок 2.2.4 –
Диаграмма переходов для
Система разбита на модули следующим образом: объявление классов для нейрона, слоя нейронов и нейронной сети помещены в отдельный заголовочный файл. Их реализация находится в файле типа *.срр. Для всех остальных классов: объявление каждого класса помещено в отдельный заголовочный файл, а реализация в отдельный файл типа *.срр. Если в каком либо классе создается экземпляр другого класса, то соответствующий заголовочный файл помещается включается в соответствующий файл *.срр.
2.3 Реализация критериев качества
Данная программная система
реализует распознавание
Программная модель нейронной сети была разработана на основе объектно-ориентированного подхода. Для реализации нейронной сети были созданы следущие классы: CNNetworkP, ClayerP и CNeuronP, описывающие абстракции Нейронная сеть, Слой нейронов и Нейрон соответственно. Кроме того, для обеспечения расширяемости системы были созданы абстрактные классы CNeuron и CNNetwork, от которых и были унаследованы классы нейрона и нейронной сети соответственно. Эти абстрактные классы представляют собой чистые интерфейсы нейрона и нейронной сети. Экземпляр класса нейронной сети использует определенное число экземпляров класса слоя нейронов. Один из этих экземпляров представляет собой входной слой сети, другой – выходной слой сети, а остальные – скрытые слои сети. Каждый экземпляр класса слоя нейронов использует набор экземпляров класса нейрон. Использование объектного подхода в данной системе существенно упростил ее разработку и модификацию. Снизил время, затраченное на ее разработку, и уменьшил размер исходного кода по сравнению с тем, который был бы, если бы был применен структурный подход. Кроме того, такой подход позволил скрыть некоторые поля классов от нежелательного доступа, который мог бы привести к краху системы или другим нежелательным последствия. Если бы эта система была написана с использованием структурного подхода, то она была бы трудна для понимания и модификации, работала бы медленней. Взаимодействие ее модулей трудней было бы реализовать.
Программа написана на объектно-ориентированном
языке программирования С++. Он позволяет
писать программный код используя
различные стили
Программа работает в диалоговом режиме с пользователем. Ее главное окно – это диалоговое окно, содержащее набор кнопок, поле ввода рисунка буквы и поля редактирования, куда выводится распознанная буква. Кнопки имеют интуитивно понятные названия, говорящие об их назначении и снабжены поясняющими значками. Описание действия по нажатию каждой кнопки можно прочитать в файле справки, который вызывается по нажатии кнопки «Справка». Поле ввода рисунка буквы представляет собой поле размером 20х20 клеток. Ввод в это поле, аналогичен вводу в графическом редакторе при увеличенном масштабе. Щелчок мыши по белой клетке изменяет ее цвет на черный; щелчок по черной изменяет ее цвет на белый. Такое сходство позволяет быстро освоиться с вводом рисунков букв. Таким образом дизайн программы полностью удовлетворяет ее функциональному назначению.
Из вышеизложенного видно, что все критерии качества в программе учтены.
3 ПРОГРАММНАЯ РЕАЛИЗАЦИЯ
Для написания программы был
выбран язык программирования С++. Он является
полностью объектно-
Структурно программа
Ниже представлено описание классов, созданных разработчиком.
Класс 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 осуществляет обучение нейронной сети, обучающим парам, которые берутся из заданного файла. В ней реализован алгоритм обучения с обратным распространением ошибки. Число итераций этого алгоритма может определяться либо допустимой величиной погрешности, которая задана в виде константы, либо с помощью параметра, определяющего число итераций и передаваемого функции в качестве параметра. На каждой итерации на вход сети подается стандартный входной вектор из обучающей пары, и сеть просчитывается. Затем ее выход сравнивается с эталонным выходом данной обучающей пары и вычисляется ошибка для каждого элемента этого вектора. Веса выходного слоя модифицируются согласно этой ошибке. Затем вычисляется ошибка для каждого выхода последнего скрытого слоя нейронной сети. И его веса изменяются точно так же, как веса выходного слоя. И так далее вплоть до входного слоя. Затем этот процесс повторяется.