2 июня 2011 в 18:21

Восстановление изображений при помощи нейросетей из песочницы


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

Как же это работает?


Карта Кохонена представляет из себя двухмерную сетку NXxNY, состоящую из нейронов. Каждый нейрон в сетке представляется квадратиком SxS — этот квадратик называется вектором веса, значения которого равны цвету соответствующего пикселя.
Для обучения в сеть подаются фрагменты изображения SxS, после чего сеть ищет самый похожий на этот фрагмент нейрон, так называемый BMU (best matching unit), и подгоняет его весовые коэффициенты таким образом, чтобы он еще больше был похож на поданный фрагмент. А потом еще тренирует соседей, но уже с меньшей интенсивностью. Чем дальше отстоит нейрон от BMU, тем меньший вклад на него оказывает поданный фрагмент. Так сеть обучается до тех пор, пока отклонения BMU для каждого поданного фрагмента достигнет некоторой минимальной величины.
Вот пару примеров, на первой картинке представлена сеть 120х120 с нейронами 3х3, а на втором рисунке сеть 24х24 с нейронами 15х15. Красота!

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

Как нейросеть «видит» картинку?


Чтобы посмотреть как нейросеть «видит» картинку, я придумал следующий метод. Берем обученную нейросеть, и для каждого пикселя в картинке создаем фрагмент SxS, подаем его в нейросеть, извлекаем из нее цвет центрального пикселя и записываем этот цвет по тем же координатам, но в новую картинку. Полученная в результате картинка отражает потенциал восстановления изображения данной нейросетью. Для экспирементов я использовал такую картинку



Благодаря этому методу я выявил несколько интересных свойств.
  1. Чем больше размер S — тем менее четким получается изображение
    На рисунке показаны изображения созданные с нейронами 3х3 и 15х15. Как видно, 3х3 вообще мало чем отличается от оригинала. В 15х15 уже получается размазанным.

  2. Чем больше нейронов в сети, тем больше палитра цветов.
    На первой картинке использовалась сетка 4х4, и 120х120 на второй. Как видно, в сети 4х4 переходы между цветами резкие.

  3. Чем больше итераций обучения, тем точнее восстановленные цвета соответствуют цветам реальной картинке и тем лучше видны детали. На первой картинке использовалась нейросеть 10x10, обученная на 10 фрагментах, а на второй на 10000 фрагментах.



Кстати, обратите внимание, восcтановление хорошо обученной сетью 10х10 и 120х120 визуально очень слабо отличаются, только если сильно присмотреться к деталям можно найти небольшие отличия.
Я оформил генератор в виде небольшого приложения, так что можно побаловаться самим (проверял на webkit и FF).

Восстановление небольших случайных повреждений


Небольшие случайные повреждения легко устраняются сетями с маленькими нейронами, например 3х3 или 5х5 вполне достаточно. Они работают быстро и качественно. Вот пример восстановление изображения в котором повреждено 25% пикселей, сетью 10x10 и нейронами 5х5



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

Восстановление крупных областей


Чтобы восстановить крупные поврежденные участки, нужно, чтобы размер нейрона S превышал размер поврежденной области. Соответственно, чем больше размер повреждений, тем более размазанным будет восстановленный участок.
На рисунке показано восстановление фрагмента 10х10 сетью с нейроном 15х15



Восстановление при <20% известных пикселей


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


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

UPD: о практическом применении, разработанных мною, приложений:
Целью моего исследования является проверить концепт, а не предоставить рабочее приложение на все случаи жизни, поэтому все разговоры о каком-либо серьезном практическом применении той версии, которая существует на сегодняшний день, не имеют никакого смысла.
Andrey @vol4ok
карма
15,0
рейтинг 0,0
Похожие публикации
Самое читаемое Разработка

