loss采样小的patch,更接近于平面运算;
方差between patch中心和它的最近neighbor;
我们的是一个软正则化器,在训练GANs时,可以在动态的对象级别上增强均匀性。
input中的每个点都去predicted shape中寻找k最近邻;
可见的region的mask就由k-nearest的指数定义;
基于以上,去计算reconstruction loss。
“找到离它最近的k个实例,哪个类别最多即可”
k的意义:
通过极限情况(k=1、k=N)判断:
k小:可能会遇见噪声
k大:模型会变得简单
如何选取:
我们一般选取一个较小的数值,通常采取 交叉验证法来选取最优的k值。(也就是说,选取k值很重要的关键是实验调参,类似于神经网络选取多少层这种,通过调整超参数来得到一个较好的结果)
学习参考链接
GAN inversion的目的是重建Xin,所以ShapeInversion才不需要paired training data。
是一个GAN网络,但是generator是一个新的树形结构:tree-GCN,特点是可以利用祖先节点的信息。论文中的FPD也是来自于这篇论文。
网络结构如下:
结合原文描述理解网络结构:
首先是预训练的tree-gan中的generator使得能从原点云生成一个完整点云,然后通过k-mask降级到缺失点云,再通过两个loss使其接近xin,这个过程中会修正参数,最后获得一个最佳的潜在向量z、生成器去生成一个最佳的xc。所以它的output还是应该是中间的xc!!!
ImportError: cannot import name 'PILLOW_VERSION' from 'PIL' (/home/renke/anaconda3/envs/shapeinversion/lib/python3.7/site-packages/PIL/__init__.py)
pillow7.0.0已经没有PILLOW_VERSION这个东西了
pillow6.1还保留着,所以只需要conda install pillow=6.1即可
一个h5py文件是 “dataset” 和 “group” 二合一的容器。
pytorch中加载数据的顺序是:
①创建一个dataset对象
②创建一个dataloader对象
③循环dataloader对象,将data,label拿到模型中去训练
epoch:训练时,所有训练数据集都训练过一次。
举个例子:
mnist 数据集有 60000 张图片作为训练数据,10000 张图片作为测试数据。假设现在选择 Batch Size = 100 对模型进行训练。迭代30000次。
每个 Epoch 要训练的图片数量:60000(训练集上的所有图像)
训练集具有的 Batch 个数: 60000/100=600
每个 Epoch 需要完成的 Batch 个数: 600
每个 Epoch 具有的 Iteration 个数: 600(完成一个Batch训练,相当于参数迭代一次)
每个 Epoch 中发生模型权重更新的次数:600
训练 10 个Epoch后,模型权重更新的次数: 600*10=6000
不同Epoch的训练,其实用的是同一个训练集的数据。 第1个Epoch和第10个Epoch虽然用的都是训练集的60000图片,但是对模型的权重更新值却是完全不同的。因为不同Epoch的模型处于代价函数空间上的不同位置,模型的训练代越靠后,越接近谷底,其代价越小。总共完成30000次迭代,相当于完成了 30000/600=50 个Epoch。
参考链接
这篇源代码的模型参数保存(在pretrain_treegan.py中)是利用自定义结构(torch.save有两个参数,第一个是{},包含了所有想要保存下来的参数;第二个是本次保存的名称):
torch.save({
'epoch': epoch,
'D_state_dict': self.D.module.state_dict(),
'G_state_dict': self.G.module.state_dict(),
'D_loss': loss_log['D_loss'],
'G_loss': loss_log['G_loss'],
'FPD': metric['FPD']
}, save_ckpt+str(epoch)+'_'+class_name+'.pt')
然后在shape_inversion.py中有对预训练模型的加载:
# load weights
checkpoint = torch.load(args.ckpt_load, map_location=self.args.device)
self.G.load_state_dict(checkpoint['G_state_dict'])
self.D.load_state_dict(checkpoint['D_state_dict'])
通过以下流程小试了一下程序能不能跑通(只为了复现一遍实验流程,所以没有在意效果,所以其实是用测试集训练的)
python pretrain_treegan.py --dataset_path ~/Data/CRN --split test --ckpt_path ./rk_pretrain_checkpoints/chair --epoch 5
【代码更改:LOAD_CHECKPOINT = None】
遇到的问题:
from scipy.misc import imread
ImportError: cannot import name ‘imread’
解决:
conda install imageio
然后再将代码中的from scipy.misc import imread改成from imageio import imread
python trainer.py --dataset CRN --class_choice chair --inversion_mode completion --mask_type k_mask --save_inversion_path ./rk_saved_results/CRN_chair --ckpt_load rk_pretrain_models/chairtree_ckpt_0_multi.pt --dataset_path ~/Data/CRN
这篇源代码的补全网络并没有保存模型进行评估,而是保存了补全结果进行评估.
python eval_completion.py --eval_with_GT true --saved_results_path rk_saved_results/CRN_chair
遇到的问题:阈值设置
min_dists[min_dists < thre]的意思是取min_dists中点的值小于阈值的点。我跑的时候发现报错了一个除数为零的问题,排查出来就出现在这个阈值上,表达的意思是之前训练输出保存下来的点离实际位置太远了。(通过下图看出的:)
不过本身只是为了看这个代码我是否跑通了,所以把阈值设置为了3就能成功跑通了,最后的结果非常bad,不过也是在意料之中。
至此,with_gt的训练及评估情况就已经跑通了,所以现在要去继续做的任务是:1.了解tree-gan 2.看懂tree-gan的代码、看懂with_gt训练网络的代码、看懂without_gt的代码 3.尝试导入kitti(without_gt的代码)进行训练 4.阅读其他论文、尝试修改网络模块
python pretrain_treegan.py --dataset_path ~/Data/CRN --split train --ckpt_path ./rk_pretrain_checkpoints/chair --class_choice plane --epoch 150
一个重要的血泪教训的知识!!
如果你的模型要跑一两天的话,你应该挂在后台:
直接在终端里跑,会话消失的时候进程就结束了。换句话说,你的终端要一直开着且保持稳定,如果意外断网了,你的训练模型就停止了。比较稳妥的方式是使用screen。
screen -S train 建立一个名为train的窗口,这样即使终端会话中断了,窗口依然存在。
conda activate xxx 激活你的环境
CUDA_VISIBLE_DEVICES=1,2 python train.py 设置显卡1和2为可用显卡,使用python运行文件
【screen相关用法】
python eval_treegan.py --dataset_path ~/Data/CRN --save_sample_path ./rk_treegan_saved_results --model_pathname ./rk_pretrain_checkpoints/plane/tree_ckpt_0_multi.pt --gpu 1
为了一次性获得所有评估,对代码进行了改动:
G_net = Generator(features=args.G_FEAT, degrees=args.DEGREE, support=args.support,args=args).to(args.device)
pathnames = glob.glob(args.model_pathname + "/*")
for i in pathnames:
checkpoint = torch.load(i, map_location=args.device)
评估结果如下:
可以看到最低值出现在第80个epoch,于是把这个设置为rk_plane.pt
接着进行了对于plane类的训练:
python trainer.py --dataset CRN --class_choice plane --inversion_mode completion --mask_type k_mask --save_inversion_path ./rk_saved_results/CRN_plane --ckpt_load rk_pretrain_checkpoints/rk_plane.pt --dataset_path ~/Data/CRN --split train
然后进行评估:
python eval_completion.py --eval_with_GT true --saved_results_path rk_saved_results/CRN_plane