Сегментация изображений python tensorflow

Выполнение сегментации изображения с помощью TensorFlow

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

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

Цель

В этом проекте мы будем использовать инфраструктуру машинного обучения TensorFlow для обучения и оценки нейронной сети сегментации изображений с использованием набора данных медицинских изображений. Мы выполним семантическую сегментацию, чтобы классифицировать каждый пиксель на МРТ-изображении сердца, независимо от того, является ли пиксель частью левого желудочка (ЛЖ) или нет.

Набор данных

Вам нужно будет зарегистрироваться на Веб-сайте Cardiac MR Left Ventricle Segmentation Challenge, и ссылки для скачивания набора данных будут отправлены вам по электронной почте. Набор данных представляет собой серию изображений сердца (в частности, МРТ-сканов с короткой осью (SAX)) с экспертной маркировкой.

Репрезентативный пример данных показан выше. Слева — МРТ-изображения, а справа — экспертно-сегментированные области (часто называемые контурами). Части изображений, входящие в состав LV, обозначены белым цветом. Извлечение данных из необработанных изображений и последующая подготовка этих изображений в этой статье не рассматриваются.

1. Визуализация набора данных

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

# function to display an image, it's label def display(display_list): plt.figure(figsize=(10, 10)) title = ['Input Image', 'Label'] for i in range(len(display_list)): display_resized = tf.reshape(display_list[i], [256, 256]) plt.subplot(1, len(display_list), i+1) plt.title(title[i]) plt.imshow(display_resized) plt.axis('off') plt.show() # display 3 random images and labels from the training set for image, label in train.take(3): sample_image, sample_label = image, label display([sample_image, sample_label])

# an image and label from validation data for image, label in val.take(1): sample_image, sample_label = image, label display([sample_image, sample_label])

2. Построение модели

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

Читайте также:  Java futuretask is running

Каждый входной пиксель может относиться к двум классам; Левый желудочек (LV) или нет, поэтому это будет вывод. Затем мы изменим форму вектора, чтобы просмотреть его как изображение.

tf.keras.backend.clear_session() # set up the model architecture model = tf.keras.models.Sequential([ Flatten(input_shape=[256, 256, 1]), Dense(64, activation='relu'), Dense(256*256*2, activation='softmax'), Reshape((256, 256, 2)) ]) # specify how to train the model with algorithm, the loss function and metrics model.compile( optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy']) # plot the model including the sizes of the model tf.keras.utils.plot_model(model, show_shapes=True)

3. Обучение модели

EPOCHS = 20 STEPS_PER_EPOCH = len(list(parsed_train_data)) VALIDATION_STEPS = 26 model_history = model.fit(train_dataset, epochs=EPOCHS, steps_per_epoch=STEPS_PER_EPOCH, validation_steps=VALIDATION_STEPS, validation_data=test_dataset, callbacks=[tensorboard_callback])

Код будет выводить каждую эпоху и статистику ее модели.

4. Оценка модели

Оценка производительности модели.

# output model statistics loss = model_history.history['loss'] val_loss = model_history.history['val_loss'] accuracy = model_history.history['accuracy'] val_accuracy = model_history.history['val_accuracy'] epochs = range(EPOCHS) plt.figure() plt.plot(epochs, loss, 'r', label='Training loss') plt.plot(epochs, val_loss, 'bo', label='Validation loss') plt.title('Training and Validation Loss') plt.xlabel('Epoch') plt.ylabel('Loss Value') plt.ylim([0, 1]) plt.legend() plt.show()

#model evaluation on the test dataset model.evaluate(test_dataset)

Модель имела потери 0,6931 и точность 0,986. Модель не работала хорошо, так как функция потерь очень высока.

5. CNN с Dice Metric Loss

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

