conda create -n pytorchdeeplab python=3.7 -y
conda activate pytorchdeeplab
pip install -r requirements.txt
补充
conda install pytorch==1.10.0 cudatoolkit=11.3 -c pytorch -c conda-forge
处理数据
# 8位
# 读取整个bacepath文件夹下的文件并且转换为8位保存到savepath
import os
import cv2
bacepath = "/mnt/sdb1/fenghaixia/Aimportant_data/water/water train png/"
savepath = './VOCdevkit/VOC2007/SegmentationClass/'
# print(f_n)
for n in os.listdir(bacepath):
imdir = bacepath + n
# print(n)
img = cv2.imread(imdir)
cropped = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cropped=cropped/255
cv2.imwrite(savepath + n[:-9]+'.png', cropped)#NOT CAHNGE THE TYPE
print('finish')
bacepath = "/mnt/sdb1/fenghaixia/Aimportant_data/water/water train/"
savepath = './VOCdevkit/VOC2007/JPEGImages/'
# print(f_n)
for n in os.listdir(bacepath):
imdir = bacepath + n
# print(n)
img = cv2.imread(imdir)
cv2.imwrite(savepath + n[:-8]+'.jpg', img)#NOT CAHNGE THE TYPE
print('finish')
二、训练
cudnn\cudnc出错
CUDA error: CUBLAS_STATUS_EXECUTION_FAILED when calling `cublasSgemm( handle, opa, opb, m, n, k, &alpha, a, lda, b, ldb, &beta, c, ldc)`
问题:我的cuda版本11.4,与代码要求的pytorch1.2.0不匹配
Previous PyTorch Versions | PyTorch
搜索到
安装后解决问题,因此以后要注意这个问题
ln -s '/mnt/sdb1/fenghaixia/Aimportant_data/veg/veg test png' test
预测
get_miou
import os
from PIL import Image
from tqdm import tqdm
import numpy as np
from deeplab import DeeplabV3
from utils.utils_metrics import compute_mIoU, show_results
import cv2
'''
进行指标评估需要注意以下几点:
1、该文件生成的图为灰度图,因为值比较小,按照PNG形式的图看是没有显示效果的,所以看到近似全黑的图是正常的。
2、该文件计算的是验证集的miou,当前该库将测试集当作验证集使用,不单独划分测试集
'''
if __name__ == "__main__":
#---------------------------------------------------------------------------#
# miou_mode用于指定该文件运行时计算的内容
# miou_mode为0代表整个miou计算流程,包括获得预测结果、计算miou。
# miou_mode为1代表仅仅获得预测结果。
# miou_mode为2代表仅仅计算miou。
#---------------------------------------------------------------------------#
miou_mode = 0
#------------------------------#
# 分类个数+1、如2+1
#------------------------------#
num_classes = 2
#--------------------------------------------#
# 区分的种类,和json_to_dataset里面的一样
#--------------------------------------------#
name_classes = ["background","aeroplane", ]
# name_classes = ["_background_","cat","dog"]
#-------------------------------------------------------#
# 指向VOC数据集所在的文件夹
# 默认指向根目录下的VOC数据集
#-------------------------------------------------------#
VOCdevkit_path = 'VOCdevkit'
image_ids = open(os.path.join(VOCdevkit_path, "VOC2007/ImageSets/Segmentation/test.txt"),'r').read().splitlines()
gt_dir = os.path.join(VOCdevkit_path, "img_png/")
miou_out_path = "miou_out"
pred_dir = os.path.join(miou_out_path, 'detection-results')
if miou_mode == 0 or miou_mode == 1:
if not os.path.exists(pred_dir):
os.makedirs(pred_dir)
print("Load model.")
deeplab = DeeplabV3()
print("Load model done.")
print("Get predict result.")
for image_id in tqdm(image_ids):
image_path = os.path.join('img',image_id+".tif")
image = Image.open(image_path)
image = deeplab.get_miou_png(image)
image=np.array(image)
image=image*255
cv2.imwrite(os.path.join(pred_dir, image_id[:-3] + "mask.png"),image)
# image=Image.open(os.path.join(pred_dir, image_id[:-3] + "mask.png"))
# image.convert('RGB')
# image.save(os.path.join(pred_dir, image_id[:-3] + "mask.png"))
# image=cv2.imread(os.path.join(pred_dir, image_id[:-3] + "mask.png"))
print("Get predict result done.")
if miou_mode == 0 or miou_mode == 2:
print("Get miou.")
hist, IoUs, PA_Recall, Precision,F1 = compute_mIoU(gt_dir, pred_dir, image_ids, num_classes, name_classes) # 执行计算mIoU的函数
print("Get miou done.")
show_results(miou_out_path, hist, IoUs, PA_Recall, Precision, name_classes)
metrics
import csv
import os
from os.path import join
import matplotlib.pyplot as plt
import numpy as np
import torch
import torch.nn.functional as F
from PIL import Image
import cv2
def f_score(inputs, target, beta=1, smooth = 1e-5, threhold = 0.5):
n, c, h, w = inputs.size()
nt, ht, wt, ct = target.size()
if h != ht and w != wt:
inputs = F.interpolate(inputs, size=(ht, wt), mode="bilinear", align_corners=True)
temp_inputs = torch.softmax(inputs.transpose(1, 2).transpose(2, 3).contiguous().view(n, -1, c),-1)
temp_target = target.view(n, -1, ct)
#--------------------------------------------#
# 计算dice系数
#--------------------------------------------#
temp_inputs = torch.gt(temp_inputs, threhold).float()
tp = torch.sum(temp_target[...,:-1] * temp_inputs, axis=[0,1])
fp = torch.sum(temp_inputs , axis=[0,1]) - tp
fn = torch.sum(temp_target[...,:-1] , axis=[0,1]) - tp
score = ((1 + beta ** 2) * tp + smooth) / ((1 + beta ** 2) * tp + beta ** 2 * fn + fp + smooth)
score = torch.mean(score)
return score
# 设标签宽W,长H
def fast_hist(a, b, n):
#--------------------------------------------------------------------------------#
# a是转化成一维数组的标签,形状(H×W,);b是转化成一维数组的预测结果,形状(H×W,)
#--------------------------------------------------------------------------------#
k = (a >= 0) & (a < n)
#--------------------------------------------------------------------------------#
# np.bincount计算了从0到n**2-1这n**2个数中每个数出现的次数,返回值形状(n, n)
# 返回中,写对角线上的为分类正确的像素点
#--------------------------------------------------------------------------------#
return np.bincount(n * a[k].astype(int) + b[k], minlength=n ** 2).reshape(n, n)
def per_class_iu(hist):
return np.diag(hist) / np.maximum((hist.sum(1) + hist.sum(0) - np.diag(hist)), 1)
def per_class_PA_Recall(hist):
return np.diag(hist) / np.maximum(hist.sum(1), 1)
def per_class_Precision(hist):
return np.diag(hist) / np.maximum(hist.sum(0), 1)
def per_Accuracy(hist):
return np.sum(np.diag(hist)) / np.maximum(np.sum(hist), 1)
def compute_mIoU(gt_dir, pred_dir, png_name_list, num_classes, name_classes=None):
print('Num classes', num_classes)
#-----------------------------------------#
# 创建一个全是0的矩阵,是一个混淆矩阵
#-----------------------------------------#
hist = np.zeros((num_classes, num_classes))
#------------------------------------------------#
# 获得验证集标签路径列表,方便直接读取
# 获得验证集图像分割结果路径列表,方便直接读取
#------------------------------------------------#
gt_imgs = [join(gt_dir, x[:-3] + "mask.png") for x in png_name_list]
pred_imgs = [join(pred_dir, x[:-3] + "mask.png") for x in png_name_list]
#------------------------------------------------#
# 读取每一个(图片-标签)对
#------------------------------------------------#
iouloewnum=1
for ind in range(len(gt_imgs)):
#------------------------------------------------#
# 读取一张图像分割结果,转化成numpy数组
#------------------------------------------------#
pred = np.array(Image.open(pred_imgs[ind]))
#------------------------------------------------#
# 读取一张对应的标签,转化成numpy数组
#------------------------------------------------#
label=cv2.imread(gt_imgs[ind])
label=cv2.cvtColor(label,cv2.COLOR_BGR2GRAY)
# label = np.array(Image.open(gt_imgs[ind]))
# 如果图像分割结果与标签的大小不一样,这张图片就不计算
if len(label.flatten()) != len(pred.flatten()):
print(
'Skipping: len(gt) = {:d}, len(pred) = {:d}, {:s}, {:s}'.format(
len(label.flatten()), len(pred.flatten()), gt_imgs[ind],
pred_imgs[ind]))
continue
#------------------------------------------------#
# 对一张图片计算21×21的hist矩阵,并累加
#------------------------------------------------#
a=label.flatten()
a//=254
b=pred.flatten()
b//=254
hist += fast_hist(a, b, num_classes)
# 每计算1张就输出一下目前已计算的图片中所有类别平均的mIoU值
ioulow=100 * per_class_iu(fast_hist(a, b, num_classes))[1]
if ioulow<35:
print(ind)
print(gt_imgs[ind])
os.remove(gt_imgs[ind])
name=gt_imgs[ind].split('/')
print('miou_out/detection-results/'+name[-1])
os.remove('miou_out/detection-results/'+name[-1])
print('img/'+name[-1][:-9]+'_sat.tif')
os.remove('img/'+name[-1][:-9]+'_sat.tif')
print('{:d} / {:d}: mIou-{:0.6f}%; mPA-{:0.6f}%; Accuracy-{:0.6f}%'.format(
ind,
len(gt_imgs),
100 * per_class_iu(fast_hist(a, b, num_classes))[1],
100 * per_class_PA_Recall(fast_hist(a, b, num_classes))[1],
100 * per_Accuracy(fast_hist(a, b, num_classes))
)
)
iouloewnum=iouloewnum+1
print(iouloewnum)
#------------------------------------------------#
# 计算所有验证集图片的逐类别mIoU值
#------------------------------------------------#
print(hist)
IoUs = per_class_iu(hist)
PA_Recall = per_class_PA_Recall(hist)
Precision = per_class_Precision(hist)
F1 = ((Precision*PA_Recall)/(Precision+PA_Recall))*2
#------------------------------------------------#
# 逐类别输出一下mIoU值
#------------------------------------------------#
if name_classes is not None:
for ind_class in range(num_classes):
print('===>' + name_classes[ind_class] + ':\tIou-' + str(round(IoUs[ind_class] * 100, 2)) \
+ '; Recall (equal to the PA)-' + str(round(PA_Recall[ind_class] * 100, 2))+ '; Precision-' + str(round(Precision[ind_class] * 100, 2)))
#-----------------------------------------------------------------#
# 在所有验证集图像上求所有类别平均的mIoU值,计算时忽略NaN值
#-----------------------------------------------------------------#
print(hist)
print('===> mIoU: ' + str(round(np.nanmean(IoUs) * 100, 2)) + '; mPA: ' + str(round(np.nanmean(PA_Recall) * 100, 2)) + '; Accuracy: ' + str(round(per_Accuracy(hist) * 100, 2)))
print('===> F1: ' + str(round(np.nanmean(F1) * 100, 2)))
return np.array(hist, np.int), IoUs, PA_Recall, Precision,F1
def adjust_axes(r, t, fig, axes):
bb = t.get_window_extent(renderer=r)
text_width_inches = bb.width / fig.dpi
current_fig_width = fig.get_figwidth()
new_fig_width = current_fig_width + text_width_inches
propotion = new_fig_width / current_fig_width
x_lim = axes.get_xlim()
axes.set_xlim([x_lim[0], x_lim[1] * propotion])
def draw_plot_func(values, name_classes, plot_title, x_label, output_path, tick_font_size = 12, plt_show = True):
fig = plt.gcf()
axes = plt.gca()
plt.barh(range(len(values)), values, color='royalblue')
plt.title(plot_title, fontsize=tick_font_size + 2)
plt.xlabel(x_label, fontsize=tick_font_size)
plt.yticks(range(len(values)), name_classes, fontsize=tick_font_size)
r = fig.canvas.get_renderer()
for i, val in enumerate(values):
str_val = " " + str(val)
if val < 1.0:
str_val = " {0:.6f}".format(val)
t = plt.text(val, i, str_val, color='royalblue', va='center', fontweight='bold')
if i == (len(values)-1):
adjust_axes(r, t, fig, axes)
fig.tight_layout()
fig.savefig(output_path)
if plt_show:
plt.show()
plt.close()
def show_results(miou_out_path, hist, IoUs, PA_Recall, Precision, name_classes, tick_font_size = 12):
draw_plot_func(IoUs, name_classes, "mIoU = {0:.6f}%".format(np.nanmean(IoUs)*100), "Intersection over Union", \
os.path.join(miou_out_path, "mIoU.png"), tick_font_size = tick_font_size, plt_show = True)
print("Save mIoU out to " + os.path.join(miou_out_path, "mIoU.png"))
draw_plot_func(PA_Recall, name_classes, "mPA = {0:.6f}%".format(np.nanmean(PA_Recall)*100), "Pixel Accuracy", \
os.path.join(miou_out_path, "mPA.png"), tick_font_size = tick_font_size, plt_show = False)
print("Save mPA out to " + os.path.join(miou_out_path, "mPA.png"))
draw_plot_func(PA_Recall, name_classes, "mRecall = {0:.6f}%".format(np.nanmean(PA_Recall)*100), "Recall", \
os.path.join(miou_out_path, "Recall.png"), tick_font_size = tick_font_size, plt_show = False)
print("Save Recall out to " + os.path.join(miou_out_path, "Recall.png"))
draw_plot_func(Precision, name_classes, "mPrecision = {0:.6f}%".format(np.nanmean(Precision)*100), "Precision", \
os.path.join(miou_out_path, "Precision.png"), tick_font_size = tick_font_size, plt_show = False)
print("Save Precision out to " + os.path.join(miou_out_path, "Precision.png"))
with open(os.path.join(miou_out_path, "confusion_matrix.csv"), 'w', newline='') as f:
writer = csv.writer(f)
writer_list = []
writer_list.append([' '] + [str(c) for c in name_classes])
for i in range(len(hist)):
writer_list.append([name_classes[i]] + [str(x) for x in hist[i]])
writer.writerows(writer_list)
print("Save confusion_matrix out to " + os.path.join(miou_out_path, "confusion_matrix.csv"))