예제 #1
0
datasetConfigDir = '/home/galen/deepLearning/poseEstimation/DenseFusion/datasets/linemod/Linemod_preprocessed/models/'
output_result_dir = 'experimentResult/eval_results/linemod'
knn = KNearestNeighbor(1)

estimator = poseNet(numPoints, numObjects)
estimator.cuda()
estimator.load_state_dict(torch.load(opt.model))
estimator.eval()

testDataset = PoseDataset('eval', numPoints, False, opt.datasetRoot, 0.0, True)
testDataLoader = torch.utils.data.DataLoader(testDataset,
                                             batch_size=1,
                                             shuffle=False,
                                             num_workers=10)

symList = testDataset.get_sym_list()
numPointsMesh = testDataset.get_num_points_mesh()
poseNetLoss = Loss(numPointsMesh, symList)

diameter = []
meta_file = open('{0}/models_info.yml'.format(datasetConfigDir), 'r')
meta = yaml.load(meta_file)
kn = 0.1  # ADD 参数设置
for obj in objList:
    diameter.append(meta[obj]['diameter'] / 1000.0 * kn)
print(diameter)

successCount = [0 for i in range(numObjects)]
numCount = [0 for i in range(numObjects)]
fw = open('{0}/eval_result_logs.txt'.format(output_result_dir), 'w')
예제 #2
0
def main():
    print('------------')
    opt.manualSeed = random.randint(1, 100)                                     # 设定随机数
    random.seed(opt.manualSeed)                                                 # 设定随机种子
    torch.manual_seed(opt.manualSeed)                                           # 设定随机种子
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')       # 设定设备

    opt.num_objects = 13                                                        # 训练数据的物体种类数目
    opt.num_points = 500                                                        # 输入点云的数目
    opt.outf = 'trained_models/linemod'                                         # 训练模型保存的目录
    opt.log_dir = 'logs/linemod'                                                # log保存的目录
    opt.repeat_epoch = 20                                                        # 重复epoch数目

    estimator = PoseNet(num_points=opt.num_points, num_obj=opt.num_objects)     # 网络构建,构建完成,对物体的6D姿态进行预测
    print(estimator)
    estimator.to(device)                                                        # 选择设备
    refiner = PoseRefineNet(num_points=opt.num_points, num_obj=opt.num_objects) # 对初步预测的姿态进行提炼
    print(refiner)
    refiner.to(device)                                                          # 选择设备

    if opt.resume_posenet != '':                                                # 对posenet模型的加载,如果有的话,
        estimator.load_state_dict(torch.load('{0}/{1}'.format(opt.outf, opt.resume_posenet)))

    if opt.resume_refinenet != '':                                              # 对refinenet模型的加载,如果有的话,
        refiner.load_state_dict(torch.load('{0}/{1}'.format(opt.outf, opt.resume_refinenet)))

        opt.refine_start = True                                                 # 标记refine网络开始训练
        opt.decay_start = True                                                  # 标记refine网络参数开始衰减
        opt.lr *= opt.lr_rate                                                   # 学习率变化
        opt.w *= opt.w_rate                                                     # 权重衰减率变化
        opt.batch_size = int(opt.batch_size / opt.iteration)                    # batchsize设定

        optimizer = optim.Adam(refiner.parameters(), lr=opt.lr)                 # 设定refine的优化器
    else:
        opt.refine_start = False                                                # 标记refine网络未开始训练
        opt.decay_start = False                                                 # 标记refine网络参数未开始衰减
        optimizer = optim.Adam(estimator.parameters(), lr=opt.lr)               # 设定posenet的优化器

    # 加载训练数据集
    dataset = PoseDataset('train', opt.num_points, True, opt.dataset_root, opt.noise_trans, opt.refine_start)
    dataloader = torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=True, num_workers=opt.workers)

    # 加载验证数据集
    test_dataset = PoseDataset('test', opt.num_points, False, opt.dataset_root, 0.0, opt.refine_start)
    test_dataloder = torch.utils.data.DataLoader(test_dataset, batch_size=1, shuffle=False, num_workers=opt.workers)

    opt.sym_list = dataset.get_sym_list()                                       # 设定对称物体列表
    opt.num_points_mesh = dataset.get_num_points_mesh()                         # 设定点云数目
    print('----------Dataset loaded!---------\nlength of the training set: {0}\nlength of the testing set: {1}\nnumber '
          'of sample points on mesh: {2}\nsymmetry object list: {3}'.format(len(dataset), len(test_dataset),
                                                                            opt.num_points_mesh, opt.sym_list))

    criterion = Loss(opt.num_points_mesh, opt.sym_list)                         # loss计算
    criterion_refine = Loss_refine(opt.num_points_mesh, opt.sym_list)           # refine_loss计算

    best_test = np.Inf                                                          # 初始位置最好的模型,loss无限大
    if opt.start_epoch == 1:                                                    # 开始训练,则删除之前的日志
        for log in os.listdir(opt.log_dir):
            os.remove(os.path.join(opt.log_dir, log))
    st_time = time.time()                                                       # 记录开始时间

    # 开始循环迭代,训练模型-----------------------------------!

    for epoch in range(opt.start_epoch, opt.nepoch):
        # 保存开始迭代的log信息
        logger = setup_logger('epoch%d' % epoch, os.path.join(opt.log_dir, 'epoch_%d_log.txt' % epoch))
        # 记录每个epoch时间
        logger.info('Train time {0}'.format(time.strftime('%Hh %Mm %Ss', time.gmtime(time.time() - st_time)) + 'Training started'))

        train_count = 0
        train_dis_avg = 0.0                                                     # 用于计算平均距离

        if opt.refine_start:                                                    # 如果refine模型,已经开始训练
            estimator.eval()
            refiner.train()
        else:
            estimator.train()

        optimizer.zero_grad()                                                   # 优化器清零梯度

        for rep in range(opt.repeat_epoch):                                     # 每次epoch重复训练次数
            for i, data in enumerate(dataloader, 0):
                points, choose, img, target, model_points, idx = data           # 读取数据
                '''
                points: 由深度图计算出来的点云,该点云数据以摄像头为参考坐标
                choose: 所选择点云的索引[bs, 1, 500]
                img: 通过box剪切下来的RGB图像
                target: 根据model_points点云信息,以及旋转偏移矩阵转换过的点云信息[bs, 500, 3]
                model_points: 目标初始帧对应的点云信息
                idx: 训练图片的下标
                '''
                # 将数据放到device上

                points, choose, img, target, model_points, idx = points.to(device), choose.to(device), img.to(device), target.to(device), model_points.to(device), idx.to(device)
                # 进行预测获得预测的姿态,和特征向量
                pred_r, pred_t, pred_c, emb = estimator(img, points, choose, idx)
                '''
                pred_r: 旋转矩阵[bs, 500, 4]
                pred_t: 偏移矩阵[bs, 500, 3]
                pred_c: 置信度[bs, 500, 1]
                '''
                # 计算loss
                loss, dis, new_points, new_target = criterion(pred_r, pred_t, pred_c, target, model_points, idx, points, opt.w, opt.refine_start)

                # 如果已经开始了refiner模型的训练
                if opt.refine_start:
                    for iter in range(0, opt.iteration):
                        pred_r, pred_t = refiner(new_points, emb, idx)          # 进行refiner预测
                        # 计算loss得到dis
                        dis, new_points, new_target = criterion_refine(pred_r, pred_t, new_target, model_points, idx, new_points)
                        dis.backward()                                          # dis进行反向传播
                else:
                    loss.backward()                                             # 否则,则对loss进行反向传播

                train_dis_avg += dis.item()                                     # 用于计算平均距离
                train_count += 1

                # log信息存储
                if train_count % opt.batch_size == 0:
                    logger.info('Train time {0} Epoch {1} Batch {2} Frame {3} Avg_dis:{4}'
                                .format(time.strftime('%Hh %Mm %Ss', time.gmtime(time.time() - st_time)),
                                        epoch, int(train_count / opt.batch_size), train_count, train_dis_avg / opt.batch_size))
                    optimizer.step()                                            # 优化器更新
                    optimizer.zero_grad()                                       # 优化器梯度清零
                    train_dis_avg = 0.0

                if train_count != 0 and train_count % 1000 == 0:                # 模型保存
                    if opt.refine_start:                                        # 已经开始refine模型
                        torch.save(refiner.state_dict(), '{0}/pose_refine_model_current.pth'.format(opt.outf))
                    else:
                        torch.save(estimator.state_dict(), '{0}.pos_model_current.pth'.format(opt.outf))

        print('------------ epoch {0} train finish -----------'.format(epoch))
        # 进行测试
        logger = setup_logger('epoch%d test' % epoch, os.path.join(opt.log_dir, 'epoch_%d_test_log.txt' % epoch))
        # 记录测试时间
        logger.info('Test time {0}'.format(time.strftime('%Hh %Mm %Ss', time.gmtime(time.time() - st_time)) + ',' + 'Testing started'))
        test_dis = 0.0
        test_count = 0
        estimator.eval()                                                        # 验证模型构建
        refiner.eval()                                                          # refiner模型

        for j, data in enumerate(test_dataloder, 0):
            points, choose, img, target, model_points, idx = data  # 读取数据
            '''
            points: 由深度图计算出来的点云,该点云数据以摄像头为参考坐标
            choose: 所选择点云的索引[bs, 1, 500]
            img: 通过box剪切下来的RGB图像
            target: 根据model_points点云信息,以及旋转偏移矩阵转换过的点云信息[bs, 500, 3]
            model_points: 目标初始帧对应的点云信息
            idx: 训练图片的下标
            '''
            # 将数据放到device上
            points, choose, img, target, model_points, idx = points.to(device), choose.to(device), img.to(
                device), target.to(device), model_points.to(device), idx.to(device)

            # 进行预测获得预测的姿态,和特征向量
            pred_r, pred_t, pred_c, emb = estimator(img, points, choose, idx)
            '''
            pred_r: 旋转矩阵[bs, 500, 4]
            pred_t: 偏移矩阵[bs, 500, 3]
            pred_c: 置信度[bs, 500, 1]
            '''

            # 对结果进行评估
            _, dis, new_points, new_target = criterion(pred_r, pred_t, pred_c, target, model_points, idx, points, opt.w, opt.refine_start)

            # 如果refine模型开始训练,则同样进行评估
            if opt.refine_start:
                for iter in range(0, opt.iteration):
                    pred_r, pred_t = refiner(new_points, emb, idx)
                    dis, new_points, new_target = criterion_refine(pred_r, pred_t, new_target, model_points, idx, new_points)

            test_dis += dis.item()                                              # 用于计算平均距离
            # 保存eval的log
            logger.info('Test time {0} Test Frame No.{1} dis:{2}'.format(time.strftime('%Hh %Mm %Ss', time.gmtime(time.time() - st_time)), test_count, dis))
            test_count += 1

        test_dis = test_dis / test_count                                        # 计算平均距离
        logger.info('Test time {0} Epoch {1} Test finish avg_dis:{2}'.format(time.strftime('%Hh %Mm %Ss', time.gmtime(time.time() - st_time)), epoch, test_dis))

        if test_dis <= best_test:                                               # 如果此次测试结果最好,则保留当前测试结果
            best_test = test_dis
            if opt.refine_start:                                                # 保存refiner
                torch.save(refiner.state_dict(), '{0}/pose_refine_model_{1}_{2}.pth'.format(opt.outf, epoch, test_dis))
            else:
                torch.save(estimator.state_dict(), '{0}/pose_model_{1}_{2}.pth'.format(opt.outf, epoch, test_dis))
            print('----------------test model save finished-------------------')

        # 参数变化

        # 判断模型是否达到衰减要求
        if best_test < opt.decay_margin and not opt.decay_start:
            opt.decay_start = True
            opt.lr *= opt.lr_rate                                               # 学习率衰减
            opt.w *= opt.w_rate                                                 # 权重衰减
            optimizer = optim.Adam(estimator.parameters(), lr=opt.lr)

        # 模型没有达到loss阈值要求,refine_start = False,则修改相关参数,传递相关数,更新dataset和dataloader
        if best_test < opt.refine_margin and not opt.refine_start:
            opt.refine_start = True
            opt.batch_size = int(opt.batch_size / opt.iteration)
            optimizer = optim.Adam(refiner.parameters(), lr=opt.lr)

            # 训练
            dataset = PoseDataset('train', opt.num_points, True, opt.dataset_root, opt.noise_trans, opt.refine_start)
            dataloader = DataLoader(dataset, batch_size=1, shuffle=True, num_workers=opt.workers)
            # 测试
            test_dataset = PoseDataset('test', opt.num_points, False, opt.dataset_root, 0.0, opt.refine_start)
            test_dataloder = DataLoader(test_dataset, batch_size=1, shuffle=False, num_workers=opt.workers)

            opt.sym_list = dataset.get_sym_list()
            opt.num_points_mesh = dataset.get_num_points_mesh()
            print('----------Dataset loaded!---------\nlength of the training set: {0}\nlength of the testing set: {1}\nnumber '
                'of sample points on mesh: {2}\nsymmetry object list: {3}'.format(len(dataset), len(test_dataset),
                                                                                  opt.num_points_mesh, opt.sym_list))
            criterion = Loss(opt.num_points_mesh, opt.sym_list)
            criterion_refine = Loss_refine(opt.num_points_mesh, opt.sym_list)
