​​​​
global使用的ERFNet。它使用的是Non-bottleneck模块来代替卷积模块。



ERF代码:

# ERFNet full model definition for Pytorch
# Sept 2017
# Eduardo Romera
#######################import torch
import torch.nn as nn
import torch.nn.functional as Fclass DownsamplerBlock (nn.Module):def __init__(self, ninput, noutput):super().__init__()self.conv = nn.Conv2d(ninput, noutput-ninput, (3, 3), stride=2, padding=1, bias=True)self.pool = nn.MaxPool2d(2, stride=2)self.bn = nn.BatchNorm2d(noutput, eps=1e-3)def forward(self, input):output = torch.cat([self.conv(input), self.pool(input)], 1)output = self.bn(output)return F.relu(output)class non_bottleneck_1d (nn.Module):def __init__(self, chann, dropprob, dilated):super().__init__()self.conv3x1_1 = nn.Conv2d(chann, chann, (3, 1), stride=1, padding=(1, 0), bias=True)self.conv1x3_1 = nn.Conv2d(chann, chann, (1, 3), stride=1, padding=(0, 1), bias=True)self.bn1 = nn.BatchNorm2d(chann, eps=1e-03)self.conv3x1_2 = nn.Conv2d(chann, chann, (3, 1), stride=1, padding=(1*dilated,0), bias=True, dilation=(dilated, 1))self.conv1x3_2 = nn.Conv2d(chann, chann, (1, 3), stride=1, padding=(0, 1*dilated), bias=True, dilation=(1, dilated))self.bn2 = nn.BatchNorm2d(chann, eps=1e-03)self.dropout = nn.Dropout2d(dropprob)def forward(self, input):output = self.conv3x1_1(input)output = F.relu(output)output = self.conv1x3_1(output)output = self.bn1(output)output = F.relu(output)output = self.conv3x1_2(output)output = F.relu(output)output = self.conv1x3_2(output)output = self.bn2(output)if (self.dropout.p != 0):output = self.dropout(output)return F.relu(output+input)class Encoder(nn.Module):def __init__(self, in_channels, num_classes):super().__init__()chans = 32 if in_channels > 16 else 16self.initial_block = DownsamplerBlock(in_channels, chans)self.layers = nn.ModuleList()self.layers.append(DownsamplerBlock(chans, 64))for x in range(0, 5):self.layers.append(non_bottleneck_1d(64, 0.03, 1)) self.layers.append(DownsamplerBlock(64, 128))for x in range(0, 2):self.layers.append(non_bottleneck_1d(128, 0.3, 2))self.layers.append(non_bottleneck_1d(128, 0.3, 4))self.layers.append(non_bottleneck_1d(128, 0.3, 8))self.layers.append(non_bottleneck_1d(128, 0.3, 16))#Only in encoder mode:self.output_conv = nn.Conv2d(128, num_classes, 1, stride=1, padding=0, bias=True)def forward(self, input, predict=False):output = self.initial_block(input)for layer in self.layers:output = layer(output)if predict:output = self.output_conv(output)return outputclass UpsamplerBlock (nn.Module):def __init__(self, ninput, noutput):super().__init__()self.conv = nn.ConvTranspose2d(ninput, noutput, 3, stride=2, padding=1, output_padding=1, bias=True)self.bn = nn.BatchNorm2d(noutput, eps=1e-3)def forward(self, input):output = self.conv(input)output = self.bn(output)return F.relu(output)class Decoder (nn.Module):def __init__(self, num_classes):super().__init__()self.layer1 = UpsamplerBlock(128, 64)self.layer2 = non_bottleneck_1d(64, 0, 1)self.layer3 = non_bottleneck_1d(64, 0, 1) # 64x64x304self.layer4 = UpsamplerBlock(64, 32)self.layer5 = non_bottleneck_1d(32, 0, 1)self.layer6 = non_bottleneck_1d(32, 0, 1) # 32x128x608self.output_conv = nn.ConvTranspose2d(32, num_classes, 2, stride=2, padding=0, output_padding=0, bias=True)def forward(self, input):output = inputoutput = self.layer1(output)output = self.layer2(output)output = self.layer3(output)em2 = outputoutput = self.layer4(output)output = self.layer5(output)output = self.layer6(output)em1 = outputoutput = self.output_conv(output)return output, em1, em2class Net(nn.Module):def __init__(self, in_channels=1, out_channels=1):  #use encoder to pass pretrained encodersuper().__init__()self.encoder = Encoder(in_channels, out_channels)self.decoder = Decoder(out_channels)def forward(self, input, only_encode=False):if only_encode:return self.encoder.forward(input, predict=True)else:output = self.encoder(input)return self.decoder.forward(output)

