Было применено два типа нормализации:
а) Нормализация с использованием математического ожидания и дисперсии.
Для
температуры и координат отдельно считается математическое ожидание и дисперсия
по формулам: ![]()
и ![]()
Затем
рассчитываются новые нормализованные значения по формуле

(16)
И записываются в файл в таком же виде
lat, lon, lat0, lon0, T0, lat1, lon1, T1,…, lat24,
lon24, T24 ![]()
T,
После чего данные можно подавать на обучение.
Чтобы
полученный выход сети соответствовал реальному используется формула ![]()
[8]
б) Нормализация с использованием минимаксной функции.
Отдельно для координат и температуры считаются максимальные и минимальные
значения в выборке. На основе этого данные нормализуются по формуле:
![]()
(17)
где:- значение, подлежащее нормализации;
[xmax, xmin] - интервал значений x;
[d1, d2] - интервал, к которому будет приведено значение x.
Мною использовался стандартный интервал [0, 1]. [8]
Обучающая выборка представляет собой совокупность примеров следующего вида:
latNorm, lonNorm, latNorm0, lonNorm0, TNorm0,
latNorm1, lonNorm1, TNorm1,…, latNorm24, lonNorm24, TNorm24![]()
TNorm,
где latNorm, lonNorm - нормализованные одним из двух представленных выше алгоритмов координаты точки, на которой будет обучаться сеть., lonNormi, i=0,…,24 - нормализованные координаты точек, относительно которых происходит аппроксимация.i, i=0,…,24 - нормализованная температура в конкретный рассматриваемый момент времени в точках с координатами lati, loni.
Такому примеру соответствует значение TNorm - нормализованная температура в точке с координатами lat, lon в этот же момент времени.
Тестовая выборка представляется в таком же самом виде.
Было использовано два вида тестовых выборок:
Выборка основанная на истории наблюдений
Выборка представляющая температурное распределение в данный момент времени.
В качестве нейронной сети для решения задачи аппроксимации использовался
многослойный персептрон. Эксперименты по обучению и тестированию проводились
как для одного, так и для двух скрытых слоёв. В качестве алгоритма обучения
применялся алгоритм обратного распространения ошибки. В качестве функции
активации была выбрана логистическая функция - нелинейная функция, задаваемая
следующим выражением:
![]()
(18)
где α - параметр наклона сигмоидальной функции [3].
Величина
ошибки подсчитывалась следующим образом:
![]()
(19)
где outi это реальный выход нейрона, а desiredouti это желаемый выход нейрона.
Сначала подбор конфигурации сети производился эмпирическим путём, то есть выбиралась конфигурация, производилось обучение, а на основе полученных результатов выбиралась та, которая давала наилучшие результаты.
Затем было решено провести более точную подборку конфигурации. Сначала были проведены исследования с одним скрытым слоем. Был написан метод, который в цикле примерно от 20 нейронов в скрытом слое до 120 для каждого шага создавал сеть с указанным числом нейронов. Затем сеть обучалась и тестировалась, результаты записывались в файл. Этап обучения и тестирования повторялся трижды для каждой конфигурации сети. На основе полученных данных выбиралась сеть с наилучшими результатами.
Далее было произведено подобное исследование для двух скрытых слоёв.
В итоге я остановился на конфигурации с двумя скрытыми слоями - 20
нейронов в первом слое, 10 во втором.
Рисунок 2.3 - Структура нейронной сети
В первом слое нейронной сети содержится 77 нейронов:
городов, для каждого по три значения (широта, долгота, температура) итого 75, плюс 2 значения (широта, долгота) для аппроксимируемой точки.
Затем скрытый слой с 20 нейронами, скрытый слой с 10 нейронами и 1 выходной нейрон выдающий температуру в аппроксимируемой точке.
При первых попытках обучить сеть на имеющемся множестве примеров возникла проблема, что каждый обучающий проход занимает слишком много времени (около минуты). Встал вопрос о необходимости ускорения работы сети. Путём анализа и замеров времени исполнения использующихся методов был вычислен метод выполняющийся гораздо дольше других. Затем он был переписан, что привело к тому, что скорость обучения возросла приблизительно в 20 раз (около 3-х секунд).
К имеющейся функциональности нейронной сети была добавлена возможность дообучения. Сеть обучается, затем веса и все необходимые параметры сохраняются в файл, а при повторном запуске есть возможность выбора между продолжением обучения и обучением с нуля. При дообучении веса и параметры берутся из указанного файла и инициализация сети происходит с использованием этих значений.
При использовании нормализации входных данных с помощью математического ожидания и дисперсии попытки обучить сеть не увенчались успехом.
Когда же использовалась нормализация с помощью минимаксной функции сеть достаточно неплохо обучалась и давала неплохие результаты при тестировании.
Обучение сети проходило не идеально - сети не удавалось обучиться на всех без исключения примерах:
При задании максимально допустимой ошибки величиной в 0.01 (что составляет около 0.7 градуса по Цельсию) сети удаётся научиться давать правильный результат для 263 тысяч примеров из 264 тысяч. Для ошибки величиной в 0.001 - около 230 тысяч из 264. То есть процесс обучения заканчивался не по распознаванию всех примеров, а по достижении максимального числа итераций. Если сделать число итераций очень большим, то сеть постепенно улучшает показания в том смысле, что распознает всё большее число примеров, но при тестировании в лучшую сторону это не сказывается, скорее даже сказывается в худшую.
Тестирование проходило на двух наборах данных:
а) Выборка основанная на истории наблюдений
б) Выборка представляющая температурное распределение в данный момент времени.
Первая гораздо больше второй. На выборке основанной на истории наблюдений сеть показывала результаты лучше, чем на данных за текущий момент. Для первой лучшим показателем является около 1.4 градуса расхождения с реальностью. Для второй около 1.7.
После обучения сети происходит формирование сетки аппроксимации рассматриваемого квадрата. На вход сети подаются координаты с некоторым шагом, полностью покрывающие квадрат. Сеть выдаёт результат - предполагаемую температуру в этой точке. Затем по полученным данным формируется матрица. Данные из этой матрице впоследствии должны отображаться в веб представлении.
Рисунок 2.4 - Температурное распределение на рассматриваемом участке
карты полученное нейронной сетью
На представленном выше графике отображено температурное распределение на участке на карте с координатами 45 - 49 градусов широты, 0 - 4 градуса восточной долготы. По оси Z откладывается температура в шкале Цельсия.
Для сравнения результатов работы нейронной сети с некоторым стандартным математическим методом аппроксимации использовалась система компьютерной алгебры Wolfram Mathematica. На том же наборе данных, который использовался при аппроксимации нейронной сетью, была произведена аппроксимация методом Эрмитовой интерполяции. Затем было произведено тестирование.
Рисунок 2.5 - Температурное распределение полученное Эрмитовой
интерполяцией
Аппроксимация получилась отличной от ожидаемой, средняя ошибка составила
около 17-ти градусов расхождения с реальностью. Я связываю это со слишком малым
набором известных данных - всего 25 известных точек. Поскольку стандартные
методы не могут обучаться им приходится делать свои суждения только по
имеющимся сведениям, которые, как в данном случае, могут быть не достаточными
для приемлемой аппроксимации.
3 РЕАЛИЗАЦИЯ ПРОГРАММНОЙ СИСТЕМЫ
В процессе реализации программной системы были применены следующие технологии и программное обеспечение:
язык программирования Java
текстовый формат обмена данными JSON
среда разработки Eclipse
OpenWeatherMap API
фреймворк JSON-Simple для работы с JSON в Java
фреймворк JavaServer Faces для разработки веб-приложений на Java
система компьютерной алгебры Wolfram Mathematica
.1 Основные возможности OpenWeatherMap API
Как уже было сказано ранее, сервис OpenWeatherMap предоставляет бесплатный API ко всем данным о погоде, к их истории, прогнозам и всему многообразию погодных карт. API обладает следующими возможностями:
Можно узнать текущие погодные сведения в некотором городе. Это делается с помощью http запроса следующим образом [9]:
а) По названию города:.openweathermap.org/data/2.5/weather?q=London,uk
б) По географическим координатам:.openweathermap.org/data/2.5/weather?lat=35&lon=139
в) По идентификатору города:.openweathermap.org/data/2.5/weather?id= 2172797
Пример выдаваемого ответа в JSON формате:
{"coord":{"lon":-0.13,"lat":51.51},"sys": {"message":0.0038,"country":"GB","sunrise":1400213168,"sunset":1400269657},"weather":[{"id":800,"main":"Clear","description":"Sky is Clear","icon":"01d"}],"base": "cmcstations","main":{"temp":282.38,"pressure":1034,"humidity":87,"temp_min":279.26,"temp_max":284.82},"wind":{"speed":1.5,"deg":60},"clouds":{"all":0},"dt":1400218487,"id":2643743,"name":"London","cod":200}
В некоторых запросах поддерживается выдача результата в XML формате, для этого достаточно добавить к запросу параметр «mode=xml».
Получение прогноза погоды на 5 дней за каждые три часа:
api.openweathermap.org/data/2.5/forecast?q=London,us&mode=xml
Прогноз на 10 дней, с одним наблюдением за день:
api.openweathermap.org/data/2.5/forecast/daily?lat=35&lon=139&cnt=10&mode=json
Получение истории наблюдений за определённый промежуток времени:
api.openweathermap.org/data/2.5/history/city?id=2885679&type=hour&start=1369728000&end=1369789200,
Здесь поиск города идёт по его идентификатору, промежуток времени указывается с использованием UNIX-времени [9].
(англ. JavaScript Object Notation) - текстовый формат обмена данными, основанный на JavaScript и обычно используемый именно с этим языком. Как и многие другие текстовые форматы, JSON легко читается людьми.
Несмотря на происхождение от JavaScript, формат считается языконезависимым и может использоваться практически с любым языком программирования. Для многих языков существует готовый код для создания и обработки данных в формате JSON.
Пусть text это строковая переменная хранящая представленный в предыдущем пункте JSON текст. Приведём пример простой программы иллюстрирующей работу фреймворка [10]:
JSONParser parser = new JSONParser();
Object obj = parser.parse(text);jsonObject = (JSONObject) obj;name = (String) jsonObject.get("name");weather = (JSONArray) jsonObject.get("main");<String> iterator = weather.iterator();(iterator.hasNext()) {.out.println(iterator.next());
}
Здесь все классы имеющие приставку JSON являются классами фреймворка.
В программе создаётся парсер, который парсит JSON текст в объект класса Object. На его основе
формируется объект класса JSONObject. Теперь из этого объекта можно извлекать необходимую информацию - в
программе в строковую переменную «name» помещается имя города. Далее создаётся
объект «weather» класса JSONArray, являющийся
аналогом java.util.List в Java,
хранящий сведения о температуре, давлении, влажности и т.п. После этого
создаётя итератор, с помощью которого осуществляется проход по всем полям «weather» с выводом значений этих полей на
экран.
.3 Библиотека Leaflet
- библиотека с открытым исходным кодом, написанная российским разработчиком Владимиром Агафонкиным на JavaScript, предназначенная для отображения карт на веб-сайтах.
Библиотека пользуется очень большой популярностью, так например библиотека используется на сайтах Flickr, Foursquare, Craigslist, Data.gov, IGN, проектах Викимедиа, OpenStreetMap, Meetup, WSJ, MapBox, CloudMade, CartoDB и других.
Приведём пример простой программы иллюстрирующей работу с библиотекой [11]:
// создаётся карта в заданном месте и определённой степенью приближения
var map = L.map('map').setView([51.505, -0.09], 13);
// добавляется OpenStreetMap слой.tileLayer(
'#"785954.files/image065.gif">
(20)
Где
![]()
-
реальное выходное состояние нейрона j-го выходного слоя нейронной
сети при подаче на её входы k-го образа, ![]()
-
требуемое выходное состояние этого нейрона.
Далее происходит вызов метода обучающего нейронную сеть:
net.teachOffLine();
Этот метод выполняет обучение сети. Раз за разом выполняя прямой и обратный проход метод стремится к минимизации ошибки, подстраивая веса соответственно методу обратного распространения. Выход из метода происходит, либо если ошибка сети станет меньше заданной пользователем, либо при достижении максимально допустимого числа итераций.
Затем, уже обученной сети предъявляются неоцененные тесты следующим образом:.compute(patternIn);
Метод compute() вычисляет «выход» сети на подаваемый тестовый экземпляр. А конкретно он вычисляет и помещает «реакцию» нейронной сети - число от 0 до 1, в поле output каждого выходного нейрона..getOutput(i);
Приведённая выше конструкция, считывает значение поля output.
.4.2 Описание проекта NetApproximationпроект, осуществляющий получение, обработку данных, вызов методов нейронной сети и формирование матрицы аппроксимации.
Проект обладает следующей структурой пакетов:
netapproximation.dao.domain.errors.log.service- состоит из одного класса Main, содержащего точку в входа в приложение - метод main(). Не содержит в себе какой-либо иной функциональности.
Перед тем как описывать пакет netapproximation.dao напишем о том, что означает аббревиатура DAO:
В программном обеспечении data access object (DAO) - это объект, который предоставляет абстрактный интерфейс к какому-либо типу базы данных или механизму хранения. Определённые возможности предоставляются независимо от того, какой механизм хранения используется и без необходимости специальным образом соответствовать этому механизму хранения. Этот шаблон проектирования применим ко множеству языков программирования, большинству программного обеспечения, нуждающемуся в хранении информации и к большей части баз данных, но традиционно этот шаблон связывают с приложениями на платформе Java Enterprise Edition, взаимодействующими с реляционными базами данных через интерфейс JDBC, потому что он появился в рекомендациях от фирмы Sun Microsystems.