estimator.cuda()
refiner = PoseRefineNet(num_points=num_points, num_obj=num_objects)
refiner.cuda()
estimator.load_state_dict(torch.load(opt.model))
refiner.load_state_dict(torch.load(opt.refine_model))
estimator.eval()
refiner.eval()

testdataset = PoseDataset_linemod('eval', num_points, False, opt.dataset_root,
                                  0.0, True)
testdataloader = torch.utils.data.DataLoader(testdataset,
                                             batch_size=1,
                                             shuffle=False,
                                             num_workers=10)

sym_list = testdataset.get_sym_list()
num_points_mesh = testdataset.get_num_points_mesh()
criterion = Loss(num_points_mesh, sym_list)
criterion_refine = Loss_refine(num_points_mesh, sym_list)

diameter = [0.109, 0.153, 0.118]

success_count = [0 for i in range(num_objects)]
num_count = [0 for i in range(num_objects)]
fw = open('{0}/eval_result_logs.txt'.format(output_result_dir), 'w')

for i, data in enumerate(testdataloader, 0):
    points, choose, img, target, model_points, idx = data
    #print('idx of object is :{0}'.format(idx[0].item()))
    print(idx[0].item() == 0)
    if len(points.size()) == 2:
예제 #4
0
def main():
    opt.manualSeed = random.randint(1, 10000)
    random.seed(opt.manualSeed)
    torch.manual_seed(
        opt.manualSeed)  #torch.manual_seed可以保证在种子值不变的情况下,每次torch.rand产生的结果相同
    # torch.cuda.manual_seed(opt.manualSeed)   torch.cuda.manual_seed_all(seed)
    # 对于可重复的实验,有必要为任何使用随机数生成的进行随机种子设置。注意,cuDNN使用非确定性算法,并且可以使用torch.backends.cudnn.enabled = False来进行禁用。

    # 根据数据集配置物体种类,用于预测位姿的点数,每个epoch训练的次数,模型保存的位置,log保存的位置
    if opt.dataset == 'linemod':
        opt.numObjects = 13
        opt.numPoints = 576
        opt.repeatEpoch = 20
        opt.modelFolder = 'trainedModels/'
        opt.logFolder = 'experimentResult/logs/'
    else:
        print('Unknown dataset')
        return

    # 定义网络,如果有训练过的模型,可加载;   确定网络优化方法
    estimator = poseNet(opt.numPoints, opt.numObjects)
    estimator.cuda()  # or estimator.to('cuda')
    if opt.resumePosenet != '':
        estimator.load_state_dict(
            torch.load('{0}/{1}'.format(opt.modelFolder, opt.resumePosenet)))

    optimizer = optim.Adam(estimator.parameters(), lr=opt.lr)

    opt.decay_start = False
    opt.refine_start = False
    # 加载训练数据和测试数据
    if opt.dataset == 'linemod':
        dataset = PoseDataset('train', opt.numPoints, opt.addNoise,
                              opt.datasetRoot, opt.noiseTrans,
                              opt.refine_start)
        test_dataset = PoseDataset('test', opt.numPoints, False,
                                   opt.datasetRoot, 0.0, opt.refine_start)

    dataLoader = torch.utils.data.DataLoader(dataset,
                                             batch_size=1,
                                             shuffle=True,
                                             num_workers=opt.workers)
    testdataLoader = torch.utils.data.DataLoader(test_dataset,
                                                 batch_size=1,
                                                 shuffle=False,
                                                 num_workers=opt.workers)
    opt.symList = dataset.get_sym_list()
    opt.numPointsMesh = dataset.get_num_points_mesh()
    print(
        '>>>>>>--------Dataset Loaded!---------<<<<<<<\nlength of the training set:{0}\nlength of the testing set:{1}\nnumber of sample points on mesh: {2}\nsymmetry object list: {3}'
        .format(len(dataset), len(test_dataset), opt.numPointsMesh,
                opt.symList))

    # 定义网络训练的误差
    poseNetLoss = Loss(opt.numPointsMesh, opt.symList)
    best_distance = np.Inf

    if opt.startEpoch == 1:
        for log in os.listdir(opt.logFolder):
            os.remove(os.path.join(opt.logFolder, log))
    st_time = time.time()

    for epoch in range(opt.startEpoch, opt.nepoch):
        # ------------------模型训练阶段------------------
        logger = setup_logger(
            'epoch%d' % epoch,
            os.path.join(opt.logFolder, 'epoch_%d_log.txt' % epoch))
        logger.info('Train time {0}'.format(
            time.strftime("%Hh %Mm %Ss", time.gmtime(time.time() - st_time)) +
            ',' + 'Training started'))
        train_count = 0
        train_dis_sum = 0.0
        estimator.train()
        optimizer.zero_grad()
        for rep in range(opt.repeatEpoch):
            for i, data in enumerate(dataLoader, 0):
                img, cloud, pointIndex, tarPoints, modelPoints, idx, ori_img = data

                img = Variable(img).cuda()
                cloud = Variable(cloud).cuda()
                pointIndex = Variable(pointIndex).cuda()
                tarPoints = Variable(tarPoints).cuda()
                modelPoints = Variable(modelPoints).cuda()
                idx = Variable(idx).cuda()
                ori_img = np.array(ori_img)

                pred_r, pred_t, pred_c, colorEmb = estimator(
                    img, cloud, pointIndex, idx)
                loss, dis, newCloud, newTarPoints = poseNetLoss(
                    pred_r, pred_t, pred_c, tarPoints, modelPoints, idx, cloud,
                    opt.w, opt.refine_start)

                loss.backward()

                train_dis_sum += dis.item()
                train_count += 1

                if train_count % opt.batchSize == 0:
                    logger.info(
                        'Train time {0} Epoch {1} Batch{2} Frame{3} Avg_dis:{4}'
                        .format(
                            time.strftime("%Hh %Mm %Ss",
                                          time.gmtime(time.time() - st_time)),
                            epoch, int(train_count / opt.batchSize),
                            train_count, train_dis_sum / opt.batchSize))
                    optimizer.step()
                    optimizer.zero_grad()
                    train_dis_sum = 0

                if train_count != 0 and train_count % 1000 == 0:
                    torch.save(
                        estimator.state_dict(),
                        '{0}/pose_model_current.pth'.format(opt.modelFolder))
        print(
            '>>>>>>>>----------epoch {0} train finish---------<<<<<<<<'.format(
                epoch))

        # ------------------模型测试阶段------------------
        logger = setup_logger(
            'epoch%d_test' % epoch,
            os.path.join(opt.logFolder, 'epoch_%d_test_log.txt' % epoch))
        logger.info('Test time {0}'.format(
            time.strftime("%Hh %Mm %Ss", time.gmtime(time.time() - st_time)) +
            ', ' + 'Testing started'))
        test_dis = 0.0
        test_count = 0
        estimator.eval()
        for j, data in enumerate(testdataLoader, 0):
            img, cloud, pointIndex, tarPoints, modelPoints, idx, ori_img = data

            img = Variable(img).cuda()
            cloud = Variable(cloud).cuda()
            pointIndex = Variable(pointIndex).cuda()
            tarPoints = Variable(tarPoints).cuda()
            modelPoints = Variable(modelPoints).cuda()
            idx = Variable(idx).cuda()
            ori_img = np.array(ori_img)

            pred_r, pred_t, pred_c, colorEmb = estimator(
                img, cloud, pointIndex, idx)
            loss, dis, newCloud, newTarPoints = poseNetLoss(
                pred_r, pred_t, pred_c, tarPoints, modelPoints, idx, cloud,
                opt.w, opt.refine_start)

            logger.info('Test time {0} Test Frame No.{1} dis:{2}'.format(
                time.strftime("%Hh %Mm %Ss",
                              time.gmtime(time.time() - st_time)), test_count,
                dis))
            test_dis += dis.item()
            test_count += 1
        test_dis = test_dis / test_count
        logger.info('Test time {0} Epoch {1} TEST FINISH Avg dis: {2}'.format(
            time.strftime("%Hh %Mm %Ss", time.gmtime(time.time() - st_time)),
            epoch, test_dis))

        # ------------------模型评估阶段-------------------
        if test_dis < best_distance:
            best_distance = test_dis
            torch.save(
                estimator.state_dict(),
                '{0}/pose_model_{1}_{2}.pth'.format(opt.modelFolder, epoch,
                                                    test_dis))
            print(epoch,
                  '>>>>>>>>----------BEST TEST MODEL SAVED---------<<<<<<<<')

        if best_distance < opt.decayMargin and not opt.decay_start:
            opt.decay_start = True
            opt.lr *= opt.lr_dr
            optimizer = optim.Adam(estimator.parameters(), lr=opt.lr)