然后是整体模型,里面包含了沙漏网络。

import torch
import torch.nn as nn
import torch.utils.data
import torch.nn.functional as F
import numpy as np
from .ERFNet import Netclass uncertainty_net(nn.Module):def __init__(self, in_channels, out_channels=1, thres=15):super(uncertainty_net, self).__init__()out_chan = 2combine = 'concat'self.combine = combineself.in_channels = in_channelsout_channels = 3self.depthnet = Net(in_channels=in_channels, out_channels=out_channels)local_channels_in = 2 if self.combine == 'concat' else 1self.convbnrelu = nn.Sequential(convbn(local_channels_in, 32, 3, 1, 1, 1),nn.ReLU(inplace=True))self.hourglass1 = hourglass_1(32)self.hourglass2 = hourglass_2(32)self.fuse = nn.Sequential(convbn(32, 32, 3, 1, 1, 1),nn.ReLU(inplace=True),nn.Conv2d(32, out_chan, kernel_size=3, padding=1, stride=1, bias=True))self.activation = nn.ReLU(inplace=True)self.thres = thresself.softmax = torch.nn.Softmax(dim=1)def forward(self, input, epoch=50):if self.in_channels > 1:rgb_in = input[:, 1:, :, :]lidar_in = input[:, 0:1, :, :]else:lidar_in = input# 1. GLOBAL NETembedding0, embedding1, embedding2 = self.depthnet(input)global_features = embedding0[:, 0:1, :, :]precise_depth = embedding0[:, 1:2, :, :]conf = embedding0[:, 2:, :, :]# 2. Fuseif self.combine == 'concat':input = torch.cat((lidar_in, global_features), 1)elif self.combine == 'add':input = lidar_in + global_featureselif self.combine == 'mul':input = lidar_in * global_featureselif self.combine == 'sigmoid':input = lidar_in * nn.Sigmoid()(global_features)else:input = lidar_in# 3. LOCAL NETout = self.convbnrelu(input)out1, embedding3, embedding4 = self.hourglass1(out, embedding1, embedding2)out1 = out1 + outout2 = self.hourglass2(out1, embedding3, embedding4)out2 = out2 + outout = self.fuse(out2)lidar_out = out# 4. Late Fusionlidar_to_depth, lidar_to_conf = torch.chunk(out, 2, dim=1)lidar_to_conf, conf = torch.chunk(self.softmax(torch.cat((lidar_to_conf, conf), 1)), 2, dim=1)out = conf * precise_depth + lidar_to_conf * lidar_to_depthreturn out, lidar_out, precise_depth, global_featuresdef convbn(in_planes, out_planes, kernel_size, stride, pad, dilation):return nn.Sequential(nn.Conv2d(in_planes, out_planes, kernel_size=kernel_size, stride=stride, padding=dilation if dilation > 1 else pad, dilation=dilation, bias=False))# nn.BatchNorm2d(out_planes))
class hourglass_1(nn.Module):def __init__(self, channels_in):super(hourglass_1, self).__init__()self.conv1 = nn.Sequential(convbn(channels_in, channels_in, kernel_size=3, stride=2, pad=1, dilation=1),nn.ReLU(inplace=True))self.conv2 = convbn(channels_in, channels_in, kernel_size=3, stride=1, pad=1, dilation=1)self.conv3 = nn.Sequential(convbn(channels_in*2, channels_in*2, kernel_size=3, stride=2, pad=1, dilation=1),nn.ReLU(inplace=True))self.conv4 = nn.Sequential(convbn(channels_in*2, channels_in*2, kernel_size=3, stride=1, pad=1, dilation=1))self.conv5 = nn.Sequential(nn.ConvTranspose2d(channels_in*4, channels_in*2, kernel_size=3, padding=1, output_padding=1, stride=2,bias=False),nn.BatchNorm2d(channels_in*2),nn.ReLU(inplace=True))self.conv6 = nn.Sequential(nn.ConvTranspose2d(channels_in*2, channels_in, kernel_size=3, padding=1, output_padding=1, stride=2,bias=False),nn.BatchNorm2d(channels_in))def forward(self, x, em1, em2):x = self.conv1(x)x = self.conv2(x)x = F.relu(x, inplace=True)x = torch.cat((x, em1), 1)x_prime = self.conv3(x)x_prime = self.conv4(x_prime)x_prime = F.relu(x_prime, inplace=True)x_prime = torch.cat((x_prime, em2), 1)out = self.conv5(x_prime)out = self.conv6(out)return out, x, x_prime
class hourglass_2(nn.Module):def __init__(self, channels_in):super(hourglass_2, self).__init__()self.conv1 = nn.Sequential(convbn(channels_in, channels_in*2, kernel_size=3, stride=2, pad=1, dilation=1),nn.BatchNorm2d(channels_in*2),nn.ReLU(inplace=True))self.conv2 = convbn(channels_in*2, channels_in*2, kernel_size=3, stride=1, pad=1, dilation=1)self.conv3 = nn.Sequential(convbn(channels_in*2, channels_in*2, kernel_size=3, stride=2, pad=1, dilation=1),nn.BatchNorm2d(channels_in*2),nn.ReLU(inplace=True))self.conv4 = nn.Sequential(convbn(channels_in*2, channels_in*4, kernel_size=3, stride=1, pad=1, dilation=1))self.conv5 = nn.Sequential(nn.ConvTranspose2d(channels_in*4, channels_in*2, kernel_size=3, padding=1, output_padding=1, stride=2,bias=False),nn.BatchNorm2d(channels_in*2),nn.ReLU(inplace=True))self.conv6 = nn.Sequential(nn.ConvTranspose2d(channels_in*2, channels_in, kernel_size=3, padding=1, output_padding=1, stride=2,bias=False),nn.BatchNorm2d(channels_in))def forward(self, x, em1, em2):x = self.conv1(x)x = self.conv2(x)x = x + em1x = F.relu(x, inplace=True)x_prime = self.conv3(x)x_prime = self.conv4(x_prime)x_prime = x_prime + em2x_prime = F.relu(x_prime, inplace=True)out = self.conv5(x_prime)out = self.conv6(out)return out
if __name__ == '__main__':batch_size = 4in_channels = 4H, W = 256, 1216model = uncertainty_net(in_channels).cuda()print(model)print("Number of parameters in model is {:.3f}M".format(sum(tensor.numel() for tensor in model.parameters())/1e6))input = torch.rand((batch_size, in_channels, H, W)).cuda().float()out = model(input)print(out[0].shape)

