Аннотация:

Опухоль головного мозга считается одним из агрессивных заболеваний среди детей и взрослых. Опухоли головного мозга составляют от 85% до 90% всех первичных опухолей центральной нервной системы (ЦНС). Ежегодно опухоли головного мозга диагностируются у около 11700 человек. 5-летняя выживаемость для людей с раковой опухолью головного мозга или ЦНС составляет примерно 34% для мужчин и 36% для женщин. Опухоли головного мозга классифицируются как доброкачественные, злокачественные, опухоли гипофиза и т. Д. Для увеличения продолжительности жизни пациентов необходимо правильно планировать лечение и проводить точную диагностику.
Лучшим методом обнаружения опухолей головного мозга является магнитно-резонансная томография ( МРТ). В результате сканирования создается огромное количество изображений данных. Эти изображения исследует радиолог. Ручное обследование может быть подвержено ошибкам из-за сложности опухолей головного мозга и их свойств.

Применение методов автоматической классификации с использованием машинного обучения (ML) и искусственного интеллекта (AI) неизменно показывает более высокую точность, чем ручная классификация. Поэтому мы предлагаем выполнять обнаружение и классификацию опухолей головного мозга с использованием алгоритмов глубокого обучения с использованием сверточной нейронной сети (CNN), искусственной нейронной сети (ANN) и передачи обучения (TL) для достижения более высокой точности. Изображения МРТ классифицируются с использованием различных «моделей глубокого обучения ИНС и CNN». Эти модели имеют перестановки и комбинации различных «сетевых параметров». Модель с максимальной точностью выбирается для дальнейшего улучшения путем точной настройки гиперпараметров сети. Целью проекта является достижение более высокой точности и надежности реальных данных МРТ с использованием знаний в области искусственного интеллекта и машинного обучения. Далее предоставить некоторые предложения по лечению, обеспечивая простой доступ к программному обеспечению через облако через мобильные приложения, платформы веб-браузеров.

Определение проблемы:

Обнаружить и классифицировать опухоль головного мозга с использованием CNN, ANN и TL в качестве актива глубокого обучения и развернуть для этого систему Flask.

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

Можете ли вы классифицировать эти МРТ?

Довольно сложно найти разницу?

Итак, первая МРТ - глиома, вторая - менингиома. Здесь мы можем понять, насколько сложно определить разницу между типами опухолей. Неправильная классификация опухолей может привести к назначению неправильного лечения и лекарств, которые могут ухудшить состояние.

Подход :

Поэтому мы предлагаем создать систему, которая классифицирует МРТ на один из следующих классов опухолей:

Доброкачественный

Злокачественный

Нет опухоли

Опухоль гипофиза

Мы строим несколько моделей ANN (искусственная нейронная сеть), CNN (сверточная нейронная сеть), TL (передача обучения) и сравниваем точность, потери и F1-баллы каждой модели, чтобы увидеть, какая модель лучше остальных.

НАЧАТЬ КОДИРОВКУ!

Данные:

Наш проект направлен на разделение МРТ на четыре класса, что делает его проблемой с четырьмя классами. Данные для наших нейронных сетей представлены в формате изображений (.jpg). Эти данные собираются из Kaggle (да / нет) и Github (частный).

В целом был использован этот набор данных.

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

Предварительная обработка:

Данные изображения, собранные с GitHub, относятся к трем классам опухолей, а данные Kaggle относятся к классу без опухолей. Эти изображения были разделены в соотношении 7: 3 для фазы обучения и тестирования соответственно.

Обрезка изображения:

МРТ содержит черный фон вокруг центрального изображения мозга. Этот черный фон не дает никакой полезной информации об опухоли и будет бесполезным при передаче в нейронные сети. Следовательно, было бы полезно обрезать изображения по основному контуру. Для этого мы используем cv2.findContours () из библиотеки ‘cv2’.

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

Увеличение:

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

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

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

Травление:

Данные после всех вышеперечисленных шагов по-прежнему находятся в отдельных форматах файлов изображений, хранящихся в соответствующих папках. Но чтобы передать данные в нейронную сеть, они должны быть преобразованы в массив NumPy. Таким образом, мы конвертируем эти изображения в четыре массива NumPy из X_train, Y_train, X_test, Y_test. Где X_train, X_test содержат изображения, а Y_train, Y_test содержат метки. Данные читаются с использованием cv2.imread (path_of_image, cv2.IMREAD_COLOR). Здесь важен cv2.IMREAD_COLOR, поскольку он определяет «размер нашего ввода позже» нейронной сети. Затем мы используем np.reshape (-1, IMG_SIZE, IMG_SIZE, 3), чтобы изменить форму данных, хранящихся в X_train, X_test. Число 3 указывает, что это изображение RGB, а не изображение в оттенках серого. Параметр IMG_SIZE предназначен для указания разрешения изображений, изображения с более высоким разрешением содержат больше деталей, но за счет большего размера рассола и меньшего IMG_SIZE могут привести к пиксельным изображениям, но сэкономить место на диске и сделать свет сети. Поэтому важно найти золотую середину для решения проблемы. (Мы выбрали это как 150) По завершении этой обработки, изменения формы и разделения изображений и меток всех изображений в обучающем и тестовом наборе мы сохраняем файлы как файлы pickle.