예제 #5
0
def main():
    opt.manualSeed = random.randint(1, 10000)
    random.seed(opt.manualSeed)
    torch.manual_seed(opt.manualSeed)

    opt.num_objects = 3
    opt.num_points = 500
    opt.outf = 'trained_models'
    opt.log_dir = 'experiments/logs'
    opt.repeat_epoch = 20

    estimator = PoseNet(num_points=opt.num_points, num_obj=opt.num_objects)
    estimator.cuda()
    refiner = PoseRefineNet(num_points=opt.num_points, num_obj=opt.num_objects)
    refiner.cuda()

    if opt.resume_posenet != '':
        estimator.load_state_dict(
            torch.load('{0}/{1}'.format(opt.outf, opt.resume_posenet)))

    if opt.resume_refinenet != '':
        refiner.load_state_dict(
            torch.load('{0}/{1}'.format(opt.outf, opt.resume_refinenet)))
        opt.refine_start = True
        opt.decay_start = True
        opt.lr *= opt.lr_rate
        opt.w *= opt.w_rate
        opt.batch_size = int(opt.batch_size / opt.iteration)
        optimizer = optim.Adam(refiner.parameters(), lr=opt.lr)
    else:
        opt.refine_start = False
        opt.decay_start = False
        optimizer = optim.Adam(estimator.parameters(), lr=opt.lr)

    dataset = PoseDataset('train', opt.num_points, True, opt.dataset_root,
                          opt.noise_trans, opt.refine_start)
    dataloader = torch.utils.data.DataLoader(dataset,
                                             batch_size=1,
                                             shuffle=True,
                                             num_workers=opt.workers)

    test_dataset = PoseDataset('test', opt.num_points, False, opt.dataset_root,
                               0.0, opt.refine_start)
    testdataloader = torch.utils.data.DataLoader(test_dataset,
                                                 batch_size=1,
                                                 shuffle=False,
                                                 num_workers=opt.workers)

    opt.sym_list = dataset.get_sym_list()
    opt.num_points_mesh = dataset.get_num_points_mesh()

    print(
        '>>>>>>>>----------Dataset loaded!---------<<<<<<<<\nlength of the training set: {0}\nlength of the testing set: {1}\nnumber of sample points on mesh: {2}'
        .format(len(dataset), len(test_dataset), opt.num_points_mesh))

    criterion = Loss(opt.num_points_mesh, opt.sym_list)
    criterion_refine = Loss_refine(opt.num_points_mesh, opt.sym_list)

    best_test = np.Inf

    if opt.start_epoch == 1:
        for log in os.listdir(opt.log_dir):
            os.remove(os.path.join(opt.log_dir, log))
    st_time = time.time()

    for epoch in range(opt.start_epoch, opt.nepoch):
        logger = setup_logger(
            'epoch%d' % epoch,
            os.path.join(opt.log_dir, 'epoch_%d_log.txt' % epoch))
        logger.info('Train time {0}'.format(
            time.strftime("%Hh %Mm %Ss", time.gmtime(time.time() - st_time)) +
            ', ' + 'Training started'))
        train_count = 0
        train_dis_avg = 0.0
        if opt.refine_start:
            estimator.eval()  # affects dropout and batch normalization
            refiner.train()
        else:
            estimator.train()
        optimizer.zero_grad()

        for rep in range(opt.repeat_epoch):
            for i, data in enumerate(dataloader, 0):
                points, choose, img, target, model_points, idx = data
                #points        ->torch.Size([500, 3])  ->在crop出来的像素区域随机选取500个点,利用相机内参结合深度值算出来的点云cloud
                #choose        ->torch.Size([1, 500])
                #img           ->torch.Size([3, 80, 80])
                #target        ->torch.Size([500, 3])  ->真实模型上随机选取的mesh点进行ground truth pose变换后得到的点
                #model_points  ->torch.Size([500, 3])  ->真实模型上随机选取的mesh点在进行pose变换前的点
                #idx           ->torch.Size([1])
                #tensor([4], device='cuda:0')
                #img和points对应rgb和点云信息,需要在网络内部fusion
                points, choose, img, target, model_points, idx = Variable(points).cuda(), \
                                                                 Variable(choose).cuda(), \
                                                                 Variable(img).cuda(), \
                                                                 Variable(target).cuda(), \
                                                                 Variable(model_points).cuda(), \
                                                                 Variable(idx).cuda()
                pred_r, pred_t, pred_c, emb = estimator(
                    img, points, choose, idx)
                loss, dis, new_points, new_target = criterion(
                    pred_r, pred_t, pred_c, target, model_points, idx, points,
                    opt.w, opt.refine_start)

                if opt.refine_start:
                    for ite in range(0, opt.iteration):
                        pred_r, pred_t = refiner(new_points, emb, idx)
                        dis, new_points, new_target = criterion_refine(
                            pred_r, pred_t, new_target, model_points, idx,
                            new_points)
                        dis.backward()
                else:
                    loss.backward()

                train_dis_avg += dis.item()
                train_count += 1

                if train_count % opt.batch_size == 0:
                    logger.info(
                        'Train time {0} Epoch {1} Batch {2} Frame {3} Avg_dis:{4}'
                        .format(
                            time.strftime("%Hh %Mm %Ss",
                                          time.gmtime(time.time() - st_time)),
                            epoch, int(train_count / opt.batch_size),
                            train_count, train_dis_avg / opt.batch_size))
                    optimizer.step()
                    optimizer.zero_grad()
                    train_dis_avg = 0

                if train_count != 0 and train_count % 1000 == 0:
                    if opt.refine_start:
                        torch.save(
                            refiner.state_dict(),
                            '{0}/pose_refine_model_current.pth'.format(
                                opt.outf))
                    else:
                        torch.save(
                            estimator.state_dict(),
                            '{0}/pose_model_current.pth'.format(opt.outf))

        print(
            '>>>>>>>>----------epoch {0} train finish---------<<<<<<<<'.format(
                epoch))

        logger = setup_logger(
            'epoch%d_test' % epoch,
            os.path.join(opt.log_dir, 'epoch_%d_test_log.txt' % epoch))
        logger.info('Test time {0}'.format(
            time.strftime("%Hh %Mm %Ss", time.gmtime(time.time() - st_time)) +
            ', ' + 'Testing started'))
        test_dis = 0.0
        test_count = 0
        estimator.eval()
        refiner.eval()

        for j, data in enumerate(testdataloader, 0):
            points, choose, img, target, model_points, idx = data
            points, choose, img, target, model_points, idx = Variable(points).cuda(), \
                                                             Variable(choose).cuda(), \
                                                             Variable(img).cuda(), \
                                                             Variable(target).cuda(), \
                                                             Variable(model_points).cuda(), \
                                                             Variable(idx).cuda()
            pred_r, pred_t, pred_c, emb = estimator(img, points, choose, idx)
            _, dis, new_points, new_target = criterion(pred_r, pred_t, pred_c,
                                                       target, model_points,
                                                       idx, points, opt.w,
                                                       opt.refine_start)

            if opt.refine_start:
                for ite in range(0, opt.iteration):
                    pred_r, pred_t = refiner(new_points, emb, idx)
                    dis, new_points, new_target = criterion_refine(
                        pred_r, pred_t, new_target, model_points, idx,
                        new_points)

            test_dis += dis.item()
            logger.info('Test time {0} Test Frame No.{1} dis:{2}'.format(
                time.strftime("%Hh %Mm %Ss",
                              time.gmtime(time.time() - st_time)), test_count,
                dis))

            test_count += 1

        test_dis = test_dis / test_count
        logger.info('Test time {0} Epoch {1} TEST FINISH Avg dis: {2}'.format(
            time.strftime("%Hh %Mm %Ss", time.gmtime(time.time() - st_time)),
            epoch, test_dis))
        if test_dis <= best_test:
            best_test = test_dis
            if opt.refine_start:
                torch.save(
                    refiner.state_dict(),
                    '{0}/pose_refine_model_{1}_{2}.pth'.format(
                        opt.outf, epoch, test_dis))
            else:
                torch.save(
                    estimator.state_dict(),
                    '{0}/pose_model_{1}_{2}.pth'.format(
                        opt.outf, epoch, test_dis))
            print(epoch,
                  '>>>>>>>>----------BEST TEST MODEL SAVED---------<<<<<<<<')

        if best_test < opt.decay_margin and not opt.decay_start:
            opt.decay_start = True
            opt.lr *= opt.lr_rate
            opt.w *= opt.w_rate
            optimizer = optim.Adam(estimator.parameters(), lr=opt.lr)

        if best_test < opt.refine_margin and not opt.refine_start:
            opt.refine_start = True
            opt.batch_size = int(opt.batch_size / opt.iteration)
            optimizer = optim.Adam(refiner.parameters(), lr=opt.lr)

            dataset = PoseDataset('train', opt.num_points, True,
                                  opt.dataset_root, opt.noise_trans,
                                  opt.refine_start)
            dataloader = torch.utils.data.DataLoader(dataset,
                                                     batch_size=1,
                                                     shuffle=True,
                                                     num_workers=opt.workers)

            test_dataset = PoseDataset('test', opt.num_points, False,
                                       opt.dataset_root, 0.0, opt.refine_start)
            testdataloader = torch.utils.data.DataLoader(
                test_dataset,
                batch_size=1,
                shuffle=False,
                num_workers=opt.workers)

            opt.sym_list = dataset.get_sym_list()
            opt.num_points_mesh = dataset.get_num_points_mesh()

            print(
                '>>>>>>>>----------Dataset loaded!---------<<<<<<<<\nlength of the training set: {0}\nlength of the testing set: {1}\nnumber of sample points on mesh: {2}'
                .format(len(dataset), len(test_dataset), opt.num_points_mesh))

            criterion = Loss(opt.num_points_mesh, opt.sym_list)
            criterion_refine = Loss_refine(opt.num_points_mesh, opt.sym_list)
