github:https://github.com/ydhongHIT/DDRNet
复现参考文章:【工程测试与训练】使用 DDRNet 测试、训练cityscapes数据集、训练自己的数据集-CSDN博客
一、项目下载
1、代码下载
作者提供的测试工程:https://github.com/ydhongHIT/DDRNet,(仅使用其预训练模型)
其他开发者复现的完整工程:https://github.com/chenjun2hao/DDRNet.pytorch(下载下来重命名为 DDRNet_record)
预训练权重:
2、数据集
└──Data
├── cityscapes
├── 其他数据集
└── list (DDRNet工程中的【./data/list】)
3、配置环境
- pytorch==1.7.0
- 3080*2
- cuda==11.1
-numpy1.20之前的版本,,可以卸载当前版本,重新安装。
二、用cityscapes数据集训练
2.1、修改【experiments/cityscapes/ddrnet23_slim.yaml】中,设置DATASET的TEST_SET、 TEST的 MODEL_FILE
原文件中这行代码是注释过的,反注释这行代码,修改为自己文件所在的路径。
2.2更改【lib/core/function.py】中的 def test()
,
在预测时会被调用。但运行时会报错。只需将该函数用下面的函数替换
def test(config, test_dataset, testloader, model,
sv_dir='', sv_pred=True):
## 作者数据读取时,使用的opencv,所以我这里保存时也用opencv了
import cv2
## 我这里设置自己的颜色,当然代码生成颜色都可以。
COLOR = [
(0, 0, 0),
(174, 199, 232),
(152, 223, 138),
(31, 119, 180),
(255, 187, 120),
(188, 189, 34),
(140, 86, 75),
(255, 152, 150),
(214, 39, 40),
(197, 176, 213),
(148, 103, 189),
(196, 156, 148),
(23, 190, 207),
(178, 76, 76),
(247, 182, 210),
(66, 188, 102),
(219, 219, 141),
(140, 57, 197),
(202, 185, 52),
(51, 176, 203),
(200, 54, 131),]
## 保存图片,用于结果对比时,了解哪个颜色代表第几类别。当然图片的名字保存为自己的类别名是最ok了。
## 这里简单起见使用数字表示
color_path = "label_color/"
os.makedirs(color_path) if not os.path.exists(color_path) else None
for i in range(len(COLOR)):
img = np.zeros((500,500,3),dtype=np.uint8)
img =img+list(COLOR[i] )
# print(img)
cv2.imwrite(os.path.join(color_path, str(i)+".png"), img)
model.eval()
with torch.no_grad():
for _, batch in enumerate(tqdm(testloader)):
image, size, name = batch
size = size[0]
pred = test_dataset.multi_scale_inference(
config,
model,
image,
scales=config.TEST.SCALE_LIST,
flip=config.TEST.FLIP_TEST)
if pred.size()[-2] != size[0] or pred.size()[-1] != size[1]:
pred = F.interpolate(
pred, size[-2:],
mode='bilinear', align_corners=config.MODEL.ALIGN_CORNERS
)
if sv_pred:
image = image.squeeze(0)
image = image.numpy().transpose((1,2,0))
image *= test_dataset.std
image += test_dataset.mean
image *= 255.0
image = image.astype(np.uint8)
_, pred = torch.max(pred, dim=1)
pred = pred.squeeze(0).cpu().numpy()
## ================================================
## 将神经网络的输出pred,转换成color图片显示,便于观察
img_lbl = np.zeros((pred.shape[0],pred.shape[1],3),dtype=np.uint8)
pred_uni = np.unique(pred)
for s in range(len(pred_uni)):
mask = pred==s
img_lbl[mask] = list(COLOR[s])
## ================================================
## 将掩码添加到原图上,便于观察。
# image = image[:,:,[2,1,0]]
# image1 = Image.fromarray(image).convert('RGBA')
# image2 = Image.fromarray(img_lbl).convert('RGBA')
# img_merge = Image.blend(image1, image2, 0.5)
# img_merge = np.array(img_merge)[:,:,:3]
## 将掩码添加到原图上,便于观察。
image = image[:,:,[2,1,0]]
img_merge = image*0.5 + img_lbl*0.5
## ================================================
## 原图,标签图,叠加图 拼接保存。
image = np.concatenate([image, img_lbl, img_merge], axis=1)
sv_path = os.path.join(sv_dir, 'test_results')
if not os.path.exists(sv_path):
os.mkdir(sv_path)
cv2.imwrite(os.path.join(sv_path, name[0]+".png"), image)
3.设置双卡运行
【./experiments/cityscapes/ddrnet23_slim.py】中设置的是双卡,该文件内的 GPUS: ( )
并不能很好的设定网络具体使用的GPU的id,但后面运行时要使用相同的GPU个数,和这里括号内的个数要一致。
具体使用哪几个训练,比如想用id为4,5 的显卡训练,命令如下:
#cpu的个数
export OMP_NUM_THREADS=2
#设备4,5
export CUDA_VISIBLE_DEVICES=4,5
训练命令
python -m torch.distributed.launch --nproc_per_node=2 tools/train.py --cfg experiments/cityscapes/ddrnet23_slim.yaml
四、问题
1.输入是cpu,模型在Gpu上
修改lib/datasets/base_dataset.py中代码
添加
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device) # 确保模型在GPU上
image = image.to(device) # 确保输入图像在GPU上
2、GPUs也是元组(0,)可以根据元组中个数设置GPU个数。改为数字就是使用单卡训练
3、出现numpy错误 ,建议重新安装numpy
或者可以把已经弃用的函数名np.int逐一修改。
报错信息:
因为np.int在之后被弃用,改为int。但是模型中用的np.int较多,如出现错误,修改如下:
在根目录下使用全局搜索工具grep,可以检查项目中其他文件,
grep -r "np.int" .
根据搜索结果,逐一打开文件并进行替换。