Слишком много проблем с памятью при семантической сегментации изображений NN (DeepLabV3+)

Сначала я объясню свою задачу: у меня есть почти 3000 изображений с двух разных веревок. Они содержат веревку 1, веревку 2 и фон. Мои метки / маски - это изображения, где, например, значение пикселя 0 представляет фон, 1 представляет первую веревку и 2 представляет вторую веревку. Вы можете увидеть как входное изображение, так и основную правду / метки здесь на рисунке 1 и 2 ниже. Обратите внимание, что моя основная истина / метка имеет только 3 значения: 0, 1 и 2. Моя входная картинка серого цвета, но для DeepLab я преобразовал ее в RGB Picture, потому что DeepLab был обучен на RGB Pictures. Но моя конвертированная картинка все еще не содержит цвета.

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

Для этой задачи я выбираю сеть семантической сегментации под названием DeepLab V3+ в Keras с TensorFlow в качестве Backend. Я хочу тренировать NN с моими почти 3000 изображениями. Размер всех изображений не превышает 100 МБ, а они составляют 300x200 пикселей. Возможно, DeepLab - не лучший выбор для моей задачи, потому что мои изображения не содержат информацию о цвете, а размер моих изображений очень мал (300x200), но я не нашел лучшего NN семантической сегментации для своей задачи.

С веб-сайта Keras я знаю, как загрузить данные с помощью flow_from_directory и как использовать метод fit_generator. Я не знаю, если мой код логически правильный...

Вот ссылки:

https://keras.io/preprocessing/image/

https://keras.io/models/model/

https://github.com/bonlime/keras-deeplab-v3-plus

Мой первый вопрос:

В моей реализации моя графическая карта использовала почти всю память (11 ГБ). Я не знаю почему. Возможно ли, что веса от DeepLab такие большие? Мой размер пакета по умолчанию 32, и все мои почти 300 изображений имеют размер менее 100 МБ. Я уже использовал config.gpu_options.allow_growth = True code, см. Мой код ниже.

Общий вопрос:

Кто-нибудь знает хорошую семантическую сегментацию NN для моей задачи? Мне не нужны NN, которые были обучены с цветными изображениями. Но мне также не нужен NN, который был обучен с помощью двоичных изображений истинности земли... Я проверил мое сырое цветное изображение (рисунок 3) с DeepLab, но полученная метка результата была не очень хороша...

Вот мой код до сих пор:

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "3"

import numpy as np
from model import Deeplabv3
import tensorflow as tf
import time
import tensorboard
import keras
from keras.preprocessing.image import img_to_array
from keras.applications import imagenet_utils
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import TensorBoard


config = tf.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.Session(config=config)

from keras import backend as K
K.set_session(session)

NAME = "DeepLab-{}".format(int(time.time()))

deeplab_model = Deeplabv3(input_shape=(300,200,3), classes=3)

tensorboard = TensorBoard(log_dir="logpath/{}".format(NAME))

deeplab_model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=['accuracy'])

# we create two instances with the same arguments
data_gen_args = dict(featurewise_center=True,
                     featurewise_std_normalization=True,
                     rotation_range=90,
                     width_shift_range=0.1,
                     height_shift_range=0.1,
                     zoom_range=0.2)
image_datagen = ImageDataGenerator(**data_gen_args)
mask_datagen = ImageDataGenerator(**data_gen_args)

# Provide the same seed and keyword arguments to the fit and flow methods
seed = 1
#image_datagen.fit(images, augment=True, seed=seed)
#mask_datagen.fit(masks, augment=True, seed=seed)

image_generator = image_datagen.flow_from_directory(
    '/path/Input/',
    target_size=(300,200),
    class_mode=None,
    seed=seed)

mask_generator = mask_datagen.flow_from_directory(
    '/path/Label/',
    target_size=(300,200),
    class_mode=None,
    seed=seed)

# combine generators into one which yields image and masks
train_generator = zip(image_generator, mask_generator)

print("compiled")

#deeplab_model.fit(X, y, batch_size=32, epochs=10, validation_split=0.3, callbacks=[tensorboard])
deeplab_model.fit_generator(train_generator, steps_per_epoch= np.uint32(2935 / 32), epochs=10, callbacks=[tensorboard])

print("finish fit")
deeplab_model.save_weights('deeplab_1.h5')
deeplab_model.save('deeplab-1')

session.close()

Вот мой код для тестирования DeepLab (от Github):

from matplotlib import pyplot as plt
import cv2 # used for resize. if you dont have it, use anything else
import numpy as np
from model import Deeplabv3
import tensorflow as tf
from PIL import Image, ImageEnhance

deeplab_model = Deeplabv3(input_shape=(512,512,3), classes=3)
#deeplab_model = Deeplabv3()
img = Image.open("Path/Input/0/0001.png")
imResize = img.resize((512,512), Image.ANTIALIAS)
imResize = np.array(imResize)
img2 = cv2.cvtColor(imResize, cv2.COLOR_GRAY2RGB)

w, h, _ = img2.shape
ratio = 512. / np.max([w,h])
resized = cv2.resize(img2,(int(ratio*h),int(ratio*w)))
resized = resized / 127.5 - 1.
pad_x = int(512 - resized.shape[0])
resized2 = np.pad(resized,((0,pad_x),(0,0),(0,0)),mode='constant')
res = deeplab_model.predict(np.expand_dims(resized2,0))
labels = np.argmax(res.squeeze(),-1)
plt.imshow(labels[:-pad_x])
plt.show()

1 ответ

Решение

Первый вопрос: DeepLabV3+ - это очень большая модель (я полагаю, что вы используете магистраль Xception?!), и 11 ГБ необходимой емкости графического процессора совершенно нормальны для 32-разрядного размера с 200x300 пикселей:) (Обучение DeeplabV3+, мне понадобилось прибл. 11 ГБ, используя пакетный размер 5 с 500x500 пикселей). Одно примечание ко второму предложению вашего вопроса: на необходимые ресурсы GPU влияют многие факторы (модель, оптимизатор, размер пакета, обрезка изображения, предварительная обработка и т. Д.), Но фактический размер набора данных не должен на него влиять. Так что не имеет значения, если ваш набор данных имеет размер 300 МБ или 300 ГБ.

Общий вопрос: вы используете небольшой набор данных. Выбор DeeplabV3+ & Xception может не подойти, так как модель может быть слишком большой. Это может привести к переоснащению. Если вы еще не получили удовлетворительных результатов, вы можете попробовать меньшую сеть. Если вы хотите придерживаться DeepLab-фреймворка, вы можете переключить магистраль с сети Xception на MobileNetV2 (в официальной версии тензорного потока она уже реализована). В качестве альтернативы, вы можете попробовать использовать автономную сеть, такую ​​как начальная сеть с головкой FCN...

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

Надеюсь, это поможет! Ура, Фрэнк

Библиотека IBM Large Model Support (LMS) позволяет обучать большие глубокие нейронные сети, которые обычно исчерпывают память графического процессора во время обучения. LMS управляет этой избыточной подпиской на память GPU, временно заменяя тензоры на память хоста, когда они не нужны.

Описание - https://developer.ibm.com/components/ibm-power/articles/deeplabv3-image-segmentation-with-pytorch-lms/

Pytorch - https://github.com/IBM/pytorch-large-model-support

TensorFlow - https://github.com/IBM/tensorflow-large-model-support

Другие вопросы по тегам