首先看一下主网络的forward函数:

in_channels = 4H, W = 256, 1216model = uncertainty_net(in_channels).cuda()
 因为输入通道为4,经过两个切片,获得rgb图像:[1,3,256,1216]和Lidar图像:[1,1,256,1216]。

然后是global net:
输入经过depthnet产生三个输出:self.depthnet = Net(in_channels=in_channels, out_channels=out_channels),NET函数就是ERFNet,三个输出为decoder的输出。

class Decoder (nn.Module):def __init__(self, num_classes):super().__init__()self.layer1 = UpsamplerBlock(128, 64)self.layer2 = non_bottleneck_1d(64, 0, 1)self.layer3 = non_bottleneck_1d(64, 0, 1) # 64x64x304self.layer4 = UpsamplerBlock(64, 32)self.layer5 = non_bottleneck_1d(32, 0, 1)self.layer6 = non_bottleneck_1d(32, 0, 1) # 32x128x608self.output_conv = nn.ConvTranspose2d(32, num_classes, 2, stride=2, padding=0, output_padding=0, bias=True)def forward(self, input):output = inputoutput = self.layer1(output)output = self.layer2(output)output = self.layer3(output)em2 = outputoutput = self.layer4(output)output = self.layer5(output)output = self.layer6(output)em1 = outputoutput = self.output_conv(output)return output, em1, em2