Сохранение этих файлов как pickle помогает нам сохранить весь наш прогресс на этапе предварительной обработки с помощью «pickle.dump ()». И позже мы можем напрямую использовать эти файлы рассола для ввода во все наши нейронные сети. Таким образом, это помогает нам сэкономить время, поскольку не выполняет предварительную обработку каждый раз, когда мы хотим обучить сеть. В следующий раз мы просто воспользуемся ‘pickle.load’ для загрузки всех данных.

Построение модели :

Интересная часть! Итак, до сих пор мы очищали, предварительно обрабатывали, дополняли, консервировали данные, и теперь мы готовы передать их в «нейронную сеть» и посмотреть, как она работает! Мы попробуем три разных, но похожих метода и посмотрим, какой из них позволяет создавать модели с более высокой точностью.

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

Искусственная нейронная сеть (ИНС):

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

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

Таким образом, мы генерируем несколько моделей, состоящих из 32,64,128 узлов и 0,1,2 плотных слоев в комбинации. Это дает нам в общей сложности 9 моделей. Модель с наивысшей точностью - это модель со 128 узлами-0 плотными слоями с точностью 80%. Неплохо для ИНС. Но точность не превышает 80%, сколько бы слоев мы ни добавляли. Таким образом, отсутствие слоев свертки мешает нам стремиться к более высокой точности.

densel = [0,1,2]
layers = [32,64,128]
for dense in densel:
    for layer in layers:
      NAME = "no_nodes-{}-no_dense-{}".format(layer, dense)
      print(NAME)
      model = Sequential()  
      model.add(Flatten(input_shape=X_train.shape[1:]))
      for _ in range(dense_layer):
         model.add(Dense(layer))
         model.add(Activation('relu')) 
         model.add(Dropout(0.25))
         model.add(Dense(4))
      model.add(Activation('softmax'))

      #Compile
      model.compile(loss='sparse_categorical_crossentropy',optimizer = "adam", metrics=['accuracy'],)
      #Fit the model
      history = model.fit(X_train, Y_train, batch_size=32, epochs=25, validation_data=(X_test,Y_test),callbacks [tensorboard,es])
      #Score
      scores = model.evaluate(X_test, Y_test, verbose=1)
      print('Test loss:', scores[0])
      print('Test accuracy:', scores[1])
      #Save model
      model.save("{}-model-{}-accuracy.h5".format(NAME,scores[1]))
      #precision    recall  f1-score   support
      y_pred = model.predict(X_test, batch_size=64, verbose=1)
      y_pred_bool = np.argmax(y_pred, axis=1)   
      print(classification_report(Y_test, y_pred_bool))
      print()
      print()

Сверточные нейронные сети (CNN):

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

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

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

Таким образом, мы генерируем несколько моделей CNN плотных слоев 0,1,2 с размером слоя 32,64,128 и количеством сверточных слоев 1,2,3. Модели создаются с комбинацией этих параметров. Таким образом, мы сгенерировали всего 21 модель. В которой модель «3-conv-128-node-1-density» имеет наивысшую точность 91%.

Теперь мы знаем, что модель, имеющая 3 слоя свертки и 1 плотный слой из 128 узлов, показывает возможность быть лучшей моделью, чем предыдущая модель ИНС. Таким образом, мы теперь настраиваем гиперпараметры этой модели, чтобы получить более высокую точность.

densel = [0,1,2]
layers = [32,64,128]
convl = [1,2,3]
for dense in densel:
  for layer in layers:
    for conv in convl:
      NAME = "{}-conv-{}-nodes-{}-dense-{}".format(conv,layer,dense)
      print(NAME)
      model = Sequential()
      model.add(Conv2D(layer, (3, 3), input_shape=X_train.shape[1:]))
      model.add(Activation('relu'))
      model.add(MaxPooling2D(pool_size=(2, 2)))
      for l in range(conv-1):
          model.add(Conv2D(layer, (3, 3))) 
          model.add(Activation('relu'))           
          model.add(MaxPooling2D(pool_size=(2, 2)))  
          model.add(Flatten())
      for _ in range(dense):
          model.add(Dense(layer))
          model.add(Activation('relu'))
          model.add(Dropout(0.25))
          model.add(Dense(4))
          model.add(Activation('softmax'))
      model.compile(loss='sparse_categorical_crossentropy',
      optimizer= "adam", metrics=['accuracy'],)
      #Fit the model
      history = model.fit(X_train, Y_train, batch_size=32, epochs=20,validation_data=(X_test,Y_test),callbacks=[tensorboard,es])

