Список форумов Форум Форум
Форум
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   medals.phpНаграды   РегистрацияРегистрация 
 ПрофильПрофиль   СудокуСудоку   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

Однослойный персептрон на PHP (10 нейронов). Работает :)))
На страницу Пред.  1, 2, 3
 
Начать новую тему   Ответить на тему    Список форумов Форум -> Наука и технологии
Предыдущая тема :: Следующая тема  
Автор Сообщение
Slav
Мастер-Флудер I
Мастер-Флудер I


Репутация: +16    

Зарегистрирован: 06.06.2006
Сообщения: 9703
Откуда: КиевЪ
Награды: Нет

СообщениеДобавлено: Пт Янв 03, 2020 11:59 am    Заголовок сообщения: Ответить с цитатой

Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Rasty
Crackpot


Репутация: +88/–10    

Зарегистрирован: 23.05.2006
Сообщения: 22187

Награды: Нет

СообщениеДобавлено: Пт Янв 10, 2020 1:47 pm    Заголовок сообщения: Ответить с цитатой

Ебусь

Короч, сча попробую сформулировать задачу, над которой уже вторую неделю мучаюсь размышляет о_О

В обычной нейросети (персептроне), каждый нейрон связан со всеми входами через свои весовые коэффициенты (которые определяются во время обучения нейросети). Картиночку выше рисовал с одним нейроном:

Admin писал(а):


По затратам времени на вычисления, штука эта весьма прожорливая. Например, если на входе у нас картинка размером 100х100 пикселей, и в скрытом слое 100 нейронов - нам надо определить 100х100х100=1000000 весовых коэффициентов. И это только для одного слоя нейросети.

Существует более крутая штука, чем персептрон - сверточная нейронная сеть. Фактически, это сейчас самый ТОПчик - AlphaGo реализован с помощью сверточной нейронной сети. Deepfake, который сейчас весьма популярен, реализован с помощью сверточной нейронной сети.

В сверточной нейронной сети есть две ключевые операции - свертка (convolution) и субдискретизация (subsampling, pooling).

Свертка:



В сверточной сети у нас есть ядро свертки (kernel) - это фактически матрица с весовыми коэффициентами, которую мы определяем во время обучения сети.

Что мы с этим ядром делаем? Берем входной слой (изображение, например). Во входном слое берем каждый элемент с координатами x и y. Вокруг элемента выделяем область с тем же размером, что и ядро свертки. Далее умножаем каждый элемент входного слоя на соответствующий элемент ядра свертки. Суммируем. Сумму записываем в те же координаты (x и y) в выходном слое. (С граничными условиями пока не ясно - я так понял, с ними никто особо не заморачивается).

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

На примере того же котяры. Оригинальный котяра сверху. Внизу 12 котяр свернутых рандомными свертками (размер ядра 5х5):



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

Вторая ключевая операция - субдискретизация (pooling). Эта операция сжимает картинку. Была картинка 100х100, стала 50х50. Есть два вида:



Разбиваем картинку на непересекающиеся квадратики 2х2. Далее на выбор: или берем максимальное значение в пределах каждого квадратика, или считаем среднее арифметическое. Чаще всего используют первый вариант (максимальное значение).

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

Схема сверточной нейронной сети:



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

В чем самый кайф сверточных нейронных сетей?

Входной слой, для удобства, можно рассматривать в виде вектора. То есть, берем исходную картинку пиксели записываем в виде строки (на самом деле столбца, если говорить о векторах). Например, картинка 5х5, пиксели пронумеровал, записал в виде строки:



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

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



Берем первый элемент входного вектора, умножаем на элемент E ядра свертки, к нему прибавляем элемент 2 умноженный на F, элемент 3 умноженный на 0, элемент 4 умноженный на 0, элемент 5 умноженный на D и т.д.

Для остальных элементов выходного вектора:



Получили матрицу. Умножаем эту матрицу на входной вектор - получаем выходной вектор.

Операция умножения матрицы на вектор обратима. Это система линейных уравнений. Линейные уравнения научились решать еще древние китайцы династии Чжоу (X век до н.э. — III век до н.э.). Система линейных уравнений имеет одно решение, если определитель (детерминант) матрицы (которую я выше нарисовал) не равен нулю и множество решений - если определитель равен нулю.

То есть, решив систему линейных уравнений, можно найти для выходного вектора входной вектор.

Или проще: картинку можно свернуть и можно развернуть обратно.

Со сверткой разобрались - она обратима. Вторая операция, субдискретизация - необратима из-за того, что мы проебуем часть информации (которую считаем несущественной). Для max pooling мы проебуем 3 значения и проебуем позицию, где находилось максимальное значение. В принципе, тут довольно широкая область для экспериментов - как заебошить хороший анпулинг и как тот или иной анпулинг будет влиять на конечный результат.

Короч. Взяли сверточную нейросеть. Обучаем ее отличать кошек от собак. Даем сетке картинку, на выходе персептрон с двумя нейронами. Один говорит, что это на 99% кошка, второй говорит, что это на 5% собака. Погрешность в пределах нормы - сеть обучилась.

Ебошим в обратную сторону. Говорим нейросети: нарисуй нам на 50% кошку и на 50% собаку. На выход персептрона кидаем эти значения. Пробежались по весовым коэффициентам на вход перспетрона. Получили массив чисел (скаляров) - таких же, которые получаем в процессе сверток и пулинга. Для каждого числа делаем анпулинг каким-нить выбранным способом. Дальше разворачиваем через ядра свертки, которые получили в процессе обучения. Дальше опять анпулинг, развертка, анпулинг, развертка, ... Получаем на 50% кошку, на 50% собаку.

Чисто навскидку. В одну сторону процесс выглядит так:



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

В обратную сторону можно сделать, например так:



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

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

Умею пользоваться тремя методами - матричным методом и методами Крамера и Гаусса.

Метод Крамера исключительно муторный - для каждого значения в выходном векторе надо считать детерминант матрицы (вот той сверточной матрицы, которая выше - E,F,0,0,D,H,I,...). Причем, если слой размером 100х100, выходные и входные вектора тогда размером 10000, размер сверточной матрицы тогда будет 10000х10000 и посчитать детерминант такой не детской матрицы (в универе мы 3х3 матрицы считали) придется 10001 раз. 1 раз - детерминант сверточной матрицы и 10000 раз детерминант, заменяя в сверточной матрице соответствующий столбец выходным вектором. Не реально.

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

Матричный метод - самый шустрый. Суть:
Есть у нас входной вектор x, выходной вектор y и матрица A. Умножение (матричное) матрицы на вектор запишем так:



Существует обратная матрица - такая, умножение которой на матрицу A даст единичную матрицу E:



Единичная матрица - это матрица, в которой везде нули, кроме главной диагонали, на которой единицы. Умножив единичную матрицу на вектор получим тот же вектор:



Умножаем правую и левую часть на обратную матрицу:



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



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

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

Самое главное преимущество матричного метода в том, что нам один раз надо найти обратную матрицу: обучили сеть, получили ядра свертки, для каждого ядра свертки один раз нашли матрицу развертки. Дальше умножаем любой выходной вектор на матрицу развертки и получаем входной вектор. Операция умножения матрицы на вектора - такая же шустрая, как и операция свертки. В методах же Крамера и Гаусса, нам каждый раз надо пересчитывать всю матрицу.

В матричном методе есть и недостаток. Если детерминант матрицы равен нулю - этот метод не работает.

Как же ту рекурсию сделать-то В принципе, можно убрать граничные условия (нахуя нам тот тор), чтобы было меньше заебов:



Тяжело. Пойду лучше бутерброд слопаю.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Slav
Мастер-Флудер I
Мастер-Флудер I


Репутация: +16    

Зарегистрирован: 06.06.2006
Сообщения: 9703
Откуда: КиевЪ
Награды: Нет

СообщениеДобавлено: Пт Янв 10, 2020 3:13 pm    Заголовок сообщения: Ответить с цитатой

Это не для среднего ума, жесть.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Rasty
Crackpot


Репутация: +88/–10    

Зарегистрирован: 23.05.2006
Сообщения: 22187

Награды: Нет

СообщениеДобавлено: Вс Янв 12, 2020 11:37 am    Заголовок сообщения: Ответить с цитатой

Матрицу развертки пока не посчитал. Чтобы ее посчитать - надо очень много травы скурить. Но чисто поиграться - можно и без нее. Короч, схемка та же:

Admin писал(а):
В обратную сторону можно сделать, например так:



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


Вместо развертки сделал со сверткой. На входе массив состоящий из 16384 значений (4 в седьмой степени). Элементы массива групируются по 4, делается unpooling, дальше четыре свертки через 4 сверточных ядра (для всей системы всего 4 ядра используется, сгенерированных рандомно в самом начале, значения от -16 до 16, целые числа). Дальше средние значения. Все это циклически повторяется 7 раз.

Для входного массива [1, 0, 0, 0, 0, 0, ...] - первый элемент 1, остальные нули:



Черные пиксели - отрицательные значения, белые - положительные.

Для входного массива [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 ...] - чередуются 1, 0, 0, 0:

Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Rasty
Crackpot


Репутация: +88/–10    

Зарегистрирован: 23.05.2006
Сообщения: 22187

Награды: Нет

СообщениеДобавлено: Пт Авг 14, 2020 10:05 am    Заголовок сообщения: Ответить с цитатой

Весьма забавная xуйня получается

Короче свёртка, всего одно ядро. На поверхности тора, естессно, как в клеточных автоматах - пиксели за левой границей берем на границе справа (для остальных границ - соответственно). Берем картиночку 2х2 пикселя. Делаем свертку. Дальше увеличиваем картиночку до 4х4 пикселей - делаем копию пикселя 4 раза в квадратике 2х2 вокруг пикселя. После нескольких итераций очень быстро уёбует в +-бесконечность, поэтому ставим ограничение (от балды) 16 сверху и -16 снизу.

Получаются вот такие зверушки:



Свертку делали с граничными условиями, поэтому зверушка находится на поверхности тора:



Крупным планом:



Если в ядре заменить один элемент на случайный:



Или на другой случайный:



Охуенно то, что таким же xуем можно сделать свертку в 3-х измерениях и третье использовать как время - тогда зверушки начинают двигаться. Пока хорошую зверушку в трех измерениях не нашел - гифку не из чего лепить. Можно туда генетический алгоритм прикручивать для поиска.

Spoiler:


3d нормально так выедает

Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Slav
Мастер-Флудер I
Мастер-Флудер I


Репутация: +16    

Зарегистрирован: 06.06.2006
Сообщения: 9703
Откуда: КиевЪ
Награды: Нет

СообщениеДобавлено: Пт Авг 14, 2020 11:36 am    Заголовок сообщения: Ответить с цитатой

xуй его знает как оно вот так вот у тебя получилось, но да, красиво смотриться)
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Начать новую тему   Ответить на тему    Список форумов Форум -> Наука и технологии Часовой пояс: GMT
На страницу Пред.  1, 2, 3
Страница 3 из 3

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


Powered by phpBB © 2001, 2005 phpBB Group
Русская поддержка phpBB