input(4,4,256,1216)首先进入ERFNet的encoder内部,经过卷积池化后拼接起来,维度变为(4,16,128,608)。接着经过layers,遍历7次。

encoder的输出为(4,128,32,152),输入进decoder。经过转置卷积进行上采样和non_bottleneck_1d,输出emb2(4,64,64,304),emb1(4,32,128,608),output(4,3256,1216)。

然后对output进行切片,global_features和precise_depth 和conf大小都为torch.Size([4, 1, 256, 1216])。
第二步融合:

        # 2. Fuseif self.combine == 'concat':input = torch.cat((lidar_in, global_features), 1)elif self.combine == 'add':input = lidar_in + global_featureselif self.combine == 'mul':input = lidar_in * global_featureselif self.combine == 'sigmoid':input = lidar_in * nn.Sigmoid()(global_features)else:input = lidar_in

combine=concat,所以将lidar数据和global feature拼接在一起,作为新的input。
第三步输入到local branch

        # 3. LOCAL NETout = self.convbnrelu(input)out1, embedding3, embedding4 = self.hourglass1(out, embedding1, embedding2)out1 = out1 + outout2 = self.hourglass2(out1, embedding3, embedding4)out2 = out2 + outout = self.fuse(out2)lidar_out = out

新的input首先经过一个卷积,维度变为32,接着将out, embedding1, embedding2共同输入到hourglass1。这里看一下沙漏网络结构。

class hourglass_1(nn.Module):def __init__(self, channels_in):super(hourglass_1, self).__init__()self.conv1 = nn.Sequential(convbn(channels_in, channels_in, kernel_size=3, stride=2, pad=1, dilation=1),nn.ReLU(inplace=True))self.conv2 = convbn(channels_in, channels_in, kernel_size=3, stride=1, pad=1, dilation=1)self.conv3 = nn.Sequential(convbn(channels_in*2, channels_in*2, kernel_size=3, stride=2, pad=1, dilation=1),nn.ReLU(inplace=True))self.conv4 = nn.Sequential(convbn(channels_in*2, channels_in*2, kernel_size=3, stride=1, pad=1, dilation=1))self.conv5 = nn.Sequential(nn.ConvTranspose2d(channels_in*4, channels_in*2, kernel_size=3, padding=1, output_padding=1, stride=2,bias=False),nn.BatchNorm2d(channels_in*2),nn.ReLU(inplace=True))self.conv6 = nn.Sequential(nn.ConvTranspose2d(channels_in*2, channels_in, kernel_size=3, padding=1, output_padding=1, stride=2,bias=False),nn.BatchNorm2d(channels_in))def forward(self, x, em1, em2):x = self.conv1(x)x = self.conv2(x)x = F.relu(x, inplace=True)x = torch.cat((x, em1), 1)x_prime = self.conv3(x)x_prime = self.conv4(x_prime)x_prime = F.relu(x_prime, inplace=True)x_prime = torch.cat((x_prime, em2), 1)out = self.conv5(x_prime)out = self.conv6(out)return out, x, x_prime


