Я нашел нейронную сеть классификации WBC, разработанную dhruvp, на github. Мы погружались в код и пытались его улучшить. Код от dhruvp находится здесь: https://github.com/dhruvp/wbc-classification. Я хотел улучшить код и посмотреть, смогу ли я внести какой-то вклад. Но перед этим давайте подробнее рассмотрим, как реализована CNN и как работает его модель.

Для нетерпеливых

Получите окончательный код здесь.

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

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

Классифицировать лейкоциты сложно

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

Нейронная сеть для спасения

Я буду опираться на все данные, предоставленные dhruvp, и постараюсь улучшить результаты и выводы. Мы будем использовать CNN для классификации WBC. Здесь мы попытаемся классифицировать лейкоциты на две основные группы: полинуклеарные и мононуклеарные.

Как мы классифицируем?

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

Процесс

  1. Карта характеристик
  2. Снижение размерности или объединение
  3. Полностью подключенный слой или плотный слой
  4. Функция стоимости
  5. Улучшения
  6. Сравнения

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

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

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

Матрица признаков

Мы можем значительно усложнить сеть, разделив ее на большое количество наборов функций. Внутри сверточной сети эти объекты фактически делятся на 3 измерения (Шширина x Ввосемь x Глубинае). Таким образом, это занимает много места в памяти и потребляет много ресурсов, если мы работаем с входным изображением большого размера. CIFAR-10 — это свободно доступный набор данных изображений для обучения нейронной сети, где изображения имеют размер 32x32x3 (32w, 32h с 3 цветовыми каналами (RGB)), поэтому один полностью связанный нейрон в первом слое будет иметь 32*32*3 = 3072 веса. В нашем примере изображения имеют размеры 640*480*3 = 921 600 весов. Довольно огромный ха!

Выбор правильных фильтров или функций активации

Фильтры или функции активации — это те, которые дают результат при сравнении двух функций. Есть множество функций активации, которые мы можем использовать. Простейшей является линейная функция. То есть он рисует прямую линию, чтобы найти совпадающие объекты и дать результат. Линейные функции точны для дискретных и предсказуемых чисел. Другой является логистическая функция, которая имеет сигмоидальный путь и выходы находятся в диапазоне (0,1). Логистическая функция обеспечивает вывод классификации, поэтому соответствует, когда мы хотим выбирать между одним и другим. Функция гиперболического тангенса является расширением логистической функции, которая дает выход или более высокий диапазон (-1, 1).

Логистические функции быстрые и очень полезные. Но в нашем случае мы хотим, чтобы наш вывод был сравнением функций. Итак, мы хотим, соответствует ли функция входным данным или нет. По сути, либо 0, либо 1, а не что-то среднее. Для этого мы используем «ReLu» или выпрямленную линейную единицу.

Сокращение накладных расходов за счет уменьшения размерности

Понижение дискретизации — это математический процесс, который уменьшает размер сетки или ядра, выполняя математическую операцию в каждой функции. В нашем примере наши изображения размером 640*480 должны быть уменьшены до 120*160. Это называется пулинг-слоем. Из многих алгоритмов объединения максимальное объединение принимает максимальное значение в массиве для создания другого массива. С другой стороны, средний пул берет среднее значение в массиве и создает другой массив. Подробнее здесь.

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

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

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

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

Улучшения

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

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

Сравнение

Я сравнил графики, сгенерированные его алгоритмом, с моими, чтобы увидеть, могу ли я внести свой вклад. Я обнаружил, что, добавляя простые исключения внутри модели, я мог добиться гораздо более гладких линий для вариационных потерь и точности, сохраняя при этом показатель точности 98,59+% на тестовых данных.

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

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

model.save('final.model')

Позже мы будем использовать keras tensorflow для импорта модели в функцию и соответствующего прогнозирования результата. Вам нужно указать место, где вы сохранили файлы тестирования. Я сохранил свой в папке images/TEST_EXTERNAL.

import tensorflow as tf

def prepare(filename):
    img_file = "../images/TEST_EXTERNAL/"+filename
    sizeX = 120
    sizeY = 160
    img_file = cv2.imread(img_file)
    img_arr = scipy.misc.imresize(arr=img_file, size=(120, 160, 3))
    return img_arr.reshape(-1, 120,160,3)
trainedModel = tf.keras.models.load_model("final.model")
prediction = model.predict([prepare('002.jpg')])
print(int(prediction))