语义分割中的类别不平衡的权重计算

这是5幅图,加上背景共5类。 

 

可以参考这篇文章https://blog.csdn.net/u012426298/article/details/81232386

对于一个多类别图片数据库,每个类别都会有一个class frequency, 该类别像素数目除以数据库总像素数目, 求出所有class frequency 的median 值,除以该类别对应的frequency 得到weight:

weight=median(weights)/weights

#coding:utf-8
from __future__ import print_function
import os
import numpy as np
import cv2
w,h=512,512
def find_pic(img,array_list,n_class,pixs):
    img_sum = np.sum(img == array_list, axis=-1)
    pix_numbers=img_sum.reshape(-1).tolist().count(3)
    if pix_numbers:
        pixs+=pix_numbers
        n_class+=1
    return pixs,n_class
def compute_class(pixs,n_class):
    return pixs/(n_class*w*h)
def frequence():
    # images_path = './trainannot_visual'
    images_path = './visual_example'
    red = np.array([0, 0, 128])
    yellow = np.array([0, 128, 128])
    green = np.array([0, 128, 0])
    blue = np.array([128, 0, 0])
    back_gro = np.array([0, 0, 0])

    images_list_path = [os.path.join(images_path,i) for i in os.listdir(images_path)]

    n_red=0
    red_pixs=0

    n_yellow = 0
    yellow_pixs = 0

    n_green= 0
    green_pixs = 0

    n_blue = 0
    blue_pixs = 0

    n_back = 0
    back_pixs = 0

    for count,image_path in enumerate(images_list_path):
        print('{}image'.format(count))

        img=cv2.imread(image_path)

        red_pixs, n_red=find_pic(img,red,n_red,red_pixs)

        yellow_pixs,n_yellow = find_pic(img, yellow,n_yellow,yellow_pixs)

        green_pixs,n_green = find_pic(img, green,n_green,green_pixs)
        blue_pixs,n_blue = find_pic(img, blue,n_blue,blue_pixs)
        #
        back_pixs,n_back = find_pic(img, back_gro,n_back,back_pixs)

    print(red_pixs, n_red)
    print(yellow_pixs,n_yellow)
    print(green_pixs, n_green)
    print(blue_pixs, n_blue)
    print(back_pixs, n_back)

    f_class_red=compute_class(red_pixs,n_red)
    f_class_yellow = compute_class(yellow_pixs, n_yellow)
    f_class_green = compute_class(green_pixs, n_green)
    f_class_blue = compute_class(blue_pixs, n_blue)
    f_class_back = compute_class(back_pixs, n_back)
    print(f_class_red,f_class_yellow,f_class_green,f_class_blue,f_class_back)

    f_class=[f_class_red,f_class_yellow,f_class_green,f_class_blue,f_class_back]

    f_class_median=np.median(np.array(f_class))
    print(f_class_median)
    print(f_class_median/np.array(f_class))
if __name__ == '__main__':
    frequence()

这样可以保证占比小的class, 权重大于1, 占比大的class, 权重小于1, 达到balancing的效果.

  • 3
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
以下是使用PyTorch实现的UNet多类别语义分割测试代码,同时包含评价指标计算: ```python import torch import numpy as np import argparse import os import cv2 from model import UNet # 导入UNet模型 from datasets import get_dataloader # 导入数据加载器 from utils.metrics import IoU, dice_coeff # 导入评价指标计算函数 def test(args): # 设置使用的GPU编号 os.environ["CUDA_VISIBLE_DEVICES"] = args.gpu # 加载测试集数据 test_loader = get_dataloader(args.data_dir, 'test', args.batch_size, args.num_workers) # 加载模型 model = UNet(num_classes=args.num_classes) model = model.cuda() # 加载预训练权重 checkpoint = torch.load(args.checkpoint) model.load_state_dict(checkpoint) # 设置模型为评价模式 model.eval() # 初始化评价指标计算变量 total_iou = 0.0 total_dice = 0.0 total_num = 0 # 遍历测试集 for i, (images, labels) in enumerate(test_loader): # 将数据移动到GPU上 images = images.cuda() labels = labels.cuda() # 前向传播,得到模型输出结果 with torch.no_grad(): outputs = model(images) # 计算评价指标 preds = torch.argmax(outputs, dim=1).cpu().numpy() labels = labels.cpu().numpy() for pred, label in zip(preds, labels): total_iou += IoU(pred, label, args.num_classes) total_dice += dice_coeff(pred, label, args.num_classes) total_num += 1 # 保存预测结果图片 if args.save_test_results: for j in range(preds.shape[0]): img = np.transpose(images[j].cpu().numpy(), (1, 2, 0)) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) pred = preds[j] label = labels[j] img_pred = np.zeros((pred.shape[0], pred.shape[1], 3), dtype=np.uint8) img_label = np.zeros((label.shape[0], label.shape[1], 3), dtype=np.uint8) for k in range(args.num_classes): img_pred[pred == k] = args.colors[k] img_label[label == k] = args.colors[k] img_pred = cv2.addWeighted(img, 0.5, img_pred, 0.5, 0) img_label = cv2.addWeighted(img, 0.5, img_label, 0.5, 0) cv2.imwrite(os.path.join(args.test_results_dir, f'{i*args.batch_size+j}_pred.png'), img_pred) cv2.imwrite(os.path.join(args.test_results_dir, f'{i*args.batch_size+j}_label.png'), img_label) # 打印评价指标结果 avg_iou = total_iou / total_num avg_dice = total_dice / total_num print(f'Average IoU: {avg_iou:.4f}') print(f'Average Dice Coefficient: {avg_dice:.4f}') if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--data_dir', type=str, default='./data', help='数据集目录') parser.add_argument('--checkpoint', type=str, default='./checkpoints/best_model.pth', help='预训练权重路径') parser.add_argument('--num_classes', type=int, default=2, help='类别数量') parser.add_argument('--batch_size', type=int, default=16, help='批量大小') parser.add_argument('--num_workers', type=int, default=4, help='数据加载器使用的进程数量') parser.add_argument('--save_test_results', action='store_true', help='是否保存测试结果图片') parser.add_argument('--test_results_dir', type=str, default='./test_results', help='测试结果图片保存目录') parser.add_argument('--gpu', type=str, default='0', help='使用的GPU编号') args = parser.parse_args() # 设置不同类别的颜色 args.colors = [(0, 0, 0), (255, 255, 255)] test(args) ``` 其,`IoU`和`dice_coeff`函数的实现可以参考以下代码: ```python import numpy as np def IoU(pred, label, num_classes): iou = 0.0 for i in range(num_classes): tp = np.sum((pred == i) & (label == i)) fp = np.sum((pred == i) & (label != i)) fn = np.sum((pred != i) & (label == i)) iou += tp / (tp + fp + fn) return iou / num_classes def dice_coeff(pred, label, num_classes): dice = 0.0 for i in range(num_classes): tp = np.sum((pred == i) & (label == i)) fp = np.sum((pred == i) & (label != i)) fn = np.sum((pred != i) & (label == i)) dice += 2 * tp / (2 * tp + fp + fn) return dice / num_classes ``` 注意,在测试代码,我们设置了不同类别的颜色,并且可以选择是否保存测试结果图片。如果需要保存图片,则需要指定`--save_test_results`参数,并且需要指定保存路径`--test_results_dir`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值