Комментарии (37)

  • +5
    Чтото не совсем понял. В тесте на востановление картинки, мы сначала обучаем нашу нейросеть картинкой, а потом скармливаем ей эту же картинку, но в которой допущены дефекты и радуемся как же хорошо у нас все востановилось?

    Гораздо интереснее было бы обучать нейросеть набором похожих картинок (пожих для того чтобы получить результаты уже после скажем пары сонет обучений, а не пары милионнов). А потом скормить ей дефектную картинку, которой не было в обучаемом наборе
    • 0
      У меня есть опасение что чем больше будет вариантов картинок тем меньше будет сходимость процесса обучения нейросети. В итоге будет только хуже. Но действительно было бы интересно посмотреть что получится.
    • 0
      > Гораздо интереснее было бы обучать нейросеть набором похожих картинок
      Я бы сказал не «гораздо интереснее», а «только так и надо». Иначе это не восстановление изображения (какого-либо), а имитация того, что сетке скормлено.
  • +2
    Не совсем, так как вы описали происходит только в последнем случае, когда повреждено более 80% процентов изображения. В остальных случаях сеть обучается по целым участкам поврежденного изображения.

    > Гораздо интереснее было бы обучать нейросеть набором похожих картинок
    Да, сам метод позволяет так делать, в чем его большой плюс. Если, например, взять последний случай с >80% процетов повреждений, и натренеровать сеть на похожих картиках листьев в лесу, то полученной сетью можно будет востановить поврежденную. Но я таким пока не занимался.
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Зависит от конкретного изображения и требуемого качества.
        Например, в данном случае бралось изображение 550x400, это 220000 пикселей. Сеть 10х10 может с нейронами 3х3 может адекватно востанавливать 15% случайных повреждений, это 33000 пикселей х 3 канала RGB получаем 99к. Сама сеть занимает 3*3*10*10=900 на три канала это 2,7k. Итого (220k-99k+2,7k)/220k = 56% по сравнению с первоначальным объемом. JPG на 80% качества дает вес примерно 123k, что сравнимо по размеру с объемом «часть картинки+сеть»
        • 0
          сорри, ошибся чуток (660k-99k+2,7k)/660k = 85%, хуже чем JPG
  • +3
    А может ли такая нейросеть увеличивать размер изображения? Например из 500*500 сделать адекватно 1000*1000?
    • +3
      Хороший вопрос. Надо попробовать.
      • 0
        Попробовал увеличивать в 4 раза. Увеличивать можно, но добиться качества лучше чем при обычном увеличении в каком нибудь фотошопе, увы, не удалось. Среднеквадратическое отклонение от оригинала при увеличению сетью получалось в 2-3 больше чем при обычном увеличении.
        Хотя, я исслеледовал только самые очевидные алгоритмы увеличения сетью, думаю, что если применить более изощренные, то можно улучшить показатели, хотя очень сомневаюсь что, увеличивая сетями, можно превзойти обычные методы.
    • +1
      Я очень давно видел утилитку которая на основе фрактальных алгоритмов делала ресайз в большую сторону круче всяких бикубических сплайнов. Это не про нейросети, но просто к слову :)
      • 0
        Была раньше хороший фрактальный распиратель — GF Print Pro, в том числе и как плагин к фотошопу.
  • 0
    Будьте добры, восстановите вот это изображение: habrastorage.org/storage/29e15dc9/a9992df3/e906c8d1/a48b6131.jpg
    Очень интересен результат.
    • 0
      Мне не понятно, что вы хотите восстановить в вашем изображении. Восстановления подразумевает повреждения, в вашем изображении же все пиксели на месте. Зашумленность и смазанность мой алгоритм не устраняет.
      Написанное мною приложение генерирует повреждение само, по заданным условиям, если вы это имели в виду — то вот вам, версия с вашим изображением dl.dropbox.com/u/159112/som-restore/restore-alman.html

      И еще. Даже если вы мне предоставите изображения с повреждениями, то я не смогу его восстановить в имеющемся приложении. Для восстановления, приложению необходимо иметь маску повреждений. Когда я генерирую повреждения, то я получаю маску. В случае же уже поврежденного изображения необходимо создавать эту маску отдельно, для этого нужно иметь: во-первых, критерии, по которым приложение смогло бы определить целый пиксель от поврежденного, во-вторых, алгоритм, который бы на основании критерия генерировал эту маску. Ни первого ни второго я пока не делал.
      • 0
        То есть, чтобы алгоритм работал мы должны ему скормить поврежденную картинку с неповрежденной, что бы была вычислена маска повреждений, а потому неким магическим образом (вычитанием?) получится обратно неповрежденная картинка? Прикольно.
        • 0
          Не совсем так, дается неповрежденная картинка, потом она же повреждается и она же восстанавливается. Маска создается во время генерации повреждения.

          Если вам кажется что это бессмысленно, то я поясню:
          Целью моего исследования, является проверить концепт, а не предоставить рабочее приложение на все случаи жизни, поэтому все разговоры о каком-либо серьезном практическом применения той версии, которая существует на сегодняшний день, не имеют никакого смысла.
          • –1
            > Целью моего исследования является проверить концепт
            Какой концепт</> Какую концепцию вы собираетесь проверить? Сможет ли алгоритм повредить изображение, а потом самостоятельно свои косяки как-то исправить (полностию или частично)? Смысл в этом? Чтобы получить стопроцентный результат в такой ситуации заведомо выгоднее выбирать самое тривиальное решение — не портить изображение вовсе. Как такая концепция? Ее и проверять не требуется.

            Отнеситесь адекватно… я просто понять не могу сути.
            • 0
              УПС… С тегами налажал.

              Какой концепт Какую концепцию вы собираетесь проверить? Сможет ли алгоритм повредить изображение, а потом самостоятельно свои косяки как-то исправить (полностию или частично)? Смысл в этом? Чтобы получить стопроцентный результат в такой ситуации заведомо выгоднее выбирать самое тривиальное решение — не портить изображение вовсе. Как такая концепция? Ее и проверять не требуется.

              Отнеситесь адекватно… я просто понять не могу сути.
              • 0
                > Какую концепцию вы собираетесь проверить?
                Возможно ли восстанавливать изображения при помощи самоорганизующися карт Кохонена.

                > Сможет ли алгоритм повредить изображение, а потом самостоятельно свои косяки как-то исправить (полностию или частично)? Смысл в этом?
                Вы, судя по профилю программист, вот попробуйте ответить на следующие вопросы, а потом я отвечу ваши:
                1) Вам на вход подано изображение с поврежденными пикселями и требуется на выходе выдать все координаты этих поврежденных пикселей. Можете мне привести алгоритм, которым вы будете их искать?
                2) Если да, то скажите сколько у вас времени займет чтобы написать этот алгоритм?
                • 0
                  > 1) Вам на вход подано изображение с поврежденными пикселями и требуется на выходе выдать все координаты этих поврежденных пикселей. Можете мне привести алгоритм, которым вы будете их искать?
                  > 2) Если да, то скажите сколько у вас времени займет чтобы написать этот алгоритм?
                  Мы начинаем скатываться в «Ad hominem».
                  > И вообще, разве нас может интересовать мнение человека лысого, с таким носом? Пусть сначала исправит нос, отрастит волосы, а потом и выскажется.

                  1) Ответ на вопрос: «За сколько это сделаю Я», не разрешит нашу, невольно затеявшуюся, полемику.
                  2) Если б я взялся за эту проблему, то начал бы сначала с постановки задачи.

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

                  Если применение сети Кохонена кардинально меняет подход к решению подобных задач, то разъясните почетче Вашу постановку задачи. Если я недостаточно углубленно изучил статью, то укажате, где в тексте есть разъяснения.
                  • +1
                    Сам себе и отвечу пожалуй… Нужно было в посте ключевые моменты работы именно восстановления описать, а я наблюдаю в нем только про обучение и то очень кратко и расплывчато.

                    > Восстановление производится итерационно, как и обучение. При восстановлении из наборов векторов наблюдаемых данных выбирается случайный вектор, в котором поврежденным является только один пиксель.
                    > Для данного вектора ищется BMU, однако метрика поиска в этом случае изменяется
                    > Таким образом из всех векторов весов выбирается наиболее «похожий», без учета компоненты, соответствующей поврежденному пикселю.
                    > После того, как BMU найден, поврежденный пиксель на изображении заменяется на соответствующий из вектора веса нейрона.
                    > Данная процедура повторяется до тех пор, пока на исходном изображении не будет ни одного поврежденного пикселя.
                    • 0
                      Рад, что вы сами разобрались, так как мне было не совсем понятно чего же хотите.

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

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

                        Так и надо было, но не только об обучении, но и о самом восстановлении (т.е. о работе, о главном). Да и не написано «простым языком» и доходчиво про то как формируется обучающая выборка. Опять же только из статьи вычитал, что нужно сделать выборку эталонных фрагментов картинок (т.е. нарезку типичных фрагментов из схожих или одного изображений), затем скормить эту выборку «детищу Хофмана». А затем уже (само)обученную сетку натравливать на поврежденное изображение.
                        Вот что и нужно было описывать «просто, на пальцах». Тогда б статья была ценной. А так получается больше на ссылку на другую статью.

                        Там, кстати, в упоминаемой работе вскольз упоминается, что данный подход можно использовать для сжатия. Вот еще одна тема, думается, достаточно востребованная.
  • 0
    Чтото ни как не разберусь как программе из статьи скормить совю картинку
    • 0
      Никак, я не делал функции загрузки своих изображений. Если вам очень хочется попробовать алгоритм на свом изображении, то вы можете скачать страницу и вставить в html-код (js-код, в случае генератора) ссылку на свое изображение.
  • 0
    Два вопроса:
    1) Есть ли статья на которую вы ссылаетесь в формате pdf? — слишком жуткий HTML на сайте.
    2) Как вы думаете — возможно ли применить данный алгоритм для задачи генерации «похожих» картинок — например берем космический снимок, обучаем на нем алгоритм, а потом генерируем похожие на него снимки.
    • 0
      1) да, есть — dl.dropbox.com/u/159112/som-restore/article.pdf
      2) думаю, что можно, но для этого необходимо уметь генерировать какие-либо базисные пиксели, на основании которых сеть будет выбирать подходящие нейроны.
      • 0
        Спасибо, очень интересная штуковина.
  • 0
    Как плагин фотоэффектов для фотожабы, ИМХО, действительно интересно.
    [irony/] по вкусу…
  • 0
    Попробуйте пожалуйста вот такой эксперимент:
    С генерируйте картинку из белого шума размера 256 на 256 — без разницы, цветную или нет.
    Пусть размер повреждения будет 16 на 16 пикселей — просто потеря объекта (черным) и 32 на 32.
    Какие результаты восстановления будут в этом случае?
    • 0
      Думаю на глаз вы не увидите разницы. В статье, на которую дана ссылка в самом начале хорошо проиллюстрированы результаты работы в сравнении с бикубическим восстановлением. Хорошо видно, что изображения с большим колличеством абстрактных деталей (листочки всякие и т.п.) «на глаз» — восстановление замечательное. Но вот с фото людей алгоритм несправился — вместо головы человека — смазанное пятно.
    • +1
      Походу, шум немного сглаживается, и поэтому восстановленный участок выделяется на общем фоне. А что выхотли проверить в этом эксперименте?

      Вот тут можете поэкспериментировать сами:
      dl.dropbox.com/u/159112/som-restore/restore-AndreyIvanoff.html
      • +1
        Огромное спасибо, хотел оценить потенциал данного метода для сжатия изображений. Поэкспериментировал с программкой, не удаляйте ее некоторое время пожалуйста. Возникли идеи по применению этого к иерархическому представлению и сжатию картинок.
  • 0
    Интересно применение данного алгоритма для ретуши фото, получается что можно сделать кисть которая помечала бы участок как поврежденный и восстанавливала его.
  • 0
    Насчет восстановления не знаю насколько хорошо, но во как фильтр для размытия или масляной кисти выглядит отлично.
  • 0
    Можете плз в свой скрипт добавить функционал «Количество проходов»? Интересно, что будет, если его восстанавливть несколько раз.
  • +3
    > По-моему весьма неплохо получилось, для такого объем повреждений.

    А по-моему это никуда не годится. Вот что получилось у вас с нейросетью, обученной на абсолютно целом исходном изображении:


    А вот что получается простым наложением известных цветов на произвольные места холста:

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