out, x, x_prime输出大小为:(4,32,256,1216),(4,64,128,608),(4,128,64,304)。
进过一个跳连接,out1 = out1 + out。接着生成的三个输出再作为下一个沙漏结构的输入。第二个结构同理,生成的输出再经过一个1x1卷积。lidar_out = out(4,2,256,1216)。
第四步后期融合:

        # 4. Late Fusionlidar_to_depth, lidar_to_conf = torch.chunk(out, 2, dim=1)lidar_to_conf, conf = torch.chunk(self.softmax(torch.cat((lidar_to_conf, conf), 1)), 2, dim=1)out = conf * precise_depth + lidar_to_conf * lidar_to_depthreturn out, lidar_out, precise_depth, global_features

将上一步输出按照维度劈开,lidar_to_conf与全局分支的conf按照维度拼接,经过softmax,再按维度劈开。生成新的置信度图。再与全局分支的depth和局部分支的depth相乘,最后相加得到最终的out。同时也输出lidar_out, precise_depth, global_features。整个框架搭建结束。

--------------------------------------------------------------------分割线----------------------------------------------------------------------------------------
除了整体的框架,接着看一下如何训练
1:定义一些参数,然后初始化优化器和迭代策略。
2:我们选择损失函数:默认为mse。

class MSE_loss(nn.Module):def __init__(self):super(MSE_loss, self).__init__()def forward(self, prediction, gt, epoch=0):err = prediction[:,0:1] - gtmask = (gt > 0).detach()mse_loss = torch.mean((err[mask])**2)#返回所有元素的平均值return mse_loss

首先我们取prediction的第一个通道所有的数值,与gt相减,计算出error。
然后判断gt>0,正确的话为true,错误的为flase,大小和gt相同,然后使用detach函数,使其不要更新。
最后计算所有像素差的平均值。
这里看一下err[mask]。这里我随便初始化然后发现err[mask]可以将高维tensor展开为一维。用view函数也可以实现该效果。

但是如果mask中有False,那么error中对应的值就会删去。用其他的函数就没有这个效果。

最后MSE即所有的损失会生成一个损失值。
global框架载入权重:

    # Load pretrained state for cityscapes in GLOBAL netif args.pretrained and not args.resume:if not args.load_external_mod:if not args.multi:target_state = model.depthnet.state_dict()else:target_state = model.module.depthnet.state_dict()check = torch.load('erfnet_pretrained.pth')for name, val in check.items():# Exclude multi GPU prefixmono_name = name[7:] if mono_name not in target_state:continuetry:target_state[mono_name].copy_(val)except RuntimeError:continueprint('Successfully loaded pretrained model')

如果不使用多卡直接载入,如果使用需要在model后面加上module。
假如不使用,target为depthnet网络的参数。即ERFNet的参数(看第一个和最后一个key)。


再查看erfnet_pretrained.pth的参数:只打印了name。

然后name[7:]是取第七个字符之后的所有字符,即mono_mame为所有不带module的name。
对比是相等的。那么:if-continue是不执行的。接着就执行try语句,那么就不会执行except语句,因为只有try报错才会交给except处理。

