Что такое «Нейронная сеть»?
Что мы себе представляем, когда слышим термин «Нейронная сеть»? Наверное, мы представляем себе какой-то искусственный интеллект, что-то такое уникальное, вроде персонажей, изображенных на слайде (в зависимости от того, кто какие фильмы в детстве смотрел).
Реальность же вообще такова, что все намного проще. Конечно, не все так однозначно, потому что уже сейчас есть такие понятия, как глубокие и самообучающиеся нейронные сети, на Youtube уже кошечек научились распознавать – но по факту, это все еще на уровне экспериментов, и явно не для прикладных задач. Поэтому мы поговорим о нейронной сети, которая более типична.
Итак, что такое нейронная сеть? Это некий Black BOX – система, которая позволяет из совокупности входящих данных что-то получить на выходе. Но для этого ее сначала нужно обучить – дать ей соответствие того, что поступает на вход, и того, что она должна выдать нам на выходе. И после того, как нейронная сеть обучится, она сможет нам выдавать данные на выходе уже автоматически.
Для чего все это нужно? Главное преимущество нейронной сети в том, что она не содержит в себе алгоритма. Она позволяет вам не думать, не анализировать закономерности, не писать алгоритм, а просто подстроиться под статистические данные.
Внутри нейронной сети будет что-то похожее на рисунок на слайде. Сначала я хотел это детально разобрать, объяснить, что такое нейрон, связи, веса связей, какие есть функции активации, архитектуры нейронных сетей, но потом решил, что нам сейчас это неважно. Об этом написано много научных работ, это изучают в институтах. А нам сейчас надо просто понимать, что нейронная сеть – это некая структурная модель, имеющая входы и выходы, а нейроны – это некие сущности, между которыми есть связи разного веса, и в процессе обучения просто происходит подстройка этих весов связей. Это – то же самое, что и у вас в голове: у каждого нейрона есть свой импульс – один может быть более возбужден, другой – менее возбужден, и поведение этих нейронов в модели зависит от того, какой вес (больший или меньший) имеют их связи.
Здесь важно то, что нейронов в нейросети может быть много, даже несколько слоев. В простейшем случае вы можете собрать нейронную сеть из одного нейрона, у которой, к примеру, будет два десятка связей. Она, например, может работать, как линейная функция – рисовать прямую или что-нибудь в этом роде. Если в сети будет уже два-три нейрона – вы получите уже нейронную сеть, которая будет аналогом линейной регрессии. Наверное, большинство из вас знает, что это такое – пользовались когда-нибудь линейной регрессией в Excel. В принципе, нейронная сеть в простейшем виде – это аналог линейной регрессии, некоторая модель, которая позволяет вам найти и продолжить ряд чисел, зависимостей. Только простейшая нейронная сеть будет выдавать уже намного более качественный результат, чем просто линейная регрессия. Плюс нейронная сеть, конечно же, сможет выявлять такие зависимости, которые вы сами не увидите, и ни за что в жизни о них даже не догадаетесь. А линейная регрессия, конечно же, этого не может.
Тем не менее, есть вопросы, на которые нейросеть дать ответ не сможет. Например, ее бесполезно спрашивать «Сколько вешать в граммах», потому что здесь по факту работает только вероятностная модель – всегда есть некоторое приближение и аппроксимация. Грубо говоря, если вы при помощи нейронной сети нарисуете параболу или синусоиду, то визуально вы на графике отклонений не заметите, но если вы рассмотрите каждую точку детально, везде будет небольшое расхождение – точный x2 вы нейронной сетью практически никогда не получите.
Что мы, как правило, думаем о нейронных сетях?
- Мы думаем, что нейронная сеть – это сложно. На самом деле, нейронная сеть – это реальная возможность для «халявы». Она позволяет вам не решать задачу, а просто взять и использовать для получения результата статистические данные. Не надо детально разбираться в вопросе, строить полноценную математическую модель – это не усложнение, это скорее, для тех людей, кто стремится решить задачу, не разбираясь в том, как она решается.
- Далее – как правило, нейронная сеть у нас ассоциируется с распознаванием голоса, образов, такими программами, как FineReader, GoogleVoice и т.д. Это лишь потому, что эти задачи без нейронной сети по-другому решить не получится. Но вообще нейронную сеть можно использовать для решения любой задачи, где есть какая-то накопленная статистика, входы и выходы, любые задачи, где применима линейная регрессия. Например, задача распознавания паттернов, аппроксимации функций, любые другие задачи, имеющие на входе модель – все это решается при помощи нейронных сетей.
- Математика. Да, нейронная сеть – это математическая модель, составленная на языке C++, но вам не придется писать этот код C++ самим. Есть удобные конструкторы: несколько кликов, и вы получаете готовую нейронную сеть.
- Ну и, конечно же, нейронная сеть не для 1С. Но я, тем не менее, здесь, и моя цель – убедить вас в том, что 1С прекрасно может работать с нейронными сетями.
Практическое применение нейронной сети для решения бизнес-задачи
Рассмотрим самый главный слайд, который я хочу сегодня показать – это типовой пример применения нейронной сети, типовая ситуация, в которой все хоть раз в жизни бывали.
На примере начальник вызывает программиста и просит, к примеру: «Хочу знать, где у меня много посетителей и мало продаж». Допустим, это розничная сеть, количество посетителей в каждом магазине фиксируется, и начальник хочет знать, какие магазины плохо работают.
Программист говорит: «Ок, завтра будет такой отчет». Конечно, обычно программист говорит по-другому: «Это очень сложно, мне нужен аналитик, опишите мне задачу подробнее, напишите ТЗ» – все этим так или иначе занимались, я сам лично этим все время занимаюсь. Но у нас другой программист, он владеет нейронными сетями, поэтому он сразу соглашается.
Проходит неделя, начальник опять вызывает программиста и говорит: «Твоя программа не работает, она не учитывает, какие продажи были проведены по акции. Если у нас в магазинах была акция, там, конечно, количество продаж увеличилось, но это не значит, что они хорошо отработали, это значит, что мы там просто цены снизили. Почему ты это не учел?»
Программист говорит: «Извините, виноват, через час переделаю». Конечно, на практике мы говорим: «Мне придется все переписывать, я не смогу учесть эти изменения». Но в данном случае будет не так: программист просто добавляет в свою выгрузку новую колонку, обучает нейронную сеть и предоставляет начальнику новый отчет.
Проходит еще неделя. Начальник опять вызывает программиста, говорит: «Ты опять накосячил. У нас каждый сезон посещаемость меняется, и к тому же по выходным совсем другая статистика – нужно учитывать еще и день недели и месяц». Обычному программисту дать на это ответ очень тяжело – я бы потерялся. Но наш программист говорит: «Да вообще не вопрос, дай мне еще часик, и я все сделаю». Добавляет в ту же модель дни недели и месяцы, переобучает нейронную сеть и получает новый вариант отчета.
На это начальник сможет только удивиться: «Как ты это делаешь?» А программист ответит: «Это секрет».
Эта картинка очень важна. Потому что программист не разбирался в задаче, он не понимал, как ее решать, не строил алгоритмов, начальник ему ничего, кроме простых примеров, не объяснял и не собирался объяснять. У программиста просто была статистика в базе, из которой он, не прибегая ни к каким аналитикам, построил модель и дальше использовал ее в отчете.
Это достаточно типовой пример использования нейронной сети для решения бизнес-задач. Где это можно еще использовать? Прогнозы ДДС, задачи бюджетирования, любые прогнозы на основании истории, любые получения из одних чисел других.
Давайте еще раз акцентируем внимание на том, что программист в итоге делает:
- Сначала он определил входы:
- В нашем случае это количество посетителей в магазинах.
- Потом туда добавляется еще наличие в магазинах акций;
- Дни недели;
- И месяцы. Всего получается четыре колонки.
- Дальше он сопоставил входам выходы. Выходы у нас – это продажи по магазинам в разрезе каждой совокупности дополнительных условий. Получился элементарный отчет, который, я думаю, сможет написать любой из тех, кто хоть как-то связан с программированием.
- А дальше он просто обучил нейросеть.
- И использовал ее результаты для решения задачи.
Что такое «Генетический алгоритм»?
Начнем следующую тему, поговорим про генетический алгоритм.
Здесь изображено то, то мы обычно представляем себе, когда думаем о генетических алгоритмах. Кажется, что это что-то такое сложное, как спираль ДНК, где различные атомы связаны друг с другом.
На самом деле, все опять достаточно банально. Генетический алгоритм – это некий алгоритм, в основе которого пять шагов, и пишется простейший генетический алгоритм минут за 15. Слайд в принципе, все это полностью иллюстрирует.
Здесь мне, наверное, стоит только рассказать, что такое особь, популяция и селекция.
Особь – это любой набор параметров, который у вас есть. Что это такое, я объясню на примере типичной задачи коммивояжера. Наверное, все более-менее знают, что это такое – это когда логисту нужно построить маршрут объезда неких точек и на выходе получить порядок объезда этих точек. В этом примере, окончательный или промежуточный порядок обхода точек – это и будет одна особь.
- Сначала генетический алгоритм генерирует этот порядок случайным образом – точка 1, 2, 3, 4, 5, 6 и т.д. Этот первый этап называется созданием начальной популяции.
- На следующем этапе происходит скрещивание особей – меняется порядок точек 3, 2, 1, 6, 5, 4 и т.д. Подробнее о том, что такое скрещивание, я покажу на следующем слайде. Или происходит мутация – замена одного параметра на произвольный для того, чтобы появлялись новые особи, а не только выбирались из существующих.
- Далее происходит селекция – из двух особей нужно выбрать лучшую. Селекция – это ключевая тема. Почему она так важна? Потому что 99% времени работы над генным алгоритмом скрыто именно вот здесь. Но это не сам генный алгоритм – это программируемое вами решение задачи.
- Потом из тех особей, которые мы отобрали, формируется новое поколение. И вы его проверяете – достигнута цель или нет.
- Причем, целью необязательно будет поиск наилучшего маршрута, вы можете поставить цель найти наиболее оптимальный вариант за выбранное время. Например, весь этот поиск может длиться 4 часа, а вам нужно найти решение за 15 минут. Так вот тот лучший маршрут, который вам система успеет выбрать за это время – это и будет ваш результат. Либо вы можете поставить условие – стоимость проезда меньше миллиона рублей. Либо что-то еще. И та результирующая популяция, к которой мы придем при достижении этого условия, и будет содержать в себе окончательную особь – результат вашего поиска.
Как выглядит скрещивание?
Берут первый и второй вариант объезда точек, и дальше его просто скрещивают – берут что-то из первого, а что-то из второго.
Здесь показано три варианта скрещивания – ничего хитрого здесь нет. Просто перемешиваются различным образом наборы параметров, получая новые.
Селекция – это уже интересно. Вам нужно выбрать самую лучшую особь, и эту задачу вам придется решить уже полностью самим. Например, если вы выбираете кратчайший маршрут объезда, вам нужно будет посчитать, сколько времени займет маршрут при таком наборе входящих параметров. Причем, это задача не генетического алгоритма, это задача, которую вы должны решить самостоятельно. Здесь нужно посчитать целевые функции по набору параметров и сравнить их между собой.
Задача селекции занимает до 99% всего времени выполнения генетического алгоритма. Как правило, задачу селекции нельзя отдать во внешнюю систему, поэтому она выполняется в той системе, которую вы оптимизируете.
Вот иллюстрация задачи коммивояжера. Все, наверное, так или иначе, сталкивались с системами управления грузоперевозками TMS (Transport Management System). В них как раз можно посчитать эти кратчайшие маршруты, причем генетический алгоритм туда заложен в 95% случаев – если нет, то это, как правило, плохая TMS-система. Я в своей практике тоже один раз написал для такой задачи генетический алгоритм – он в 5 раз ускорил нахождение маршрута, при этом качество прокладки маршрутов также улучшилось.
У генетических алгоритмов также есть свои минусы. Наверное, вы уже догадались, что точные установки результата в них невозможны. Генетический алгоритм не гарантирует, что он выберет лучшее решение. И если генетический алгоритм после четырех часов работы нашел вам какое-то решение, вы не можете быть уверенным, что оно – лучшее, возможно, найдется и более быстрый маршрут проезда. Генетический алгоритм гарантирует только то, что это решение лучше, чем другие, при выборе данных в такой последовательности.
Технологии для построения нейросети
Вернемся к нейросетям – теперь уже с практической стороны. Рассмотрим, что нужно, чтобы использовать их в своем коде.
Сначала нужно выбрать инструментальное средство. Я в свое время выбирал из трех. Не будем спорить, что лучше, каждый выбирает средство по своим личным предпочтениям:
- Есть языки высокого уровня, которые позволяют решать различные задачи.
- Если вы умеете что-то писать на C++ – можно использовать его для построения нейросети.
- Также можно найти много информации по построению нейросетей на Python – этот язык классически используется для сложной алгоритмики.
- И есть язык R – это язык математики, который так же, как и C++, используется для математических вычислений.
- 1С – это, естественно, наш основной инструмент.
- И Matlab – инструмент, который для этих целей применяется, наверное, чаще всего.
Быстродействие:
- Если мы напишем нейросеть на C++ или на Python, она будет работать чуть-чуть быстрее, чем та, которую мы получим из Matlab, но в целом оба класса инструментов позволяют очень быстро получать результат, потому что в Matlab тоже компилируемая библиотека.
- В 1С, к сожалению, все очень медленно работает. К тому же, если написать нейросеть на 1С, ее придется очень долго обучать – от нескольких часов до нескольких дней.
Скорость разработки:
- На 1С, конечно, быстро разрабатывать, но писать нейросеть придется руками.
- В Matlab есть уже готовые средства визуальной разработки.
- На R или Python есть свои библиотечки, но писать придется тоже руками.
Функциональность:
- Языки R и Python лидируют по функциональности для написания нейросетей, потому что они используют специализированные библиотеки – очень мощные и серьезные.
- В Matlab функциональность по созданию нейросети чуть-чуть уступает, там нет самых последних, самых крутых нововведений, но большая часть функций (20 видов нейронных сетей) там есть.
- А в 1С вам доступно, конечно, только написание простейшего перцептрона и его обучение.
Вывод понятен – я выбрал Matlab.
Использование Matlab для разработки нейросети
Matlab генерирует библиотеку на .NET, дальше мы эту библиотеку используем в 1С – в этом нет ничего сложного.
Как это сделать в Matlab?
- В Matlab есть замечательная кнопка Import Data – она понимает любые форматы – текстовые, csv, xls – в 1С я бы мечтал о такой функции. Импорт очень простой – он разберет файл любого формата, покажет, какие в нем есть колонки, вы выбираете те, которые вам нужны, нажимаете «Записать» – выбираете, что хотите импортировать в матрицу, и он вам это импортирует в свой воркспейс. Matlab всегда работает только с матрицами – там нет никаких переменных, никаких чисел – вообще ничего.
- Дальше вы в командной строке пишите волшебное слово nftool – запускается мастер создания нейронной сети.
- Разобраться с этим мастером проблем не составляет – это все «гуглится». Единственное, что нам нужно будет выбрать из того воркспейса, куда вы импортировали – это:
- Входы (Data), на которых нейросеть должна обучаться (в нашем случае, это будет количество посетителей, месяц, день и наличие акции)
- И итоговые величины, выходы (target) – будут соответствовать продаже магазина.
- Далее там будет кнопка Train, которая запускает обучение нейросети. Можно выбрать метод обучения, но, как правило, все, что Matlab выбирает по умолчанию, в наших случаях будет верно, только для каких-то серьезных задач там нужно будет выбирать особые параметры. Процесс обучения обычно занимает 5-10 минут.
- После этого у вас появляется окошко, где есть кнопка для генерации Matlab Function – вы получаете функцию на языке Matlab.
- Далее в консоли пишете еще одно волшебное слово – deploytool. Это специальный инструмент для того, чтобы сделать саму dll. Здесь тоже ничего сложного и хитрого нет – выбираете функцию, которую будете превращать в dll, называете ее так, как вам нравится, выбираете, что это будет .NET Assembly (сборка .NET). Единственное, что здесь стоит прокомментировать, что версии Matlab бывают x86 и x64. Соответственно, если вы хотите использовать эту dll на сервере, значит, используйте x64, а если на клиенте, то выбирайте x86. Либо вам придется идти на различные хитрости, вроде COM+ оберток и т.д.
Если кто-то захочет разобраться с тем, как нейросеть делается в Matlab – это реально «гуглится» за минут 5-10, там проблем нет.
Использование библиотеки нейросети в 1С
А с 1С все немного сложнее. Дело в том, что Matlab очень плохо работает с COM-объектами, он генерирует не полноценную COM-библиотеку, которую можно использовать в 1С – он подразумевает, что библиотека на входе должна получать какие-то параметры, а с такой библиотекой 1С работать не умеет. Поэтому лучше использовать .NET сразу, да и регистрировать его каждый раз не нужно. Для этого случая на Инфостарт есть замечательная публикация //infostart.ru/public/238584/ – «Использование .NET сборок в 1С». Большое спасибо программисту – мы не раз ее применяли.
Как это работает? Даже если вам не интересно знать про нейросети, сейчас .NET – очень популярный язык, на нем много пишут, поэтому будет полезно научиться использовать его в 1С.
На слайде вы видите пример использования нейросети в 1С. Кода тут 3 строчки – остальное комментарии:
- Создается объект-обертка NetObjetToIDispatch45.
- Далее загружается сборка – это та dll, которую вам генерировал Matlab. Важный момент – эту сборку даже не надо регистрировать. Вы можете этих нейросеток создавать хоть десятками, а потом в коде просто меняете одну строчку, и у вас загружается одна сетка, другая, третья, четвертая. В моем случае это был СКД-отчет, в котором когда пользователь выбирал вариант отчета, у него подгружались разные варианты dll. А сам код отчета, что самое интересное, был один и тот же.
- Потом создаете тип нейросети – когда вы деплоили функцию, вы указали класс, и название самой библиотеки – их и нужно сюда написать.
- Следующим шагом создается массив данных – объект нейросети. Здесь есть небольшая сложность – как я уже говорил, Matlab работает только с массивами, причем только со своими массивами – эти массивы называются MWArray. Для них есть отдельные сборки, и когда Matlab создает сборку dll для деплоя, он рядом помещает библиотеку MWArray.dll – поэтому ее найти не проблема. Но для нас главное, что ее тоже нужно загрузить, чтобы получить тип матлабовского массива.
- Обратите внимание, что массив мы будем создавать на основе обычного массива COMSaveArray – кто в 1С работал с COM-объектами, тот понимает, что если вы передаете массив в COM-объект, то надо создать не 1С-массив, а массив COMSaveArray, чтобы у вас не дай бог ничего не вылетело. Итак, мы создаем массив (здесь у меня единички – это количество строк и колонок).
- Наконец, передаем этот массив внутрь нейросети
- И получаем результат.
Строчек кода получается совсем немного, но дальше на основании этого шаблона вы можете делать любые вариации – допустим, у вас будет не один элемент, а 10 (если у вас 10 входов было).
Технологии для генетических алгоритмов
Теперь несколько слов о практическом применении генетического алгоритма.
Поскольку наша прикладная задача находится в 1С, а основная тема генетического алгоритма – это селекция, следовательно, ни Matlab, ни R, ни C++ мы для генетического алгоритма использовать не будем. Для того чтобы нам выбрать лучшую особь, нужно использовать ту логику, которая заложена в 1С, соответственно, нам нужно использовать генетический алгоритм непосредственно в нашем 1С-ном решении.
Генетический алгоритм – это очень просто: там нет структурных вычислений, нет какой-то нереальной логики, нет математики. Вам достаточно написать 10 строчек кода: выбрать лучшую особь и сгенерировать случайным образом популяцию – это все, что нужно для нормальной работы генетического алгоритма.
Код 1С я здесь даже не привожу, потому что он будет у каждого свой – нужно просто запомнить последовательность действий.
Данная статья написана по итогам доклада, прочитанного на конференции INFOSTART EVENT 2016 DEVELOPER.