예제 #6
0
refiner = PoseRefineNet(num_points=num_points,
                        num_obj=num_objects)  # PoseRefineNet网络模型构建
refiner.to(device)

estimator.load_state_dict(torch.load(opt.model))  # PoseNet模型参数加载
refiner.load_state_dict(torch.load(opt.refine_model))  # PoseRefineNet模型参数加载
estimator.eval()
refiner.eval()

# 以eval模式,加载数据
test_dataset = PoseDataset('eval', num_points, False, opt.dataset_root, 0.0,
                           True)
test_dataloader = DataLoader(test_dataset, batch_size=1, shuffle=False)

sym_list = test_dataset.get_sym_list()  # 获取对称物体的索引
num_points_mesh = test_dataset.get_num_points_mesh()  # 500

criterion = Loss(num_points_mesh, sym_list)  # Loss加载
criterion_refine = Loss_refine(num_points_mesh, sym_list)  # Loss_refine加载

diameter = []  # 存储模型给定的半径标准,与结果对比
meta_file = open(dataset_config_dir, 'r')  # 读取model.info文件
meta = yaml.load(meta_file)  # 加载model.info文件

for obj in objlist:
    diameter.append(meta[obj]['diameter'] / 1000.0 * 0.1)  # 存储到diameter中

success_count = [0 for i in range(num_objects)]  # 用于记录每个目标合格的数目
num_count = [0 for i in range(num_objects)]  # 用于记录每个目标物体测试总数目