竞赛简介

多年来,技术已经彻底改变了我们的世界,改变了我们每天的生活,一切都可以通过轻松地点击实现连接和访问。oneAPI就是这样一个技术堆栈,它在构建许多创新解决方案方面具有巨大的潜力。 通过这次比赛精心策划的问题,您既可以更多地了解和体验人工智能技术在特定领域的运用,包括在机器学习、深度学习和分析等方面,还可以进一步体验与实践,用这些技术解决某个问题或实现某个功能。 在本次黑客马拉松过程中,开发人员还可以获得英特尔®专家的免费实践培训。本次大赛旨在鼓励使用下列一项或多项oneAPI相关工具,共包含二个赛题,您可任选一或两个报名参赛。 欢迎您来展示自己的技术才能,迎接挑战,赢取奖励。

在这次比赛中,我选择了赛题1和Xception网络作为此次的任务。

Xception网络是一种深度卷积神经网络,它在图像分类和图像分割等计算机视觉领域中表现出色。本文将探讨Xception网络在Cityscapes数据集上的图像分割应用。


Cityscapes数据集简介

Xception的一个小小创新,能够解决图像分割_图像分割

Cityscapes数据集是一个广泛使用的图像分割数据集,其中包含来自50个不同城市的5000张高分辨率图像。这些图像是在日常城市场景中捕获的,例如街道、建筑物和车辆等。每个图像都有精确的像素级标注,可以用于训练和评估图像分割算法。

## Xception网络简介

Xception网络是一种深度卷积神经网络,它采用了深度可分离卷积层来减少参数数量和计算量。深度可分离卷积层将常规卷积分成两个步骤:深度卷积和逐点卷积。深度卷积在每个输入通道上执行卷积操作,而逐点卷积在每个通道之间执行卷积操作。这种方法可以显著减少参数数量,并提高模型的准确性和速度。

## Xception网络在Cityscapes数据集上的应用

Xception网络在Cityscapes数据集上的应用主要是图像分割。图像分割是将图像中的每个像素分类为不同的物体或背景的过程。在Cityscapes数据集中,我们可以将像素分为道路、建筑物、车辆等类别。

Xception网络在Cityscapes数据集上的表现非常出色。在最新的评估中,Xception网络在Cityscapes测试集上获得了84.1%的像素级准确率,超过了其他先进的图像分割算法。

##训练代码:
def train():
opts = get_argparser_train().parse_args(args=[])
if opts.dataset.lower() == 'cityscapes':
    opts.num_classes = 19

# Setup visualization
vis = Visualizer(port=opts.vis_port,
                 env=opts.vis_env) if opts.enable_vis else None
if vis is not None:  # display options
    vis.vis_table("Options", vars(opts))

os.environ['CUDA_VISIBLE_DEVICES'] = opts.gpu_id
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print("Device: %s" % device)

# Setup random seed
torch.manual_seed(opts.random_seed)
np.random.seed(opts.random_seed)
random.seed(opts.random_seed)

train_dst, val_dst = get_dataset(opts)
train_loader = data.DataLoader(
    train_dst, batch_size=opts.batch_size, shuffle=True, num_workers=2,
    drop_last=True)  # drop_last=True to ignore single-image batches.
val_loader = data.DataLoader(
    val_dst, batch_size=opts.val_batch_size, shuffle=True, num_workers=2)
print("Dataset: %s, Train set: %d, Val set: %d" %
      (opts.dataset, len(train_dst), len(val_dst)))

# Set up model (all models are 'constructed at network.modeling)
model = network.modeling.__dict__[opts.model](num_classes=opts.num_classes, output_stride=opts.output_stride)
if opts.separable_conv and 'plus' in opts.model:
    network.convert_to_separable_conv(model.classifier)
utils.set_bn_momentum(model.backbone, momentum=0.01)

# Set up metrics
metrics = StreamSegMetrics(opts.num_classes)

# Set up optimizer
optimizer = torch.optim.SGD(params=[
    {'params': model.backbone.parameters(), 'lr': 0.1 * opts.lr},
    {'params': model.classifier.parameters(), 'lr': opts.lr},
], lr=opts.lr, momentum=0.9, weight_decay=opts.weight_decay)
# optimizer = torch.optim.SGD(params=model.parameters(), lr=opts.lr, momentum=0.9, weight_decay=opts.weight_decay)
# torch.optim.lr_scheduler.StepLR(optimizer, step_size=opts.lr_decay_step, gamma=opts.lr_decay_factor)
if opts.lr_policy == 'poly':
    scheduler = utils.PolyLR(optimizer, opts.total_itrs, power=0.9)
elif opts.lr_policy == 'step':
    scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=opts.step_size, gamma=0.1)

# Set up criterion
# criterion = utils.get_loss(opts.loss_type)
if opts.loss_type == 'focal_loss':
    criterion = utils.FocalLoss(ignore_index=255, size_average=True)
elif opts.loss_type == 'cross_entropy':
    criterion = nn.CrossEntropyLoss(ignore_index=255, reduction='mean')

def save_ckpt(path):
    """ save current model
    """
    torch.save({
        "cur_itrs": cur_itrs,
        "model_state": model.module.state_dict(),
        "optimizer_state": optimizer.state_dict(),
        "scheduler_state": scheduler.state_dict(),
        "best_score": best_score,
    }, path)
    print("Model saved as %s" % path)

utils.mkdir('./result/checkpoints')
# Restore
best_score = 0.0
cur_itrs = 0
cur_epochs = 0
if opts.ckpt is not None and os.path.isfile(opts.ckpt):
    checkpoint = torch.load(opts.ckpt, map_location=torch.device('cpu'))
    model.load_state_dict(checkpoint["model_state"])
    model = nn.DataParallel(model)
    model.to(device)
    if opts.continue_training:
        optimizer.load_state_dict(checkpoint["optimizer_state"])
        scheduler.load_state_dict(checkpoint["scheduler_state"])
        cur_itrs = checkpoint["cur_itrs"]
        best_score = checkpoint['best_score']
        print("Training state restored from %s" % opts.ckpt)
    print("Model restored from %s" % opts.ckpt)
    del checkpoint  # free memory
else:
    print("[!] Retrain")
    model = nn.DataParallel(model)
    model.to(device)

# ==========   Train Loop   ==========#
vis_sample_id = np.random.randint(0, len(val_loader), opts.vis_num_samples,
                                  np.int32) if opts.enable_vis else None  # sample idxs for visualization
denorm = utils.Denormalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  # denormalization for ori images

if opts.test_only:
    model.eval()
    val_score, ret_samples = validate(
        opts=opts, model=model, loader=val_loader, device=device, metrics=metrics, ret_samples_ids=vis_sample_id)
    print(metrics.to_str(val_score))
    return

interval_loss = 0
while True:
    # 开始训练
    model.train()
    cur_epochs += 1
    for (images, labels) in train_loader:
        cur_itrs += 1

        images = images.to(device, dtype=torch.float32)
        labels = labels.to(device, dtype=torch.long)

        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        np_loss = loss.detach().cpu().numpy()
        interval_loss += np_loss
        if vis is not None:
            vis.vis_scalar('Loss', cur_itrs, np_loss)

        if (cur_itrs) % 10 == 0:
            interval_loss = interval_loss / 10
            print("Epoch %d, Itrs %d/%d, Loss=%f" %
                  (cur_epochs, cur_itrs, opts.total_itrs, interval_loss))
            interval_loss = 0.0

        if (cur_itrs) % opts.val_interval == 0:
            save_ckpt('./result/checkpoints/latest_%s_%s_os%d.pth' %
                      (opts.model, opts.dataset, opts.output_stride))
            print("validation...")
            model.eval()
            val_score, ret_samples = validate(
                opts=opts, model=model, loader=val_loader, device=device, metrics=metrics,
                ret_samples_ids=vis_sample_id)
            print(metrics.to_str(val_score))
            if val_score['Mean IoU'] > best_score:  # save best model
                best_score = val_score['Mean IoU']
                save_ckpt('./result/checkpoints/best_%s_%s_os%d.pth' %
                          (opts.model, opts.dataset, opts.output_stride))

            if vis is not None:  
                vis.vis_scalar("[Val] Overall Acc", cur_itrs, val_score['Overall Acc'])
                vis.vis_scalar("[Val] Mean IoU", cur_itrs, val_score['Mean IoU'])
                vis.vis_table("[Val] Class IoU", val_score['Class IoU'])

                for k, (img, target, lbl) in enumerate(ret_samples):
                    img = (denorm(img) * 255).astype(np.uint8)
                    target = train_dst.decode_target(target).transpose(2, 0, 1).astype(np.uint8)
                    lbl = train_dst.decode_target(lbl).transpose(2, 0, 1).astype(np.uint8)
                    concat_img = np.concatenate((img, target, lbl), axis=2)  # concat along width
                    vis.vis_image('Sample %d' % k, concat_img)
            model.train()
        scheduler.step()

        if cur_itrs >= opts.total_itrs:
            return

## 训练下效果测试

柏林街道测试

Xception的一个小小创新,能够解决图像分割_卷积_02

亚琛街道测试

Xception的一个小小创新,能够解决图像分割_图像分割_03

美因茨街道测试

Xception的一个小小创新,能够解决图像分割_数据集_04

效果都能够很不错,保持一个很好的分割效果。

总结:

Xception网络是一种高效且准确的深度卷积神经网络,在Cityscapes数据集上表现出色。它可以用于各种计算机视觉任务,包括图像分类、目标检测和图像分割等。未来,我可以应用并且看到更多基于Xception网络的创新应用。