我已经在 CelebAMask-HQ 数据集 ( https://github.com/switchablenorms/CelebAMask-HQ ) 上训练了官方的 Tensorflow deeplab 模型 ( https://github.com/tensorflow/models/tree/master/research/deeplab ) ,拥有一个可以语义分割所有面部片段(例如眼睛、鼻子等)的模型。我在超参数设置上花费的时间很少,并使用默认设置:
CUDA_VISIBLE_DEVICES=0 python "${WORK_DIR}"/deeplab/train.py \
--logtostderr \
--train_split="train" \
--model_variant="xception_65" \
--atrous_rates=6 \
--atrous_rates=12 \
--atrous_rates=18 \
--output_stride=16 \
--decoder_output_stride=4 \
--train_crop_size="1025,1025" \
--train_batch_size=2 \
--training_number_of_steps=45000 \
--fine_tune_batch_norm=false \
--tf_initial_checkpoint="${WORK_DIR}/deeplab/pretrained_models/deeplabv3_pascal_trainval/model.ckpt" \
--train_logdir="${WORK_DIR}/deeplab/logs" \
--dataset="celeba" \
--dataset_dir="${WORK_DIR}/deeplab/datasets/celeba/tfrecords_padded/"
我唯一调整的是类权重,其中我根据总数据集中属于每个类的所有像素的比率计算了类权重。这些计算的比率是:
class_ratio = {0: 0.287781127731224, #BG
1: 0.31428004829848194, #hair
2: 0.25334614328648697, #face
3: 0.008209905199792278, #brows
4: 0.0044636011242926155, #eyes
5: 0.020564768086557928, #nose
6: 0.004150659950132944, #u_lip
7: 0.00680743101856918, #l_lip
8: 0.0030163743167156494, #mouth
9: 0.040800302545885576, #neck
10: 0.008106960279456135, #ears
11: 0.03355246488702522, #clothes
12: 0.009293231642880359, #hat
13: 0, #ear_ring -> 0
14: 0, #glasses -> 0
15: 0 #necklace -> 0
}
作为类权重,我取1/<class_ratio>
,所以背景的类权重是 3.57,眉毛的类权重是 121.95。
最后,我做了一些数据增强,比如旋转、翻转和改变亮度。
我的结果相当不错,但是当我将训练集的一些图像输入到模型中时,有一些值得注意的地方。在原始分段下方:
如您所见,分割的结果非常好,但尤其是眼睛、眉毛和鼻子等较小的类别并没有像我希望的那样“紧密分割”。基本上对于所有被模型分割的图像,眼睛、鼻子和眉毛都大于原始分割。因此,我想更改一些超参数以获得更小类的更严格的分割结果。
关于为较小的班级获得更严格的结果的可能方法有什么建议吗?我目前根据总数据集中属于每个类的像素的绝对百分比计算类权重的方法效果很好,但也许另一种计算类权重的方法效果更好?还是能够进行精细分割的不同底层模型结构?
任何帮助表示赞赏。谢谢!