Новости web-panda https://web-panda.ru Авторский блог @CatOstrovsky. Только все самое интересное о JavaScript, PHP, NodeJS... ru 🍕Slices🍕 https://web-panda.ru/post/slices 🍕Slices🍕 — это интересная головоломка, от которой будут в восторге ✌ люди всех возрастов! Ваша цель: собрать пиццы из шести кусков что бы получить 🍖 бонусные очки и перейти на новый уровень!

Скачать на Android: http://demo.web-panda.ru/slices.apk

Приятной игры! ;-) Соревнуйтесь со своими близкими и друзьями, зарабатывайте больше очков!

Особенности игры

  • Интересный и простой геймплей
  • Бесконечное количество уровней
  • Отличная графика
  • Приятное звуковое сопровождение
  • НИКАКОГО ДОНАТА
  • НИКАКОЙ РЕКЛАМЫ

Благодарности

НаименованиеГде?Ссылка
flaticonГрафика и дизаинflaticon.com
freesoundЗвук и эффектыfreesound.org
laggedИдея и механикаlagged.com
   

  

Project in GitHub

]]>
Sat, 12 Jan 2019 14:00:50 +0000 Пример Konstantin Ostrovsky
WallPepper 🌶️ https://web-panda.ru/post/wallpepper

Любите красивые, красочные и заставки или Вам больше по-душе мрачные обои? Как бы там ни было, новый сервис Wall Pepper позволит каждому найти идеальную заставку для любимого девайса! В базе более 10 000 000 обоев на любой вкус!

ПЕРЕЙТИ на https://wallpepper.web-panda.ru

 

🌶️🔥🥇  Wall Pepper - потрясающий сервис для поиска обоев для различных устройств. ⚠ Использует API нескольких CDN с изображениями, соответственно имеет огромнейшую базу с изображениями! 👌

]]>
Sat, 12 Jan 2019 13:37:11 +0000 Пример Konstantin Ostrovsky
Стабильный, бесплатный самообновляемый IPTV-плейлист https://web-panda.ru/post/iptv-playlist-free

IPTV - это отличный способ бесплатно получить доступ к тысячам Российских и зарубежных телеканалов в высоком качестве с любого устройства. Самообновляемые IPTV-плейлисты - это самые надежные источники IPTV.

Я пробовал множество IPTV-плейлистов, но стабильность их работы оставляла желать лучшего. Именно поэтому я решил самостоятельно написать скрипт, который ежедневно генерировал бы стабильный IPTV-плейлист. В моем плейлисте более 500 каналов, собранных из различных источников. Ежедневно в 21:00 по МСК производится автоматическое обновление каналов. Отбираются лучшие каналы у которых самый лучший отклик. Соответственно все каналы в плейлисте максимально быстро загружаются и обеспечивают лучшее качество.

Основная цель которая стояла передо мной - создание стабильного плейлиста с наличием региональных каналов и множеством кино-каналов.

В настоящее время проект стабильно работает, но все еще находится в стадии БЕТА-тестирования. Буду рад каждому кто хочет поддержать проект, пишите в комментариях если наблюдается не стабильная работа каналов или они слишком долго грузятся. Инструкцию по установке и общую информацию для пользователей Вы найдете на странице проекта.

Ссылка на плейлист: https://iptv.web-panda.ru/pl.m3u

Ссылка на проект: https://iptv.web-panda.ru/

]]>
Thu, 20 Dec 2018 10:41:48 +0000 Пример Konstantin Ostrovsky
Распознавание образов встроенное в Chrome https://web-panda.ru/post/detect-face-chrome

Фотографии составляют большую часть информации в Интернете, особенно в современную эпоху. Некоторые из этих изображений состоят из узнаваемых областей, таких как человеческие лица, текст, штрих-коды и QR-коды. Эти области имеют много вариантов использования, но их обнаружение очень затратно в вычислительном отношении. К счастью, производители оборудования, особенно на мобильных устройствах, уже начали поддерживать эти функции на своих платформах. Они были использованы внескольких приложенях, таких как распознавание лиц в камерах, приложения для сканирования штрих-кодов и многие другие. С другой стороны, веб-приложения по-прежнему не имеют доступа к этим аппаратным возможностям, что делает необходимым использование вычислительно-требовательных библиотек и сторонних сервисов. API обнаружения лиц призван изменить это.

Мало кто знает, но в chrome с 2018-09-07 добавлена возможность распознавания лиц. Пока это лишь экспериментальная технология и для ее активации необходимо включить "экспериментальные возможности".
Начиная с Chrome 70 (бета-версия от 13 сентября 2018 года), API обнаружения формы уже доступен для Origin Trial. Это означает что пользователям Chrome старше 70 версии могут прямо сейчас начать пользоваться распознаванием образов, не включая никаких флагов.

 

Зачем?

В настоящее время очень популярными являются VR и AR технологии. Благодаря распознаванию образов, к примеру, сделаны маски и трансформации лиц в медиа-социальных сетях, таких как vk.com и instagram.com. До самого веба эта технология постепенно добирается. Уже есть множество frameworks для создания VR и AR приложений. Такие как A-frameWebVRPrimroseReact VR и Argon.js. Но стабильная нативная поддержка распознавания лиц в браузере это все равно круто и безусловно за этим будущее. 

Это далеко не все возможности этой технологии. Когда она получит лучшую поддержку, я уверен что будет разработано множество развлекательных приложений, которых мы еще никогда не видели.

Включаем экспериментальные возможности Chrome

Для включения экспериментальных возможностей перейдите по ссылке:  chrome://flags/#enable-experimental-web-platform-features

Включите экспериментальные возможности:

И перезапустите браузер. Проверить работоспособность можно вызвав в консоли класс FaceDetector. Если включены экспериментальные возможности, то класс будет доступен и Вы увидите следующее:

Использование

Достаточно не просто было найти документацию по функциям, которые еще официально не вышли в свет. Я наткнулся на очень интересную статью, в ней достаточно подробно возможности распознавания лиц и рассмотрена техническая сторона вопроса.

Источник изображения

В качестве источника изображения на котором будет производиться распознавание можно использовать:

  1. HTMLImageElement () - в этом случае будет использоваться статическое изображение. Если в ссылке будет находиться gif, то будет использоваться первый кадр анимации;
  2. HTMLVideoElement () - в качестве источника Вы можете использовать видео. В этом случае будет взят текущий кадр и с ним произведены операции. Соответственно если Вы хотите сделать realtime распознавание лиц в видео, то необходимо неоднократно находить и выделять лица для различных кадров;
  3. HTMLCanvasElement () - содержимое canvas в текущий момент будет использоваться для вычислительных операций.

 

Обнаружение лиц

Обнаружение лица может быть сделано с помощью FaceDetector интерфейса. FaceDetector представляет базовый компонент платформы для обнаружения человеческих лиц на изображениях. Чтобы начать пользоваться FaceDetector Вам нужно всего лишь создать его экземпляр при помощи JavaScript.

const faceDetector = new FaceDetector ({ 
    maxDetectedFaces: 10, 
    fastMode: true 
});

FaceDetector принимает два необязательных аргумента:

  • maxDetectedFaces - максимальное количество лиц для поиска в источнике изображения;
  • fastMode - говорит браузеру попытаться установить приоритет скорости над точностью.

Затем метод FaceDetector экземпляра detect() можно использовать для обнаружения человеческих лиц из данного источника изображения.

const imageSource = document.querySelector ('img'); 
// так же Вы можете использовать 

faceDetector.detect() возвращает Promise, в который принимается массив из объектов типа DetectedFace. Структура этого объекта следующая:

  • boundingBox - объект, описывающий прямоугольник, который указывает положение и границы на изображении, где было обнаружено лицо. Эти координаты можно использовать для графического отображения найденных координат, к примеру отрисовать их при помощи canvas.
  • landmarks - массив Landmark объектов. Ориентир - это интересная особенность распознавания. В этом массиве могут быть найденные элементы лица: нос, рот, глаза и т.д. Или не быть, если системе не удалось их распознать, в таком случае значение будет null.

Специально для Вас я подготовил пример работы класса FaceDetector:

Распознавание текста

Не менее популярной возможностью перевода текста является перевод текста по снимку, либо перевод в реальном времени. Google уже давно предоставляет эту возможность пользователю в своём приложении для мобильных устройств. Принцип использования этого метода перевода очень прост и не требует таких затратных по времени операций как ввод текста вручную.

Благодаря новому классу TextDetector, эта возможность стала доступна и в браузере. Класс TextDetector не имеет аргументов, соответственно чтобы создать экземпляр необходимо написать следующее:

const textDetector = new TextDetector();

Просто! Не так ли? У объекта класса TextDetector есть метод detect(), который позволяет определить текст по изображению. В качестве аргументов так же как и в FaceDetector можно передавать , и . Возвращает функция detect() - Promise, аргументом в resolve передается объект типа DetectedText, который имеет следующие ключи:

  • boundingBox - объект, описывающий прямоугольник, который указывает положение и границы на изображении, где был обнаружен текст;
  • rawValue - строковое значение обнаруженного текста.

Пример работы класса TextDetector:

Распознавание QR-кодов

Достаточно давно технология передачи информации при помощи QR или BarCode является очень популярной. Полагаю потом что человеку легче сканировать изображение, чем писать ссылки на сайты или другую информацию вручную. Так же в ссылки в QR-кодах можно добавлять специальные метки для отслеживания и аналитики переходов. Это очень удобная и полезная технология. Сгенерировать QR-код можно даже онлайн, к примеру на этом сервисе.

Новый класс BarcodeDetector позволяет нам распознавать информацию, которую хранит BarCode. Класс TextDetector не имеет аргументов, соответственно чтобы создать экземпляр необходимо написать следующее:

const textDetector = new TextDetector();

У объекта класса BarcodeDetector есть метод detect(), который позволяет определить текст по BarCode. В качестве аргументов так же как и в FaceDetector можно передавать , и . Возвращает функция detect() - Promise, аргументом в resolve передается объект типа DetectedBarcode, который имеет следующие ключи:

  • boundingBox - объект, описывающий прямоугольник, который указывает положение и границы на изображении, где был обнаружен штрих-код.
  • rawValue - строковое значение, которое было декодировано из штрих-кода.
  • cornerPoints - массив точек, соответствующих координатам каждого угла обнаруженного штрих-кода. Он начинается с верхнего левого угла и идет по часовой стрелке. Точки не обязательно представляют правильный прямоугольник или квадрат из-за искажений перспективы.

Пример работы класса BarcodeDetector:

Заключение

Технология распознавания образов все еще находится в стадии разработки, но полагаю в скором будущем будет представлена в Stable версии WebKit и тогда ее можно будет безопасно использовать в своих проектах. API распознавания образов - это отличное решение, которое вносит единообразие в проекты и исключает необходимость использования сторонних библиотек. 

Куда в будущем может повернуть эта технология трудно даже представить, возможно эти технологии будут использоваться для улучшения качества жизни людей с ограниченными возможностями или использоваться в сложных интерактивных приложениях. 

]]>
Wed, 19 Dec 2018 14:16:32 +0000 JavaScript Konstantin Ostrovsky
Принципы построения нейронных сетей. Пишем простую нейросеть на JavaScript https://web-panda.ru/post/brainjs-simple Рассмотрим базовые принципы работы нейронных сетей, узнаем про Brain.js и попробуем подкрепить теорию на практике. Напишем свою первую нейронную сеть, которая будет уметь чуть больше чем ничего, но чуть меньше чем что-то. Статья не претендует на пособие по разработке нейронных сетей, я постараюсь дать Вам базовые знания и представления о работе нейросетей, которыми обладаю сам>

