python train.py --batch_size=8
显卡显存太小,只能跑batch size为8的,训练250个epoch。
python evaluate.py --visu
结果:
eval mean loss: 0.488872
eval accuracy: 0.878444
eval avg class acc: 0.851238
airplane: 0.980
bathtub: 0.860
bed: 0.950
bench: 0.700
bookshelf: 0.900
bottle: 0.950
bowl: 0.950
car: 1.000
chair: 0.970
cone: 0.900
cup: 0.650
curtain: 0.800
desk: 0.791
door: 0.850
dresser: 0.651
flower_pot: 0.200
glass_box: 0.950
guitar: 1.000
keyboard: 1.000
lamp: 0.950
laptop: 1.000
mantel: 0.950
monitor: 0.940
night_stand: 0.698
person: 0.950
piano: 0.860
plant: 0.780
radio: 0.800
range_hood: 0.910
sink: 0.750
sofa: 0.960
stairs: 0.850
stool: 0.800
table: 0.810
tent: 0.950
toilet: 0.960
tv_stand: 0.820
vase: 0.810
wardrobe: 0.650
xbox: 0.800
论文中的结果是:86.2/89.2,相比论文中差了一些,可能是batch size的问题。
代码在part_seg下,进去sh download_data.sh
下载数据集,然后运行trian.py
训练,test.py
测试。分割任务的显存占用更高,我只能跑batchsize=4的…。最终模型的结果比论文里也低了接近两个点(0.8197/0.837)。
Accuracy: 0.923867
IoU: 0.819725
02691156 Total Number: 341
02691156 Accuracy: 0.9096132876935942
02691156 IoU: 0.8228572722404234
02773838 Total Number: 14
02773838 Accuracy: 0.9517263003758022
02773838 IoU: 0.7696178300040108
02954340 Total Number: 11
02954340 Accuracy: 0.8923338109796698
02954340 IoU: 0.7994510477239435
02958343 Total Number: 158
02958343 Accuracy: 0.9047723118262955
02958343 IoU: 0.734290400637856
03001627 Total Number: 704
03001627 Accuracy: 0.9394946531815962
03001627 IoU: 0.8910455703735352
03261776 Total Number: 14
03261776 Accuracy: 0.9178562164306641
03261776 IoU: 0.7298440933227539
03467517 Total Number: 159
03467517 Accuracy: 0.9630299694133255
03467517 IoU: 0.9014740949906643
03624134 Total Number: 80
03624134 Accuracy: 0.8905808448791503
03624134 IoU: 0.8044050216674805
03636649 Total Number: 286
03636649 Accuracy: 0.8275325214946186
03636649 IoU: 0.7223616379957932
03642806 Total Number: 83
03642806 Accuracy: 0.9772439060440983
03642806 IoU: 0.9505088530391096
03790512 Total Number: 51
03790512 Accuracy: 0.8500167996275658
03790512 IoU: 0.633358824486826
03797390 Total Number: 38
03797390 Accuracy: 0.9923725128173828
03797390 IoU: 0.921830227500514
03948459 Total Number: 44
03948459 Accuracy: 0.9490793401544745
03948459 IoU: 0.7901863618330522
04099429 Total Number: 12
04099429 Accuracy: 0.7942575613657633
04099429 IoU: 0.5516049861907959
04225987 Total Number: 31
04225987 Accuracy: 0.9462758341143208
04225987 IoU: 0.7356803032659716
04379243 Total Number: 848
04379243 Accuracy: 0.9443713494066922
04379243 IoU: 0.7989320575066332
定义了训练的过程。
定义所需的各种参数和默认值,打包放在FLAGS里,可以在命令行进行交互。
使用tf.train.exponential_decay()
函数对lr和bn_momentum进行衰减。
tf.train.exponential_decay(
BASE_LEARNING_RATE, # Base learning rate.the value will be decayed.
batch * BATCH_SIZE, # Current index into the dataset.
DECAY_STEP, # Decay step.
DECAY_RATE, # Decay rate.
staircase=True) # True:decay every decay step.
# False:decay every real setp.
设置loss、model等节点,和超参数、place holder一起放在ops
里。并不真正run,控制每个epoch的训练。
把训练数据分成len(TRAIN_FILES)
份。每份数据中,按照batch_size
取一个batch进行训练。一个batch的数据进行数据增强,包括rotate和jitter,是由provider.py
实现的。
根据ops
里ph相关的参数构造feed_dict
,并从中取出构造的训练、预测、loss等节点,作为sess.run()
的参数进行训练。
与train的部分相同,也是把测试文件份成几分,每一份把每个batch喂进去,计算总的准确率,作为训练中每个epoch的测试。
models文件夹下,存放了训练所用的三种网络结构,cls、seg、T-NET。所用到的卷积等网络结构,在utils/tf_uitl.py
中实现。
网络输入为B*N*3
。B是batch_size,N是一个样本中点的个数,3是点云维度(三维坐标)。这里把一个样本看做了N*3
的矩阵,类似二维图片,之后在其上进行卷积等操作。
值得说明的是,网络提取的特征不是3这个维度,这个维度在网络开始就被卷成了1,特征维度是输入expand出的新维度。
论文中所提及的MLP,在这里也是用卷积实现的。
这个文件实现了网络的分类结构。
输出为B*40
,是每个样本对于每个类别的概率。
网络结构在get_model()
中定义,loss则在get_loss
中定义。
按照网络流程,将整个网络分为以下几个阶段。
网络输入:[B,N,3,1]
。
[1,3]
的卷积核将电云的宽卷成1,使用64个卷积核,得到输出维度[B,N,1,64]
。再接一个[1,1]
的卷积核,再次提取特征。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]
。[B,N,1,64]
。[1,1]
卷积,将特征升维到[B,N,1,1024]
。[B,1024]
。[B,40]
。loss分为三部分:
这个文件夹提供了一些工具函数。
实现数据的读取,单个文件路径存在.txt文件中,从中读取文件名,join父路径,读到数据,做成数据集。
提供了一些三维数据处理的函数,包括点云和volume的转换,点云可视化,点云的读写。
自己封装的一些层,实现了各种卷积,pooling,fc。也实现了权重初始化的函数。
但是网络好像只用到了2D卷积,max pooing?
实现了数据读取,数据处理,数据增强的函数。
包括: