Предыстория такова. Прочитал книгу Тарика Рашида
"Создаем нейронную сеть" и написал свою маленькую библиотеку для экспериментов с нейросетью. В книге используется язык Python, что и вам советую. Я использовал язык Pixilang, это мой выбор, никаких преимуществ он не даёт, зато я к нему привык. Затем прочитал несколько статей в интернете и внёс в свой код небольшие правки.
Здесь описывается самая простая классическая нейронная сеть, сейчас чаще используют куда более сложные архитектуры.
Целью экспериментов является проверка, что код работает, желание "пощупать" нейронную сеть на низком уровне, понять её возможности и ограничения. Никаких прикладных задач не ставилось, эксперименты
just for fun.
Эксперимент 1
Итак, у нас имеется фрагмент изображения, его размеры 26 на 26 пиксель. Удаляем центральную часть 20 на 20 пиксель и у нас осталась кромка, шириной всего в 3 пикселя.
Задача нейросети - восстановить потерянную центральную часть.
Эту задачу я выбрал потому, что нет необходимости готовить базу с размеченными данными для обучения. Для этого подойдёт любая фотография.
На вход нейросети поступает 276 пикселей, а на выходе нейросети получаем 400 пикселей. Каждый пиксель - это три байта, красная, зелёная и синяя составляющая пикселя, поэтому, кажется, что необходимо 276*3=828 входных нейронов и 400*3=1200 выходных нейронов.
Но мы оставим 276 входных нейронов и 400 выходных и будем каждый фрагмент прогонять по сети 3 раза, каждый канал отдельно (RGB - красный, зелёный, синий). Затем, на выходе, объединим полученные каналы в одно изображение.
Делаю я это из предположения, что цвета действуют одинаково. Если на кромке есть фрагмент полосы сверху и снизу, то полоса есть и по отсутствующей центральной части. Это одинаково и для красного канала и для зелёного и для синего.
По возможности, нужно стараться уменьшить размеры нейросети, так как объём вычислений возрастает нелинейно c увеличению размеров сети.
Для примера:
Сеть состоит из 2 входных и 2 выходных нейронов.
Связей между нейронами - 4, именно количество связей определяет объём вычислений. Если нужно делать 3 прохода, то требуется обработка 4*3=12 связей.
Если сделать сеть из 6 входных и 6 выходных нейронов, то даже с одним проходом, необходимо обработать 36 связей, что уже в три раза больше.
У меня получилась сеть: 276 входных нейронов, 2 скрытых слоя по 300 нейронов и выход - 400 нейронов. В качестве функции активации используется модифицированная Leaky RELU.
На вход подавал значения яркости цвета пикселя, делённое на 255, что бы привести значение к диапазону от 0 до 1. На выходе полученное значение (0..1) умножал на 255, что бы получить необходимый диапазон от 0 до 255.
Сразу замечу, что здесь нейросеть не генерирует изображение, а показывает наиболее статистически вероятный цвет отсутствующих пикселей. Для генерации используют намного более сложные архитектуры сети ( Генеративно-состязательная сеть).
Хотя я пытался генерировать узор с помощью простой нейросети (неудачно), но об этом в следующий раз.
Для восстановления фрагмента 20 на 20 пикселей используется кромка, шириной всего в 3 пикселя, так что чудес не ждите.
Каждый маленький квадратик - это один пиксель.
Слева - исходный фрагмент 26*26 пиксель, на нейросеть подаётся только кромка в 3 пикселя.
Справа - кромка, которая подавалась на нейросеть и по центру то, что выдала нейросеть. Можно сравнить центральные части обоих изображений, что бы оценить результат работы нейросети.
Ещё, для примера, результат с одним и тем же фрагментом на разных фазах обучения.
Во время обучения заметил один момент. Если в обучающих примерах подряд, на одном и том же месте идёт ярко выраженный объект, то после его исчезновения, он некоторое время остаётся на выходе сети.
То же самое, как со зрением. Если смотреть в темноте на экран, то потом, некоторое время, перед глазами будет стоять прямоугольник.
Я брал обучающие примеры последовательно с фотографии и на 34 примерах была черная полоса. Что произошло дальше, смотрите на картинках. Слева, сразу после того, как в обучающих примерах исчезла полоса, а справа - через 9 обучающих примеров.
Полоса долго не исчезала, она то бледнела, то снова становилась хорошо заметной и постепенно сошла на нет.
Как решить эту проблему? Мои варианты.
- Брать обучающие фрагменты в случайном порядке
- Поворачивать обучающие примеры
- В конце обучения прогнать нейросеть через однотонный рисунок без ярко выраженных элементов
На сегодня всё. Следующие эксперименты в следующих статьях.
Видео с четырьмя экспериментами. Эксперимент из этой статьи идёт первым.
Подписывайтесь, ставьте лайки, пишите свои варианты экспериментов, возможно я их реализую.
Пока.
foo52ru