Введем понятие ИНС - искусственная нейронная сеть. т.e. сеть построенная при помощи компьютерной системы;

НС - нейронная сеть мозга человека.

Что такое ИНС?

Нейронная сеть — это последовательность нейронов, соединенных между собой синапсами. Структура нейронной сети пришла в мир программирования прямиком из биологии. Благодаря такой структуре, машина обретает способность анализировать и даже запоминать различную информацию. Нейронные сети также способны не только анализировать входящую информацию, но и воспроизводить ее из своей памяти.

Давайте начнем с Вашего представления о ИНС. Исходя из общепринятых знаний, многие думают что ИНС представляют собой копию человеческой НС в коре головного мозга. Некий набор алгоритмов и накопленных знаний, благодаря которым сеть принимает дальнейшие решения. Это суждение верно, но не стоит переоценивать ее возможности. Если наша ИНС умеет варить Вам кофе с утра, то вряд ли она сможет приготовить Вам завтрак, если Вы сами ее этому не научите. Из этого можно сделать вывод, что ИНС выполняет лишь те функции, которым она обучена. Самообучающиеся нейронные сети это не миф, но пока еще не удалось разработать стабильную сеть, которая самостоятельно генерировала бы алгоритмы для решения различных задач.

Для понимания устройства нейронной сети давайте немного окунемся в биологию и устройство человеческого мозга и проведем некоторые параллели с устройством ИНС. Это не так сложно, как может показаться! 

Нейронная сеть (биологическая нейронная сеть) — совокупность нейронов головного и спинного мозга центральной нервной системы (ЦНС) и ганглия периферической нервной системы (ПНС), которые связаны или функционально объединены в нервной системе, выполняют специфические физиологические функции.

Нейронная сеть состоит из группы или групп химически или функционально связанных нейронов. Один нейрон может быть связан со многими другими нейронами, а общее количество нейронов и связей в сети может быть достаточно большим. Место контакта нейронов называется синапсом, типичный синапс — аксо-дендритический химический. Передача импульсов осуществляется химическим путём с помощью медиаторов или электрическим путём посредством прохождения ионов из одной клетки в другую.

Представление о нейронных сетях оказало значительное влияние на технологии искусственного интеллекта, в попытке построить математическую модель нейронной сети был создан обширный инструментарий искусственных нейронных сетей, широко используемый в прикладной математике и информатике.

Давайте более подробно разберем это определение. Из него следует что нейронная сеть представляет собой некоторое количество нейронов, связанных между собой. Сколько нейронов в мозге человека? По подсчетам многих ученых, мозг человека состоит из порядка 100 миллиардов нейронов (плюс-минус пара миллиардов). Именно эта цифра долгие годы приводилась в учебниках по нейробиологии и психологии. Каждый из нейронов является вычислительной единицей, которая обрабатывает входящую информацию и передает ее дальше. Для получения информации у нейрона есть входные каналы, которые называются синапсы. Синапсы это каналы, по которым в нейрон поступает информация из других нейронов. На рисунке синапсы обозначены буквой W, а другие нейроны буквой X. Каждый синапс обладает весом, чем больше вес синапса, тем больше результат работы нейрона будет преобладать в дальнейших вычислениях. Рассмотрим работу синапсов на примере изображения:

Разноцветные круги слева - нейроны. Линиями изображены синапсы. Как видно, каждый синапс обладает весом. Этот вес проставляется случайным образом в диапазоне от 0 до 1. На изображении справа изображена работа сумматора. Сумматор - это функция, которая рассчитывает вес входных сигналов и передает их дальше в функцию активации, об этом чуть позже. Давайте попробуем рассчитать вес входных сигналов, если результаты работы нейронов были следующие:

  • 1 - 0.35
  • 2 - 0.12
  • 3 - 0.6

Важно понимать что ИНС оперирует данными в диапазоне от 0 до 1. Вычисление веса в сумматоре производится пос следующей формуле:

(L1 * W1) +  (L2 * W2) + (L3 * W3) = W

Функция совершенно линейна, из этого мы получаем следующую формулу:

(0.35 * 0.1) + (0.12 * 0.3) + (0.6 * 0.2) = 0.191

Таким образом мы получили некую единицу, вес который будет передан в функцию активации. 

Функция активации — это способ нормализации входных данных. То есть, если на входе у вас будет большое число, пропустив его через функцию активации, вы получите выход в нужном вам диапазоне.

Функций активации достаточно много поэтому мы рассмотрим самые основные: Линейная, Сигмоид (Логистическая) и Гиперболический тангенс. Главные их отличия — это диапазон значений.

Линейная функция


Эта функция почти никогда не используется, за исключением случаев, когда нужно протестировать нейронную сеть или передать значение без преобразований.

Сигмоид


Это самая распространенная функция активации, ее диапазон значений [0,1]. Именно на ней показано большинство примеров в сети, также ее иногда называют логистической функцией. Соответственно, если в вашем случае присутствуют отрицательные значения (например, акции могут идти не только вверх, но и вниз), то вам понадобиться функция которая захватывает и отрицательные значения.

Гиперболический тангенс

Имеет смысл использовать гиперболический тангенс, только тогда, когда ваши значения могут быть и отрицательными, и положительными, так как диапазон функции [-1,1]. Использовать эту функцию только с положительными значениями нецелесообразно так как это значительно ухудшит результаты вашей нейросети.


Подведем итоги. Что мы узнали про ИНС?

У нейрона есть входы. На них подаются сигналы в виде чисел. Каждый вход имеет свой вес (тоже число). Сигналы на входе умножаются на соответствующие веса. Получаем набор «взвешенных» входных сигналов.

