66import torch .nn .parallel
77import torch .optim as optim
88import torch .utils .data
9- from torch .autograd import Variable
109from pointnet .dataset import PartDataset
1110from pointnet .model import PointNetDenseCls
1211import torch .nn .functional as F
12+ from tqdm import tqdm
13+ import numpy as np
1314
1415
1516parser = argparse .ArgumentParser ()
2122 '--nepoch' , type = int , default = 25 , help = 'number of epochs to train for' )
2223parser .add_argument ('--outf' , type = str , default = 'seg' , help = 'output folder' )
2324parser .add_argument ('--model' , type = str , default = '' , help = 'model path' )
25+ parser .add_argument ('--dataset' , type = str , required = True , help = "dataset path" )
26+ parser .add_argument ('--class_choice' , type = str , default = 'Chair' , help = "class_choice" )
2427
2528
2629opt = parser .parse_args ()
3235torch .manual_seed (opt .manualSeed )
3336
3437dataset = PartDataset (
35- root = 'shapenetcore_partanno_segmentation_benchmark_v0' ,
38+ root = opt . dataset ,
3639 classification = False ,
37- class_choice = ['Chair' ])
40+ class_choice = [opt . class_choice ])
3841dataloader = torch .utils .data .DataLoader (
3942 dataset ,
4043 batch_size = opt .batchSize ,
4144 shuffle = True ,
4245 num_workers = int (opt .workers ))
4346
4447test_dataset = PartDataset (
45- root = 'shapenetcore_partanno_segmentation_benchmark_v0' ,
48+ root = opt . dataset ,
4649 classification = False ,
47- class_choice = ['Chair' ],
50+ class_choice = [opt . class_choice ],
4851 train = False )
4952testdataloader = torch .utils .data .DataLoader (
5053 test_dataset ,
6770if opt .model != '' :
6871 classifier .load_state_dict (torch .load (opt .model ))
6972
70- optimizer = optim .SGD (classifier .parameters (), lr = 0.01 , momentum = 0.9 )
73+ optimizer = optim .Adam (classifier .parameters (), lr = 0.001 , betas = (0.9 , 0.999 ))
74+ scheduler = optim .lr_scheduler .StepLR (optimizer , step_size = 20 , gamma = 0.5 )
7175classifier .cuda ()
7276
7377num_batch = len (dataset ) / opt .batchSize
7478
7579for epoch in range (opt .nepoch ):
80+ scheduler .step ()
7681 for i , data in enumerate (dataloader , 0 ):
7782 points , target = data
78- points , target = Variable (points ), Variable (target )
7983 points = points .transpose (2 , 1 )
8084 points , target = points .cuda (), target .cuda ()
8185 optimizer .zero_grad ()
9498 if i % 10 == 0 :
9599 j , data = next (enumerate (testdataloader , 0 ))
96100 points , target = data
97- points , target = Variable (points ), Variable (target )
98101 points = points .transpose (2 , 1 )
99102 points , target = points .cuda (), target .cuda ()
100103 classifier = classifier .eval ()
101104 pred , _ = classifier (points )
102105 pred = pred .view (- 1 , num_classes )
103106 target = target .view (- 1 , 1 )[:, 0 ] - 1
104-
105107 loss = F .nll_loss (pred , target )
106108 pred_choice = pred .data .max (1 )[1 ]
107109 correct = pred_choice .eq (target .data ).cpu ().sum ()
108110 print ('[%d: %d/%d] %s loss: %f accuracy: %f' % (epoch , i , num_batch , blue ('test' ), loss .item (), correct .item ()/ float (opt .batchSize * 2500 )))
109111
110- torch .save (classifier .state_dict (), '%s/seg_model_%d.pth' % (opt .outf , epoch ))
112+ torch .save (classifier .state_dict (), '%s/seg_model_%s_%d.pth' % (opt .outf , opt .class_choice , epoch ))
113+
114+ ## benchmark mIOU
115+ shape_ious = []
116+ for i ,data in tqdm (enumerate (testdataloader , 0 )):
117+ points , target = data
118+ points = points .transpose (2 , 1 )
119+ points , target = points .cuda (), target .cuda ()
120+ classifier = classifier .eval ()
121+ pred , _ = classifier (points )
122+ pred_choice = pred .data .max (2 )[1 ]
123+
124+ pred_np = pred_choice .cpu ().data .numpy ()
125+ target_np = target .cpu ().data .numpy () - 1
126+
127+ for shape_idx in range (target_np .shape [0 ]):
128+ parts = np .unique (target_np [shape_idx ])
129+ part_ious = []
130+ for part in parts :
131+ I = np .sum (np .logical_and (pred_np [shape_idx ] == part , target_np [shape_idx ] == part ))
132+ U = np .sum (np .logical_or (pred_np [shape_idx ] == part , target_np [shape_idx ] == part ))
133+ if U == 0 :
134+ iou = 0
135+ else :
136+ iou = I / float (U )
137+ part_ious .append (iou )
138+ shape_ious .append (np .mean (part_ious ))
139+
140+ print ("mIOU for class {}: {}" .format (opt .class_choice , np .mean (shape_ious )))
0 commit comments