#dice coef function def dice_coef(y_true, y_pred, smooth=1): indices = K.argmax(y_pred, 3) indices = K.reshape(indices, [-1, 256, 256, 1]) true_cast = y_true indices_cast = K.cast(indices, dtype='float32') axis = [1, 2, 3] intersection = K.sum(true_cast * indices_cast, axis=axis) union = K.sum(true_cast, axis=axis) + K.sum(indices_cast, axis=axis) dice = K.mean((2. * intersection + smooth)/(union + smooth), axis=0) return dice #clear the backend session to free up memory tf.keras.backend.clear_session() #define the layers of the model architecture layers = [ Conv2D(input_shape=[256, 256, 1], filters=100, kernel_size=5, strides=2, padding="same", activation=tf.nn.relu, name="Conv1"), MaxPool2D(pool_size=2, strides=2, padding="same"), Conv2D(filters=200, kernel_size=5, strides=2, padding="same", activation=tf.nn.relu), MaxPool2D(pool_size=2, strides=2, padding="same"), Conv2D(filters=300, kernel_size=3, strides=1, padding="same", activation=tf.nn.relu), Conv2D(filters=300, kernel_size=3, strides=1, padding="same", activation=tf.nn.relu), Conv2D(filters=2, kernel_size=1, strides=1, padding="same", activation=tf.nn.relu), Conv2DTranspose(filters=2, kernel_size=31, strides=16, padding="same") ] #create a sequential model with the defined layers model = tf.keras.models.Sequential(layers) #compiling the model model.compile( optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy']) #setting up and running the model EPOCHS = 20 STEPS_PER_EPOCH = len(list(parsed_train_data)) VALIDATION_STEPS = 26 model_history = model.fit(train_dataset, epochs=EPOCHS, steps_per_epoch=STEPS_PER_EPOCH, validation_steps=VALIDATION_STEPS, validation_data=test_dataset)

Модель имела убыток 0,0871 и точность 0,9830.

Читайте также:  Python заполнить массив датами

Мы снова запустим модель на этот раз с 30 эпохами и измерим потери метрики в кости.

tf.keras.backend.clear_session() layers=layers # the layers in our model architecture model = tf.keras.models.Sequential(layers) # the model model.compile( optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=[dice_coef,'accuracy']) # setting up and running the model using 30 passes EPOCHS = 30 STEPS_PER_EPOCH = len(list(parsed_train_data)) model_history = model.fit(train_dataset, epochs=EPOCHS, steps_per_epoch=STEPS_PER_EPOCH, validation_data=test_dataset) #evaluating the model using the test dataset model.evaluate(test_dataset)

Модель улучшилась, дав потери 0,0863, коэффициент кости 0,049 и точность 0,983.

Источник

Какова архитектура UNet?

В Керасе мы имеем Con2D , Con2DTranspose , MaxPooling2D а также UpSampling2D слои, чтобы сделать вашу жизнь проще. Но мы будем использовать сырые API TensorFlow 2.0 для создания модели.

Возможно, модель получила название «UNet» из-за некоторой U-образной формы, полученной с помощью пропускаемых соединений. Оставим это изобретателям! 😅

Обсуждать данные

Наш набор данных происходит от Городские пейзажи по DanB на Kaggle, Изображения выглядят так,

Правая часть — это маска, а левая часть — это фактическое изображение. Мы разделим эти изображения с ImageOps используя подушку.

Набор данных имеет несколько масок разных классов с соответствующими цветами. Для нашей простоты мы только пытаемся сегментировать «дорогу», представленную на изображении. Обратите внимание, что дорога имеет цвет RGB (128, 63, 126). Наша модель выведет двоичную маску, состоящую только из 1 и 0. Наше входное изображение будет изображением формы (128, 128, 3), а целью будет маска формы (128, 128, 1). Таким образом, пиксель, имеющий значение RGB (128, 63, 126), будет иметь значение 1 в целевой маске. Все остальные пиксели будут иметь значение 0.

Готовимся к операции!

Мы определим методы для четырех операций:

  1. conv2d_down : Обычная свертка вместе с активацией Leaky ReLU.
  2. maxpool_down : Максимальное объединение операций с допустимым заполнением.
  3. conv2d_up : Транспонированная свертка для повышения качества изображения.
  4. maxpool_up : Повышение дискретизации, например, UpSampling2D Керас слой.
Читайте также:  Running php scripts on server

Есть больше!

Вот и все!

Надеюсь, это было интересно. Счастливого машинного обучения!

Источник

Оцените статью