Далее этот набор попадает в сумматор, которой просто складывает все входные сигналы, помноженные на веса. Получившееся число называют взвешенной суммой.

Затем взвешенная сумма преобразуется функцией активации и мы получаем выход нейрона.

Виды ИНС

Мы разобрались со структурой искусственного нейрона. Искусственные нейронные сети состоят из совокупности искусственных нейронов. Возникает логичный вопрос – а как располагать/соединять друг с другом эти самые искусственные нейроны?

Как правило, в большинстве нейронных сетей есть так называемый входной слой, который выполняет только одну задачу – распределение входных сигналов остальным нейронам. Нейроны этого слоя не производят никаких вычислений.

На этом схожесть заканчивается и начинаются различия...

Однослойные нейронные сети

В однослойных нейронных сетях сигналы с входного слоя сразу подаются на выходной слой. Он производит необходимые вычисления, результаты которых сразу подаются на выходы.

Выглядит однослойная нейронная сеть следующим образом:

На этой картинке входной слой обозначен кружками (он не считается за слой нейронной сети), а справа расположен слой обычных нейронов.

Нейроны соединены друг с другом стрелками. Над стрелками расположены веса соответствующих связей (весовые коэффициенты).

Однослойная нейронная сеть (Single-layer neural network) — сеть, в которой сигналы от входного слоя сразу подаются на выходной слой, который и преобразует сигнал и сразу же выдает ответ.

Многослойные нейронные сети

Такие сети, помимо входного и выходного слоев нейронов, характеризуются еще и скрытым слоем (слоями). Понять их расположение просто – эти слои находятся между входным и выходным слоями.

Такая структура нейронных сетей копирует многослойную структуру определенных отделов мозга.

Название скрытый слой получил неслучайно. Дело в том, что только относительно недавно были разработаны методы обучения нейронов скрытого слоя. До этого обходились только однослойными нейросетями.

Многослойные нейронные сети обладают гораздо большими возможностями, чем однослойные.

Работу скрытых слоев нейронов можно сравнить с работой большого завода. Продукт (выходной сигнал) на заводе собирается по стадиям. После каждого станка получается какой-то промежуточный результат. Скрытые слои тоже преобразуют входные сигналы в некоторые промежуточные результаты.

Сети прямого распространения

Можно заметить одну очень интересную деталь на картинках нейросетей в примерах выше.

Во всех примерах стрелки строго идут слева направо, то есть сигнал в таких сетях идет строго от входного слоя к выходному.

Сети прямого распространения (Feedforward neural network) (feedforward сети) — искусственные нейронные сети, в которых сигнал распространяется строго от входного слоя к выходному. В обратном направлении сигнал не распространяется.

Такие сети широко используются и вполне успешно решают определенный класс задач: прогнозирование, кластеризация и распознавание.

Однако никто не запрещает сигналу идти и в обратную сторону.

Сети с обратными связями

В сетях такого типа сигнал может идти и в обратную сторону. В чем преимущество?

Дело в том, что в сетях прямого распространения выход сети определяется входным сигналом и весовыми коэффициентами при искусственных нейронах.

А в сетях с обратными связями выходы нейронов могут возвращаться на входы. Это означает, что выход какого-нибудь нейрона определяется не только его весами и входным сигналом, но еще и предыдущими выходами (так как они снова вернулись на входы).

Возможность сигналов циркулировать в сети открывает новые, удивительные возможности нейронных сетей. С помощью таких сетей можно создавать нейросети, восстанавливающие или дополняющие сигналы. Другими словами такие нейросети имеют свойства кратковременной памяти (как у человека).

Классификация ИНС

Как уже стало известно, невозможно написать ИНС для всех нужд и потребностей, поэтому перед учеными появилась задача: классифицировать ИНС по назначению. Из наиболее распространенных назначений ИНС можно выделить следующие:

Классификация образов. Задача состоит в указании принадлежности входного образа (например, речевого сигнала или рукописного символа), представленного вектором признаков, одному или нескольким предварительно определенным классам. К известным приложениям относятся распознавание букв, распознавание речи, классификация сигнала электрокардио-граммы, классификация клеток крови, обеспечение деятельности биометрических сканеров и т. п.

Кластеризация/категоризация. При решении задачи кластеризации, которая известна также как классификация образов без учителя, отсутствует обучающая выборка с метками классов. Алгоритм кластеризации основан на подобии образов и размещает близкие образы в один кластер. Известны случаи применения кластеризации для извлечения знаний, сжатия данных и исследования свойств данных.

Аппроксимация функций. Предположим, что имеется обучающая выборка пар данных вход-выход, которая генерируется неизвестной функцией, зависящей от некоторого аргумента, искаженной шумом. Задача ап-проксимации состоит в нахождении оценки неизвестной функции. Аппроксимация функций необходима при решении многочисленных инженерных и научных задач моделирования. Типичным примером является шумоподавление при приеме сигнала различной природы, вне зависимости от передаваемой информации.

Предсказание/прогноз. Пусть заданы n дискретных отсчетов {y (t1), y (t2)..., y (tn)} в последовательные моменты времени t1, t2,..., tn. Задача состоит в предсказании значения y (tn+1) в некоторый будущий момент времени tn+1. Предсказание/прогноз имеют значительное влияние на принятие решений в бизнесе, науке и технике. Предсказание цен на фондовой бирже и прогноз погоды являются типичными приложениями техники предсказания/прогноза.

Оптимизация. Многочисленные проблемы в математике, статистике, технике, науке, медицине и экономике могут рассматриваться как проблемы оптимизации. Задачей алгоритма оптимизации является нахождение такого решения, которое удовлетворяет системе ограничений и максимизирует или минимизирует целевую функцию. Задача коммивояжера об оптимальной загрузке самолета, назначение штата работников по ряду умений и факторов являются классическими примерами задач оптимизации.

Память, адресуемая по содержанию (ассоциативная память). В модели вычислений фон Неймана обращение к памяти доступно только посредством адреса, который не зависит от содержания памяти. Более того, если допущена ошибка в вычислении адреса, то может быть найдена совершенно иная информация. Ассоциативная память доступна по указанию заданного содержания. Содержимое памяти может быть вызвано даже по частичному входу или искаженному содержанию. Ассоциативная память может прекрасно найти применение при создании мультимедийных информационных баз данных.

Управление. Рассмотрим динамическую систему, заданную совокупностью векторов входного управляющего воздействия, текущего состояния, выходного вектора системы. Классической постановкой задачи является расчет
управляющего воздействия, чтобы в конкретный момент времени система находилась в определенной желаемой точке. Примером является оптимальное управление двигателем, рулевое управление на кораблях, самолетах.

Отлично! Но как научить сеть делать то, что я от нее хочу? Может нужно помочь ей? Или она сама себя обучит? 

Искусственная нейронная сеть – это совокупность искусственных нейронов. Теперь давайте возьмем, например, 100 нейронов и соединим их друг с другом. Ясно, что при подаче сигнала на вход, мы получим что-то бессмысленное на выходе.

Значит нам надо менять какие-то параметры сети до тех пор, пока входной сигнал не преобразуется в нужный нам выходной.

Что мы можем менять в нейронной сети?

Изменять общее количество искусственных нейронов бессмысленно по двум причинам. Во-первых, увеличение количества вычислительных элементов в целом лишь делает систему тяжеловеснее и избыточнее. Во-вторых, если вы соберете 1000 дураков вместо 100, то они все-равно не смогут правильно ответить на вопрос.

Сумматор изменить не получится, так как он выполняет одну жестко заданную функцию – складывать. Если мы его заменим на что-то или вообще уберем, то это вообще уже не будет искусственным нейроном.

Если менять у каждого нейрона функцию активации, то мы получим слишком разношерстную и неконтролируемую нейронную сеть. К тому же, в большинстве случаев нейроны в нейронных сетях одного типа. То есть они все имеют одну и ту же функцию активации.

Остается только один вариант – менять веса связей.

Обучение нейронной сети (Training) — поиск такого набора весовых коэффициентов, при котором входной сигнал после прохода по сети преобразуется в нужный нам выходной.

Такой подход к термину «обучение нейронной сети» соответствует и биологическим нейросетям. Наш мозг состоит из огромного количества связанных друг с другом нейросетей. Каждая из них в отдельности состоит из нейронов одного типа (функция активации одинаковая). Мы обучаемся благодаря изменению синапсов – элементов, которые усиливают/ослабляют входной сигнал.

Однако есть еще один важный момент. Если обучать сеть, используя только один входной сигнал, то сеть просто «запомнит правильный ответ». Со стороны будет казаться, что она очень быстро «обучилась». И как только вы подадите немного измененный сигнал, ожидая увидеть правильный ответ, то сеть выдаст бессмыслицу.

В самом деле, зачем нам сеть, определяющая лицо только на одном фото. Мы ждем от сети способности обобщать какие-то признаки и узнавать лица и на других фотографиях тоже.

Именно с этой целью и создаются обучающие выборки.

Обучающая выборка (Training set) — конечный набор входных сигналов (иногда вместе с правильными выходными сигналами), по которым происходит обучение сети.

После обучения сети, то есть когда сеть выдает корректные результаты для всех входных сигналов из обучающей выборки, ее можно использовать на практике.

Однако прежде чем пускать свежеиспеченную нейросеть в бой, часто производят оценку качества ее работы на так называемой тестовой выборке.

Тестовая выборка (Testing set) — конечный набор входных сигналов (иногда вместе с правильными выходными сигналами), по которым происходит оценка качества работы сети.

Мы поняли, что такое «обучение сети» – подбор правильного набора весов. Теперь возникает вопрос – а как можно обучать сеть? В самом общем случае есть два подхода, приводящие к разным результатам: обучение с учителем и обучение без учителя.

Обучение с учителем

Суть данного подхода заключается в том, что вы даете на вход сигнал, смотрите на ответ сети, а затем сравниваете его с уже готовым, правильным ответом.

Важный момент. Не путайте правильные ответы и известный алгоритм решения! Вы можете обвести пальцем лицо на фото (правильный ответ), но не сможете сказать, как это сделали (известный алгоритм). Тут такая же ситуация.

Затем, с помощью специальных алгоритмов, вы меняете веса связей нейронной сети и снова даете ей входной сигнал. Сравниваете ее ответ с правильным и повторяете этот процесс до тех пор, пока сеть не начнет отвечать с приемлемой точностью (как я говорил в 1 главе, однозначно точных ответов сеть давать не может).

Обучение без учителя

Обучение без учителя применяют тогда, когда у нас нет правильных ответов на входные сигналы. В этом случае вся обучающая выборка состоит из набора входных сигналов.

Что же происходит при таком обучении сети? Оказывается, что при таком «обучении» сеть начинает выделять классы подаваемых на вход сигналов. Короче говоря – сеть начинает кластеризацию.

Например, вы демонстрируете сети конфеты, пирожные и торты. Вы никак не регулируете работу сети. Вы просто подаете на ее входы данные о данном объекте. Со временем сеть начнет выдавать сигналы трех разных типов, которые и отвечают за объекты на входе.

Обучение без учителя (Unsupervised learning) — вид обучения сети, при котором сеть самостоятельно классифицирует входные сигналы. Правильные (эталонные) выходные сигналы не демонстрируются.

Выводы

В этой главе вы узнали все о структуре искусственного нейрона, а также получили полное представление о том, как он работает (и о его математической модели).

Более того, вы теперь знаете о различных видах искусственных нейронных сетей: однослойные, многослойные, а также feedforward сети и сети с обратными связями.

Вы также ознакомились с тем, что представляет собой обучение сети с учителем и без учителя.

Вы уже знаете необходимую теорию.  Давайте попробуем подкрепить наши знания на практике.


Практика

Наиболее распространенным решением является использование Python для построения ИНС. Существует огромное множество готовых решений и библиотек для построения ИНС. Но так как мы лучше знакомы с веб языками программирования, то мы будем использовать JavaScript. При работе с ИНС Вам вряд ли придется их самостоятельно писать, но понимать принцип работы ИНС необходимо понимать при работе с ними.
Мы будем использовать популярную JavaScript библиотеку brain.js

В библиотеке уже реализованы все необходимые инструменты для работы с ИНС и нам лишь необходимо передать необходимые параметры для создания нужного нам экземпляра brain.js. Первый релиз библиотеки состоялся 1 января 2018г. Правильнее будет сказать, что первый релиз после упадка библиотеки состоялся 1 января 2018г. Библиотека brain.js является работой энтузиастов, которые не стали равнодушны к закрытию проекта brain и создали собственный форк, который по сей день очень активно развивается. Начать работать с brain.js очень просто, для этого Вам необходимо пройти несколько шагов:

  • Установить NodeJS и NPM, либо использовать версию для браузера (ее можно подключить прямо в документ с CDN);
  • Если Вы решили использовать NodeJS, то Вам необходимо установить пакет brain.js, выполнив команду npm install brain.js и подключить ее в файл командой const brain = require('brain.js');
  • Создать экземпляр объекта ИНС, передав необходимые параметры конструктору: const net = new brain.NeuralNetwork({...});
  • Тренировать сеть при помощи команды train и набора тренировочных данных;
  • Использовать ИНС при помощи команды run;

Библиотека имеет отличный пример работы в котором на первом этапе Вам необходимо создать тренировочные данные для ИНС выбирая цвет текста на разноцветных плитках, который лучше видно. На втором этапе после обучения, ИНС сама будет определять какой цвет текста будет лучше видно на разноцветных плитках. Пример находится по этому адресу. Так же существует отличный интерактивный урок по работе с brain.js на scrimba. Еще больше примеров и уроков можно найти в WIKI на GitHub.

Вот некоторая техническая информация которая может понадобиться Вам при работе с brain.js. Я не нашел русского перевода, поэтому перевел самостоятельно, поправьте если я где-то допустил ошибку.

Использование brain.js в браузере требует вычислительных затрат, поэтому вы должны попытаться обучить сеть в автономном режиме (или на рабочем месте) и использовать опции toFunction()или toJSON(), чтобы подключить предварительно обученную сеть к своему веб-сайту.

Используйте train()для обучения сети с массивом обучающих данных. Сеть должна быть обучена со всеми данными в один прием train(). Большее количество тренировочных шаблонов, вероятно, займет больше времени, но обычно приводит к тому, что сеть лучше классифицирует новые шаблоны.

Тренировка с NeuralNetwork

Каждый тренировочный шаблон должен иметь an inputи an output, оба из которых могут быть либо массивом чисел от 0 до 1 , либо хешем чисел от 0 до 1. Для демонстрации цветового контраста это выглядит примерно так:

const net = new brain.NeuralNetwork();

net.train([{input: { r: 0.03, g: 0.7, b: 0.5 }, output: { black: 1 }},
           {input: { r: 0.16, g: 0.09, b: 0.2 }, output: { white: 1 }},
           {input: { r: 0.5, g: 0.5, b: 1.0 }, output: { white: 1 }}]);

const output = net.run({ r: 1, g: 0.4, b: 0 });  // { white: 0.99, black: 0.002 }

Для обучения с RNNTimeStep, LSTMTimeStepиGRUTimeStep
Каждый шаблон тренировки может:

- Быть массивом чисел
- Быть массивом массивов чисел

Пример использования массива чисел:

const net = new brain.recurrent.LSTMTimeStep();

net.train([
  [1, 2, 3]
]);

const output = net.run([1, 2]);  // 3

Пример использования массива чисел:

const net = new brain.recurrent.LSTMTimeStep({
  inputSize: 2,
  hiddenLayers: [10],
  outputSize: 2
});

net.train([
  [1, 3],
  [2, 2],
  [3, 1],
]);

const output = net.run([[1, 3], [2, 2]]);  // [3, 1]

Для обучения с RNN, LSTMиGRU
Каждый шаблон тренировки может:

- Быть массивом значений
 - Будь строкой
- Есть input и output
Любой из которых может массив значений или строка

Пример использования прямых строк:

const net = new brain.recurrent.LSTM();

net.train([
  'doe, a deer, a female deer',
  'ray, a drop of golden sun',
  'me, a name I call myself',
]);

const output = net.run('doe');  // ', a deer, a female deer'

Пример использования строк с входами и выходами:

const net = new brain.recurrent.LSTM();

net.train([
  { input: 'I feel great about the world!', output: 'happy' },
  { input: 'The world is a terrible place!', output: 'sad' },
]);

const output = net.run('I feel great about the world!');  // 'happy'

Варианты обучения

train() принимает хэш опций в качестве второго аргумента:

net.train(data, {
                            // Defaults values --> expected validation
      iterations: 20000,    // максимальное количество итераций обучающих данных -> число больше 0 
      errorThresh: 0.005,   // допустимый процент ошибок из обучающих данных - > число от 0 до 1 
      log: false,           // true для использования console.log, когда функция предоставляется, она используется -> либо true, либо функция 
      logPeriod: 10,        // итерации между выходом из системы -> число больше 0 
      learningRate: 0.3,    // масштабирование дельтой для повышения скорости тренировки -> число от 0 до 1 
      momentum: 0.1,        // масштабирование с значением изменения следующего слоя -> число между 0 и 1 
      callback: null,       // периодический обратный вызов, который может быть запущен во время обучения -> null или функция 
      callbackPeriod: 10,   // количество итераций данных обучения между вызовами обратного вызова -> число больше 0 
      timeout: Infinity     // максимальное количество миллисекунд, для которых нужно тренироваться -> число больше 0 
});

Сеть прекращает обучение, когда выполняется один из двух критериев: ошибка обучения опустилась ниже порога (по умолчанию 0.005) или 20000достигнуто максимальное количество итераций (по умолчанию ).

Тренируясь по умолчанию не дам вам знать , как она делает до конца, но установить logдля , trueчтобы получить периодические обновления на текущей ошибке обучения сети. Ошибка обучения должна уменьшаться каждый раз. Обновления будут распечатаны на консоли. Если вы установите logфункцию, эта функция будет вызываться с обновлениями, а не выводиться на консоль.

Скорость обучения - это параметр, который влияет на скорость обучения в сети. Это число от 0до 1. Если скорость обучения близка 0, обучение займет больше времени. Если скорость обучения ближе 1, она будет тренироваться быстрее, но результаты обучения могут быть ограничены локальным минимумом и плохо работать с новыми данными. ( Переоснащение ) Скорость обучения по умолчанию - 0.3.

JSON
Сериализация или загрузка в состоянии обученной сети с помощью JSON:

const json = net.toJSON();
net.fromJSON(json);

Автономная функция
Вы также можете получить настраиваемую автономную функцию из обученной сети, которая действует так же, как run():

const run = net.toFunction();
const output = run({ r: 1, g: 0.4, b: 0 });
console.log(run.toString()); // copy and paste! no need to import brain.js

Активация
Этот параметр позволяет указать, какую функцию активации должна использовать ваша нейронная сеть. Есть в настоящее время четыре поддерживаемых функций активации, сигмовидные по - умолчанию:

sigmoid
- relu
- leaky-relu (с этой опцией доступен параметр «leakyReluAlpha», по умолчанию 0,01)
- tanh


Вот таблица (спасибо, Википедия!), Обобщающая множество функций активации - Функция активации

Скрытые слои
Вы можете использовать это, чтобы указать количество скрытых слоев в сети и размер каждого слоя. Например, если вы хотите два скрытых слоя - первый с 3 узлами, а второй с 4 узлами, вы должны дать:

hiddenLayers: [3, 4]
По умолчанию brain.js используется один скрытый слой с размером, пропорциональным размеру входного массива.

Типы нейронных сетей

Теперь когда мы знаем что представляют из себя ИНС и обладаем технической информацией по работе с brain.js можно приступить к написанию своей первой ИНС. Я буду использовать repl.it для публикации кода и NodeJS для вычислительных процессов что бы не нагружать Ваши браузеры. 

В качестве первого примера предлагаю написать нейронную сеть по расчету XOR. XOR - это операция, которая принимает значение «истина» только если всего один из аргументов имеет значение «истина».

Более подробно изучить работу XOR Вы можете в отличной статье fealsoft на habr.com.

Пример 1

В реальной жизни эта ИНС конечно же является абсолютно бесполезной, но отлично подходит для простого промера. В качестве тренировочных данных на вход мы будем передавать два аргумента, а на выход результат XOR. К примеру [input: [0,0];output: 0,input:[0,1];output:1, ....]. Таким образом наша ИНС найдет закономерность и будет самостоятельно выявлять XOR. Важно понимать фактически она не будет высчитывать XOR, она будет делать предсказания каким может быть XOR для введенных аргументов. Весь код имеет комментарии и не вижу необходимости более детально углубляться в подробности реализации, Вы можете попробовать поменять значения передаваемые в функцию run и проверить корректность работы ИНС. Пример ИНС для расчета XOR:

Разрабатывать бесполезную ИНС для выполнения элементарных вычислений безумно "увлекательное " занятие, не так ли? Вы наверняка хотели бы создавать нейросети, которые будут уметь отвечать пользователю, проявлять признаки интеллекта или хотя бы будут как-то полезны обществу. Не вопрос!

Пример 2

Предположим что у Вы являетесь психологом в учебном заведении и перед Вами поставили цель: выявить эмоциональное состояние учащихся. Казалось бы спросить "Какое у тебя сегодня настроение?" дело совершенно плёвое, но когда это необходимо сделать 30 000 раз каждый день(именно столько учащихся Вам необходимо опросить) - это уже становится проблемой.

Предположим что в учебном заведении есть закрытая социальная сеть, в которой учащиеся ежедневно оставляют более 500 000 сообщений. Эта информация строго конфиденциальная, но Вы имеете к ней доступ, так как подписали договор о не разглашении. Отлично! Теперь у нас есть несколько миллионов сообщений вместо 30 000 учеников! 

Эмм... Звучит не особо оптимистично, но помимо психологии Вы увлекаетесь построением ИНС. Действительно. Зачем заниматься классификацией сообщений самому, если это может сделать машина и дать Вам отчет.

Перед нами стоит следующая задача:  Построить ИИС которая будет определять эмоциональное состояние человека по сообщению.

Входными данными является сообщение пользователя.

Выходными данными является строка: "хорошее" - если эмоциональный окрас сообщения позитивный, "плохое" - если эмоциональный окрас сообщения агрессивный или депрессивный.

Пример работы:

Сообщение "Завтра будет просто ужасный день!"

Результат "плохое"

Погрешность конечно оставляет желать лучшего, после 1000 итераций она составляет около 0.011. Это довольно большая цифра если мы говорим о классификации. Если увеличить количество обучающего материала и увеличить количество итераций, то можно добиться более внушительных результатов, но это займет слишком много времени в рамках чтения этой статьи.

