华为开源自研AI框架昇思MindSpore应用案例:ICNet用于实时的语义分割
ICNet用于实时的语义分割
ICNet 被广泛应用于实时的语义分割领域。它在处理图像数据时,能够以较高的效率进行语义分割操作,为相关领域的研究和实际应用提供了有力的支持。ICNet 的实时性使其在众多场景中都具有很大的优势,例如在视频处理、自动驾驶等对实时性要求较高的领域,ICNet 能够快速准确地对图像进行语义分割,为后续的决策和处理提供关键信息。
如果你对MindSpore感兴趣,可以关注昇思MindSpore社区
一、环境准备
1.进入ModelArts官网
云平台帮助用户快速创建和部署模型,管理全周期AI工作流,选择下面的云平台以开始使用昇思MindSpore,获取安装命令,安装MindSpore2.0.0-alpha版本,可以在昇思教程中进入ModelArts官网
选择下方CodeLab立即体验
等待环境搭建完成
2.使用CodeLab体验Notebook实例
选择ModelArts Upload Files上传Git文件,地址为GitHub - yfjcode/ICNet: mindspore icnet model
选择Kernel环境
切换至GPU环境,切换成第一个限时免费
进入昇思MindSpore官网,点击上方的安装
获取安装命令
回到Notebook中,在第一块代码前加入命令
conda update -n base -c defaults conda
安装MindSpore 2.0 GPU版本
conda install mindspore=2.0.0a0 -c mindspore -c conda-forge
安装mindvision
pip install mindvision
安装下载download
pip install download
二、应用体验
1.模型准备
根据原作者提示
环境准备与数据读取 本案例基于MindSpore-CPU版本实现,在CPU上完成模型训练。
案例实现所使用的数据:Cityscape Dataset Website
为了下载数据集,我们首先需要在Cityscapes数据集官网进行注册,并且最好使用edu教育邮箱进行注册,此后等待几天,就可以下载数据集了,这里我们下载了两个文件:gtFine_trainvaltest.zip和leftImg8bit_trainvaltest.zip (11GB)。
下载完成后,我们对数据集压缩文件进行解压,文件的目录结构如下所示。
由于我们是在CPU上跑得,原本数据集有1个多G,全部拿来跑得话,很容易掉卡,故我们就选择一个城市的一些图片完成。
首先要处理数据,生成对应的.mindrecord 和 .mindrecord.db文件
需要注意的是,在生成这两个文件之前,我们要建立一个文件夹,用cityscapes_mindrecord命名,放在cityscapes文件夹的同级目录下: 而且要保持cityscapes_mindrecord文件夹里面为空
下面是构建数据集的代码:注意,要保持cityscapes_mindrecord文件夹里面为空,报错可能是文件夹已经有文件了,文件夹地址为:/home/ma-user/work/ICNet/data/cityscapes_mindrecord
需要删掉/data/cityscapes_mindrecord文件
删掉文件后,需要修改路径,删掉/home/ma-user/work/ICNet,用./替换,之后直接运行代码块即可
"""Prepare Cityscapes dataset"""
import os
import random
import argparse
import numpy as np
from PIL import Image
from PIL import ImageOps
from PIL import ImageFilter
import mindspore.dataset as de
from mindspore.mindrecord import FileWriter
import mindspore.dataset.vision as transforms
import mindspore.dataset.transforms as tcdef _get_city_pairs(folder, split='train'):"""Return two path arrays of data set img and mask"""def get_path_pairs(image_folder, masks_folder):image_paths = []masks_paths = []for root, _, files in os.walk(image_folder):for filename in files:if filename.endswith('.png'):imgpath = os.path.join(root, filename)foldername = os.path.basename(os.path.dirname(imgpath))maskname = filename.replace('leftImg8bit', 'gtFine_labelIds')maskpath = os.path.join(masks_folder, foldername, maskname)if os.path.isfile(imgpath) and os.path.isfile(maskpath):image_paths.append(imgpath)masks_paths.append(maskpath)else:print('cannot find the mask or image:', imgpath, maskpath)print('Found {} images in the folder {}'.format(len(image_paths), image_folder))return image_paths, masks_pathsif split in ('train', 'val'):# "./Cityscapes/leftImg8bit/train" or "./Cityscapes/leftImg8bit/val"img_folder = os.path.join(folder, 'leftImg8bit/' + split)# "./Cityscapes/gtFine/train" or "./Cityscapes/gtFine/val"mask_folder = os.path.join(folder, 'gtFine/' + split)# The order of img_paths and mask_paths is one-to-one correspondenceimg_paths, mask_paths = get_path_pairs(img_folder, mask_folder)return img_paths, mask_pathsdef _sync_transform(img, mask):"""img and mask augmentation"""a = random.Random()a.seed(1234)base_size = 1024crop_size = 960# random mirrorif random.random() < 0.5:img = img.transpose(Image.FLIP_LEFT_RIGHT)mask = mask.transpose(Image.FLIP_LEFT_RIGHT)crop_size = crop_size# random scale (short edge)short_size = random.randint(int(base_size * 0.5), int(base_size * 2.0))w, h = img.sizeif h > w:ow = short_sizeoh = int(1.0 * h * ow / w)else:oh = short_sizeow = int(1.0 * w * oh / h)img = img.resize((ow, oh), Image.BILINEAR)mask = mask.resize((ow, oh), Image.NEAREST)# pad cropif short_size < crop_size:padh = crop_size - oh if oh < crop_size else 0padw = crop_size - ow if ow < crop_size else 0img = ImageOps.expand(img, border=(0, 0, padw, padh), fill=0)mask = ImageOps.expand(mask, border=(0, 0, padw, padh), fill=0)# random crop crop_sizew, h = img.sizex1 = random.randint(0, w - crop_size)y1 = random.randint(0, h - crop_size)img = img.crop((x1, y1, x1 + crop_size, y1 + crop_size))mask = mask.crop((x1, y1, x1 + crop_size, y1 + crop_size))# gaussian blur as in PSPif random.random() < 0.5:img = img.filter(ImageFilter.GaussianBlur(radius=random.random()))# final transformoutput = _img_mask_transform(img, mask)return outputdef _class_to_index(mask):"""class to index"""# Reference:# https://github.com/mcordts/cityscapesScripts/blob/master/cityscapesscripts/helpers/labels.py_key = np.array([-1, -1, -1, -1, -1, -1,-1, -1, 0, 1, -1, -1,2, 3, 4, -1, -1, -1,5, -1, 6, 7, 8, 9,10, 11, 12, 13, 14, 15,-1, -1, 16, 17, 18])# [-1, ..., 33]_mapping = np.array(range(-1, len(_key) - 1)).astype('int32')# assert the valuevalues = np.unique(mask)for value in values:assert value in _mapping# Get the index of each pixel value in the mask corresponding to _mappingindex = np.digitize(mask.ravel(), _mapping, right=True)# According to the above index, according to _key, get the correspondingreturn _key[index].reshape(mask.shape)def _img_transform(img):return np.array(img)def _mask_transform(mask):target = _class_to_index(np.array(mask).astype('int32'))return np.array(target).astype('int32')def _img_mask_transform(img, mask):"""img and mask transform"""input_transform = tc.Compose([transforms.ToTensor(),transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225), is_hwc=False)])img = _img_transform(img)mask = _mask_transform(mask)img = input_transform(img)img = np.array(img).astype(np.float32)mask = np.array(mask).astype(np.float32)return (img, mask)def data_to_mindrecord_img(prefix='cityscapes-2975.mindrecord', file_num=1,root='./', split='train', mindrecord_dir="./"):"""to mindrecord"""mindrecord_path = os.path.join(mindrecord_dir, prefix)writter = FileWriter(mindrecord_path, file_num)img_paths, mask_paths = _get_city_pairs(root, split)cityscapes_json = {"images": {"type": "int32", "shape": [1024, 2048, 3]},"mask": {"type": "int32", "shape": [1024, 2048]},}writter.add_schema(cityscapes_json, "cityscapes_json")images_files_num = len(img_paths)for index in range(images_files_num):img = Image.open(img_paths[index]).convert('RGB')img = np.array(img, dtype=np.int32)mask = Image.open(mask_paths[index])mask = np.array(mask, dtype=np.int32)row = {"images": img, "mask": mask}# print("images",img, "mask", mask)# print("images_files_num,index, img_paths[index],mask_paths[index]",images_files_num,index,img_paths[index],mask_paths[index])if (index + 1) % 10 == 0:print("writing {}/{} into mindrecord".format(index + 1, images_files_num))writter.write_raw_data([row])writter.commit()def get_Image_crop_nor(img, mask):image = np.uint8(img)mask = np.uint8(mask)image = Image.fromarray(image)mask = Image.fromarray(mask)output = _sync_transform(image, mask)return outputdef create_icnet_dataset(mindrecord_file, batch_size=16, device_num=1, rank_id=0):"""create dataset for training"""a = random.Random()a.seed(1234)ds = de.MindDataset(mindrecord_file, columns_list=["images", "mask"],num_shards=device_num, shard_id=rank_id, shuffle=True)ds = ds.map(operations=get_Image_crop_nor, input_columns=["images", "mask"], output_columns=["image", "masks"])ds = ds.batch(batch_size=batch_size, drop_remainder=False)return dsdataset_path="./data/cityscapes/"
mindrecord_path="./data/cityscapes_mindrecord/"data_to_mindrecord_img(root=dataset_path, mindrecord_dir=mindrecord_path)
# if __name__ == '__main__':
# parser = argparse.ArgumentParser(description="dataset_to_mindrecord")
# parser.add_argument("--dataset_path", type=str, default="/home/ma-user/work/ICNet/data/cityscapes/", help="dataset path")
# parser.add_argument("--mindrecord_path", type=str, default="/home/ma-user/work/ICNet/data/cityscapes_mindrecord/",
# help="mindrecord_path")# args_opt = parser.parse_args()
# data_to_mindrecord_img(root=args_opt.dataset_path, mindrecord_dir=args_opt.mindrecord_path)
可以看到已经生成的对应的数据集文件,然后我们创建稍后用到的数据
注意修改路径
prefix = 'cityscapes-2975.mindrecord'
train_mindrecord_dir="/home/ma-user/work/ICNet/data/cityscapes_mindrecord"
train_train_batch_size_percard=4
device_num=1
rank_id=0mindrecord_dir = train_mindrecord_dir
mindrecord_file = os.path.join(mindrecord_dir, prefix)
print("mindrecord_file",mindrecord_file)
# print("cfg['train'][‘’train_batch_size_percard‘]",cfg['train']["train_batch_size_percard"])dataset = create_icnet_dataset(mindrecord_file, batch_size=train_train_batch_size_percard,device_num=device_num, rank_id=rank_id)
print(dataset)
2.模型构建
建立需要训练模型的一些参数:(这里只是展示,不运行,具体参数运行在后面)
1.Model
model: name: "icnet" backbone: "resnet50v1" base_size: 1024 # during augmentation, shorter size will be resized between [base_size0.5, base_size2.0] crop_size: 960 # end of augmentation, crop to training
2.Optimizer
optimizer: init_lr: 0.02 momentum: 0.9 weight_decay: 0.0001
3.Training
train: train_batch_size_percard: 4 valid_batch_size: 1 cityscapes_root: "/data/cityscapes/" epochs: 10 val_epoch: 1 # run validation every val-epoch ckpt_dir: "./ckpt/" # ckpt and training log will be saved here mindrecord_dir: '/home/ma-user/work/ICNet/data/cityscapes_mindrecord' pretrained_model_path: '/home/ma-user/work/ICNet/root/cacheckpt/resnet50-icnet-150_2.ckpt' save_checkpoint_epochs: 5 keep_checkpoint_max: 10
4.Valid
test: ckpt_path: "" # set the pretrained model path correctly
注意修改路径
train_epochs=10
train_data_size = dataset.get_dataset_size()
print("data_size", train_data_size)
epoch = train_epochs
project_path="/home/ma-user/work/ICNet/"
train_pretrained_model_path="/home/ma-user/work/ICNet/root/cacheckpt/resnet50-icnet-150_2.ckpt"
import mindspore as ms
import mindspore.nn as nn
import mindspore.ops as ops
from src.loss import ICNetLoss
from src.models.resnet50_v1 import get_resnet50v1b__all__ = ['ICNetdc']class ICNetdc(nn.Cell):"""Image Cascade Network"""def __init__(self, nclass=19, pretrained_path="", istraining=True, norm_layer=nn.SyncBatchNorm):super(ICNetdc, self).__init__()self.conv_sub1 = nn.SequentialCell(_ConvBNReLU(3, 32, 3, 2, norm_layer=norm_layer),_ConvBNReLU(32, 32, 3, 2, norm_layer=norm_layer),_ConvBNReLU(32, 64, 3, 2, norm_layer=norm_layer))self.istraining = istrainingself.ppm = PyramidPoolingModule()self.backbone = SegBaseModel(root=pretrained_path, istraining=istraining)self.head = _ICHead(nclass, norm_layer=norm_layer)self.loss = ICNetLoss()self.resize_bilinear = nn.ResizeBilinear()self.__setattr__('exclusive', ['conv_sub1', 'head'])def construct(self, x, y):"""ICNet_construct"""if x.shape[0] != 1:x = x.squeeze()# sub 1x_sub1 = self.conv_sub1(x)h, w = x.shape[2:]# sub 2x_sub2 = self.resize_bilinear(x, size=(h / 2, w / 2))_, x_sub2, _, _ = self.backbone(x_sub2)# sub 4_, _, _, x_sub4 = self.backbone(x)# add PyramidPoolingModulex_sub4 = self.ppm(x_sub4)output = self.head(x_sub1, x_sub2, x_sub4)if self.istraining:outputs = self.loss(output, y)else:outputs = outputreturn outputsclass PyramidPoolingModule(nn.Cell):"""PPM"""def __init__(self, pyramids=None):super(PyramidPoolingModule, self).__init__()self.avgpool = ops.ReduceMean(keep_dims=True)self.pool2 = nn.AvgPool2d(kernel_size=15, stride=15)self.pool3 = nn.AvgPool2d(kernel_size=10, stride=10)self.pool6 = nn.AvgPool2d(kernel_size=5, stride=5)self.resize_bilinear = nn.ResizeBilinear()def construct(self, x):"""ppm_construct"""feat = xheight, width = x.shape[2:]x1 = self.avgpool(x, (2, 3))x1 = self.resize_bilinear(x1, size=(height, width), align_corners=True)feat = feat + x1x2 = self.pool2(x)x2 = self.resize_bilinear(x2, size=(height, width), align_corners=True)feat = feat + x2x3 = self.pool3(x)x3 = self.resize_bilinear(x3, size=(height, width), align_corners=True)feat = feat + x3x6 = self.pool6(x)x6 = self.resize_bilinear(x6, size=(height, width), align_corners=True)feat = feat + x6return featclass _ICHead(nn.Cell):"""Head"""def __init__(self, nclass, norm_layer=nn.SyncBatchNorm, **kwargs):super(_ICHead, self).__init__()self.cff_12 = CascadeFeatureFusion12(128, 64, 128, nclass, norm_layer, **kwargs)self.cff_24 = CascadeFeatureFusion24(2048, 512, 128, nclass, norm_layer, **kwargs)self.conv_cls = nn.Conv2d(128, nclass, 1, has_bias=False)self.outputs = list()self.resize_bilinear = nn.ResizeBilinear()def construct(self, x_sub1, x_sub2, x_sub4):"""Head_construct"""outputs = self.outputsx_cff_24, x_24_cls = self.cff_24(x_sub4, x_sub2)x_cff_12, x_12_cls = self.cff_12(x_cff_24, x_sub1)h1, w1 = x_cff_12.shape[2:]up_x2 = self.resize_bilinear(x_cff_12, size=(h1 * 2, w1 * 2),align_corners=True)up_x2 = self.conv_cls(up_x2)h2, w2 = up_x2.shape[2:]up_x8 = self.resize_bilinear(up_x2, size=(h2 * 4, w2 * 4),align_corners=True) # scale_factor=4,outputs.append(up_x8)outputs.append(up_x2)outputs.append(x_12_cls)outputs.append(x_24_cls)return outputsclass _ConvBNReLU(nn.Cell):"""ConvBNRelu"""def __init__(self, in_channels, out_channels, kernel_size=3, stride=2, padding=1, dilation=1,groups=1, norm_layer=nn.SyncBatchNorm, bias=False, **kwargs):super(_ConvBNReLU, self).__init__()self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, pad_mode='pad', padding=padding,dilation=dilation,group=1, has_bias=False)self.bn = norm_layer(out_channels, momentum=0.1)self.relu = nn.ReLU()def construct(self, x):x = self.conv(x)x = self.bn(x)x = self.relu(x)return xclass CascadeFeatureFusion12(nn.Cell):"""CFF Unit"""def __init__(self, low_channels, high_channels, out_channels, nclass, norm_layer=nn.SyncBatchNorm, **kwargs):super(CascadeFeatureFusion12, self).__init__()self.conv_low = nn.SequentialCell(nn.Conv2d(low_channels, out_channels, 3, pad_mode='pad', padding=2, dilation=2, has_bias=False),norm_layer(out_channels, momentum=0.1))self.conv_high = nn.SequentialCell(nn.Conv2d(high_channels, out_channels, kernel_size=1, has_bias=False),norm_layer(out_channels, momentum=0.1))self.conv_low_cls = nn.Conv2d(in_channels=out_channels, out_channels=nclass, kernel_size=1, has_bias=False)self.resize_bilinear = nn.ResizeBilinear()self.scalar_cast = ops.ScalarCast()self.relu = ms.nn.ReLU()def construct(self, x_low, x_high):"""cff_construct"""h, w = x_high.shape[2:]x_low = self.resize_bilinear(x_low, size=(h, w), align_corners=True)x_low = self.conv_low(x_low)x_high = self.conv_high(x_high)x = x_low + x_highx = self.relu(x)x_low_cls = self.conv_low_cls(x_low)return x, x_low_clsclass CascadeFeatureFusion24(nn.Cell):"""CFF Unit"""def __init__(self, low_channels, high_channels, out_channels, nclass, norm_layer=nn.SyncBatchNorm, **kwargs):super(CascadeFeatureFusion24, self).__init__()self.conv_low = nn.SequentialCell(nn.Conv2d(low_channels, out_channels, 3, pad_mode='pad', padding=2, dilation=2, has_bias=False),norm_layer(out_channels, momentum=0.1))self.conv_high = nn.SequentialCell(nn.Conv2d(high_channels, out_channels, kernel_size=1, has_bias=False),norm_layer(out_channels, momentum=0.1))self.conv_low_cls = nn.Conv2d(in_channels=out_channels, out_channels=nclass, kernel_size=1, has_bias=False)self.resize_bilinear = nn.ResizeBilinear()self.relu = ms.nn.ReLU()def construct(self, x_low, x_high):"""ccf_construct"""h, w = x_high.shape[2:]x_low = self.resize_bilinear(x_low, size=(h, w), align_corners=True)x_low = self.conv_low(x_low)x_high = self.conv_high(x_high)x = x_low + x_highx = self.relu(x)x_low_cls = self.conv_low_cls(x_low)return x, x_low_clsclass SegBaseModel(nn.Cell):"""Base Model for Semantic Segmentation"""def __init__(self, nclass=19, backbone='resnet50', root="", istraining=False):super(SegBaseModel, self).__init__()self.nclass = nclassif backbone == 'resnet50':self.pretrained = get_resnet50v1b(ckpt_root=root, istraining=istraining)def construct(self, x):"""forwarding pre-trained network"""x = self.pretrained.conv1(x)x = self.pretrained.bn1(x)x = self.pretrained.relu(x)x = self.pretrained.maxpool(x)c1 = self.pretrained.layer1(x)c2 = self.pretrained.layer2(c1)c3 = self.pretrained.layer3(c2)c4 = self.pretrained.layer4(c3)return c1, c2, c3, c4
def poly_lr(base_lr, decay_steps, total_steps, end_lr=0.0001, power=0.9):for i in range(total_steps):step_ = min(i, decay_steps)yield (base_lr - end_lr) * ((1.0 - step_ / decay_steps) ** power) + end_lr
optimizer_init_lr=0.02
optimizer_weight_decay = 0.0001
optimizer_momentum= 0.9
train_save_checkpoint_epochs=5
train_keep_checkpoint_max = 10
rank_id = 0
device_id = 0
device_num =1# from src.lr_scheduler import poly_lr
import os
import sys
import logging
import argparse
# import yaml
import mindspore.nn as nn
from mindspore import Model
from mindspore import context
from mindspore import set_seed
from mindspore.context import ParallelMode
from mindspore.communication import init
from mindspore.train.callback import CheckpointConfig
from mindspore.train.callback import ModelCheckpoint
from mindspore.train.callback import LossMonitor
from mindspore.train.callback import TimeMonitoriters_per_epoch = train_data_size
total_train_steps = iters_per_epoch * epoch
base_lr = optimizer_init_lr
iter_lr = poly_lr(base_lr, total_train_steps, total_train_steps, end_lr=0.0, power=0.9)network = ICNetdc(pretrained_path=train_pretrained_model_path, norm_layer=nn.BatchNorm2d)optim = nn.SGD(params=network.trainable_params(), learning_rate=iter_lr, momentum=optimizer_momentum,weight_decay=optimizer_weight_decay)model = Model(network, optimizer=optim, metrics=None)config_ck_train = CheckpointConfig(save_checkpoint_steps=iters_per_epoch * train_save_checkpoint_epochs,keep_checkpoint_max=train_keep_checkpoint_max)
ckpoint_cb_train = ModelCheckpoint(prefix='ICNet', directory=project_path + 'ckpt' + str(device_id),config=config_ck_train)
time_cb_train = TimeMonitor(data_size=dataset.get_dataset_size())
loss_cb_train = LossMonitor()
print("train begins------------------------------")
model.train(epoch=epoch, train_dataset=dataset, callbacks=[ckpoint_cb_train, loss_cb_train, time_cb_train],dataset_sink_mode=True)
3.模型验证
import os
import time
import sys
import argparse
import yaml
import numpy as np
from PIL import Image
import mindspore.ops as ops
from mindspore import load_param_into_net
from mindspore import load_checkpoint
from mindspore import Tensor
import mindspore.dataset.vision as vision
from src.models import ICNet
from src.metric import SegmentationMetric
from src.logger import SetupLoggerclass Evaluator:"""evaluate"""def __init__(self):# self.cfg = config# get valid dataset images and targetsself.image_paths, self.mask_paths = _get_city_pairs(dataset_path, "val")# self.image_paths,# self.mask_paths # create network# self.model = ICNetdc(nclass=19, pretrained_path=train_pretrained_model_path, norm_layer=nn.BatchNorm2d,istraining=False)self.model = ICNet(nclass=19, pretrained_path=train_pretrained_model_path, istraining=False)# load ckptcheckpoint_path="/home/ma-user/work/ICNet/ckpt0/ICNet-10_1.ckpt"ckpt_file_name = checkpoint_pathparam_dict = load_checkpoint(ckpt_file_name)load_param_into_net(self.model, param_dict)# evaluation metricsself.metric = SegmentationMetric(19)def eval(self):"""evaluate"""self.metric.reset()model = self.modelmodel = model.set_train(False)logger.info("Start validation, Total sample: {:d}".format(len(self.image_paths)))list_time = []for i in range(len(self.image_paths)):image = Image.open(self.image_paths[i]).convert('RGB') # image shape: (W,H,3)mask = Image.open(self.mask_paths[i]) # mask shape: (W,H)image = self._img_transform(image) # image shape: (3,H,W) [0,1]mask = self._mask_transform(mask) # mask shape: (H,w)image = Tensor(image)expand_dims = ops.ExpandDims()image = expand_dims(image, 0)start_time = time.time()output = model(image)end_time = time.time()step_time = end_time - start_timeoutput = output.asnumpy()mask = np.expand_dims(mask.asnumpy(), axis=0)self.metric.update(output, mask)list_time.append(step_time)mIoU, pixAcc = self.metric.get()average_time = sum(list_time) / len(list_time)print("avgmiou", mIoU)print("avg_pixacc", pixAcc)print("avgtime", average_time)def _img_transform(self, image):"""img_transform"""to_tensor = vision.ToTensor()normalize = vision.Normalize([.485, .456, .406], [.229, .224, .225], is_hwc=False)image = to_tensor(image)image = normalize(image)return imagedef _mask_transform(self, mask):mask = self._class_to_index(np.array(mask).astype('int32'))return Tensor(np.array(mask).astype('int32')) # torch.LongTensordef _class_to_index(self, mask):"""assert the value"""values = np.unique(mask)self._key = np.array([-1, -1, -1, -1, -1, -1,-1, -1, 0, 1, -1, -1,2, 3, 4, -1, -1, -1,5, -1, 6, 7, 8, 9,10, 11, 12, 13, 14, 15,-1, -1, 16, 17, 18])self._mapping = np.array(range(-1, len(self._key) - 1)).astype('int32')for value in values:assert value in self._mapping# Get the index of each pixel value in the mask corresponding to _mappingindex = np.digitize(mask.ravel(), self._mapping, right=True)# According to the above index index, according to _key, the corresponding mask image is obtainedreturn self._key[index].reshape(mask.shape)def _get_city_pairs(folder, split='train'):"""get dataset img_mask_path_pairs"""def get_path_pairs(image_folder, mask_folder):img_paths = []mask_paths = []for root, _, files in os.walk(image_folder):for filename in files:if filename.endswith('.png'):imgpath = os.path.join(root, filename)foldername = os.path.basename(os.path.dirname(imgpath))maskname = filename.replace('leftImg8bit', 'gtFine_labelIds')maskpath = os.path.join(mask_folder, foldername, maskname)if os.path.isfile(imgpath) and os.path.isfile(maskpath):img_paths.append(imgpath)mask_paths.append(maskpath)else:print('cannot find the mask or image:', imgpath, maskpath)print('Found {} images in the folder {}'.format(len(img_paths), image_folder))return img_paths, mask_pathsif split in ('train', 'val', 'test'):# "./Cityscapes/leftImg8bit/train" or "./Cityscapes/leftImg8bit/val"img_folder = os.path.join(folder, 'leftImg8bit/' + split)# "./Cityscapes/gtFine/train" or "./Cityscapes/gtFine/val"mask_folder = os.path.join(folder, 'gtFine/' + split)img_paths, mask_paths = get_path_pairs(img_folder, mask_folder)return img_paths, mask_paths
train_ckpt_dir="./ckpt/"
model_name="icnet"
model_backbone="resnet50v1"
checkpoint_path="./ckpt0/ICNet-10_1.ckpt"logger = SetupLogger(name="semantic_segmentation",save_dir=train_ckpt_dir,distributed_rank=0,filename='{}_{}_evaluate_log.txt'.format(model_name,model_backbone))evaluator = Evaluator()
evaluator.eval()
最后根据路径的图片获取语义分割文本
相关文章:
华为开源自研AI框架昇思MindSpore应用案例:ICNet用于实时的语义分割
ICNet用于实时的语义分割 ICNet 被广泛应用于实时的语义分割领域。它在处理图像数据时,能够以较高的效率进行语义分割操作,为相关领域的研究和实际应用提供了有力的支持。ICNet 的实时性使其在众多场景中都具有很大的优势,例如在视频处理、自…...
CAN201 Introduction to Networking(计算机网络)Pt.2 传输层
文章目录 3. Transport Layer(传输层)3.1 Multiplexing and demultiplexing(多路复用和多路分解)3.2 Connectionless transport:UDP3.3 Principles of reliable data transfer3.4 Pipelined communication3.5 TCP: con…...
HashMap
一、什么是 基于哈希表的数据结构允许以O(1)的时间复杂度进行元素的插入,查询和删除 二、底层结构 1.数据结构 在1.8以后,数组链表红黑树 数组:HashMap底层是一个数组,每个数组元素存放一个链表或红黑树(在JDK 1.…...
JavaScript甘特图 dhtmlx-gantt
背景 需求是在后台中,需要用甘特图去展示管理任务相关视图,并且不用依赖vue,兼容JavaScript原生开发。最终使用dhtmlx-gantt,一个半开源的库,基础功能免费,更多功能付费。 甘特图需求如图: 调…...
基于无线传感器网络的无线光照强度采集系统(附详细使用教程+完整代码+原理图+完整课设报告)
🎊项目专栏:【Zigbee课程设计系列文章】(附详细使用教程完整代码原理图完整课设报告) 前言 👑由于无线传感器网络(也即是Zigbee)作为🌐物联网工程的一门必修专业课,具有…...
单元测试中创建多个线程测试 ThreadLocal
单元测试中创建多个线程测试 ThreadLocal 在单元测试中,可以通过以下方式创建多个线程来测试 ThreadLocal 的行为。 目标 验证 ThreadLocal 在多线程环境下是否能正确隔离每个线程的数据。 实现步骤 定义需要测试的类 包含 ThreadLocal 对象的类,提供…...
【 Sonarqube】可视化Java项目单元测试覆盖率统计框架搭建
一、项目背景: 一个小公司的朋友反应他们那边Java项目单元测试有,但还没有可视化统计覆盖率数据,没法统计就不能直观的看到单测的覆盖率,Java的覆盖率统计框架还是比较成熟,部署起来也不是很难,下面我们逐…...
安装CentOS(新手教程超详细)
安装CentOS 1. 安装虚拟机 1.1下载虚拟机软件 VMware(VMware by Broadcom - Cloud Computing for the Enterprise) 我们使用的是VMware Workstation VirtualBox(Downloads – Oracle VirtualBox) 如果使用的是Windows系统,下载带for Windows hosts的版本 1.2…...
一起来看--红黑树
【欢迎关注编码小哥,学习更多实用的编程方法和技巧】 红黑树是一种自平衡的二叉搜索树,广泛应用于计算机科学中,尤其是在实现关联数组和集合时。它的设计旨在确保在最坏情况下,基本动态集合操作(如插入、删除和查找&am…...
【Hackthebox 中英 Write-Up】通过 POST 请求绕过前端限制:基于 Cookie 的认证与数据提取实操指南
Bypassing Frontend Restrictions with POST Requests: A Practical Guide to Cookie-Based Authentication and Data Extraction 通过 POST 请求绕过前端限制 Objective | 目标 The purpose of this exercise is to understand how POST requests work and how to authentica…...
comctl32.dll没有被指定在window运行怎么解决?
一、文件丢失问题:comctl32.dll没有被指定在Windows上运行怎么解决? comctl32.dll是Windows操作系统中的一个重要组件,它负责提供用户界面元素,如按钮、对话框和列表视图等。当系统提示“comctl32.dll没有被指定在Windows上运行”…...
EC-Final 2024游记
长篇流水账预警 Day -? 某天上乒乓课时看到懋神群里了我们队问有时间打ec吗,才知道我们最终还是进ec了,也成为了我们学校唯一一支没有金牌的ec队伍,然而此时整个队伍板子都扔了,一个多月没做过题,我脑子就…...
我的Opencv
1.安装Opencv pip install opencv-python 2.读取图像 3.写图像 4. 显示图像 5.waitKey() 6.读视频并播放视频 7.写视频 8. 获取摄像头视频 9.色彩转换 # BGR to GRAY imgGRAY cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # BGR to RGB imgRGB cv2.cvtColor(img, cv2.COLOR_…...
Pandas-缺失数据处理
文章目录 一. 简介1. 缺失数据简介2. NaN简介① 查看NaN,NAN,nan② 两个NaN也不相等③ isnull/isna方法④ notnull/notna 二. 加载缺失值1. 来源2. 加载数据,不包含默认缺失值3.加载数据,手动指定缺失值 三.处理缺失值1. 加载数据…...
windows编译llama.cpp GPU版本
Build 指南 https://github.com/ggerganov/llama.cpp/blob/master/docs/build.md 一、Prerequire 具体步骤(以及遇到的坑): 如果你要使用CUDA,请确保已安装。 1.安装 最新的 cmake, git, anaconda, pip 配置pyt…...
绝美的数据处理图-三坐标轴-散点图-堆叠图-数据可视化图
clc clear close all %% 读取数据 load(MyColor.mat) %读取颜色包for iloop 1:25 %提取工作表数据data0(iloop) {readtable(data.xlsx,sheet,iloop)}; end%% 解析数据 countzeros(23,14); for iloop 1:25index(iloop) { cell2mat(table2array(data0{1,iloop}(1,1)))};data(i…...
计算机网络500题2024-2025学年度第一学期复习题库(选择、判断、填空)
一、单选题 1、( )是实现两个同种网络互连的设备 A. 网桥 B. 网关 C. 集线器 D. 路由器 2、10M以太网有三种接口标准,其中10BASE-T采用( ) A. 双绞线 B. 粗同轴电缆 C. 细同轴电缆 D. 光纤 3、HDLC是哪…...
python学opencv|读取图像(二十二)使用cv2.polylines()绘制多边形
【1】引言 前序学习进程中,已经掌握了使用pythonopencv绘制线段、矩形和圆形的基本操作,相关链接包括且不限于: python学opencv|读取图像(十八)使用cv2.line创造线段-CSDN博客 python学opencv|读取图像(…...
skywalking配置项indexReplicasNumber不生效问题
indexReplicasNumber: 的配置原来是 indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}, 修改为 indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:1} 但从es查询索引显示的副本数还是0,删除es中的数据,重启sk…...
2024年终回顾
前言 很久没有更新博客,因为工作内容主要是内场开发,后来有点和互联网脱轨,断断续续上来看一下。这个总结应该也很简单,涉及以下的几个内容进行逐一说明 一、就业问题 这个问题可能很尖锐,从大环境来说,去…...
【深度学习】卷积网络代码实战ResNet
ResNet (Residual Network) 是由微软研究院的何凯明等人在2015年提出的一种深度卷积神经网络结构。ResNet的设计目标是解决深层网络训练中的梯度消失和梯度爆炸问题,进一步提高网络的表现。下面是一个ResNet模型实现,使用PyTorch框架来展示如何实现基本的…...
算法基础一:冒泡排序
一、冒泡排序 1、定义 冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。 …...
第 29 章 - ES 源码篇 - 网络 IO 模型及其实现概述
前言 本文介绍了 ES 使用的网络模型,并介绍 transport,http 接收、响应请求的代码入口。 网络 IO 模型 Node 在初始化的时候,会创建网络模块。网络模块会加载 Netty4Plugin plugin。 而后由 Netty4Plugin 创建对应的 transports࿰…...
工作流引擎之Flowable
一、概述 Flowable是一个使用Java编写的轻量级业务流程引擎,专为处理复杂业务流程而设计。作为业务流程管理(BPM)领域的重要工具,Flowable不仅支持BPMN 2.0标准的流程定义,还提供了丰富的API接口和可视化工具…...
学习threejs,THREE.CircleGeometry 二维平面圆形几何体
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.CircleGeometry 圆形…...
网络编程UDP—socket实现(C++)
网络编程UDP—socket实现 前言UDP客户端和服务端UDP使用场景UDP socket C代码示例服务端接收数据示例(bindrecvfrom 阻塞式接收信息):bind 绑定-监听 函数为什么一般都是监听所有网络接口呢?为什么需要用inet_addr进行转换&#x…...
个人用途虚拟机VM 17安装Ubuntu 16.04.5 图解
1.安装环境软件准备工作 1)下载 免费版VMware Pro 17 https://softwareupdate.vmware.com/cds/vmw-desktop/ws/17.6.1/24319023/windows/core/VMware-workstation-17.6.1-24319023.exe.tar 2)Ubuntu 16.04.5 LTS 64位 64-bit PC (AMD64) desktop imag…...
音视频入门基础:MPEG2-TS专题(23)——通过FFprobe显示TS流每个packet的信息
音视频入门基础:MPEG2-TS专题系列文章: 音视频入门基础:MPEG2-TS专题(1)——MPEG2-TS官方文档下载 音视频入门基础:MPEG2-TS专题(2)——使用FFmpeg命令生成ts文件 音视频入门基础…...
安卓project级别build.gradle和主module的build.gradle
以穿山甲为例讲解 如下图 gradle和gradle插件对应关系 Android Gradle 插件 8.7 版本说明 | Android Studio | Android Developers gradle对应在项目里的配置为 gradle插件对应的位置为...
【Qt】多元素控件:QListWidget、QTableWidget、QTreeWidget
目录 QListWidget 核心属性: 核心方法: 核心信号: 例子: QListWidgetItem QTableWidget 核心方法: 核心信号 QTableWidgetItem 例子: QTreeWidget 核心方法: 核心信号:…...
服务器nfs文件共享
1. 配置 NFS 服务器(NFS Server) 在 Ubuntu/Debian 上: sudo apt update sudo apt install nfs-kernel-server在 CentOS/RHEL 上: sudo yum install nfs-utils1.2 创建共享目录 选择一个要共享的目录,并确保该目录的权限正确设置。例如,假设我们要共享 /srv/nfs 目录…...
【hackmyvm】soul靶机wp
tags: HMVrbash绕过图片隐写PHP配置解析 1. 基本信息^toc 文章目录 1. 基本信息^toc2. 信息收集3. 图片解密3.1. 爆破用户名3.2. 绕过rbash3.3. 提权检测 4. 获取webshell4.1. 修改php配置 5. www-data提权gabriel6. gabriel提取到Peter7. Peter提权root 靶机链接 https://ha…...
安装winserver2008R2虚拟机步骤
一、服务器系统介绍 1.1什么是服务器? 服务器英文名称为“Server”,指的是网络环境下为客户机(Client)提供某种服务的专用计算机,服务器安装有网络操作系统(如Windows 2000 Server、Linux、Unix等)和各种服务器应用系统软件(如Web服务、电子…...
跟着 8.6k Star 的开源数据库,搞 RAG!
过去 9 年里,HelloGitHub 月刊累计收录了 3000 多个开源项目。然而,随着项目数量的增加,不少用户反馈:“搜索功能不好用,找不到想要的项目!” 这让我意识到,仅仅收录项目是不够的,还…...
RCE漏洞
一、课程知识点 1、远程代码执行漏洞原理与利用 2、常见的代码执行函数 3、常见的命令执行函数 4、常见的绕过姿势 5、命令执行漏洞防范 二、技术目标 1、掌握命令执行漏洞的原理 2、掌握 PHP 命令执行和代码执行的相关函数 3、掌握常见的绕过姿势 4、掌握代码执行漏洞防御措施…...
数据通信系统的主要性能指标
1.码元速率 n 误码率 2.数据传输速率 n 误比特率 3.时延 n 往返时间 RTT 1. 码元速率 n 码元 ( Code element) n 码元是 数字信号的计量单位 ( Signal element ), 又称为符号( Symbol )。 n 码元 是指在使用时域表示…...
C语言中的贪心算法
贪心算法(Greedy Algorithm)是一种在每一步选择中都采取当前最优解的算法,希望通过局部最优解的选择,最终得到全局最优解。它常用于解决最优化问题,如最小生成树、最短路径等。本文将从理论到实践,逐步引导…...
使用envoyfilter添加请求头
该envoyfilter实现了这样一个功能,如果请求头中含有Sw8,则添加请求头HasSw8: true。 1. 内嵌lua脚本 apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata:name: add-header-filternamespace: demo-bookinfo # 可根据实际情况调整命…...
【机器学习】回归
文章目录 1. 如何训练回归问题2. 泛化能力3. 误差来源4. 正则化5. 交叉验证 1. 如何训练回归问题 第一步:定义模型 线性模型: y ^ b ∑ j w j x j \hat{y} b \sum_{j} w_j x_j y^b∑jwjxj 其中,( w ) 是权重,( b )…...
Elasticsearch名词解释
文章目录 1.什么是Elasticsearch?2.什么是elastic stack(ELK)?3.什么是Lucene?4.什么是文档(document)?5.什么是词条(term)?6.什么是正向索引?7.什么是倒排索引?8.ES中的索引(index)9.映射(Mapping)10.DSL11.elastcisearch与my…...
把Huggingface下载的arrow数据集转化为json格式
Arrow2json 使用默认的Huggingface路径 以allenai/tulu-3-sft-mixture数据集为例。 使用load_dataset即可: from datasets import load_dataset# 加载数据集 dataset load_dataset("allenai/tulu-3-sft-mixture")# 指定保存路径 output_dir "~/…...
手机联系人 查询 添加操作
Android——添加联系人_android 添加联系人-CSDN博客 上面连接添加联系人已测试 是可以 Android : 获取、添加、手机联系人-ContentResolver简单应用_contentresolver 添加联系人-CSDN博客...
kkFileView集成springboot:使用自定义预览接口(非minio预览接口),发现无法预览资源
目录 1、背景2、原因分析3、解决办法 1、背景 按照项目验收要求,需要对minio中存储的数据进行加密 之前提供给kkFileView的预览地址都是获取的minio预览地址 由于minio中的资源进行了加密处理,所以我们自定义预览接口(进行解密操作ÿ…...
C++ 设计模式:观察者模式(Observer Pattern)
链接:C 设计模式 链接:C 设计模式 - 模板方法 链接:C 设计模式 - 策略模式 观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主…...
Mono 和 IL2Cpp的区别
Mono特征: 标准项目中有Assembly-CSharp.dll , 但在更复杂的项目或特定配置中,可能会有其他.dll或结构变更 在游戏的数据目录下看到一系列的.dll文件,这些文件的语言一般为中间语言 CE附加 , 查看是否有Mono.dll相关模块 目录有MonoBleedingEdge文件夹 IL2Cpp 标准项目应该…...
Windows平台ROBOT安装
Windows环境下ROBOT的安装,按照下文进行部署ROBOT的前提是你的python已安装并且环境变量已设置好. 一、安装setuptools 1、下载后安装 https://pypi.python.org/pypi/setuptools/ 下载你需要的包 setuptools-75.6.0.tar.gz 解压下载的包在命令行中进入该包,敲击如下命令后…...
DevOps实战:用Kubernetes和Argo打造自动化CI/CD流程(2)
DevOps实战:用Kubernetes和Argo打造自动化CI/CD流程(2) 背景 Tips 翻遍国内外的文档,关于 Argo 作为 CI/CD 当前所有开源的文档,博客,argo官方文档。得出的结论是: argo官方给出的例子都相对…...
深入浅出 MyBatis | CRUD 操作、配置解析
3、CRUD 3.1 namespace namespace 中的包名要和 Dao/Mapper 接口的包名一致! 比如将 UserDao 改名为 UserMapper 运行发现抱错,这是因为 UserMapper.xml 中没有同步更改 namespace 成功运行 给出 UserMapper 中的所有接口,接下来一一对…...
Hutool 发送 HTTP 请求的几种常见写法
最简单的 GET 请求: String result HttpUtil.get("https://www.baidu.com");带参数的 GET 请求: // 方法1: 直接拼接URL参数 String result HttpUtil.get("https://www.baidu.com?name张三&age18");// 方法2: 使用 HashMap…...
计算机网络|数据流向剖析与分层模型详解
文章目录 一、网络中的数据流向二、计算机网络通信模型1.OSI 模型2.TCP/IP 模型3.TCP/IP五层模型3.1 分层架构描述3.2各层地址结构3.3UDP数据包报头结构 三、总结 一、网络中的数据流向 在计算机网络中,数据的流向是指数据从发送端到接收端的传输路径。数据流向涉及…...