2023年11月29日发(作者:)

【实验记录】PSPNetPyTorch

⽂章⽬录

环境配置

#

创建虚拟环境

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,半天没

反应过来。