Советую сохранять результаты обучения и не заставлять сеть учиться каждый раз когда Вы ее запускаете. Сохранить результаты обучения сети можно при помощи функции toJSON. Далее полученную строку сохраните в файл и при последующем запуске при помощи команды fromJSON выгрузите результаты вычислений обратно в сеть.

В работе ИНС всегда будут присутствовать ошибки, тем более на первых порах. Ведь ИНС подобно ребенку, в раннем возрасте ей свойственно часто ошибаться. Чем больше тренировок и качественнее будет обучающий материал, тем более точными будут результаты работы ИНС.


В заключение хочу сказать что JavaScript безусловно не является языком наиболее подходящим для построения ИНС. Вы наверно уже заметили как медленно проходит процесс обучения. Это вызвано тем что NodeJS, как и JavaScript является однопоточным и не раскрывает все вычислительные возможности процессора. Разработчики brain.js обещают улучшить производительность с выходом 2-й версии. Хотя и сейчас есть возможность использовать мощность видеопроцессора при помощи WebGL, но работу через GPU в brain.js поддерживают только neural networks. Для дальнейшего изучения рекомендую посмотреть в сторону Python.

 

Источники:

  1. https://neuralnet.info/chapter/основы-инс/
  2. https://habr.com/company/epam_systems/blog/317050/
  3. https://habr.com/post/312450/
  4. https://habr.com/post/40137/
  5. https://habr.com/post/398645/
  6. https://tproger.ru/translations/javascript-brain-neural-framework/
  7. https://itnan.ru/post.php?c=1&p=304414
  8. https://habr.com/post/183462/
  9. https://medium.com/openmindonline/emotion-detection-with-javascript-neural-networks-5a408f84eb75
]]>
Tue, 18 Dec 2018 09:18:43 +0000 JavaScript Konstantin Ostrovsky
Lodash - функции будущего в JS уже сегодня https://web-panda.ru/post/lodash-first-steps

Каждый разработчик ценит свое время и всегда ищет способы избежать дублирования кода и написания одинаковых реализаций под различные проекты. Lodash - библиотека с огромным количеством функций для работы с различными структурами данных. Опытный программист всегда найдет способ не писать велосипеды с костылями, а использовать готовые, проверенные решения. Тем более если эти решения хорошо структурированы и отлично задокументированы

Lodash - это библиотека JavaScript, которая помогает программистам писать более компактный и простой в обслуживании JavaScript код.

Его можно разбить на несколько основных направлений:

  • Utilities - для упрощения общих задач программирования, таких как определение типа, а также упрощение математических операций.;
  • Function - упрощение связывания, декорирование, сдерживание, дросселирование, debouncing, currying и изменение указателя;
  • String - функции преобразования для выполнения основных операций с строками, такие как обрезка, преобразование в верхний регистр, случай верблюда и т.д.;
  • Array - создание, разбиение, объединение, изменение и сжатие;
  • Collection - итерация, сортировка, фильтрация, расщепление и строительство;
  • Object - доступ, расширение, слияние, дефолты и преобразование;
  • Seq  - caching, упаковка, фильтрация и тестирование.

 

Библиотека доступна для установки с CDN без использования сборщиков, доступна на npm, есть поддержка TypeScript. Начать пользоваться Lodash очень просто, поэтому мы не будем уделять внимание установке. Если у Вас возникнут сложности - можете обратиться к документации, здесь подробно рассмотрены все варианты подключения библиотеки.

С появлением ES6 репутация Lodash слегка пошатнулась для некоторых разработчиков. Причиной этому стало появление большого количество функций для работы с структурами и добавление новых типов данных. В ES6 появилось большое количество функций для работы с массивами:

  • forEach - используется для перебора массива;
  • filter - используется для фильтрации массива через callback функцию;
  • map -  используется для трансформации массива;
  • every/some - методы используются для проверки массива;
  • reduce/reduceRight - используется для последовательной обработки каждого элемента массива с сохранением промежуточного результата.

Более подробную информацию по этим функциям Вы можете найти здесь.

Так же появились такие нововведения как:

Но несмотря на это польза библиотеки все равно не вызывает ни капли сомнения, JavaScript еще не скоро "впитает" или повторит все возможности Lodash.

Для того что бы понять удобство использования Lodash, давайте попробуем его в деле.

Предположим что мы делаем интернет-магазин и что бы снизить нагрузку на сервер мы решили переложить сложную логику сортировки и фильтрации на JavaScript. Логика будет следующая:

1) Пользователь открывает страницу - подгружаются все товары магазина и кладутся в переменную;

2) При взаимодействии с фильтрами и сортировками - JavaScript выполняет манипуляции с данными и выводит их пользователю;

В терминологии lodash коллекция - это набор объектов(сущностей), который заключен в массив. В данном случае наши товары являются сущностями, а массив с товарами - коллекцией. Таким образом мы можем применять все методы для коллекций из существующих в Lodash. Наши товары будут представлены в виде объектов и собраны в коллекцию вида:


var products = [
    {
        id: 0,
        name: "Товар 1",
        price: 1200,
        color: "Красный",
        размер: "XL"
    },
    ....
]

Lodash хранится в переменной _. С технической стороны: переменная _   - это объект Lodash, который содержит в себе множество методов (свойств).  Из этого следует что к переменной Lodash можно обращаться как к обычному объекту, используя "_.", таким образом для вызова функции "filter" нам потребуется написать следующее "_.filter(...)". Это важно для понимания и правильного восприятия структуры библиотек, во избежание эффекта "абракадабры" для разработчика (я написал вот так, а оно там как-то само все сделало). 

Для реализации задумки необходимо вывести два фильтра и одну сортировку:

  1. по цвету;
  2. по размеру;
  3. сортировка по цене.

Дабы сильно не заморачиваться, я сделал простые