【阅读笔记】《Depth-Aware CNN for RGB-D Segmentation》(二)——代码部分(一)train.py

本文记录了博主阅读论文《Depth-Aware CNN for RGB-D Segmentation》代码的笔记的第一部分,train.py文件。更新于2019.03.21。

train.py文件

import部分

代码前3行调用的工具包的作用,见博客123

import time
from tensorboardX import SummaryWriter
from collections import OrderedDict

from options.train_options import TrainOptions

从第4行开始调用的就是内部的包了,调用的是文件./options/train_options.py

from options.train_options import TrainOptions

这里调用的TrainOptions中包括两部分,显示部分和训练部分。其中,显示部分包括的参数有:

  • display_freq:在屏幕上显示训练结果的频率;
  • print_freq:在控制台(console)上显示训练结果的频率;
  • save_latest_freq:保存最新结果的频率;
  • save_epoch_freq:在一个epoch最后保存checkpoints的频率;
  • no_html:不向[opt.checkpoints_dir]/[opt.name]/web/保存中间的训练结果;
  • debug:每次循环只进行一次epoch并显示。

训练部分包括的参数有:

  • loadfroms:从32s或16s处加载,继续训练;
  • continue_train:加载最新的模型继续训练;
  • use_softmax:除非指定用softmax loss,否则使用log-softmax;
  • phase:train,val,test等;
  • nepochs:epoch的个数(默认100);
  • iterSize:初始学习率下的迭代次数(默认10,博主认为文件中这个注释写错了);
  • maxbatchsize:最大batchsize,默认-1;
  • warmup_iters:初始学习率下的迭代次数;
  • beta1:adam算法的动量;
  • lr:adam算法的初始学习率;
  • lr_power:学习率政策的指数;
  • momentum:sgd算法的动量;
  • wd:sgd的权重下降(weight decay)。

from data.data_loader import CreateDataLoader