其中try-except语句参考:添加链接描述
mono_name键对应的值就copy给val。将原始的模型参数赋值给预训练模型的参数?(存疑)
开始训练:在一个epoch里面要执行这么多操作。

    for epoch in range(args.start_epoch, args.nepochs):print("\n => Start EPOCH {}".format(epoch + 1))print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))print(args.save_path)# Adjust learning rateif args.lr_policy is not None and args.lr_policy != 'plateau':scheduler.step()lr = optimizer.param_groups[0]['lr']print('lr is set to {}'.format(lr))# Define container objectsbatch_time = AverageMeter()data_time = AverageMeter()losses = AverageMeter()score_train = AverageMeter()score_train_1 = AverageMeter()metric_train = Metrics(max_depth=args.max_depth, disp=args.use_disp, normal=args.normal)# Train model for args.nepochsmodel.train()# compute timingend = time.time()# Load datasetfor i, (input, gt) in tqdm(enumerate(train_loader)):# Time dataloaderdata_time.update(time.time() - end)# Put inputs on gpu if possibleif not args.no_cuda:input, gt = input.cuda(), gt.cuda()prediction, lidar_out, precise, guide = model(input, epoch)loss = criterion_local(prediction, gt)loss_lidar = criterion_lidar(lidar_out, gt)loss_rgb = criterion_rgb(precise, gt)loss_guide = criterion_guide(guide, gt)loss = args.wpred*loss + args.wlid*loss_lidar + args.wrgb*loss_rgb + args.wguide*loss_guidelosses.update(loss.item(), input.size(0))metric_train.calculate(prediction[:, 0:1].detach(), gt.detach())score_train.update(metric_train.get_metric(args.metric), metric_train.num)score_train_1.update(metric_train.get_metric(args.metric_1), metric_train.num)# Clip gradients (usefull for instabilities or mistakes in ground truth)if args.clip_grad_norm != 0:nn.utils.clip_grad_norm(model.parameters(), args.clip_grad_norm)# Setup backward passoptimizer.zero_grad()loss.backward()optimizer.step()# Time trainig iterationbatch_time.update(time.time() - end)end = time.time()# Print infoif (i + 1) % args.print_freq == 0:print('Epoch: [{0}][{1}/{2}]\t''Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t''Loss {loss.val:.4f} ({loss.avg:.4f})\t''Metric {score.val:.4f} ({score.avg:.4f})'.format(epoch+1, i+1, len(train_loader), batch_time=batch_time,loss=losses,score=score_train))


首先lr_policy不为空,但是lr_policy等于’plateau’。所以直接跳过if语句。
接着跳入AverageMeter函数中:

class AverageMeter(object):"""Computes and stores the average and current value"""def __init__(self):self.reset()def reset(self):self.val = 0self.avg = 0self.sum = 0self.count = 0def update(self, val, n=1):self.val = valself.sum += val * nself.count += nself.avg = self.sum / self.count

再跳入matric函数:三个参数默认为(85,false,false)。

class Metrics(object):def __init__(self, max_depth=85.0, disp=False, normal=False):self.rmse, self.mae = 0, 0self.num = 0self.disp = dispself.max_depth = max_depthself.min_disp = 1.0/max_depthself.normal = normaldef calculate(self, prediction, gt):valid_mask = (gt > 0).detach()self.num = valid_mask.sum().item()prediction = prediction[valid_mask]gt = gt[valid_mask]if self.disp:prediction = torch.clamp(prediction, min=self.min_disp)prediction = 1./predictiongt = 1./gtif self.normal:prediction = prediction * self.max_depthgt = gt * self.max_depthprediction = torch.clamp(prediction, min=0, max=self.max_depth)#(min=0,max=1/85),input张量每个元素的夹紧到区间 [min,max][min,max],并返回结果到一个新张量abs_diff = (prediction - gt).abs()self.rmse = torch.sqrt(torch.mean(torch.pow(abs_diff, 2))).item()self.mae = abs_diff.mean().item()def get_metric(self, metric_name):return self.__dict__[metric_name]

然后模型设置为train模式:
在一个epoch中遍历dataloader,将输入和gt输入到cuda中。将输入输送到model中,产生四个输出。然后将四个输出分别和gt计算损失。然后在赋予每个w一个权重。


接着损失进行更新,将loss和batch的值传入到losses中的update函数。

第一次更新,若batch=4:val = loss,sum = loss4, count = 4, avg=4loss/count 。那个avg就是loss,第二次sum = loss_14+loss_24,count=8,avg = loss_14+loss_24/8,总结为总损失除以总的batch数

