我首先解释一下我的任务:我从两条不同的绳索上获得了近3000张图像。它们包含绳索1,绳索2和背景。我的标签/遮罩是图像,例如,像素值0表示背景,像素值1表示第一根绳子,而2表示第二根绳子。您可以在下面的图片1和2中看到输入图片和地面真理/标签。请注意,我的基本真理/标签只有3个值:0、1和2。
我的输入图片是灰色的,但是对于DeepLab,我将其转换为RGB图片,因为DeepLab是在RGB图片上训练的。但是我转换后的图片仍然不包含颜色。
该任务的想法是神经网络应该从绳索中学习结构,因此即使有knote,它也可以正确标记绳索。因此颜色信息并不重要,因为我的绳索具有不同的颜色,因此可以很容易地使用KMeans创建地面真相/标签。
对于此任务,我选择Keras中以TensorFlow作为后端的语义分割网络,称为DeepLab V3 +。我想用我的近3000张图像训练NN。图片的大小小于100MB,均为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
我的第一个问题是:
在我的实现中,我的图形卡几乎使用了所有内存(11GB)。我不知道为什么DeepLab的权重可能有那么大吗?我的Batchsize默认为32,我所有的近300张图像都小于100MB。我已经使用过config.gpu_options.allow_growth = True代码,请参见下面的代码。
一般问题:
有人知道我的任务有很好的语义分割NN吗?我不需要经过彩色图像训练的神经网络。但是我也不需要NN,它是用二进制地面真相图片训练的...
我用DeepLab测试了原始彩色图像(图片3),但是得到的结果标签不好...
到目前为止,这是我的代码:
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()
最佳答案
第一个问题:DeepLabV3 +是一个非常大的模型(我假设您使用的是Xception骨干网!!),对于32×200x300像素的bachsize,11 GB的GPU容量是完全正常的:)(训练DeeplabV3 +,我大约需要2GB。 11 GB,批处理大小为5(500x500像素)。问题第二句话的一个注释:所需的GPU资源受许多因素(模型,优化器,批处理大小,图像裁剪,预处理等)的影响,但数据集的实际大小不应该影响它。因此,您的数据集是300MB还是300GB都没有关系。
一般问题:您正在使用一个小的数据集。选择DeeplabV3 +和Xception可能不合适,因为模型可能太大。这可能会导致过度拟合。如果尚未获得令人满意的结果,则可以尝试使用较小的网络。如果要坚持使用DeepLab框架,则可以将主干从Xception网络切换到MobileNetV2(在正式的tensorflow版本中已经实现)。另外,您可以尝试使用独立网络,例如带有FCN头的Inception网络...
在每种情况下,必须使用具有训练有素的特征表示的预训练编码器。如果找不到基于灰度输入图像的理想模型的良好初始化,只需使用在RGB图像上预训练的模型,然后使用灰度数据集扩展预训练(基本上,您可以将任何大型rgb数据集转换为灰度)并在使用数据之前微调灰度输入的权重。
我希望这有帮助!干杯,弗兰克