2023年11月29日发(作者:)
【实验记录】PSPNet(PyTorch)
⽂章⽬录
环境配置
#
创建虚拟环境
conda create -n pytorch-pspnet python==3.7
pip install torch==1.0.0
pip install tensorboardX
conda install opencv
conda install pillow
conda install pyaml
# clone
源⽂件
git clone https://github.com/hszhao/semseg.git
环境配置过程中的问题记录:
1)pip install apex 后 import 报错
TypeError: Class advice impossible in Python3. Use the @implementer class decorator instead
参考:
解决: 卸载 pip 安装的 apex,确保当前 CUDA 版本和 PyTorch 版本⼀致的前提下,执⾏:
git clone https://github.com/NVIDIA/apex.git
cd apex
pip install -v --no-cache-dir --global-option="--cpp_ext" --global-option="--cuda_ext" .
注意: 不要忘记第三条命令最后的点
# 安装 apex 时报错
FileNotFoundError: [Errno 2] No such file or directory: '/home/usr/local/cuda-9.0:/bin/nvcc': '/home/usr/local/cuda-9.0:/bin/nvcc'
发现很奇怪的在路径⾥多了 ,输⼊ 检查环境变量,看来应该是 前⾯冒号的问题。
“:”vi ~/.bashrc:$PATH
# :$CUDA_HOME
将后⾯的删掉
export CUDA_HOME=/data/zyy/usr/local/cuda-9.0:$CUDA_HOME
source ~/.bashrc
2)opencv 报错
image = or(image, _BGR2RGB) # convert cv2 read image from BGR order to RGB order
: OpenCV(3.4.2) /tmp/build/80754af9/opencv-suite_74/work/modules/imgproc/src/:253: error: (-215:Assertion failed) VScn:
:contains(scn) && VDcn::contains(dcn) && VDepth::contains(depth) in function 'CvtHelper'
参考:
解决: 看到是在 BGR 转 RGB 时出了错,在尝试过上⾯两种⽅法之后,均排除了这些问题,后来通过加⼊ 发
image = ('uint8')
现数据异常,为 ‘NoneType’,说明数据没有被正确加载,通过检查 的 37 ⾏左右:
util/
image_name = (data_root, line_split[0])
label_name = (data_root, line_split[1])
打印输出 image_name,发现果然是路径不对,要确保数据的索引⽂件格式为这样:
JPEGImages/2007_ SegmentationClassAug/2007_
修改好之后问题解决。
在VOC数据集上训练
1. 数据集
这⾥⽤的是 VOC 增强数据集,⽂章内有说明如何组织数据。
将数据 放在 下,数据集索引⽂件放在 下,
SegmentationClassAugsemseg/dataset/voc2012semseg/dataset/voc2012/ImageSets/Segmentation
修改 ⽬录下的配置⽂件⽬录设置。
config/voc2012/
这⾥需要的⽂件只有原图(JPEGImages),标签⽂件(SegmentatinClass),数据划分⽂件(ImageSets)和 以及
。
#
配置⽂件,主要留意⼀下路径要正确
DATA:
data_root: /data/zyy/code/semseg/dataset/voc2012
train_list: /data/zyy/code/semseg/dataset/voc2012/ImageSets/Segmentation/train_aug.txt
val_list: /data/zyy/code/semseg/dataset/voc2012/ImageSets/Segmentation/val.txt
classes: 21
另外,由于显存⼤⼩不够,训练 batch 适当减⼩,这⾥设置为了 5。
2. 执⾏训练
sh tool/ voc2012 pspnet101
第⼀个参数是数据集名称,第⼆个参数是⽹络名称
在 可以下载预训练模型,将模型放在 ⽂件夹下即可。
initmodel
如果要取消预训练:
# model/ 30
修改第⾏
pretrained=False
在训练时进⾏验证:
#
TRAIN:
...
evaluate: True # evaluate on validation set, extra gpu memory needed and small batch_size_val is recommend
训练正常跑起来输出:
3. 执⾏测试
将训练好的 model 放在 ⽂件中指定的路径下,或者修改 ⽂件的路径指向 model 所在位置,都可以很随意~
configconfig
这⾥我先⽤验证集做测试(因为 VOC 数据的测试集没有 ground-truth)
#
TEST:
test_list: /data/zyy/code/semseg/dataset/voc2012/ImageSets/Segmentation/val.txt
split: val # split in [train, val and test]
base_size: 512 # based size for scaling
test_h: 473
test_w: 473
scales: [1.0] # evaluation scales, ms as [0.5, 0.75, 1.0, 1.25, 1.5, 1.75]
has_prediction: False # has prediction already or not
index_start: 0 # evaluation start index in list
index_step: 0 # evaluation step index in list, 0 means to end
test_gpu: [0,1]
model_path: exp/voc2012/pspnet101/model/train_epoch_80.pth # evaluation model path
save_folder: exp/voc2012/pspnet101/result/epoch_80/val # results save folder
colors_path: dataset/voc2012/voc2012_colors.txt # path of dataset colors
names_path: dataset/voc2012/voc2012_names.txt # path of dataset category names
test_list
:要做测试的图⽚索引txt⽂件
运⾏测试程序执⾏命令:
sh tool/test.sh voc2012 pspnet101
第⼀个参数是模型名称,第⼆个参数是⽹络名称
测试问题记录:
# 错误信息
RuntimeError: cuda runtime error (11) : invalid argument at /pytorch/aten/src/THC/:405
解决: 原因可能是 1)多GPU测试,或者 2)PyTorch版本与显卡不兼容。
在这⾥我的报错是由于后者,我的显卡是 RTX2080(Ti),PyTorch 1.0,如果换成 RTX1080(Ti)就没有问题,⽐较简单的解决⽅案是,
将 python ⽂件中的 设置成 ,即可得到⼀个静态 CUDA error,此时虽然报错但并不影响后
ark = TrueFalse
⾯的运⾏。
4. 可视化
# 使⽤ tensorboard 可视化训练过程
tensorboard --logdir=run1:$EXP1,run2:$EXP2 --port=6789
quick demo:
PYTHONPATH=./ python tool/demo.py --config=config/ade20k/ade20k_pspnet50.yaml --image=figure/demo/ADE_val_00001515.jpg TEST.scales '[1.0]'
--config
:配置⽂件的路径
--image
:要测试的图⽚路径
在⾃⼰的数据集上训练
为了避免改名称的⿇烦,⾃⼰的数据也套⽤ VOC 数据的组织格式和名称。将⾃⼰的数据放在 下,分别⽤
semseg/dataset/voc2012
JPEGImagesSegmentationClass
和 存放训练图像和标签⽂件。
在 下,⽣成⾃⼰数据集的 和 索引⽂件,注意格式为:
voc2012/ImageSets/Segmentation
#
JPEGImages/图⽚名.后缀 SegmentationClass/标签名.后缀
JPEGImages/图⽚名.后缀 SegmentationClass/标签名.后缀
...
提供⼀个转换⾃⼰数据的脚本,前提时你的索引⽂件同原 VOC 数据索引⽂件格式相同,每⾏只有图⽚数据的名称,运⾏以下脚本⽣成新的
txt ⽂件:
import os
def create_txt(file, out_file):
if os.path.exists(out_file):
os.remove(out_file)
old_file = open(file)
new_file = open(out_file, 'w')
lines = old_file.readlines()
for line in lines:
line = line.strip('n')
new_line = 'JPEGImages/'+line+'.png' +' '+'SegmentationClass/'+line+'.png'+'n'
new_file.write(new_line)
old_file.close()
new_file.close()
if __name__=='__main__':
root = 'pathtoSegmentation'
ori_file = os.path.join(root, '')
out_file = os.path.join(root, 'trainval_')
create_txt(ori_file, out_file)
在 ⽬录下对配置⽂件 ,根据⾃⼰数据特点修改训练参数:
config/voc2012/.yaml
#
配置⽂件,主要留意⼀下路径要正确
DATA:
data_root: /data/zyy/code/semseg/dataset/voc2012
train_list: /data/zyy/code/semseg/dataset/voc2012/ImageSets/Segmentation/train.txt
val_list: /data/zyy/code/semseg/dataset/voc2012/ImageSets/Segmentation/val.txt
classes: 2
...
train_h: 512
train_w: 512
batch_size: 5
建⽴⽂件 和 ,根据⾃⼰数据集的类别进⾏修改:其中 names ⽂件是数据集的类别名称,colors ⽂
voc2012_voc2012_
件是最后测试时为不同类别覆盖的颜⾊,⽐如第⼀⾏ 就对应背景⿊⾊, 对应第⼀个飞机类别的红⾊,⾃⼰根据情况设置就好
0 0 0128 0 0
了。
依然执⾏训练命令:
sh tool/ voc2012 pspnet101
注意1: 数据集的 label 要确保是 uint8 的(位深度=8),根据类别个数设定每⼀类在 label 上的像素值,⽐如我的⼆分类就是背景像素
值为 0,前景像素值为 1。
注意2: 在做测试时,可以选择⽤ val 或 test 数据,其中 split 等于 val 时需要提供标签,⽽ test 不需要提供标签。
训练问题记录:
# 错误信息
/pytorch/aten/src/THCUNN/:99: void cunn_SpatialClassNLLCriterion_updateOutput_kernel(T *, T *, T *, long *, T *, int, int, int, in
t, int, long) [with T = float, AccumT = float]: block: [3,0,0], thread: [672,0,0] Assertion `t >= 0 && t < n_classes` failed.
RuntimeError: cuDNN error: CUDNN_STATUS_MAPPING_ERROR
解决:查了很久的原因,蠢了。忘记了 VOC 数据最基本的东西,其标签像素值就代表了类别,背景类像素值为 0,第⼀类像素值为 1,以
此类推… 最重要的是 255 是 ignored label,在⾃然图像⾥表⽰描边,是会被忽略的。我⽤的眼底数据集很坑,背景像素是 255,半天没
反应过来。


发布评论