接着计算metric_train。输入参数为prediction[:, 0:1].detach(), gt.detach()。对应维度为torch.Size([4, 1, 256, 1216])和(4,1,256,1216)。
计算调用metric的calcute函数:
valid_mask=(4,1,256,1216),由True和false组成,这里默认为true。
num=4x1x256x1216=1245184。
prediction相当于展开大小为1245184。
gt同理大小为1245184。
disp为false,跳过if语句。
norm默认不存在,跳过if语句。
clamp函数将prediction限制到0-85,然后计算预测值与真实值之间的差距。
rmse 和mae公式。

然后metric_train调用get_metric函数,我们返回metric_train的key:metric_name,对应的value。

    def get_metric(self, metric_name):return self.__dict__[metric_name]

在上一步我们计算了metric_train,他是一个字典:

rmse对应的值就为0.408595,和metric_train的num=1245184一起作为参数的输入进update函数。生成了新的score_train。

同理生成新的score_train1,惟一的区别是两个评价指标一个是RMSE一个是MAE。
然后清空梯度,损失反向传播,优化器更新。
运行完一个epoch后输出:
训练集的RMSE,是score_train的平均值。
训练集的MAE,是score_train_1的平均值。
将验证集的valid_loader(验证集数据), model, criterion_lidar, criterion_rgb, criterion_local, criterion_guide, epoch输入进验证集的模型中。得到验证集三个输出:score_valid, score_valid_1, losses_valid

保存模型:

        if total_score < lowest_loss:to_save = Truebest_epoch = epoch+1lowest_loss = total_scoresave_checkpoint({'epoch': epoch + 1,'best epoch': best_epoch,'arch': args.mod,'state_dict': model.state_dict(),'loss': lowest_loss,'optimizer': optimizer.state_dict()}, to_save, epoch)

看一下validate的代码:和train的代码很像就不一一介绍了

def validate(loader, model, criterion_lidar, criterion_rgb, criterion_local, criterion_guide, epoch=0):# batch_time = AverageMeter()losses = AverageMeter()metric = Metrics(max_depth=args.max_depth, disp=args.use_disp, normal=args.normal)score = AverageMeter()score_1 = AverageMeter()# Evaluate modelmodel.eval()# Only forward pass, hence no grads neededwith torch.no_grad():# end = time.time()for i, (input, gt) in tqdm(enumerate(loader)):if not args.no_cuda:input, gt = input.cuda(non_blocking=True), gt.cuda(non_blocking=True)prediction, lidar_out, precise, guide = model(input, epoch)loss = criterion_local(prediction, gt, epoch)loss_lidar = criterion_lidar(lidar_out, gt, epoch)loss_rgb = criterion_rgb(precise, gt, epoch)loss_guide = criterion_guide(guide, gt, epoch)loss = args.wpred*loss + args.wlid*loss_lidar + args.wrgb*loss_rgb + args.wguide*loss_guidelosses.update(loss.item(), input.size(0))metric.calculate(prediction[:, 0:1], gt)score.update(metric.get_metric(args.metric), metric.num)score_1.update(metric.get_metric(args.metric_1), metric.num)

