Класифікація зображень за допомогою ЗНМ

16 хв. читання

Всім привіт! Сьогоднішня моя стаття буде про дипломний проект, який я захистив буквально декілька днів тому 😁 Отже, трохи ознайомлю вас зі справою.

На нашій кафедрі КІ (комп'ютерна інженерія) був проект по аналізу біомедичних зображень, що тривав 2 роки. Завданням цього проекту було створити систему автоматизованої мікроскопії (САМ) для допомоги лікарям-онкологам у їхній роботі. Мені було потрібно розробити програмний модуль для класифікації біомедичних зображень використовуючи ЗНМ (згорткові нейронні мережі) з метою діагностування передракових станів молочної залози. Що з цього вийшло та які складнощі мені довелося подолати я розповім далі. Отож, поїхали!

Передмова

Що таке біомедичне зображення? Якщо по-простому, то

Біомедичне зображення — анатомо-функціональний образ органів людини.

Ми працювали з двома видами таких зображень: цитологічні (зображення клітин) та гістологічні (зображення тканин).

Класифікація зображень за допомогою ЗНМ
Цитологія
Класифікація зображень за допомогою ЗНМ
Гістологія

Ці зображення були отримані з камери мікроскопа. Як бачите, гістологічні зображення є «складнішими» за структурою, ніж цитологічні, а також вони значно нижчої якості та чіткості. Цей факт значно вплинув на розроблену модель ЗНМ, але це ви побачите згодом.

Стаття не є гідом для побудови нейронної мережі, тобто я не буду занурюватися у деталі, оскільки стаття не про те, як працюють нейронні мережі. Буду старатися пояснити основні, на мою думку, моменти, розповім про власний досвід використання ЗНМ, проблеми з якими зіткнувся і шляхи їх вирішення.

Отож, розпочнемо здалеку 😀

Вступ

Недавно на Codeguida були дві цікаві новини про штучний інтелект: «У Facebook придумали AI, що перетворює один стиль музики на інший» та «AI розпізнає людину за ходою». Тобто дуже великої популярності набуває застосування нейронних мереж та й взагалі штучного інтелекту в різних сферах суспільства та економіки. Особливої актуальності набувають задачі класифікації різного роду інформації. Зокрема, для класифікації зображень використовують згорткові нейронні мережі, про які сьогодні й піде мова 🙄.

Якщо ви вирішили використовувати нейронну мережу у своєму проекті, то рано чи пізно перед вами постане проблема дуже великого часу навчання вашої моделі. Тому, для розв'язку цієї проблеми використовують різні технології пришвидшення обчислень. Другим моїм завданням було пришвидшити навчання моєї моделі, яку я тоді ще навіть не розробив. Та що там казати, тоді я й уявлення не мав про нейронні мережі, а тим більше про ЗНМ 😅

Графічні процесори, як універсальний засіб прискорювання

Приблизно з 2003 року ГП почали застосовувати для «неграфічних обчислень» (симуляція фізики, обробка сигналів, різні інженерні розрахунки). Це почали робити тому, що графічні процесори у декілька разів (а сучасні ГП і у декілька десятків разів) перевершують ЦП за обчислювальною продуктивністю. Зараз на ринку існують дві компанії, які випускають відеокарти: можна сказати вічні конкуренти — Nvidia та AMD (нещодавно читав новину про те, що Intel ніби планує повернутись на ринок до 2020 року).

Отож, все було ніби круто, розробники почали використовувати графічні процесори для обчислень, проте, головною проблемою залишалося те, що не було єдиного інтерфейсу для їх програмування. Тоді використовували OpenGL та Direct3D 😏 І що ви думаєте? Компанія Nvidia розробляє власну технологію для програмування ГП, що називається CUDA. Хто ще не читав мої статті про CUDA — можете зробити це тут і тут. На мою думку, єдиним мінусом CUDA є те, що з її допомогою можна програмувати тільки графічні процесори компанії Nvidia, які зараз не є дуже дешеві.

Отже, на кафедрі мені вручили відеокарту компанії Nvidia (GTX 950), дуже хорошу книжку Роберта Каллана, що називається «Основні концепції нейронних мереж» та побажали удачі з дипломним проектом 😂.

Вибір бібліотек машинного навчання

Після того, як я прочитав книжку та отримав основні знання про нейронні мережі, я передивився багато відеоуроків та прочитав багато статей на різних ресурсах для того, щоб зрозуміти як і для чого люди застосовують їх на практиці. В основному всі писали на Python та використовували Tensorflow або Keras. Оскільки на кафедрі ми писали на Java, то мені було важливо знайти бібліотеку саме для неї. Після проведення аналізу наявних бібліотек машинного навчання я склав таблицю в якій наведено найбільш популярні з них на даний час (це суто моя думка).

Бібліотека Мова
Tensorflow Python/Java/JS
Keras Python
DL4J Java
Torch Python
Theano Python

Свій вибір я зупинив на бібліотеці Deeplearning4j (DL4J), яка сподобалася мені своєю елегантністю та простотою. Чому не Tensorflow? На мою думку, він трохи складний для початківців, має складне API. Якщо ви вирішите займатися нейронними мережами на Python, то я б радив почати з Keras, оскільки він дуже простий у вивченні. При використанні Keras, ви можете використовувати в ролі бекенду як Tensorflow так і Theano, оскільки Keras — високорівневий, багатофункціональний API.

Отже, завантаживши бібліотеку та відкривши тестовий приклад по класифікації, я намагався зрозуміти код, зрозуміти процес навчання даної мережі, а головне — чому це працює? 😏.

Навчання нейромережі

Сама собою нейромережа не варта абсолютно нічого, якби дивно це не звучало 😆. Для того, щоб вона могла видавати якийсь результат – її потрібно навчити. Взагалі, що таке навчання нейромережі? Це процес, в якому її параметри налаштовуються за певним алгоритмом (цей алгоритм називається алгоритмом навчання) таким чином, щоб вона на виході давала правильні результати. Розрізняють алгоритми навчання з вчителем та без вчителя.

Класифікація зображень за допомогою ЗНМ
Розподіл алгоритмів навчання нейромереж

Процес навчання з вчителем застосовується тоді, коли вхідні дані вже розділені на певні класи. Тобто нейромережа знає правильні відповіді й на їх основі підлаштовує свої параметри. Для прикладу візьмемо класифікацію цифр. Оскільки цифр є 10, то у нас є і 10 класів 🙄. Отже, на вхід нейромережі поступає зображення. Далі, після «магії», що відбувається всередині, на виході ми отримуємо клас даного зображення. Оскільки для кожного вхідного зразка нейромережа знає правильну відповідь, то за допомогою функції втрат ми можемо порахувати помилку, тобто різницю між виходом нейромережі та правильним результатом, а вже після цього підкоригувати вагові коефіцієнти. Ці кроки повторюються, поки помилка не буде в допустимих межах (або не закінчиться кількість епох). Якщо вхідні дані розбиті на класи, то ми вирішуємо задачу класифікації. Класичними алгоритмами навчання є алгоритм зворотного поширення помилки та метод градієнтного спуску, які і було використано.

Класифікація зображень за допомогою ЗНМ
Процес навчання з вчителем

При навчанні без вчителя нейромережа не знає правильних відповідей. Тому, за певними закономірностями чи подібністю даних сама відносить їх до певних класів (кластерів). Ця задача називається кластеризацією. Кластеризація в декілька разів програє за точністю класифікації, думаю вам зрозуміло чому 😉.

Згорткова нейронна мережа (ЗНМ)

Згорткова нейронна мережа (ЗНМ) — тип багатошарової нейронної мережі, яка застосовується для розпізнавання зображень.

Класифікація зображень за допомогою ЗНМ
Структура ЗНМ

Свою назву мережа отримала від операції, що називається згортка і часто використовується для оброблення зображень. В даному типі нейромережі використовується три види шарів: згортковий шар (convolution), шар субдискретизації (subsampling, pooling) та повнозв'язний шар (fully-connected). Послідовність цих шарів визначає якість роботи ЗНМ.

Коротко розглянемо принцип роботи таких нейронних мереж. До вхідного зображення застосовується набір фільтрів із заданим розміром вікна (ядра). Після чого ми отримуємо декілька карт ознак, кількість яких зазвичай дорівнює кількості фільтрів. Ядро кожного фільтра ініціалізується випадковими значеннями, внаслідок цього кожен фільтр визначає на зображенні певну властивість (це щось схоже на функцію редактора GIMP, де ви можете відфільтрувати зображення задавши ядро і розмір фільтра, тобто при різних значеннях ядра ми отримаємо різний результат). У даному відео пояснюється принцип роботи фільтрів на основі згортки.

Для зменшення розмірності зображення застосовують шар пулінгу (субдискретизації). Останнім шаром іде повнозв'язний шар, що формує вихід нейромережі.

Послідовність дій виглядає наступним чином (наприклад, візьмемо кольорове зображення розміром 32 на 32 пікселі):

  1. У вхідних даних [32×32×3] міститься вихідна інформація про зображення (в даному випадку 32 — ширина, 32 — висота, 3 — кольорові канали R, G, B).
  2. Згортковий шар перемножує значення фільтра на вихідні значення пікселів зображення (поелементне множення), після чого всі добутки сумуються, тобто цей шар виконує згортку зображення.
    Класифікація зображень за допомогою ЗНМ
    Згортка зображення фільтром
    Для прикладу, якщо використовується 12 фільтрів, обсяг зображення буде [32×32×12].
  3. Шар пулінгу виконує операцію для зниження розмірності, в результаті чого обсяг може зменшитися до [16×16×12]. Логіка роботи така: якщо на попередній операції згортки вже були виявлені деякі властивості (ознаки), то для подальшої обробки такий детальний образ вже непотрібний, і він «ущільнюється» до менш детальної картинки.
  4. Повнозв'язний шар виводить N-мірний вектор (N — кількість класів) для визначення потрібного класу. Це відбувається шляхом звернення до виходу попереднього шару (карта ознак) та визначення властивостей, які найбільш характерні для певного класу.

Саме в такий спосіб ЗНМ шар за шаром перетворює вхідне зображення, починаючи з вихідних значень пікселів і закінчуючи визначенням класу.

І так, ще раз для закріплення 😊:

  1. В найпростішому випадку архітектура ЗНМ — набір шарів, які перетворюють образ зображення у якийсь інший вихідний образ (наприклад, визначення класу до якого відноситься зображення).
  2. Кожен шар відповідає за певний етап процесу обробки зображення.
  3. Кожен шар отримує на вході об'ємну 3D інформацію і перетворює її зі збереженням 3D-об'єму за допомогою певної функції.

Вибрати готову модель чи створити власну?

Після проведення великої кількості експериментів з вже готовими моделями ЗНМ (AlexNet, GoogleNet та інші), які не дали потрібної точності під час класифікації (в мене була ціль, що точність має бути не нижче 90%), я швиденько «накидав» наступну структуру ЗНМ.

Класифікація зображень за допомогою ЗНМ
Структура ЗНМ для класифікації біомедичних зображень

У згортковому шарі 5х5 — розмір фільтра, 100 — кількість фільтрів. У вас могло виникнути питання чим відрізняється структура від моделі? 🤔 Структура — послідовність шарів, модель — повністю налаштована нейромережа, тобто задані функції активації, алгоритм навчання та оптимізації, а також інші параметри, яких є дуже багато і які я дуже довго підбирав, щоб досягнути потрібної точності 😯. Основні параметри розробленої моделі наведено у таблиці.

Параметр Цитологія Гістологія
Норма навчання 5e-3 7e-3
L2-регуляризація 5e-7 54e-7
Функція активації ReLU ReLU
Градієнтна нормалізація На кожному шарі -
Алгоритм оптимізації (мінімізації помилки) Метод стохастичного градієнта Метод спряжених градієнтів
Функція активації повнозв'язного шару ReLU TANH
Функція активації вихідного шару Sigmoid Sigmoid
Функція втрат Negative Log Likelihood Negative Log Likelihood

В результаті проведення експериментів, створена модель показала точність класифікації від 90% до 98.2% для біомедичних зображень розміром 128х128 та 224х224 пікселів.

Далі, я розробив графічний інтерфейс для своєї програми використавши JavaFX та бібліотеку Material Design — JFoenix. Так з'явився проект Neuronix — програмний засіб для класифікації зображень використовуючи ЗНМ та графічні процесори. Коротко пробіжимося по функціоналу:

  • можливість використовувати як CPU так і GPU для обчислень;
  • можливість отримати зображення з камери;
  • можливість створювати власні моделі ЗНМ;
  • можливість навчати створені моделі та класифікувати зображення з їх допомогою.

Детальніше можете почитати на сторінці проекту тут.

Спочатку цей проект був задуманий тільки для біомедичних зображень, а потім я змінив свою думку і вирішив додати можливість класифікації будь-яких зображень. Тобто ви можете створити власну модель та вказати директорії із зображеннями, які ви бажаєте.

Класифікація зображень за допомогою ЗНМ
Головне вікно програми
Класифікація зображень за допомогою ЗНМ
Налаштування
Класифікація зображень за допомогою ЗНМ
Навчання
Класифікація зображень за допомогою ЗНМ
Класифікація

Тестування

Для тестування використовувався ПК з такою конфігурацією:

Процесор AMD Athlon 64 x2 Dual Core, 2.51ГГц
Оперативна пам'ять 4ГБ, DDR2
Відеокарта Nvidia GTX 950 Asus, серія Strix, 2Гб, GDDR5
PCI Express 2.0
Операційна система Windows 10 Pro

Як бачите, відеокарта найдорожча 😅 Отож, зображення кожного виду були поділені на 5 класів. Кількість цитологічних зображень 80, гістологічних ‒ 91 (це дуже мало, але більше ми не могли взяти тому, що цієї інформації немає у вільному доступі). Для першого експерименту використовувалися кольорові зображення (формату JPEG) роздільною здатністю 128х128 пікселів. Для кожного виду зображень було проведено 3 досліди. Після кожного досліду, в моделі мережі коригувалися деякі параметри для досягнення кращого результату, а саме: норма навчання, алгоритм оптимізації.

Класифікація зображень за допомогою ЗНМ
Час навчання для зображень 128 пікселів

Як видно з рисунка, ГП дає прискорення приблизно в 4 рази. Я вважаю, що це дуже хороший результат. На наступному рисунку наведено точність класифікації, що досягає ~98% для цитологічних зображень та ~94% для гістологічних.

Класифікація зображень за допомогою ЗНМ
Точність класифікації

Для другого експерименту використовувалися ті ж самі зображення, але з роздільною здатністю 224х224 пікселі. Тут час навчання суттєво відрізняється, оскільки на вхід подаються зображення більшого розміру, що ускладнює обчислення.

Класифікація зображень за допомогою ЗНМ
Час навчання для зображень 224 пікселі

Точність класифікації при даному розмірі зображень для цитології сягає ~98.2%, а для гістології стабільних 90%.

Класифікація зображень за допомогою ЗНМ
Точність класифікації

Як я вже писав — гістологічні зображення складніші за структурою від цитологічних. Також в нашому наборі тренувальних даних гістологічні зображення значно нижчої якості. Як бачите це суттєво вплинуло на точність класифікації. Детальніше про проведені експерименти ви можете почитати тут.

Проблеми з якими я зіткнувся

В процесі навчання нейронної мережі велику роль відіграють компоненти комп'ютера. Мій старенький комп (купував у далекому 2009) не витягує такого навантаження 😆 Неможливо виграти в часі тільки шляхом розпаралелювання на програмному рівні. Навіть, якщо весь код буде виконуватися паралельно на 100%, то він буде повільнішим на слабкішому процесорі. Я маю на увазі, що тут велику роль відіграє швидкість та об'єм оперативної пам'яті, швидкість шини PCI Express, тип відеопам'яті та багато інших факторів. Конкретно для відеокарти, яку я використовував, я б рекомендував наступні комплектуючі:

  • RAM 4GB, DDR3 або DDR4;
  • Intel Pentium G4400 або i3-4170;
  • PCI Express 3.0.

Інколи, під час навчання нейронної мережі, не вистачає відеопам'яті (це при малому розмірі зображень), тому, я б рекомендував відеокарту з об'ємом пам'яті не менше 4 Гб, або ж збільшити об'єм RAM до 8 Гб (при заповненні відеопам'яті, дані завантажуються в RAM).

Основною проблемою була нестача відеопам'яті та дуже мала кількість тренувальних даних.

Також було дуже важко з першої спроби підібрати параметри для моделі, оскільки їх дуже багато і всі вони взаємопов'язані. Я, напевно, зробив десь 50+ симуляцій, поки отримав хорошу модель 😲.

Якщо б я зараз робив схожий проект — я б використовував Python та Keras, оскільки я також експериментував з даними технологіями і вони показали трохи кращі результати по швидкості навчання та й по класифікації також (на ~2.5%, а в машинному навчанні — це дуже багато, повірте 🙂).

Висновки

ЗНМ зараз дуже гаряча тема, оскільки ці нейронні мережі застосовуються майже всюди. Саме завдяки активному впровадженню графічних процесорів для пришвидшення обчислень вони набули такої популярності. ImageNet Classification with Deep Convolutional Neural Networks — саме ця стаття дала новий поштовх у розвитку машинного навчання, а саме ЗНМ.

В наш час легше перерахувати сфери в яких нейронні мережі не застосовуються, ніж навпаки.

    Лектор з Prometheus 😋 

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

Оскільки я зовсім недавно у темі машинного навчання, то будь ласка виправляйте якщо щось, можливо, не так 😏 А також пропонуйте теми про які, можливо, хотіли б почитати. Можливо, вас зацікавила б тема генерування зображень за допомогою нейронної мережі? Якщо так — пишіть в коментарі.

Надіюся, що вам було цікаво 😊. Якісних вам моделей та до зустрічі!

Проект на GitHub.

Додаткові матеріали

  1. Ключові рекомендації по глибинному навчанні;
  2. Класифікація образів за допомогою згорткової нейронної мережі;
  3. Про методи навчання нейронних мереж прямого поширення.
Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.8K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація