小菊的语义分割3🌼——数据预处理及像素级分类实现原理
1. 数据预处理
思路: 读取train.txt文件,获取训练图像及对应标签的文件路径,读取图像,将图像转化为tensor之后,resize调整图像尺寸大小并进行归一化处理,之后也可通过旋转,色偏,增加噪声等方式进行数据增强。注意要保证图像和标签的处理一致。
padding可以使图像在resize时不失真
2. label map 标签映射
如图就是我们的语义分割标签图像,相同颜色(像素值)的像素点代表的是同一类物体。假设像我们这个标签图像所展示的那样,我们需要分割出来图片中的猫和狗,那对我们的语义分割任务来说就是总共要分3类:0 背景;1 猫;2 狗;因此,我们需要创建一个[Height, Width, N_classes]数组来表示每一个像素点的类别;如下图所示:
label[0, 0] = [1, 0, 0] 说明[0, 0]位置是背景,label[1, 1] = [0, 1, 0]说明[1, 1]这个像素点属于猫。我们Reshape之后好像更方便大家理解:
seg_labels = np.reshape(seg_labels, (-1,NCLASSES))
[[1, 0, 0],
[1, 0, 0],
[1, 0, 0],
[1, 0, 0],
[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
[0, 0, 1],
...
]
这就是我们最后用来和预测结果计算损失的数据啦🌼相信大家对为什么这样做还有点云里雾里的感觉,那么接下来就让我们揭开语义分割的神秘面纱吧🌼
3. 像素级分类原理
了解完lable的具体格式之后,我们来看一下网络的最后几层设计:
x = Conv2D(n_classes,(1,1), padding='vaild' )(x)
x = Reshape((-1,n_classes))(x)
output = Softmax()(x)
这个和我们label的处理是一致的,输出的是每一个像素点属于哪一类的概率,如下图:
tensor表示:
[[0.4, 0.3, 0.3],
[0.7, 0.2, 0.1],
[0.8, 0.2, 0.0],
[0.8, 0.1, 0.1],
...
]
将我们处理之后的label和预测得到的结果传给我们的损失函数就能计算出loss了,这样我们就实现了像素级的分类————也就是语义分割了🌼
下面是包含了数据预处理,损失定义等整个模型训练过程的train.py文件,大家稍作修改就可以训练自己的语义分割模型了🌼
import numpy as np
from PIL import Image
import keras
from keras import backend as K
from keras.optimizers import Adam
from keras.layers import Lambda
from keras.callbacks import TensorBoard, ModelCheckpoint, ReduceLROnPlateau, EarlyStopping
# 标签像素值对应的物体类别, 0为背景
CLASSES = {
'[0 0 0]' : 0, # 背景
'[7 7 7]' : 1,
'[26 26 26]' : 2,
}
NCLASSES = 2
HEIGHT = 576
WIDTH = 576
BATCH_SIZE = 2
# train.txt和val.txt的文件路径
path_train_txt = ''
path_val_txt = ''
# train的图像和标签路径
path_Xtrain = ''
path_Xlabel = ''
# val的图像和标签路径
path_Yval = ''
path_Ylabel = ''
# labels映射
def label_map(labels):
labelmap = np.zeros((int(HEIGHT),int(WIDTH),NCLASSES))
for h in range(int(HEIGHT)):
for w in range(int(WIDTH)):
if str(labels[h, w]) in CLASSES.keys():
c = CLASSES[str(labels[h, w])]
else:
c = 0
labelmap[h, w, c] = 1
return labelmap
def data_generator(mode):
assert mode in ['train', 'val'], \
'mode must be ethier \'train\' or \'val\''
if mode == 'train':
with open(path_train_txt, 'r') as f:
lines = f.readlines()
np.random.shuffle(lines)
n = len

本文详细介绍了语义分割任务中数据预处理的步骤,包括图像尺寸调整、归一化、数据增强等,并阐述了标签映射和像素级分类原理。通过Keras和TensorFlow实现模型训练,利用数据生成器加载数据,定义损失函数并进行模型编译与训练。同时,展示了如何优化标签处理以提高效率。

794

被折叠的 条评论
为什么被折叠?