Sparse and noisy LiDAR completion with RGB guidance and uncertainty代码相关推荐

  1. 网上流行护眼色的RGB值和颜色代码

    网上流行护眼色的RGB值和颜色代码 绿豆沙色能有效的减轻长时间用电脑的用眼疲劳! 色调:85,饱和度:123,亮度:205: RGB颜色红:199,绿:237,蓝:204: 十六进制颜色:#C7EDC ...

  2. (转)网上流行护眼色的RGB值和颜色代码

    网上流行护眼色的RGB值和颜色代码 绿豆沙色能有效的减轻长时间用电脑的用眼疲劳! 色调:85,饱和度:123,亮度:205: RGB颜色红:199,绿:237,蓝:204: 十六进制颜色:#C7EDC ...

  3. js 实现rgb和十六进制的代码转化

    十六进制转化为RGB function set16ToRgb(str){// 十六进制颜色代码的正则表达式var reg = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$// ...

  4. 灰色的rgb值_一行代码实现图片的灰色效果

    今天是清明节,警笛长鸣,万众默哀.送别英雄,生活继续. 大部分的app配图,今天都是灰色.这种图片的转换在python里非常容易实现.一行代码搞定. 下面是DE8UG上次说个故事:再见VB.你好,精彩 ...

  5. 图片格式之YUV420 转RGB格式(含代码)

    在数字图像处理种YUV格式也是我们经常遇到,与RGB一样也是一种编码格式,开始主要用于电视系统以及模拟视频领域.YUV,分为三个分量,"Y"表示明亮度(Luminance或Luma ...

  6. python如何设置rgb颜色_Python 转换RGB颜色值的示例代码

    题目:转换RBG颜色值 我们知道在网页中的颜色值设置都是用16进制的RGB来表示的,比如#FFFFFF,表示R:255,G:255,B:255的白色. 现在请设计一个函数可以转换RGB的16进制至10 ...

  7. python中rgb颜色_Python 转换RGB颜色值的示例代码

    题目:转换RBG颜色值 我们知道在网页中的颜色值设置都是用16进制的RGB来表示的,比如#FFFFFF,表示R:255,G:255,B:255的白色. 现在请设计一个函数可以转换RGB的16进制至10 ...

  8. 分枝定界图解(含 Real-Time Loop Closure in 2D LIDAR SLAM论文部分解读及BB代码部分解读)

    分枝定界图解 网上对分枝定界的解读很多都是根据这篇必不可少的论文<Real-Time Loop Closure in 2D LIDAR SLAM>来的. 分枝定界是一种深度优先的树形搜索方 ...

  9. python rgb转整数_Python 转换RGB颜色值的示例代码

    题目:转换RBG颜色值 我们知道在网页中的颜色值设置都是用16进制的RGB来表示的,比如#FFFFFF,表示R:255,G:255,B:255的白色. 现在请设计一个函数可以转换RGB的16进制至10 ...

最新文章

  1. Java全角、半角字符的关系以及转换
  2. BZOJ 2731 Luogu P3219 [HNOI2012]三角形覆盖问题 (扫描线)
  3. mysql数据库操作指令汇总
  4. 洛谷T172100 商店-贪心
  5. Linux(15)-C/C++、PHP、JAVA概述
  6. Scikit-Learn 新版本发布!一行代码秒升级
  7. C#设计模式--设配器模式
  8. Html 5 Input type=range 滑动条
  9. SpringBoot 简易拦截器实现
  10. linux双网卡同时访问内外网
  11. Oracle VM VirtualBox 打开Ubuntu出现0x00000000指令引用的0x00000000内存,该内存不能为written的解决方案
  12. 五粮液前三季净赚173亿背后:Q3净利增速下滑,3大流通股东减持
  13. QT全局键盘检测(即失焦后依旧可以检测到键盘事件)
  14. android 程序运行,Android如何保持程序一直运行
  15. 简单酷炫时尚设计开场视频模板剪辑素材
  16. 用for循环输出俄文的“字母表”
  17. 运单编号快速加单引号和逗号
  18. odbc驱动怎么安装
  19. android修改默认遥控器键值,android 中遥控器键值的添加和修改
  20. Openssl生成自签名证书并导入浏览器脚本

热门文章

  1. NameNode自动HA(高可用) 集群搭建和启动
  2. Java——【习题】java泛型练习题
  3. 小程序毕设作品之微信小程序点餐系统毕业设计(2)小程序功能
  4. 墨者WordPress插件漏洞分析溯源
  5. 传奇GOM引擎补丁安装教程图解,传奇pak补丁介绍
  6. Django的前后端分离以及Rest风格接口开发大全
  7. 5 大最常用 C++ 经典算法
  8. 【DL】时间序列的深度学习
  9. 在Linux系统上运行.net core程序
  10. 小程序适配H5端跨域问题解决