调用的是文件./data/custom_dataset_data_loader.py。允许的数据库模式有nyuv2vocsunrgbdstanfordindoor。具体可以看./data文件夹下对应的文件(如nyuv2_dataset.py

from models.models import create_model

可选择的模型类别有DeeplabVGGDeeplabVGG_HHADeeplabResnet。同样可以查看./models下的对应文件。具体模型定义参见Deeplab.py文件部分Deeplab_HHA.py文件部分。

import utils.util as util

调用的是文件./utils/utils.py,其中包括了评估用的度量,包括_fast_histlabel_accuracy_score(返回accuracy score评估结果,包括overall accuracy,mean accuracy,mean IU和fwavacc)。

余下部分的代码来自于https://github.com/ycszen/pytorch-seg/blob/master/transform.py,针对cityscape标注图颜色做了修改使其匹配。包括uint82bin(返回整数 n n n的二进制,根据比特计数),labelcolormap(针对cityscape有特殊的,否则用默认的),Colorizetensor2im(将Tensor转成Numpy array),tensor2label(将一个one-hot tensor转换成彩色label图),save_imagemkdirsmkdir

from utils.visualizer import Visualizer

这一句加载的是文件./utils/visualizer.py。其中包括display_current_results(可以选择是显示图片还是保存,如果是tf_log就在tensorboard输出显示图片,如果是use_html就将图片保存成html文件),plot_current_errors(错误标注和值得dictionary),print_current_errors(格式与plotCurrentErros中的errors相同)和save_images(将图片保存至磁盘)。

训练部分

训练设置部分:

opt = TrainOptions().parse()	#从TrainOptions中读取参数
iter_path = os.path.join(opt.checkpoints_dir, opt.name, 'iter.txt')	#合成路径,找到iter.txt文件存入iter_path
ioupath_path = os.path.join(opt.checkpoints_dir, opt.name, 'MIoU.txt')	#合成路径,找到MIoU.txt文件存入路径ioupath_path

#如果继续训练
if opt.continue_train:
	#尝试从iter.txt中读取start_epoch和epoch_iter;如果失败就将start_epoch设成1,epoch_iter设成0。
    try:
        start_epoch, epoch_iter = np.loadtxt(iter_path, delimiter=',', dtype=int)
    except:
        start_epoch, epoch_iter = 1, 0
    
    # 尝试从MIoU.txt文件中读取best_iou,如果失败就将best_iou设成0。
    try:
        best_iou = np.loadtxt(ioupath_path, dtype=float)
    except:
        best_iou = 0.
    # 显示从start_epoch的第epoch_iter开始恢复训练,之前的最优IoU为best_iou。
    print('Resuming from epoch %d at iteration %d, previous best IoU %f' % (start_epoch, epoch_iter, best_iou))

# 否则(从头训练),start_epoch为1,epoch_iter为0,best_iou为0。
else:
    start_epoch, epoch_iter = 1, 0
    best_iou = 0.

加载数据:

data_loader = CreateDataLoader(opt)
dataset, dataset_val = data_loader.load_data()
dataset_size = len(dataset)
print('#training images = %d' % dataset_size)

模型创建及训练:

# 直接加载模型,允许的模型有DeeplabVGG,DeeplabVGG_HHA和DeeplabResnet
model = create_model(opt, dataset.dataset)
# print (model) 打印模型
visualizer = Visualizer(opt)
total_steps = (start_epoch - 1) * dataset_size + epoch_iter	#一个epoch中的迭代次数
#在规定的epoch数内进行下面的过程
for epoch in range(start_epoch, opt.nepochs):
    epoch_start_time = time.time()	#记录开始时间
    # 如果当前epoch不是初始epoch,将epoch_iter除以dataset_size取余数
    if epoch != start_epoch:
        epoch_iter = epoch_iter % dataset_size
    
    # 网络训练
    model.model.train()
    for i, data in enumerate(dataset, start=epoch_iter):
        iter_start_time = time.time()
        total_steps += opt.batchSize
        epoch_iter += opt.batchSize

        ############## Forward and Backward Pass 前向和后向传播 ######################
        model.forward(data)
        model.backward(total_steps, opt.nepochs * dataset.__len__() * opt.batchSize + 1)

        ############## update tensorboard and web images 更新tensorboard和web图片 ######################
        if total_steps % opt.display_freq == 0:	# 如果到了显示频率,就显示图片
            visuals = model.get_visuals(total_steps)	# 定义于Deeplab.py文件中,用于记录损失和可用于显示的结果
            visualizer.display_current_results(visuals, epoch, total_steps)	# 定义于visualizer.py文件中,用于显示或保存visuals中的结果

        ############## Save latest Model 保存最新的模型 ######################
        if total_steps % opt.save_latest_freq == 0:	# 如果到了保存频率就保存图片
            print('saving the latest model (epoch %d, total_steps %d)' % (epoch, total_steps))
            model.save('latest')
            np.savetxt(iter_path, (epoch, epoch_iter), delimiter=',', fmt='%d')
        # 可以输出训练消耗的时间
        # print time.time()-iter_start_time

    # end of epoch 结束当前epoch

    # 开始模型评估
    model.model.eval()
    if dataset_val!=None:	#如果有交叉验证集
        label_trues, label_preds = [], []
        for i, data in enumerate(dataset_val):
            seggt, segpred = model.forward(data,False)	# False进行测试,默认是True(训练)
            # 将数据格式从CUDA Tensor转成numpy格式,不能直接转,需要先转成cpu float-tensor,再转成numpy。
            # 数据转换的原因是,对tensor进行处理必须重新启动一个Session,否则无法对其重新赋值或判断。而转成numpy就好处理了。
            # 另一个原因是,torch的tesnor和numpy的array会共享存储空间,修改一个另一个也会被修改。
            # 不过博主的电脑上试验,可以直接转换成array,不知道是不是python版本的问题。博主电脑上try.cpu().numpy、try.numpy()和np.array(try)都可以实现将tensor try变成array。而且可以直接对tensor赋值。
            seggt = seggt.data.cpu().numpy()
            segpred = segpred.data.cpu().numpy()

            label_trues.append(seggt)
            label_preds.append(segpred)

        # 返回正确率评估结果,包括overall accuracy(acc),mean accuracy(acc_cls),mean IU(mean_iu)和fwavacc(fwavacc)。
        metrics = util.label_accuracy_score(
            label_trues, label_preds, n_class=opt.label_nc)
            
        # 将metrics的格式转换成numpy array。
        metrics = np.array(metrics)
        
        # 变成百分数
        metrics *= 100
        print('''\
                Validation:
                Accuracy: {0}
                Accuracy Class: {1}
                Mean IU: {2}
                FWAV Accuracy: {3}'''.format(*metrics))
        model.update_tensorboard(metrics,total_steps)	# 更新显示界面
    iter_end_time = time.time()	# 记录迭代时间

    print('End of epoch %d / %d \t Time Taken: %d sec' %
          (epoch+1, opt.nepochs, time.time() - epoch_start_time))
    
    # 如果当前的平均iou是最优的,那么保存这个模型作为best。
    if metrics[2]>best_iou:
        best_iou = metrics[2]
        print('saving the model at the end of epoch %d, iters %d, loss %f' % (epoch, total_steps, model.trainingavgloss))
        model.save('best')

    ### save model for this epoch 保存这个epoch下的模型
    if epoch % opt.save_epoch_freq == 0:
        print('saving the model at the end of epoch %d, iters %d, loss %f' % (epoch, total_steps, model.trainingavgloss))
        model.save('latest')
        model.save(epoch)
        np.savetxt(iter_path, (epoch + 1, 0), delimiter=',', fmt='%d')

加入星球了解更多分割知识:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值