安装环境:
作者GitHub上的描述:Python 2.7, TensorFlow 1.0.1, CUDA 8.0 and cuDNN 5.1 on Ubuntu 14.04.此外还需要h5py模块。
linux中配置环境为:Anaconda3.4.0,Python2.7,Tensorflow1.4.0以及h5py(安装主要参考清华镜像网站+TensorFlow官网安装介绍),CUDA8.0(官网下载,需要事先查看自己的显卡版本是否支持CUDA8.0),cuDNN6.1(需要在nvidia官网上注册账号再下载,安装的时候第一次装成了5.1,与tensorflow版本不兼容,后面换成6.1。tensoflow和cuda、cudnn的对应关系可以在这里找到:https://www.tensorflow.org/install/source)
清华镜像站tensorflow:https://mirrors.tuna.tsinghua.edu.cn/tensorflow/windows/gpu/
cudnn下载地址:https://developer.nvidia.com/rdp/cudnn-archive
cuda下载地址:https://developer.nvidia.com/cuda-toolkit-archive
实验室台式机的配置是:tensorflow1.1.0(清华镜像网站下载) + cuda8.0 + cudnn5.1 + python3.5.2(直接安装在anaconda虚拟环境中)
代码运行:
1.分类classification:
1.1 train
python train.py --batch_size=my_size --max_epoch=my_epoch
batch_size和max_epoch都可以自行设置,设置的batch_size越小,最后训练的准确率越低。如要更改provider.py文件中的DATA_DIR(存放数据的文件夹),也一定要同时更新train.py中的TRAIN.FILES以及TEST_FILES,因为它们斗鱼DATA_DIR有关
还可以通过TensorBoard分析网络结构,监测训练的过程:
tensorboard --logdir log
1.2 evaluate
python evaluate.py --visu
2. 语义分割以及识别part segmentation:
首先下载数据:
cd part_seg
sh download_data
之后运行train.py进行训练,运行test.py进行测试,得到结果。
3. 代码分析:
3.1 train.py
train.py主要定义了训练的过程。前面parser定义了一些默认的参数,之后导入model(神经网络模型)以及确定LOG、TRAIN以及TEST文件夹的位置。
之后定义了获得学习率和衰减的函数:get_learning_rate(batch) get_bn_decay(batch)
train函数:设置loss、model等节点,和超参数、place holder一起放在ops里。并不真正run,为训练做好准备,控制每个epoch的训练。
train_one_epoch(sess, ops, train_writer):把下载好的训练文件(TRAIN_FILES文件夹下)先随机打乱,之后按照batch的数目进行训练,其中每一次都要通过旋转和扰动两个函数(定义在provider中)扩大batched点云,其实就是对current_data进行了处理,并且根据jittered_data生成feed_dict,最后输出平均损耗mean loss和准确率accuracy
eval_one_epoch(sess, ops, test_writer):对于每个测试文件,都要把每个batch数据喂进去,通过sess.run函数得到每次的summary, step, loss_val, pred_val,最终输出 mean loss,accuracy以及avg class acc(平均识别准确率)
3.2 models:
models文件夹下,存放了训练所用的三种网络结构,cls(识别)、seg(分割)、T-NET(一种微型网络,可以保证点云在经过刚体变换之后,仍然保持语义标签不变。值得一提的是,麻雀虽小五脏俱全,它本身也于大网络类似,实现所用到的基础模块包括特征抽取层、最大池化层以及全连接层等)。所用到的卷积等网络结构,底层实现部分在utils/tf_uitl.py中。
网络输入为B*N*3。B是batch_size,N是一个样本中点的个数,3是点云维度(三维坐标)。这里把一个样本看做了N*3的矩阵,类似二维图片,之后在其上进行卷积等操作。
值得说明的是,网络提取的特征不是3这个维度,这个维度在网络开始就被卷成了1,特征维度是输入expand出的新维度。
论文中所提及的MLP,在这里也是用卷积实现的。
3.3 pointnet_cls.py:
将各种网络组织在了一起,使得结构更加清晰。
get_model定义了网络结构,get_loss定义了损耗。
网络结构
按照网络流程,将整个网络分为以下几个阶段。
网络输入:[B,N,3,1]。
1. Input Transform Net与原始输入相乘
2.特征提取
这部分使用的都是2d-conv。
首先用[1,3]的卷积核将点云的宽卷成1,使用64个卷积核,得到输出维度[B,N,1,64]。再接一个[1,1]的卷积核,再次提取特征。
3. Feature Transform-Net与抽取出的特征相乘
这个部分看做子网络,单独使用model/transform_net.py实现。
实现过程中,先用几次[1,1]的卷积将特征升维,得到[B,N,1,1024]。然后在N维度上使用max pooling,reshape得到[B,1024]。在经过FC进行特征降维,得到[B,256]。再生成一个[256,64*64]的T-NET,相乘后得到[B,4096],reshape成[B,64,64]。
T-NET和原输入tensor做张量乘法,expand第二维,得到STN的输出[B,N,1,64]。
4.特征整合
又是一系列的[1,1]卷积,将特征升维到[B,N,1,1024]。
5.对称操作(Symmetry Function )
在N维度上使用max pooling,再reshape掉为1的维度,得到[B,1024]。
6.预测结果
接续几个全连接和drop out,降维到40,得到结果[B,40]。
loss设计
loss分为三部分:
classify_loss:分类的交叉熵损失。
mat_diff_loss:这个用于强迫T-NET把自己学的很正交。
reg_weight:正则项。
参考原文:https://blog.csdn.net/pikachu_777/article/details/83541115