Трансферное обучение (TL):

Трансферное обучение - это метод машинного обучения, при котором модель, обученная одной задаче, перенаправляется на другую связанную задачу. Доступно множество предварительно обученных моделей, которые действительно хороши для классификации изображений. Мы можем использовать эти предварительно обученные модели для классификации МРТ с использованием трансферного обучения. Предварительно обученные модели доступны в keras.applications.

Во-первых, нам нужно импортировать эти модели и преобразовать их в последовательную модель keras. Входной слой этих предварительно обученных моделей может различаться по входной форме, поэтому нам нужно изменить входную форму в соответствии с нашим (IMG_SIZE, IMG_SIZE, 3). Кроме того, выходной слой этих предварительно обученных models настроен на классификацию 1000 классов изображений, но у нас есть только четыре класса. Итак, мы открываем последний слой и добавляем плотный слой из четырех узлов и функции активации «softmax».

Теперь мы устанавливаем обучаемый параметр каждого слоя как False и запускаем модель для нескольких эпох. Эта модель должна работать лучше, чем все наши предыдущие модели, поскольку она хорошо обучена и ее гиперпараметры точно настроены. Единственная проблема с использованием TL - это размер и глубина модели больше, чем у простых моделей ANN и CNN.

На этот раз мы тренировались только на расширенных данных на ResNet50, MobileNet_v2, VGG16, VGG19, InceptionV3. Из них VGG16 показал наивысшую точность тестирования 94% и результат F1-Score 94! Таким образом, эта модель превзошла все наши модели ИНС, CNN и TL.

vgg16_model = vgg16.VGG16()
model = Sequential()
for layer in vgg16_model.layers[:-1]:
     model.add(layer) # convert to sequantial model
for layer in model.layers:
     layer.trainable = False
     model.add(Dense(4,activation = 'softmax'))
model.compile(loss='sparse_categorical_crossentropy',optimizer= "adam", metrics=['accuracy'],)
history = model.fit(X_train, Y_train,batch_size=32, epochs=20, validation_data=(X_test,Y_test), callbacks=[tensorboard])

Резюме :

Итак, мы создали несколько моделей с использованием ANN, CNN, TL. Эти модели имеют разную точность и оценку F1. Чтобы максимально использовать возможности каждой модели, мы используем «ансамблевое обучение»! Ансамблевое обучение - это процесс, с помощью которого стратегически создаются несколько моделей машинного обучения для решения конкретной проблемы. Они объединяют решения из нескольких моделей для повышения общей производительности.

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

Развертывание Flask:

Итак, до сих пор все выполняется через командную строку, и нет внешнего интерфейса, который мог бы превратить этот проект в целостную систему. Давайте воспользуемся Flask - платформой веб-приложений на основе python. Используя Flask, мы можем связать эти модели с графическим интерфейсом в браузере. После того, как модель запустится локально, мы можем позже развернуть ее в AWS, Heroku, Google Cloud и т. Д.

ALLOWED_EXTENSIONS = set(['jpg', 'jpeg', 'png'])
IMG_SIZE = 150 # size of images
UPLOAD_FOLDER = 'uploads'
model = load_model("model/best_model.h5")
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
def prepare(filepath):
    img_array = cv2.imread(filepath, cv2.IMREAD_COLOR)  
    new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE)) 
    return new_array.reshape(1, IMG_SIZE, IMG_SIZE, 3)
def predict(file):
    prediction = model.predict([prepare(file)])
    if np.argmax(prediction)==0:    
        output="glioma"
    if np.argmax(prediction)==1:
        output="meningioma"
    if np.argmax(prediction)==2:
        output="no_tumor"
    if np.argmax(prediction)==3:
        output="pituitary" 
    return output
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
@app.route("/")
def template_test():
    return render_template('home.html', label='', imagesource='file://null')
@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
            file.save(file_path)
            output = predict(file_path) #call predict fn
    return render_template("home.html", label=output, imagesource=file_path)
@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'],filename)
if __name__ == "__main__":
    app.run(debug=False, threaded=False)

Приведенный выше код сохраняется в Flask Project как app.py. Этот файл python инициализирует наше приложение Flask и отображает шаблон HTML, в который мы можем загрузить МРТ, и он будет предсказывать класс опухоли.

Запустите файл app.py Flask, мы перейдем на http://127.0.0.1:5000/, где запускается приложение flask. Тестируем на случайном изображении и смотрим прогноз.

Мы видим, что класс опухоли, предсказанный нашим Flask, верен!

Заключение :

Наконец, мы создали модели ANN, CNN, TL, которые успешно классифицируют опухоли головного мозга, и подключили Flask для веб-сервиса.

(:

Ссылки:

Сайт проекта



Сообщение Kaggle: Классификация опухолей головного мозга (МРТ)

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

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