├── README.md ├── Result └── deeplab-v3P │ ├── 1.png │ ├── 2.png │ ├── top_mosaic_09cm_area6.tif │ └── top_mosaic_09cm_area8.tif ├── dataset ├── test_path_list.csv ├── train_path_list.csv └── val_path_list.csv ├── deeplab_v3p.py ├── deeplab_v3p_train.py ├── predict.py └── utils ├── Median_frequency_balance.py ├── color_utils.py ├── compute_mean.py └── data_utils.py /README.md: -------------------------------------------------------------------------------- 1 | # Deeplab v3-Plus 2 | Deeplab v3-plus for semantic segmentation of remote sensing(pytorch) 3 | 4 | ## 数据集: 5 | 在ISPRS Vaihigen 2D语义标签比赛数据集上评估了deeplab v3+的表现。该数据集由33张大小不同的高分辨率遥感影像组成,每张影像都是从德国Vaihigen市高空中获取的真正射影象(TOP)。在某种程度上,这个数据集的遥感印象与普通的自然影像没有差别,他们均是由三个通道组成。所以,我们可以将其看作是普通图片。数据集还包括与每个影像对应的归一化数字表面模型(nDSM)。在这33张图像中,16张提供了精细标注的ground truth,其余17张并未公布ground truth。整个数据集包含六个类别:不透水表面、建筑、低植被、树木、汽车、杂波/背景。 6 | 7 | ## 文件夹列表: 8 | + dataset:存放处理好的数据集的文件夹(处理好的数据集太大没办法放上来,所以以下train、val、test文件夹是没有上传的。可以去官网http://www2.isprs.org/commissions/comm2/wg4/vaihingen-2d-semantic-labeling-contest.html 9 | 下载然后自己处理,裁剪成512×512的图片,并自己划分训练集与验证集) 10 | + train文件夹:存放训练集图片; 11 | + val文件夹:存放验证集图片 12 | + test文件夹:存放测试集图片 13 | + train_path_list.csv:存放训练集图片及标签的实际存储位置的索引文件 14 | + val_path_list.csv:存放验证集图片及标签的实际存储位置的索引文件 15 | + test_path_list.csv:存放测试集图片实际存储位置的索引文件 16 | + Result:保存模型参数与预测结果的文件夹 17 | + utils: 18 | + data_utils:读取数据 19 | + color_utils:给预测图上色 20 | + Median_frequency_balance.py:计算各类别权重 21 | + compute_mean.py:计算数据集均值、方差 22 | + deeplab_v3p.py:deeplab v3 plus的模型 23 | + deeplab_v3p_train.py:想要训练模型直接运行这个文件 24 | + predict.py:多尺度测试。使用训练好的模型进行预测 25 | 26 | ## 预测结果展示: 27 | 见Result/deeplab v3P/1.png与Result/deeplab v3P/2.png,这个文件夹下其他两张图是这两张预测图对应的原图 28 | -------------------------------------------------------------------------------- /Result/deeplab-v3P/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AI-Chen/Deeplab-v3-Plus-pytorch-/1810d3ce5e003a6f5802dcb5585ccded1435bc16/Result/deeplab-v3P/1.png -------------------------------------------------------------------------------- /Result/deeplab-v3P/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AI-Chen/Deeplab-v3-Plus-pytorch-/1810d3ce5e003a6f5802dcb5585ccded1435bc16/Result/deeplab-v3P/2.png -------------------------------------------------------------------------------- /Result/deeplab-v3P/top_mosaic_09cm_area6.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AI-Chen/Deeplab-v3-Plus-pytorch-/1810d3ce5e003a6f5802dcb5585ccded1435bc16/Result/deeplab-v3P/top_mosaic_09cm_area6.tif -------------------------------------------------------------------------------- /Result/deeplab-v3P/top_mosaic_09cm_area8.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AI-Chen/Deeplab-v3-Plus-pytorch-/1810d3ce5e003a6f5802dcb5585ccded1435bc16/Result/deeplab-v3P/top_mosaic_09cm_area8.tif -------------------------------------------------------------------------------- /dataset/test_path_list.csv: -------------------------------------------------------------------------------- 1 | edge,image,label,ndsm,ndvi 2 | dataset/test/edges/0004.png,dataset/test/images/top_mosaic_09cm_area4.tif,dataset/test/labels/004.png,dataset/test/ndsms/00001.tif,dataset/test/ndvis/00001.tif 3 | dataset/test/edges/0006.png,dataset/test/images/top_mosaic_09cm_area6.tif,dataset/test/labels/006.png,dataset/test/ndsms/00002.tif,dataset/test/ndvis/00002.tif 4 | dataset/test/edges/0008.png,dataset/test/images/top_mosaic_09cm_area8.tif,dataset/test/labels/008.png,dataset/test/ndsms/00003.tif,dataset/test/ndvis/00003.tif 5 | dataset/test/edges/0010.png,dataset/test/images/top_mosaic_09cm_area10.tif,dataset/test/labels/010.png,dataset/test/ndsms/00004.tif,dataset/test/ndvis/00004.tif 6 | dataset/test/edges/0012.png,dataset/test/images/top_mosaic_09cm_area12.tif,dataset/test/labels/012.png,dataset/test/ndsms/00005.tif,dataset/test/ndvis/00005.tif 7 | dataset/test/edges/0014.png,dataset/test/images/top_mosaic_09cm_area14.tif,dataset/test/labels/014.png,dataset/test/ndsms/00006.tif,dataset/test/ndvis/00006.tif 8 | dataset/test/edges/0016.png,dataset/test/images/top_mosaic_09cm_area16.tif,dataset/test/labels/016.png,dataset/test/ndsms/00007.tif,dataset/test/ndvis/00007.tif 9 | dataset/test/edges/0022.png,dataset/test/images/top_mosaic_09cm_area22.tif,dataset/test/labels/022.png,dataset/test/ndsms/00008.tif,dataset/test/ndvis/00008.tif 10 | dataset/test/edges/0024.png,dataset/test/images/top_mosaic_09cm_area24.tif,dataset/test/labels/024.png,dataset/test/ndsms/00008.tif,dataset/test/ndvis/00008.tif 11 | dataset/test/edges/0035.png,dataset/test/images/top_mosaic_09cm_area35.tif,dataset/test/labels/035.png,dataset/test/ndsms/00008.tif,dataset/test/ndvis/00008.tif 12 | dataset/test/edges/0038.png,dataset/test/images/top_mosaic_09cm_area38.tif,dataset/test/labels/038.png,dataset/test/ndsms/00008.tif,dataset/test/ndvis/00008.tif 13 | -------------------------------------------------------------------------------- /dataset/val_path_list.csv: -------------------------------------------------------------------------------- 1 | edge,image,label,ndsm,ndvi 2 | dataset/val/edges/00001.png,dataset/val/images/00001.png,dataset/val/labels/00001.png,dataset/val/ndsms/00001.tif,dataset/val/ndvis/00001.tif 3 | dataset/val/edges/00002.png,dataset/val/images/00002.png,dataset/val/labels/00002.png,dataset/val/ndsms/00002.tif,dataset/val/ndvis/00002.tif 4 | dataset/val/edges/00003.png,dataset/val/images/00003.png,dataset/val/labels/00003.png,dataset/val/ndsms/00003.tif,dataset/val/ndvis/00003.tif 5 | dataset/val/edges/00004.png,dataset/val/images/00004.png,dataset/val/labels/00004.png,dataset/val/ndsms/00004.tif,dataset/val/ndvis/00004.tif 6 | dataset/val/edges/00005.png,dataset/val/images/00005.png,dataset/val/labels/00005.png,dataset/val/ndsms/00005.tif,dataset/val/ndvis/00005.tif 7 | dataset/val/edges/00006.png,dataset/val/images/00006.png,dataset/val/labels/00006.png,dataset/val/ndsms/00006.tif,dataset/val/ndvis/00006.tif 8 | dataset/val/edges/00007.png,dataset/val/images/00007.png,dataset/val/labels/00007.png,dataset/val/ndsms/00007.tif,dataset/val/ndvis/00007.tif 9 | dataset/val/edges/00008.png,dataset/val/images/00008.png,dataset/val/labels/00008.png,dataset/val/ndsms/00008.tif,dataset/val/ndvis/00008.tif 10 | dataset/val/edges/00009.png,dataset/val/images/00009.png,dataset/val/labels/00009.png,dataset/val/ndsms/00009.tif,dataset/val/ndvis/00009.tif 11 | dataset/val/edges/00010.png,dataset/val/images/00010.png,dataset/val/labels/00010.png,dataset/val/ndsms/00010.tif,dataset/val/ndvis/00010.tif 12 | dataset/val/edges/00011.png,dataset/val/images/00011.png,dataset/val/labels/00011.png,dataset/val/ndsms/00011.tif,dataset/val/ndvis/00011.tif 13 | dataset/val/edges/00012.png,dataset/val/images/00012.png,dataset/val/labels/00012.png,dataset/val/ndsms/00012.tif,dataset/val/ndvis/00012.tif 14 | dataset/val/edges/00013.png,dataset/val/images/00013.png,dataset/val/labels/00013.png,dataset/val/ndsms/00013.tif,dataset/val/ndvis/00013.tif 15 | dataset/val/edges/00014.png,dataset/val/images/00014.png,dataset/val/labels/00014.png,dataset/val/ndsms/00014.tif,dataset/val/ndvis/00014.tif 16 | dataset/val/edges/00015.png,dataset/val/images/00015.png,dataset/val/labels/00015.png,dataset/val/ndsms/00015.tif,dataset/val/ndvis/00015.tif 17 | dataset/val/edges/00016.png,dataset/val/images/00016.png,dataset/val/labels/00016.png,dataset/val/ndsms/00016.tif,dataset/val/ndvis/00016.tif 18 | dataset/val/edges/00017.png,dataset/val/images/00017.png,dataset/val/labels/00017.png,dataset/val/ndsms/00017.tif,dataset/val/ndvis/00017.tif 19 | dataset/val/edges/00018.png,dataset/val/images/00018.png,dataset/val/labels/00018.png,dataset/val/ndsms/00018.tif,dataset/val/ndvis/00018.tif 20 | dataset/val/edges/00019.png,dataset/val/images/00019.png,dataset/val/labels/00019.png,dataset/val/ndsms/00019.tif,dataset/val/ndvis/00019.tif 21 | dataset/val/edges/00020.png,dataset/val/images/00020.png,dataset/val/labels/00020.png,dataset/val/ndsms/00020.tif,dataset/val/ndvis/00020.tif 22 | dataset/val/edges/00021.png,dataset/val/images/00021.png,dataset/val/labels/00021.png,dataset/val/ndsms/00021.tif,dataset/val/ndvis/00021.tif 23 | dataset/val/edges/00022.png,dataset/val/images/00022.png,dataset/val/labels/00022.png,dataset/val/ndsms/00022.tif,dataset/val/ndvis/00022.tif 24 | dataset/val/edges/00023.png,dataset/val/images/00023.png,dataset/val/labels/00023.png,dataset/val/ndsms/00023.tif,dataset/val/ndvis/00023.tif 25 | dataset/val/edges/00024.png,dataset/val/images/00024.png,dataset/val/labels/00024.png,dataset/val/ndsms/00024.tif,dataset/val/ndvis/00024.tif 26 | dataset/val/edges/00025.png,dataset/val/images/00025.png,dataset/val/labels/00025.png,dataset/val/ndsms/00025.tif,dataset/val/ndvis/00025.tif 27 | dataset/val/edges/00026.png,dataset/val/images/00026.png,dataset/val/labels/00026.png,dataset/val/ndsms/00026.tif,dataset/val/ndvis/00026.tif 28 | dataset/val/edges/00027.png,dataset/val/images/00027.png,dataset/val/labels/00027.png,dataset/val/ndsms/00027.tif,dataset/val/ndvis/00027.tif 29 | dataset/val/edges/00028.png,dataset/val/images/00028.png,dataset/val/labels/00028.png,dataset/val/ndsms/00028.tif,dataset/val/ndvis/00028.tif 30 | dataset/val/edges/00029.png,dataset/val/images/00029.png,dataset/val/labels/00029.png,dataset/val/ndsms/00029.tif,dataset/val/ndvis/00029.tif 31 | dataset/val/edges/00030.png,dataset/val/images/00030.png,dataset/val/labels/00030.png,dataset/val/ndsms/00030.tif,dataset/val/ndvis/00030.tif 32 | dataset/val/edges/00031.png,dataset/val/images/00031.png,dataset/val/labels/00031.png,dataset/val/ndsms/00031.tif,dataset/val/ndvis/00031.tif 33 | dataset/val/edges/00032.png,dataset/val/images/00032.png,dataset/val/labels/00032.png,dataset/val/ndsms/00032.tif,dataset/val/ndvis/00032.tif 34 | dataset/val/edges/00033.png,dataset/val/images/00033.png,dataset/val/labels/00033.png,dataset/val/ndsms/00033.tif,dataset/val/ndvis/00033.tif 35 | dataset/val/edges/00034.png,dataset/val/images/00034.png,dataset/val/labels/00034.png,dataset/val/ndsms/00034.tif,dataset/val/ndvis/00034.tif 36 | dataset/val/edges/00035.png,dataset/val/images/00035.png,dataset/val/labels/00035.png,dataset/val/ndsms/00035.tif,dataset/val/ndvis/00035.tif 37 | dataset/val/edges/00036.png,dataset/val/images/00036.png,dataset/val/labels/00036.png,dataset/val/ndsms/00036.tif,dataset/val/ndvis/00036.tif 38 | dataset/val/edges/00037.png,dataset/val/images/00037.png,dataset/val/labels/00037.png,dataset/val/ndsms/00037.tif,dataset/val/ndvis/00037.tif 39 | dataset/val/edges/00038.png,dataset/val/images/00038.png,dataset/val/labels/00038.png,dataset/val/ndsms/00038.tif,dataset/val/ndvis/00038.tif 40 | dataset/val/edges/00039.png,dataset/val/images/00039.png,dataset/val/labels/00039.png,dataset/val/ndsms/00039.tif,dataset/val/ndvis/00039.tif 41 | dataset/val/edges/00040.png,dataset/val/images/00040.png,dataset/val/labels/00040.png,dataset/val/ndsms/00040.tif,dataset/val/ndvis/00040.tif 42 | dataset/val/edges/00041.png,dataset/val/images/00041.png,dataset/val/labels/00041.png,dataset/val/ndsms/00041.tif,dataset/val/ndvis/00041.tif 43 | dataset/val/edges/00042.png,dataset/val/images/00042.png,dataset/val/labels/00042.png,dataset/val/ndsms/00042.tif,dataset/val/ndvis/00042.tif 44 | dataset/val/edges/00043.png,dataset/val/images/00043.png,dataset/val/labels/00043.png,dataset/val/ndsms/00043.tif,dataset/val/ndvis/00043.tif 45 | dataset/val/edges/00044.png,dataset/val/images/00044.png,dataset/val/labels/00044.png,dataset/val/ndsms/00044.tif,dataset/val/ndvis/00044.tif 46 | dataset/val/edges/00045.png,dataset/val/images/00045.png,dataset/val/labels/00045.png,dataset/val/ndsms/00045.tif,dataset/val/ndvis/00045.tif 47 | dataset/val/edges/00046.png,dataset/val/images/00046.png,dataset/val/labels/00046.png,dataset/val/ndsms/00046.tif,dataset/val/ndvis/00046.tif 48 | dataset/val/edges/00047.png,dataset/val/images/00047.png,dataset/val/labels/00047.png,dataset/val/ndsms/00047.tif,dataset/val/ndvis/00047.tif 49 | dataset/val/edges/00048.png,dataset/val/images/00048.png,dataset/val/labels/00048.png,dataset/val/ndsms/00048.tif,dataset/val/ndvis/00048.tif 50 | dataset/val/edges/00049.png,dataset/val/images/00049.png,dataset/val/labels/00049.png,dataset/val/ndsms/00049.tif,dataset/val/ndvis/00049.tif 51 | dataset/val/edges/00050.png,dataset/val/images/00050.png,dataset/val/labels/00050.png,dataset/val/ndsms/00050.tif,dataset/val/ndvis/00050.tif 52 | dataset/val/edges/00051.png,dataset/val/images/00051.png,dataset/val/labels/00051.png,dataset/val/ndsms/00051.tif,dataset/val/ndvis/00051.tif 53 | dataset/val/edges/00052.png,dataset/val/images/00052.png,dataset/val/labels/00052.png,dataset/val/ndsms/00052.tif,dataset/val/ndvis/00052.tif 54 | dataset/val/edges/00053.png,dataset/val/images/00053.png,dataset/val/labels/00053.png,dataset/val/ndsms/00053.tif,dataset/val/ndvis/00053.tif 55 | dataset/val/edges/00054.png,dataset/val/images/00054.png,dataset/val/labels/00054.png,dataset/val/ndsms/00054.tif,dataset/val/ndvis/00054.tif 56 | dataset/val/edges/00055.png,dataset/val/images/00055.png,dataset/val/labels/00055.png,dataset/val/ndsms/00055.tif,dataset/val/ndvis/00055.tif 57 | dataset/val/edges/00056.png,dataset/val/images/00056.png,dataset/val/labels/00056.png,dataset/val/ndsms/00056.tif,dataset/val/ndvis/00056.tif 58 | dataset/val/edges/00057.png,dataset/val/images/00057.png,dataset/val/labels/00057.png,dataset/val/ndsms/00057.tif,dataset/val/ndvis/00057.tif 59 | dataset/val/edges/00058.png,dataset/val/images/00058.png,dataset/val/labels/00058.png,dataset/val/ndsms/00058.tif,dataset/val/ndvis/00058.tif 60 | dataset/val/edges/00059.png,dataset/val/images/00059.png,dataset/val/labels/00059.png,dataset/val/ndsms/00059.tif,dataset/val/ndvis/00059.tif 61 | dataset/val/edges/00060.png,dataset/val/images/00060.png,dataset/val/labels/00060.png,dataset/val/ndsms/00060.tif,dataset/val/ndvis/00060.tif 62 | dataset/val/edges/00061.png,dataset/val/images/00061.png,dataset/val/labels/00061.png,dataset/val/ndsms/00061.tif,dataset/val/ndvis/00061.tif 63 | dataset/val/edges/00062.png,dataset/val/images/00062.png,dataset/val/labels/00062.png,dataset/val/ndsms/00062.tif,dataset/val/ndvis/00062.tif 64 | dataset/val/edges/00063.png,dataset/val/images/00063.png,dataset/val/labels/00063.png,dataset/val/ndsms/00063.tif,dataset/val/ndvis/00063.tif 65 | dataset/val/edges/00064.png,dataset/val/images/00064.png,dataset/val/labels/00064.png,dataset/val/ndsms/00064.tif,dataset/val/ndvis/00064.tif 66 | dataset/val/edges/00065.png,dataset/val/images/00065.png,dataset/val/labels/00065.png,dataset/val/ndsms/00065.tif,dataset/val/ndvis/00065.tif 67 | dataset/val/edges/00066.png,dataset/val/images/00066.png,dataset/val/labels/00066.png,dataset/val/ndsms/00066.tif,dataset/val/ndvis/00066.tif 68 | dataset/val/edges/00067.png,dataset/val/images/00067.png,dataset/val/labels/00067.png,dataset/val/ndsms/00067.tif,dataset/val/ndvis/00067.tif 69 | dataset/val/edges/00068.png,dataset/val/images/00068.png,dataset/val/labels/00068.png,dataset/val/ndsms/00068.tif,dataset/val/ndvis/00068.tif 70 | dataset/val/edges/00069.png,dataset/val/images/00069.png,dataset/val/labels/00069.png,dataset/val/ndsms/00069.tif,dataset/val/ndvis/00069.tif 71 | dataset/val/edges/00070.png,dataset/val/images/00070.png,dataset/val/labels/00070.png,dataset/val/ndsms/00070.tif,dataset/val/ndvis/00070.tif 72 | dataset/val/edges/00071.png,dataset/val/images/00071.png,dataset/val/labels/00071.png,dataset/val/ndsms/00071.tif,dataset/val/ndvis/00071.tif 73 | dataset/val/edges/00072.png,dataset/val/images/00072.png,dataset/val/labels/00072.png,dataset/val/ndsms/00072.tif,dataset/val/ndvis/00072.tif 74 | dataset/val/edges/00073.png,dataset/val/images/00073.png,dataset/val/labels/00073.png,dataset/val/ndsms/00073.tif,dataset/val/ndvis/00073.tif 75 | dataset/val/edges/00074.png,dataset/val/images/00074.png,dataset/val/labels/00074.png,dataset/val/ndsms/00074.tif,dataset/val/ndvis/00074.tif 76 | dataset/val/edges/00075.png,dataset/val/images/00075.png,dataset/val/labels/00075.png,dataset/val/ndsms/00075.tif,dataset/val/ndvis/00075.tif 77 | dataset/val/edges/00076.png,dataset/val/images/00076.png,dataset/val/labels/00076.png,dataset/val/ndsms/00076.tif,dataset/val/ndvis/00076.tif 78 | dataset/val/edges/00077.png,dataset/val/images/00077.png,dataset/val/labels/00077.png,dataset/val/ndsms/00077.tif,dataset/val/ndvis/00077.tif 79 | dataset/val/edges/00078.png,dataset/val/images/00078.png,dataset/val/labels/00078.png,dataset/val/ndsms/00078.tif,dataset/val/ndvis/00078.tif 80 | dataset/val/edges/00079.png,dataset/val/images/00079.png,dataset/val/labels/00079.png,dataset/val/ndsms/00079.tif,dataset/val/ndvis/00079.tif 81 | dataset/val/edges/00080.png,dataset/val/images/00080.png,dataset/val/labels/00080.png,dataset/val/ndsms/00080.tif,dataset/val/ndvis/00080.tif 82 | dataset/val/edges/00081.png,dataset/val/images/00081.png,dataset/val/labels/00081.png,dataset/val/ndsms/00081.tif,dataset/val/ndvis/00081.tif 83 | dataset/val/edges/00082.png,dataset/val/images/00082.png,dataset/val/labels/00082.png,dataset/val/ndsms/00082.tif,dataset/val/ndvis/00082.tif 84 | dataset/val/edges/00083.png,dataset/val/images/00083.png,dataset/val/labels/00083.png,dataset/val/ndsms/00083.tif,dataset/val/ndvis/00083.tif 85 | dataset/val/edges/00084.png,dataset/val/images/00084.png,dataset/val/labels/00084.png,dataset/val/ndsms/00084.tif,dataset/val/ndvis/00084.tif 86 | dataset/val/edges/00085.png,dataset/val/images/00085.png,dataset/val/labels/00085.png,dataset/val/ndsms/00085.tif,dataset/val/ndvis/00085.tif 87 | dataset/val/edges/00086.png,dataset/val/images/00086.png,dataset/val/labels/00086.png,dataset/val/ndsms/00086.tif,dataset/val/ndvis/00086.tif 88 | dataset/val/edges/00087.png,dataset/val/images/00087.png,dataset/val/labels/00087.png,dataset/val/ndsms/00087.tif,dataset/val/ndvis/00087.tif 89 | dataset/val/edges/00088.png,dataset/val/images/00088.png,dataset/val/labels/00088.png,dataset/val/ndsms/00088.tif,dataset/val/ndvis/00088.tif 90 | dataset/val/edges/00089.png,dataset/val/images/00089.png,dataset/val/labels/00089.png,dataset/val/ndsms/00089.tif,dataset/val/ndvis/00089.tif 91 | dataset/val/edges/00090.png,dataset/val/images/00090.png,dataset/val/labels/00090.png,dataset/val/ndsms/00090.tif,dataset/val/ndvis/00090.tif 92 | dataset/val/edges/00091.png,dataset/val/images/00091.png,dataset/val/labels/00091.png,dataset/val/ndsms/00091.tif,dataset/val/ndvis/00091.tif 93 | dataset/val/edges/00092.png,dataset/val/images/00092.png,dataset/val/labels/00092.png,dataset/val/ndsms/00092.tif,dataset/val/ndvis/00092.tif 94 | dataset/val/edges/00093.png,dataset/val/images/00093.png,dataset/val/labels/00093.png,dataset/val/ndsms/00093.tif,dataset/val/ndvis/00093.tif 95 | dataset/val/edges/00094.png,dataset/val/images/00094.png,dataset/val/labels/00094.png,dataset/val/ndsms/00094.tif,dataset/val/ndvis/00094.tif 96 | dataset/val/edges/00095.png,dataset/val/images/00095.png,dataset/val/labels/00095.png,dataset/val/ndsms/00095.tif,dataset/val/ndvis/00095.tif 97 | dataset/val/edges/00096.png,dataset/val/images/00096.png,dataset/val/labels/00096.png,dataset/val/ndsms/00096.tif,dataset/val/ndvis/00096.tif 98 | dataset/val/edges/00097.png,dataset/val/images/00097.png,dataset/val/labels/00097.png,dataset/val/ndsms/00097.tif,dataset/val/ndvis/00097.tif 99 | dataset/val/edges/00098.png,dataset/val/images/00098.png,dataset/val/labels/00098.png,dataset/val/ndsms/00098.tif,dataset/val/ndvis/00098.tif 100 | dataset/val/edges/00099.png,dataset/val/images/00099.png,dataset/val/labels/00099.png,dataset/val/ndsms/00099.tif,dataset/val/ndvis/00099.tif 101 | dataset/val/edges/00100.png,dataset/val/images/00100.png,dataset/val/labels/00100.png,dataset/val/ndsms/00100.tif,dataset/val/ndvis/00100.tif 102 | dataset/val/edges/00101.png,dataset/val/images/00101.png,dataset/val/labels/00101.png,dataset/val/ndsms/00101.tif,dataset/val/ndvis/00101.tif 103 | dataset/val/edges/00102.png,dataset/val/images/00102.png,dataset/val/labels/00102.png,dataset/val/ndsms/00102.tif,dataset/val/ndvis/00102.tif 104 | dataset/val/edges/00103.png,dataset/val/images/00103.png,dataset/val/labels/00103.png,dataset/val/ndsms/00103.tif,dataset/val/ndvis/00103.tif 105 | dataset/val/edges/00104.png,dataset/val/images/00104.png,dataset/val/labels/00104.png,dataset/val/ndsms/00104.tif,dataset/val/ndvis/00104.tif 106 | dataset/val/edges/00105.png,dataset/val/images/00105.png,dataset/val/labels/00105.png,dataset/val/ndsms/00105.tif,dataset/val/ndvis/00105.tif 107 | dataset/val/edges/00106.png,dataset/val/images/00106.png,dataset/val/labels/00106.png,dataset/val/ndsms/00106.tif,dataset/val/ndvis/00106.tif 108 | dataset/val/edges/00107.png,dataset/val/images/00107.png,dataset/val/labels/00107.png,dataset/val/ndsms/00107.tif,dataset/val/ndvis/00107.tif 109 | dataset/val/edges/00108.png,dataset/val/images/00108.png,dataset/val/labels/00108.png,dataset/val/ndsms/00108.tif,dataset/val/ndvis/00108.tif 110 | dataset/val/edges/00109.png,dataset/val/images/00109.png,dataset/val/labels/00109.png,dataset/val/ndsms/00109.tif,dataset/val/ndvis/00109.tif 111 | dataset/val/edges/00110.png,dataset/val/images/00110.png,dataset/val/labels/00110.png,dataset/val/ndsms/00110.tif,dataset/val/ndvis/00110.tif 112 | dataset/val/edges/00111.png,dataset/val/images/00111.png,dataset/val/labels/00111.png,dataset/val/ndsms/00111.tif,dataset/val/ndvis/00111.tif 113 | dataset/val/edges/00112.png,dataset/val/images/00112.png,dataset/val/labels/00112.png,dataset/val/ndsms/00112.tif,dataset/val/ndvis/00112.tif 114 | dataset/val/edges/00113.png,dataset/val/images/00113.png,dataset/val/labels/00113.png,dataset/val/ndsms/00113.tif,dataset/val/ndvis/00113.tif 115 | dataset/val/edges/00114.png,dataset/val/images/00114.png,dataset/val/labels/00114.png,dataset/val/ndsms/00114.tif,dataset/val/ndvis/00114.tif 116 | dataset/val/edges/00115.png,dataset/val/images/00115.png,dataset/val/labels/00115.png,dataset/val/ndsms/00115.tif,dataset/val/ndvis/00115.tif 117 | dataset/val/edges/00116.png,dataset/val/images/00116.png,dataset/val/labels/00116.png,dataset/val/ndsms/00116.tif,dataset/val/ndvis/00116.tif 118 | dataset/val/edges/00117.png,dataset/val/images/00117.png,dataset/val/labels/00117.png,dataset/val/ndsms/00117.tif,dataset/val/ndvis/00117.tif 119 | dataset/val/edges/00118.png,dataset/val/images/00118.png,dataset/val/labels/00118.png,dataset/val/ndsms/00118.tif,dataset/val/ndvis/00118.tif 120 | dataset/val/edges/00119.png,dataset/val/images/00119.png,dataset/val/labels/00119.png,dataset/val/ndsms/00119.tif,dataset/val/ndvis/00119.tif 121 | dataset/val/edges/00120.png,dataset/val/images/00120.png,dataset/val/labels/00120.png,dataset/val/ndsms/00120.tif,dataset/val/ndvis/00120.tif 122 | dataset/val/edges/00121.png,dataset/val/images/00121.png,dataset/val/labels/00121.png,dataset/val/ndsms/00121.tif,dataset/val/ndvis/00121.tif 123 | dataset/val/edges/00122.png,dataset/val/images/00122.png,dataset/val/labels/00122.png,dataset/val/ndsms/00122.tif,dataset/val/ndvis/00122.tif 124 | dataset/val/edges/00123.png,dataset/val/images/00123.png,dataset/val/labels/00123.png,dataset/val/ndsms/00123.tif,dataset/val/ndvis/00123.tif 125 | dataset/val/edges/00124.png,dataset/val/images/00124.png,dataset/val/labels/00124.png,dataset/val/ndsms/00124.tif,dataset/val/ndvis/00124.tif 126 | dataset/val/edges/00125.png,dataset/val/images/00125.png,dataset/val/labels/00125.png,dataset/val/ndsms/00125.tif,dataset/val/ndvis/00125.tif 127 | dataset/val/edges/00126.png,dataset/val/images/00126.png,dataset/val/labels/00126.png,dataset/val/ndsms/00126.tif,dataset/val/ndvis/00126.tif 128 | dataset/val/edges/00127.png,dataset/val/images/00127.png,dataset/val/labels/00127.png,dataset/val/ndsms/00127.tif,dataset/val/ndvis/00127.tif 129 | dataset/val/edges/00128.png,dataset/val/images/00128.png,dataset/val/labels/00128.png,dataset/val/ndsms/00128.tif,dataset/val/ndvis/00128.tif 130 | dataset/val/edges/00129.png,dataset/val/images/00129.png,dataset/val/labels/00129.png,dataset/val/ndsms/00129.tif,dataset/val/ndvis/00129.tif 131 | dataset/val/edges/00130.png,dataset/val/images/00130.png,dataset/val/labels/00130.png,dataset/val/ndsms/00130.tif,dataset/val/ndvis/00130.tif 132 | dataset/val/edges/00131.png,dataset/val/images/00131.png,dataset/val/labels/00131.png,dataset/val/ndsms/00131.tif,dataset/val/ndvis/00131.tif 133 | dataset/val/edges/00132.png,dataset/val/images/00132.png,dataset/val/labels/00132.png,dataset/val/ndsms/00132.tif,dataset/val/ndvis/00132.tif 134 | dataset/val/edges/00133.png,dataset/val/images/00133.png,dataset/val/labels/00133.png,dataset/val/ndsms/00133.tif,dataset/val/ndvis/00133.tif 135 | dataset/val/edges/00134.png,dataset/val/images/00134.png,dataset/val/labels/00134.png,dataset/val/ndsms/00134.tif,dataset/val/ndvis/00134.tif 136 | dataset/val/edges/00135.png,dataset/val/images/00135.png,dataset/val/labels/00135.png,dataset/val/ndsms/00135.tif,dataset/val/ndvis/00135.tif 137 | dataset/val/edges/00136.png,dataset/val/images/00136.png,dataset/val/labels/00136.png,dataset/val/ndsms/00136.tif,dataset/val/ndvis/00136.tif 138 | dataset/val/edges/00137.png,dataset/val/images/00137.png,dataset/val/labels/00137.png,dataset/val/ndsms/00137.tif,dataset/val/ndvis/00137.tif 139 | dataset/val/edges/00138.png,dataset/val/images/00138.png,dataset/val/labels/00138.png,dataset/val/ndsms/00138.tif,dataset/val/ndvis/00138.tif 140 | dataset/val/edges/00139.png,dataset/val/images/00139.png,dataset/val/labels/00139.png,dataset/val/ndsms/00139.tif,dataset/val/ndvis/00139.tif 141 | dataset/val/edges/00140.png,dataset/val/images/00140.png,dataset/val/labels/00140.png,dataset/val/ndsms/00140.tif,dataset/val/ndvis/00140.tif 142 | dataset/val/edges/00141.png,dataset/val/images/00141.png,dataset/val/labels/00141.png,dataset/val/ndsms/00141.tif,dataset/val/ndvis/00141.tif 143 | dataset/val/edges/00142.png,dataset/val/images/00142.png,dataset/val/labels/00142.png,dataset/val/ndsms/00142.tif,dataset/val/ndvis/00142.tif 144 | dataset/val/edges/00143.png,dataset/val/images/00143.png,dataset/val/labels/00143.png,dataset/val/ndsms/00143.tif,dataset/val/ndvis/00143.tif 145 | dataset/val/edges/00144.png,dataset/val/images/00144.png,dataset/val/labels/00144.png,dataset/val/ndsms/00144.tif,dataset/val/ndvis/00144.tif 146 | dataset/val/edges/00145.png,dataset/val/images/00145.png,dataset/val/labels/00145.png,dataset/val/ndsms/00145.tif,dataset/val/ndvis/00145.tif 147 | dataset/val/edges/00146.png,dataset/val/images/00146.png,dataset/val/labels/00146.png,dataset/val/ndsms/00146.tif,dataset/val/ndvis/00146.tif 148 | dataset/val/edges/00147.png,dataset/val/images/00147.png,dataset/val/labels/00147.png,dataset/val/ndsms/00147.tif,dataset/val/ndvis/00147.tif 149 | dataset/val/edges/00148.png,dataset/val/images/00148.png,dataset/val/labels/00148.png,dataset/val/ndsms/00148.tif,dataset/val/ndvis/00148.tif 150 | dataset/val/edges/00149.png,dataset/val/images/00149.png,dataset/val/labels/00149.png,dataset/val/ndsms/00149.tif,dataset/val/ndvis/00149.tif 151 | dataset/val/edges/00150.png,dataset/val/images/00150.png,dataset/val/labels/00150.png,dataset/val/ndsms/00150.tif,dataset/val/ndvis/00150.tif 152 | dataset/val/edges/00151.png,dataset/val/images/00151.png,dataset/val/labels/00151.png,dataset/val/ndsms/00151.tif,dataset/val/ndvis/00151.tif 153 | dataset/val/edges/00152.png,dataset/val/images/00152.png,dataset/val/labels/00152.png,dataset/val/ndsms/00152.tif,dataset/val/ndvis/00152.tif 154 | dataset/val/edges/00153.png,dataset/val/images/00153.png,dataset/val/labels/00153.png,dataset/val/ndsms/00153.tif,dataset/val/ndvis/00153.tif 155 | dataset/val/edges/00154.png,dataset/val/images/00154.png,dataset/val/labels/00154.png,dataset/val/ndsms/00154.tif,dataset/val/ndvis/00154.tif 156 | dataset/val/edges/00155.png,dataset/val/images/00155.png,dataset/val/labels/00155.png,dataset/val/ndsms/00155.tif,dataset/val/ndvis/00155.tif 157 | dataset/val/edges/00156.png,dataset/val/images/00156.png,dataset/val/labels/00156.png,dataset/val/ndsms/00156.tif,dataset/val/ndvis/00156.tif 158 | dataset/val/edges/00157.png,dataset/val/images/00157.png,dataset/val/labels/00157.png,dataset/val/ndsms/00157.tif,dataset/val/ndvis/00157.tif 159 | dataset/val/edges/00158.png,dataset/val/images/00158.png,dataset/val/labels/00158.png,dataset/val/ndsms/00158.tif,dataset/val/ndvis/00158.tif 160 | dataset/val/edges/00159.png,dataset/val/images/00159.png,dataset/val/labels/00159.png,dataset/val/ndsms/00159.tif,dataset/val/ndvis/00159.tif 161 | dataset/val/edges/00160.png,dataset/val/images/00160.png,dataset/val/labels/00160.png,dataset/val/ndsms/00160.tif,dataset/val/ndvis/00160.tif 162 | -------------------------------------------------------------------------------- /deeplab_v3p.py: -------------------------------------------------------------------------------- 1 | import math 2 | import torch 3 | import torch.nn as nn 4 | import torch.nn.functional as F 5 | 6 | class Bottleneck(nn.Module): 7 | expansion = 4 8 | 9 | def __init__(self, inplanes, planes, stride=1, rate=1, downsample=None): 10 | super(Bottleneck, self).__init__() 11 | self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False) 12 | self.bn1 = nn.BatchNorm2d(planes) 13 | self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, 14 | dilation=rate, padding=rate, bias=False) 15 | self.bn2 = nn.BatchNorm2d(planes) 16 | self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False) 17 | self.bn3 = nn.BatchNorm2d(planes * 4) 18 | self.relu = nn.ReLU(inplace=True) 19 | self.downsample = downsample 20 | self.stride = stride 21 | self.rate = rate 22 | 23 | def forward(self, x): 24 | residual = x 25 | 26 | out = self.conv1(x) 27 | out = self.bn1(out) 28 | out = self.relu(out) 29 | 30 | out = self.conv2(out) 31 | out = self.bn2(out) 32 | out = self.relu(out) 33 | 34 | out = self.conv3(out) 35 | out = self.bn3(out) 36 | 37 | if self.downsample is not None: 38 | residual = self.downsample(x) 39 | 40 | out += residual 41 | out = self.relu(out) 42 | 43 | return out 44 | 45 | class ResNet(nn.Module): 46 | 47 | def __init__(self, nInputChannels, block, layers, os=16, pretrained=False): 48 | self.inplanes = 64 49 | super(ResNet, self).__init__() 50 | if os == 16: 51 | strides = [1, 2, 2, 1] 52 | rates = [1, 1, 1, 2] 53 | blocks = [1, 2, 4] 54 | elif os == 8: 55 | strides = [1, 2, 1, 1] 56 | rates = [1, 1, 2, 2] 57 | blocks = [1, 2, 1] 58 | else: 59 | raise NotImplementedError 60 | 61 | # Modules 62 | self.conv1 = nn.Conv2d(nInputChannels, 64, kernel_size=7, stride=2, padding=3, bias=False) 63 | self.bn1 = nn.BatchNorm2d(64) 64 | self.relu = nn.ReLU(inplace=True) 65 | self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) 66 | 67 | self.layer1 = self._make_layer(block, 64, layers[0], stride=strides[0], rate=rates[0]) 68 | self.layer2 = self._make_layer(block, 128, layers[1], stride=strides[1], rate=rates[1]) 69 | self.layer3 = self._make_layer(block, 256, layers[2], stride=strides[2], rate=rates[2]) 70 | self.layer4 = self._make_MG_unit(block, 512, blocks=blocks, stride=strides[3], rate=rates[3]) 71 | 72 | self._init_weight() 73 | 74 | if pretrained: 75 | self._load_pretrained_model() 76 | 77 | def _make_layer(self, block, planes, blocks, stride=1, rate=1): 78 | downsample = None 79 | if stride != 1 or self.inplanes != planes * block.expansion: 80 | downsample = nn.Sequential( 81 | nn.Conv2d(self.inplanes, planes * block.expansion, 82 | kernel_size=1, stride=stride, bias=False), 83 | nn.BatchNorm2d(planes * block.expansion), 84 | ) 85 | 86 | layers = [] 87 | layers.append(block(self.inplanes, planes, stride, rate, downsample)) 88 | self.inplanes = planes * block.expansion 89 | for i in range(1, blocks): 90 | layers.append(block(self.inplanes, planes)) 91 | 92 | return nn.Sequential(*layers) 93 | 94 | def _make_MG_unit(self, block, planes, blocks=[1,2,4], stride=1, rate=1): 95 | downsample = None 96 | if stride != 1 or self.inplanes != planes * block.expansion: 97 | downsample = nn.Sequential( 98 | nn.Conv2d(self.inplanes, planes * block.expansion, 99 | kernel_size=1, stride=stride, bias=False), 100 | nn.BatchNorm2d(planes * block.expansion), 101 | ) 102 | 103 | layers = [] 104 | layers.append(block(self.inplanes, planes, stride, rate=blocks[0]*rate, downsample=downsample)) 105 | self.inplanes = planes * block.expansion 106 | for i in range(1, len(blocks)): 107 | layers.append(block(self.inplanes, planes, stride=1, rate=blocks[i]*rate)) 108 | 109 | return nn.Sequential(*layers) 110 | 111 | def forward(self, input): 112 | x = self.conv1(input) 113 | x = self.bn1(x) 114 | x = self.relu(x) 115 | x = self.maxpool(x) 116 | 117 | x = self.layer1(x) 118 | low_level_feat = x 119 | x = self.layer2(x) 120 | x = self.layer3(x) 121 | x = self.layer4(x) 122 | return x, low_level_feat 123 | 124 | def _init_weight(self): 125 | for m in self.modules(): 126 | if isinstance(m, nn.Conv2d): 127 | # n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels 128 | # m.weight.data.normal_(0, math.sqrt(2. / n)) 129 | torch.nn.init.kaiming_normal_(m.weight) 130 | elif isinstance(m, nn.BatchNorm2d): 131 | m.weight.data.fill_(1) 132 | m.bias.data.zero_() 133 | 134 | def _load_pretrained_model(self): 135 | pretrain_dict = torch.load("utils/resnet101-5d3b4d8f.pth", map_location=torch.device('cpu')) 136 | model_dict = {} 137 | state_dict = self.state_dict() 138 | for k, v in pretrain_dict.items(): 139 | if k in state_dict: 140 | model_dict[k] = v 141 | state_dict.update(model_dict) 142 | self.load_state_dict(state_dict) 143 | 144 | def ResNet101(nInputChannels=3, os=16, pretrained=False): 145 | model = ResNet(nInputChannels, Bottleneck, [3, 4, 23, 3], os, pretrained=pretrained) 146 | return model 147 | 148 | class ASPP_module(nn.Module): 149 | def __init__(self, inplanes, planes, rate): 150 | super(ASPP_module, self).__init__() 151 | if rate == 1: 152 | kernel_size = 1 153 | padding = 0 154 | else: 155 | kernel_size = 3 156 | padding = rate 157 | self.atrous_convolution = nn.Conv2d(inplanes, planes, kernel_size=kernel_size, 158 | stride=1, padding=padding, dilation=rate, bias=False) 159 | self.bn = nn.BatchNorm2d(planes) 160 | self.relu = nn.ReLU() 161 | 162 | self._init_weight() 163 | 164 | def forward(self, x): 165 | x = self.atrous_convolution(x) 166 | x = self.bn(x) 167 | 168 | return self.relu(x) 169 | 170 | def _init_weight(self): 171 | for m in self.modules(): 172 | if isinstance(m, nn.Conv2d): 173 | # n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels 174 | # m.weight.data.normal_(0, math.sqrt(2. / n)) 175 | torch.nn.init.kaiming_normal_(m.weight) 176 | elif isinstance(m, nn.BatchNorm2d): 177 | m.weight.data.fill_(1) 178 | m.bias.data.zero_() 179 | 180 | class DeepLabv3_plus(nn.Module): 181 | def __init__(self, nInputChannels=3, n_classes=21, os=16, pretrained=False, _print=True): 182 | if _print: 183 | print("Constructing DeepLabv3+ model...") 184 | print("Number of classes: {}".format(n_classes)) 185 | print("Output stride: {}".format(os)) 186 | print("Number of Input Channels: {}".format(nInputChannels)) 187 | super(DeepLabv3_plus, self).__init__() 188 | 189 | # Atrous Conv 190 | self.resnet_features = ResNet101(nInputChannels, os, pretrained=pretrained) 191 | 192 | # ASPP 193 | if os == 16: 194 | rates = [1, 6, 12, 18] 195 | elif os == 8: 196 | rates = [1, 12, 24, 36] 197 | else: 198 | raise NotImplementedError 199 | 200 | self.aspp1 = ASPP_module(2048, 256, rate=rates[0]) 201 | self.aspp2 = ASPP_module(2048, 256, rate=rates[1]) 202 | self.aspp3 = ASPP_module(2048, 256, rate=rates[2]) 203 | self.aspp4 = ASPP_module(2048, 256, rate=rates[3]) 204 | 205 | self.relu = nn.ReLU() 206 | 207 | self.global_avg_pool = nn.Sequential(nn.AdaptiveAvgPool2d((1, 1)), 208 | nn.Conv2d(2048, 256, 1, stride=1, bias=False), 209 | 210 | nn.ReLU()) 211 | 212 | self.conv1 = nn.Conv2d(1280, 256, 1, bias=False) 213 | self.bn1 = nn.BatchNorm2d(256) 214 | 215 | # adopt [1x1, 48] for channel reduction. 216 | self.conv2 = nn.Conv2d(256, 48, 1, bias=False) 217 | self.bn2 = nn.BatchNorm2d(48) 218 | 219 | self.last_conv = nn.Sequential(nn.Conv2d(304, 256, kernel_size=3, stride=1, padding=1, bias=False), 220 | nn.BatchNorm2d(256), 221 | nn.ReLU(), 222 | nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1, bias=False), 223 | nn.BatchNorm2d(256), 224 | nn.ReLU(), 225 | nn.Conv2d(256, n_classes, kernel_size=1, stride=1)) 226 | 227 | def forward(self, input): 228 | x, low_level_features = self.resnet_features(input) 229 | x1 = self.aspp1(x) 230 | x2 = self.aspp2(x) 231 | x3 = self.aspp3(x) 232 | x4 = self.aspp4(x) 233 | x5 = self.global_avg_pool(x) 234 | x5 = F.upsample(x5, size=x4.size()[2:], mode='bilinear', align_corners=True) 235 | 236 | x = torch.cat((x1, x2, x3, x4, x5), dim=1) 237 | 238 | x = self.conv1(x) 239 | x = self.bn1(x) 240 | x = self.relu(x) 241 | x = F.upsample(x, size=(int(math.ceil(input.size()[-2]/4)), 242 | int(math.ceil(input.size()[-1]/4))), mode='bilinear', align_corners=True) 243 | 244 | low_level_features = self.conv2(low_level_features) 245 | low_level_features = self.bn2(low_level_features) 246 | low_level_features = self.relu(low_level_features) 247 | 248 | 249 | x = torch.cat((x, low_level_features), dim=1) 250 | x = self.last_conv(x) 251 | x = F.upsample(x, size=input.size()[2:], mode='bilinear', align_corners=True) 252 | 253 | return x 254 | 255 | def freeze_bn(self): 256 | for m in self.modules(): 257 | if isinstance(m, nn.BatchNorm2d): 258 | m.eval() 259 | 260 | def __init_weight(self): 261 | for m in self.modules(): 262 | if isinstance(m, nn.Conv2d): 263 | # n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels 264 | # m.weight.data.normal_(0, math.sqrt(2. / n)) 265 | torch.nn.init.kaiming_normal_(m.weight) 266 | elif isinstance(m, nn.BatchNorm2d): 267 | m.weight.data.fill_(1) 268 | m.bias.data.zero_() 269 | 270 | def get_1x_lr_params(model): 271 | """ 272 | This generator returns all the parameters of the net except for 273 | the last classification layer. Note that for each batchnorm layer, 274 | requires_grad is set to False in deeplab_resnet.py, therefore this function does not return 275 | any batchnorm parameter 276 | """ 277 | b = [model.resnet_features] 278 | for i in range(len(b)): 279 | for k in b[i].parameters(): 280 | if k.requires_grad: 281 | yield k 282 | 283 | def get_10x_lr_params(model): 284 | """ 285 | This generator returns all the parameters for the last layer of the net, 286 | which does the classification of pixel into classes 287 | """ 288 | b = [model.aspp1, model.aspp2, model.aspp3, model.aspp4, model.conv1, model.conv2, model.last_conv] 289 | for j in range(len(b)): 290 | for k in b[j].parameters(): 291 | if k.requires_grad: 292 | yield k 293 | 294 | 295 | if __name__ == "__main__": 296 | model = DeepLabv3_plus(nInputChannels=3, n_classes=6, os=8, pretrained=True, _print=True) 297 | model.eval() 298 | image = torch.randn(1, 3, 512, 512) 299 | with torch.no_grad(): 300 | output = model.forward(image) 301 | print(output.size()) -------------------------------------------------------------------------------- /deeplab_v3p_train.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torchvision.utils as vutils 3 | import numpy as np 4 | import os 5 | from torch.autograd import Variable 6 | import torch.nn as nn 7 | import torch.optim as optim 8 | from tensorboardX import SummaryWriter 9 | from utils.data_utils import Mydataset 10 | from torch.utils.data import DataLoader 11 | import torchvision.transforms as transforms 12 | from datetime import datetime 13 | from deeplab_v3p import DeepLabv3_plus 14 | import tensorflow as tf 15 | from sklearn.metrics import accuracy_score 16 | 17 | os.environ["CUDA_VISIBLE_DEVICES"] = "0" 18 | tf.logging.set_verbosity(tf.logging.INFO) 19 | 20 | class args: 21 | train_path = 'dataset/train_path_list.csv' 22 | val_path = 'dataset/val_path_list.csv' 23 | result_dir = 'Result/' 24 | batch_size = 2 25 | learning_rate = 0.001 26 | max_epoch = 50 27 | 28 | best_train_acc = 0.80 29 | 30 | now_time = datetime.now() 31 | time_str = datetime.strftime(now_time,'%m-%d_%H-%M-%S') 32 | 33 | log_dir = os.path.join(args.result_dir,time_str) 34 | if not os.path.exists(log_dir): 35 | os.makedirs(log_dir) 36 | 37 | writer = SummaryWriter(log_dir) 38 | #---------------------------1、加载数据--------------------------- 39 | #数据预处理设置 40 | normMean = [0.46099097, 0.32533738, 0.32106236] 41 | normStd = [0.20980413, 0.1538582, 0.1491854] 42 | normTransfrom = transforms.Normalize(normMean, normStd) 43 | transform = transforms.Compose([ 44 | transforms.ToTensor(), 45 | normTransfrom, 46 | ]) 47 | #构建Mydataset实例 48 | train_data = Mydataset(path=args.train_path,transform=transform) 49 | val_data = Mydataset(path=args.val_path,transform=transform) 50 | #构建DataLoader 51 | train_loader = DataLoader(dataset=train_data, batch_size=args.batch_size, shuffle=True) 52 | val_loader = DataLoader(dataset=val_data, batch_size=args.batch_size, shuffle=True, drop_last=True) 53 | 54 | #---------------------------2、定义网络--------------------------- 55 | net = DeepLabv3_plus(nInputChannels=3, n_classes=6, os=8, pretrained=True, _print=True) 56 | net.cuda() 57 | 58 | #---------------------------3、初始化预训练权重、定义损失函数、优化器、设置超参数、--------------------------- 59 | if torch.cuda.is_available(): 60 | w = torch.Tensor([0.71280016, 0.77837713, 0.93428148, 1.0756635, 16.18921045, 28.26338505]).cuda() 61 | else: 62 | w = torch.Tensor([0.71280016, 0.77837713, 0.93428148, 1.0756635, 16.18921045, 28.26338505]) 63 | criterion = nn.CrossEntropyLoss(weight= w).cuda() #选择损失函数 64 | optimizer = optim.SGD(net.parameters(),lr=args.learning_rate,momentum=0.9,dampening=0.1) 65 | scheduler = torch.optim.lr_scheduler.StepLR(optimizer=optimizer,step_size=10,gamma=0.5) 66 | 67 | #---------------------------4、训练网络--------------------------- 68 | for epoch in range(args.max_epoch): 69 | loss_sigma = 0.0 70 | acc_sigma = 0.0 71 | loss_val_sigma = 0.0 72 | acc_val_sigma = 0.0 73 | net.train() 74 | for i,data in enumerate(train_loader): 75 | inputs, labels = data 76 | inputs = Variable(inputs.cuda()) 77 | labels = Variable(labels.cuda()) 78 | labels = labels.long().cuda() 79 | optimizer.zero_grad() 80 | outputs = net.forward(inputs) 81 | 82 | loss = criterion(outputs, labels) 83 | predicts = torch.argmax(outputs, dim=1) 84 | acc_train = accuracy_score(np.reshape(labels.cpu(),[-1]),np.reshape(predicts.cpu(),[-1])) 85 | loss.backward() 86 | optimizer.step() 87 | # 统计预测信息 88 | loss_sigma += loss.item() 89 | acc_sigma += acc_train 90 | if i % 10 == 9 : 91 | loss_avg = loss_sigma /10 92 | acc_avg = acc_sigma/10 93 | loss_sigma = 0.0 94 | acc_sigma = 0.0 95 | tf.logging.info("Training:Epoch[{:0>3}/{:0>3}] Iter[{:0>3}/{:0>3}] Loss:{:.4f} Acc:{:.4f}".format( 96 | epoch + 1, args.max_epoch,i+1,len(train_loader),loss_avg,acc_avg)) 97 | writer.add_scalar("LOSS", loss_avg, epoch) 98 | writer.add_scalar("LEARNING_RATE", scheduler.get_lr()[0], epoch) 99 | # 保存模型 100 | if (acc_avg) > best_train_acc: 101 | # 保存acc最高的模型 102 | net_save_path = os.path.join(log_dir, 'net_params.pkl') 103 | torch.save(net.state_dict(), net_save_path) 104 | best_train_acc = acc_avg 105 | tf.logging.info('Save model successfully to "%s"!' % (log_dir + 'net_params.pkl')) 106 | 107 | net.eval() 108 | for i, data in enumerate(val_loader): 109 | inputs, labels = data 110 | inputs = Variable(inputs.cuda()) 111 | labels = Variable(labels.cuda()) 112 | labels = labels.long().cuda() 113 | with torch.no_grad(): 114 | outputs = net.forward(inputs) 115 | predicts = torch.argmax(outputs, dim=1) 116 | acc_val = accuracy_score(np.reshape(labels.cpu(), [-1]), np.reshape(predicts.cpu(), [-1])) 117 | loss_val = criterion(outputs, labels) 118 | # 统计预测信息 119 | loss_val_sigma += loss_val.item() 120 | #acc_val_sigma += acc_val 121 | tf.logging.info("After 1 epoch:acc_val:{:.4f},loss_val:{:.4f}".format(acc_val_sigma/(len(val_loader)), loss_val_sigma/(len(val_loader)))) 122 | acc_val_sigma = 0.0 123 | loss_val_sigma = 0.0 124 | 125 | writer.close() 126 | net_save_path = os.path.join(log_dir,'net_params_end.pkl') 127 | torch.save(net.state_dict(),net_save_path) -------------------------------------------------------------------------------- /predict.py: -------------------------------------------------------------------------------- 1 | from utils.data_utils import Mydataset 2 | from torch.utils.data import DataLoader 3 | import torchvision.transforms as transforms 4 | from deeplab_v3p import DeepLabv3_plus 5 | import torch 6 | import numpy as np 7 | import cv2 8 | import torch.nn.functional as F 9 | from utils.color_utils import color_annotation 10 | from sklearn.metrics import accuracy_score 11 | import tensorflow as tf 12 | 13 | tf.logging.set_verbosity(tf.logging.INFO) 14 | 15 | pretrained_path = 'Result/11-18_12-15-21/net_params.pkl' 16 | output_path = 'Result/11-18_12-15-21/' 17 | scales = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] 18 | OA_all = [] 19 | classes = 6 20 | normMean = [0.46099097, 0.32533738, 0.32106236] 21 | normStd = [0.20980413, 0.1538582, 0.1491854] 22 | crop_h = 512 23 | crop_w = 512 24 | 25 | # 构建模型,载入训练好的权重参数 26 | net = DeepLabv3_plus(nInputChannels=3, n_classes=6, os=8, pretrained=True, _print=True) 27 | net.eval() 28 | if torch.cuda.is_available(): 29 | #支持cuda计算的情况下 30 | net = net.cuda() 31 | pretrained_dict = torch.load(pretrained_path,map_location=torch.device('cuda')) 32 | net.load_state_dict(pretrained_dict) 33 | else: 34 | # 不支持cuda计算的情况下 35 | pretrained_dict = torch.load(pretrained_path, map_location=torch.device('cpu')) 36 | net.load_state_dict(pretrained_dict) 37 | 38 | # 数据预处理设置 39 | normMean = [0.46099097, 0.32533738, 0.32106236] 40 | normTransfrom = transforms.Normalize(normMean, normStd) 41 | transform = transforms.Compose([ 42 | transforms.ToTensor(), 43 | normTransfrom, 44 | ]) 45 | # 构建Mydataset实例 46 | test_data = Mydataset(path='dataset/test_path_list.csv', transform=transform) 47 | test_loader = DataLoader(dataset=test_data, batch_size=1, shuffle=False) 48 | 49 | def net_process(model, image, flip=True): 50 | input = torch.from_numpy(image.transpose((2, 0, 1))).float() 51 | if torch.cuda.is_available(): 52 | input = input.unsqueeze(0).cuda() 53 | else: 54 | input = input.unsqueeze(0) 55 | if flip: 56 | input = torch.cat([input, input.flip(3)], 0) 57 | with torch.no_grad(): 58 | output = model(input) 59 | _, _, h_i, w_i = input.shape 60 | _, _, h_o, w_o = output.shape 61 | if (h_o != h_i) or (w_o != w_i): 62 | output = F.interpolate(output, (h_i, w_i), mode='bilinear', align_corners=True) 63 | output = F.softmax(output, dim=1) 64 | if flip: 65 | output = (output[0] + output[1].flip(2)) / 2 66 | else: 67 | output = output[0] 68 | output = output.data.cpu().numpy() 69 | output = output.transpose(1, 2, 0) 70 | return output 71 | 72 | 73 | def scale_process(model, image, classes, crop_h, crop_w, h, w, mean, stride_rate=2/3): 74 | ori_h, ori_w, _ = image.shape 75 | pad_h = max(crop_h - ori_h, 0) 76 | pad_w = max(crop_w - ori_w, 0) 77 | pad_h_half = int(pad_h / 2) 78 | pad_w_half = int(pad_w / 2) 79 | if pad_h > 0 or pad_w > 0: 80 | image = cv2.copyMakeBorder(image, pad_h_half, pad_h - pad_h_half, pad_w_half, pad_w - pad_w_half, 81 | cv2.BORDER_CONSTANT, value=mean) 82 | new_h, new_w, _ = image.shape 83 | stride_h = int(np.ceil(crop_h * stride_rate)) 84 | stride_w = int(np.ceil(crop_w * stride_rate)) 85 | grid_h = int(np.ceil(float(new_h - crop_h) / stride_h) + 1) 86 | grid_w = int(np.ceil(float(new_w - crop_w) / stride_w) + 1) 87 | prediction_crop = np.zeros((new_h, new_w, classes), dtype=float) 88 | count_crop = np.zeros((new_h, new_w), dtype=float) 89 | for index_h in range(0, grid_h): 90 | for index_w in range(0, grid_w): 91 | s_h = index_h * stride_h 92 | e_h = min(s_h + crop_h, new_h) 93 | s_h = e_h - crop_h 94 | s_w = index_w * stride_w 95 | e_w = min(s_w + crop_w, new_w) 96 | s_w = e_w - crop_w 97 | image_crop = image[s_h:e_h, s_w:e_w].copy() 98 | count_crop[s_h:e_h, s_w:e_w] += 1 99 | prediction_crop[s_h:e_h, s_w:e_w, :] += net_process(model,image_crop) 100 | prediction_crop /= np.expand_dims(count_crop, 2) 101 | prediction_crop = prediction_crop[pad_h_half:pad_h_half + ori_h, pad_w_half:pad_w_half + ori_w] 102 | prediction = cv2.resize(prediction_crop, (w, h), interpolation=cv2.INTER_LINEAR) 103 | return prediction 104 | 105 | if __name__ == '__main__': 106 | for i,data in enumerate(test_loader): 107 | print(i) 108 | input, label = data 109 | input = np.squeeze(input.numpy(), axis=0) 110 | image = np.transpose(input, (1, 2, 0)) 111 | h, w, _ = image.shape 112 | prediction = np.zeros((h, w, classes), dtype=float) 113 | for scale in scales: 114 | base_size = 0 115 | if h > w: 116 | base_size = h 117 | else: 118 | base_size = w 119 | long_size = round(scale * base_size) 120 | new_h = long_size 121 | new_w = long_size 122 | if h > w: 123 | new_w = round(long_size / float(h) * w) 124 | else: 125 | new_h = round(long_size / float(w) * h) 126 | image_scale = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_LINEAR) 127 | prediction += scale_process(net, image_scale, classes, crop_h, crop_w, h, w, normMean) 128 | prediction /= len(scales) 129 | prediction = np.argmax(prediction, axis=2) 130 | color_annotation(prediction, output_path + str(i) + ".png") 131 | OA = accuracy_score(np.reshape(prediction,[-1]), np.reshape(label,[-1])) 132 | print("the " + str(i) + "th image's OA:" + str(OA)) 133 | OA_all.append(OA) 134 | print(np.mean(OA_all)) 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /utils/Median_frequency_balance.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import os, sys 3 | import numpy as np 4 | import cv2 5 | 6 | 7 | def calcalate_weight(count): 8 | frequence = np.array(count) / sum(count) 9 | 10 | sort_frequence = sorted(frequence) 11 | size = len(frequence) 12 | 13 | if size % 2 == 0: 14 | median = (sort_frequence[size//2] + sort_frequence[size//2-1])/2 15 | if size % 2 == 1: 16 | median = sort_frequence[(size - 1) // 2] 17 | 18 | class_weight = median / frequence 19 | 20 | return class_weight 21 | 22 | 23 | class_pixels_count = [21815349, 20417332, 16272917, 18110438, 945687, 526083] 24 | train_dict = {0: 20575010, 1: 18841600, 2: 15697486, 3: 13634255, 4: 905904, 5: 518900, 25 | } 26 | train_count = list(train_dict.values()) 27 | 28 | val_dict = {0: 1240339, 1: 1575732, 2: 2412952, 3: 2638662, 4: 39783, 5: 7183, 29 | } 30 | val_count = list(val_dict.values()) 31 | 32 | train_weight = calcalate_weight(train_count) 33 | print(train_weight) 34 | #[ 0.71280016 0.77837713 0.93428148 1.0756635 16.18921045 28.26338505] 35 | 36 | val_weight = calcalate_weight(val_count) 37 | print(val_weight) 38 | # [ 1.13520215 0.89357549 0.58353233 0.53361723 35.39289395 196.02331895] 39 | -------------------------------------------------------------------------------- /utils/color_utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | 4 | # 给标签图上色 5 | 6 | def color_annotation(img, output_path): 7 | 8 | ''' 9 | 10 | 给class图上色 11 | 12 | ''' 13 | 14 | color = np.ones([img.shape[0], img.shape[1], 3]) 15 | 16 | color[img==0] = [255, 255, 255] #不透水地表 17 | 18 | color[img==1] = [255, 0, 0] #建筑 19 | 20 | color[img==2] = [0, 255, 0] # 树木 21 | 22 | color[img==3] = [255, 255, 0] # 低层植被 23 | 24 | color[img==4] = [0, 255, 255] # 汽车 25 | 26 | color[img == 5] = [0, 0, 255] #水面 27 | 28 | 29 | 30 | cv2.imwrite(output_path,color) -------------------------------------------------------------------------------- /utils/compute_mean.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | import numpy as np 4 | import cv2 5 | import random 6 | import pandas as pd 7 | 8 | """ 9 | 随机挑选CNum张图片,进行按通道计算均值mean和标准差std 10 | 先将像素从0~255归一化至 0-1 再计算 11 | """ 12 | 13 | 14 | train_csv_path = '../dataset/train_path_list.csv' 15 | 16 | CNum = 960 # 挑选多少图片进行计算 17 | 18 | img_h, img_w = 512, 512 19 | imgs = np.zeros([img_w, img_h, 3, 1]) 20 | means, stdevs = [], [] 21 | 22 | data = pd.read_csv(train_csv_path) #获取csv表中的数据 23 | data = data.sample(frac=0.20) # shuffle , 随机挑选图片 24 | data = data.reset_index(drop = True) #重新添加index,drop表示丢弃原有index一列 25 | 26 | for i in range(CNum): 27 | img_path = '../' + data.ix[i,1] 28 | img = cv2.imread(img_path) 29 | img = cv2.resize(img, (img_h, img_w)) 30 | img = img[:, :, :, np.newaxis] 31 | imgs = np.concatenate((imgs, img), axis=3) 32 | print(i) 33 | 34 | imgs = imgs.astype(np.float32)/255. 35 | 36 | 37 | for i in range(3): 38 | pixels = imgs[:,:,i,:].ravel() # 拉成一行 39 | means.append(np.mean(pixels)) 40 | stdevs.append(np.std(pixels)) 41 | 42 | means.reverse() # BGR --> RGB 43 | stdevs.reverse() 44 | 45 | print("normMean = {}".format(means)) 46 | print("normStd = {}".format(stdevs)) 47 | print('transforms.Normalize(normMean = {}, normStd = {})'.format(means, stdevs)) 48 | 49 | -------------------------------------------------------------------------------- /utils/data_utils.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | from torch.utils.data import Dataset 3 | import pandas as pd 4 | import numpy as np 5 | import torchvision.transforms as transforms 6 | 7 | class Mydataset(Dataset): 8 | def __init__(self, path, transform=None, target_transform=None): 9 | ''' 10 | :param path: 存储有图片存放地址、对应标签的文件的地址; 11 | :param transform: 定义了各种包括随即裁剪、旋转、仿射等在内的对图像的预处理操作 12 | :param target_transform: 13 | ''' 14 | data = pd.read_csv(path) # 获取csv表中的数据 15 | imgs = [] 16 | for i in range(len(data)): 17 | imgs.append((data.ix[i,1], data.ix[i,2])) 18 | self.imgs = imgs 19 | self.transform = transform 20 | self.target_transform = target_transform 21 | 22 | def __getitem__(self, item): 23 | fn, label = self.imgs[item] 24 | img = Image.open(fn).convert('RGB') 25 | gt = np.array(Image.open(label)) 26 | # 进行数据增强,并转换数据格式为tensor 27 | if self.transform is not None: 28 | img = self.transform(img) 29 | #gt = gt.astype(np.long) 30 | return img, gt 31 | 32 | def __len__(self): 33 | return len(self.imgs) 34 | 35 | if __name__ == "__main__": 36 | # 数据预处理设置 37 | normMean = [0.46099097, 0.32533738, 0.32106236] 38 | normStd = [0.20980413, 0.1538582, 0.1491854] 39 | normTransfrom = transforms.Normalize(normMean, normStd) 40 | transform = transforms.Compose([ 41 | transforms.ToTensor(), 42 | normTransfrom, 43 | ]) 44 | # 构建Mydataset实例 45 | train_data = Mydataset(path='../dataset/train_path_list.csv', transform=transform) 46 | img, gt = train_data.__getitem__(0) 47 | print(img.shape,gt) --------------------------------------------------------------------------------