16
16
import time
17
17
18
18
import argparse
19
+ from sklearn .metrics import confusion_matrix , cohen_kappa_score , accuracy_score
19
20
import numpy as np
20
21
from PIL import Image
21
22
import scipy .io as sio
26
27
27
28
28
29
import windows as win
29
- from rle import myrlestring
30
30
# import salt_baseline as sb
31
31
# import salt_data as sd
32
32
import fst3d_feat as fst
@@ -95,11 +95,20 @@ def scat3d_to_3d_nxn_2layer(x, reuse=tf.AUTO_REUSE, psis=None, phi=None, layer_p
95
95
9 : 7 ,
96
96
7 : 5 ,
97
97
5 : 3 ,
98
- 3 : 1
98
+ 3 : 1 ,
99
+ 1 : 1
99
100
}
100
- lambda1_d = ds_amounts [psis [0 ].kernel_size [1 ]]; band1_d = 3
101
- lambda2_d = ds_amounts [psis [1 ].kernel_size [1 ]]; band2_d = 3
102
- lambdax_d = ds_amounts [phi .kernel_size [1 ]];
101
+ def avg_cube_side (kernel_size ):
102
+ # started doing this for cubes with spatial size 1
103
+ avg_cube_side_ = int (round (np .prod (kernel_size [:2 ])** (1 / 2.0 )))
104
+ if avg_cube_side_ % 2 == 0 :
105
+ avg_cube_side_ += 1
106
+ return avg_cube_side_
107
+ lambda1_d = ds_amounts [ avg_cube_side (psis [0 ].kernel_size ) ];
108
+ lambda2_d = ds_amounts [ avg_cube_side (psis [1 ].kernel_size ) ];
109
+ lambdax_d = ds_amounts [ avg_cube_side (phi .kernel_size ) ];
110
+ band1_d = 3
111
+ band2_d = 3
103
112
104
113
U1 = tf .layers .max_pooling3d (U1 , (lambda1_d ,band1_d ,1 ), (lambda1_d ,band1_d ,1 ), padding = 'same' )
105
114
@@ -119,7 +128,6 @@ def scat3d_to_3d_nxn_2layer(x, reuse=tf.AUTO_REUSE, psis=None, phi=None, layer_p
119
128
increasing_psi = win .fst3d_psi_factory (psis [1 ].kernel_size , used_params )
120
129
if increasing_psi .nfilt > 0 :
121
130
U2s .append (fst .scat3d (U1 [res_i :(res_i + 1 ),:,:,:,:], increasing_psi , layer_params [1 ]))
122
-
123
131
U2 = tf .concat (U2s , 4 )
124
132
# U2 is (1,bands,h,w,lambda2)
125
133
@@ -157,8 +165,17 @@ def slice_idx(s, k, f):
157
165
[p1b , p1h , p1w ] = slice_idxs (U1 .shape [1 :4 ], phi .kernel_size )
158
166
[p2b , p2h , p2w ] = slice_idxs (x .shape [1 :4 ], phi .kernel_size )
159
167
160
- S1 = fst .scat3d (U1 [:, :,(p1h ):- (p1h ), (p1w ):- (p1w ), :], phi , layer_params [2 ])
161
- S0 = fst .scat3d (x [:, :,(p2h ):- (p2h ), (p2w ):- (p2w ), :], phi , layer_params [2 ])
168
+ if not (p1h == 0 and p1w == 0 ):
169
+ S1 = fst .scat3d (U1 [:, :,(p1h ):- (p1h ), (p1w ):- (p1w ), :], phi , layer_params [2 ])
170
+ else :
171
+ # if the size of the spatial kernel is 1 in the spatial dimension we
172
+ # don't need to do this.
173
+ S1 = fst .scat3d (U1 , phi , layer_params [2 ])
174
+
175
+ if not (p2h == 0 and p2w == 0 ):
176
+ S0 = fst .scat3d (x [:, :,(p2h ):- (p2h ), (p2w ):- (p2w ), :], phi , layer_params [2 ])
177
+ else :
178
+ S0 = fst .scat3d (x , phi , layer_params [2 ])
162
179
163
180
# just to get the size down to 1 (flattening step)
164
181
S0 = tf .reshape (S0 , [- 1 , final_size , final_size , 1 ])
@@ -205,12 +222,17 @@ def gabor_mag_filter(x, reuse=tf.AUTO_REUSE, psis=None, layer_params=None, final
205
222
9 : 7 ,
206
223
7 : 5 ,
207
224
5 : 3 ,
208
- 3 : 1
225
+ 3 : 1 ,
226
+ 1 : 1
209
227
}
210
228
lambda1_d = ds_amounts [psis [0 ].kernel_size [1 ]]; band1_d = 3
211
229
212
230
U1 = tf .layers .max_pooling3d (U1 , (lambda1_d ,band1_d ,1 ), (lambda1_d ,band1_d ,1 ), padding = 'same' )
213
- U1 = tf .reshape (U1 , [- 1 , final_size , final_size ])
231
+ U1 = tf .reshape (U1 , [1 , - 1 , final_size , final_size , 1 ])
232
+
233
+ # SX downsampling from ST for comparable feature size
234
+ U1 = tf .layers .max_pooling3d (U1 , (lambda1_d ,1 ,1 ), (lambda1_d ,1 ,1 ), padding = 'same' )
235
+ U1 = tf .squeeze (U1 )
214
236
215
237
return tf .transpose (U1 , [1 , 2 , 0 ])
216
238
@@ -587,19 +609,30 @@ def load_or_preprocess_data(data, write_path, backup_write_root, st_net_spec=pav
587
609
}
588
610
sts_dict = {
589
611
'paviaU' : st_net_spec_struct ([9 ,9 ,9 ],[9 ,9 ,9 ],[9 ,9 ,9 ]),
612
+ 'paviaU_dist' : st_net_spec_struct ([5 ,7 ,7 ],[5 ,7 ,7 ],[5 ,7 ,7 ]),
613
+ 'paviaU_SSS' : st_net_spec_struct ([7 ,3 ,3 ],[7 ,3 ,3 ],[7 ,3 ,3 ]),
590
614
'7' : st_net_spec_struct ([7 ,7 ,7 ],[7 ,7 ,7 ],[7 ,7 ,7 ]),
591
615
'9' : st_net_spec_struct ([9 ,9 ,9 ],[9 ,9 ,9 ],[9 ,9 ,9 ]),
592
616
'5' : st_net_spec_struct ([5 ,5 ,5 ],[5 ,5 ,5 ],[5 ,5 ,5 ]),
593
617
'3' : st_net_spec_struct ([3 ,3 ,3 ],[3 ,3 ,3 ],[3 ,3 ,3 ]),
594
618
'Botswana' : st_net_spec_struct ([7 ,7 ,7 ],[7 ,5 ,5 ],[7 ,5 ,5 ]),
619
+ 'Botswana_dist' : st_net_spec_struct ([7 ,9 ,9 ],[7 ,5 ,5 ],[7 ,5 ,5 ]),
620
+ 'Botswana_SSS' : st_net_spec_struct ([3 ,5 ,5 ],[3 ,5 ,5 ],[3 ,5 ,5 ]),
595
621
'KSC' : st_net_spec_struct ([5 ,9 ,9 ],[5 ,7 ,7 ],[5 ,7 ,7 ]),
596
- 'PU_SSS' : st_net_spec_struct ([9 ,7 ,7 ],[9 ,3 ,3 ],[9 ,3 ,3 ]),
597
- 'IP_SSS' : st_net_spec_struct ([5 ,9 ,9 ],[5 ,5 ,5 ],[5 ,5 ,5 ]),
598
- 'IP_gabor' : st_net_spec_struct ([5 ,9 ,9 ],None ,None ),
599
- 'PU_gabor' : st_net_spec_struct ([9 ,7 ,7 ],None ,None ),
600
- 'KSC_gabor' : st_net_spec_struct ([5 ,9 ,9 ],None ,None ),
601
- 'Botswana_gabor' : st_net_spec_struct ([7 ,7 ,7 ],None ,None ),
622
+ 'KSC_SSS' : st_net_spec_struct ([3 ,7 ,7 ],[3 ,1 ,1 ],[3 ,1 ,1 ]),
623
+ 'KSC_dist' : st_net_spec_struct ([3 ,7 ,7 ],[3 ,7 ,7 ],[3 ,7 ,7 ]),
624
+ 'IP' : st_net_spec_struct ([5 ,9 ,9 ],[5 ,5 ,5 ],[5 ,5 ,5 ]),
625
+ 'IP_dist' : st_net_spec_struct ([7 ,9 ,9 ],[7 ,9 ,9 ],[7 ,9 ,9 ]),
626
+ 'IP_SSS' : st_net_spec_struct ([5 ,1 ,1 ],[5 ,1 ,1 ],[5 ,1 ,1 ]),
602
627
'tang' : st_net_spec_struct (None ,None ,None ),
628
+ 'IP_dist_gabor' : st_net_spec_struct ([7 ,9 ,9 ],None ,None ),
629
+ 'IP_SSS_gabor' : st_net_spec_struct ([5 ,1 ,1 ],None ,None ),
630
+ 'KSC_dist_gabor' : st_net_spec_struct ([3 ,7 ,7 ],None ,None ),
631
+ 'KSC_SSS_gabor' : st_net_spec_struct ([3 ,7 ,7 ],None ,None ),
632
+ 'Botswana_dist_gabor' : st_net_spec_struct ([7 ,9 ,9 ],None ,None ),
633
+ 'Botswana_SSS_gabor' : st_net_spec_struct ([3 ,5 ,5 ],None ,None ),
634
+ 'paviaU_dist_gabor' : st_net_spec_struct ([5 ,7 ,7 ],None ,None ),
635
+ 'paviaU_SSS_gabor' : st_net_spec_struct ([7 ,3 ,3 ],None ,None ),
603
636
}
604
637
605
638
def many_svm_evals (args ):
@@ -645,14 +678,17 @@ def many_svm_evals(args):
645
678
end = time .time ()
646
679
print ('Training done. Took %is' % int (end - start ))
647
680
648
- n_correct = 0
681
+ predictions = np . zeros_like ( valY )
649
682
for i in tqdm (range (0 ,valY .shape [0 ],bs ), desc = 'Getting Val Accuracy' ):
650
- p_label = clf .predict (valX .squeeze ()[i :i + bs ]);
651
- n_correct += (p_label == valY [i :i + bs ]).sum ()
652
- acc = float (n_correct ) / valY .shape [0 ]
683
+ predictions [i :i + bs ] = clf .predict (valX .squeeze ()[i :i + bs ])
684
+ overall_acc = accuracy_score (valY , predictions )
685
+ C = confusion_matrix (valY , predictions ).astype (float )
686
+ per_class = np .diag (C ) / C .sum (axis = 1 )
687
+ average_acc = np .mean (per_class )
688
+ kappa = cohen_kappa_score (valY , predictions )
653
689
print ('Done with %s' % mask_path )
654
- print ('SVM has validation accuracy %.2f' % (acc * 100 ) )
655
- results [mask_path ] = acc
690
+ print ('SVM has validation OA %.2f, AA %.2f, kappa %.4f ' % (overall_acc * 100 , average_acc * 100 , kappa ) )
691
+ results [mask_path ] = ( overall_acc , average_acc , kappa )
656
692
657
693
npz_path = os .path .join (args .model_root , 'SVM_results_%i.npz' % (random .randint (0 ,1e10 )))
658
694
np .savez (npz_path , results = results )
@@ -683,19 +719,37 @@ def svm_predict(args):
683
719
s = args .network_spatial_size - 1
684
720
trainX , trainY , valX , valY = get_train_val_splits (data , labels , train_mask , val_mask , (s ,s ,0 ))
685
721
722
+ # Cs = 2.0**np.array(range(-20,21,2))
723
+ # accs = np.zeros_like(Cs)
724
+ # for j, C in enumerate(Cs):
725
+ # print('starting training')
726
+ # start = time.time()
727
+ # clf = SVC(kernel='linear', C=C)
728
+ # clf.fit(trainX.squeeze(), trainY)
729
+ # overall_acc = clf.score(valX.squeeze(), valY)
730
+ # accs[j] = overall_acc
731
+ # end = time.time()
732
+ # print('Training done. Took %is' % int(end - start))
733
+ # print('C %f. Got %f' % (C, overall_acc))
734
+
735
+
686
736
print ('starting training' )
687
737
start = time .time ()
688
- clf = SVC (kernel = 'linear' )
738
+ clf = SVC (kernel = 'linear' , C = args . svm_regularization_param )
689
739
clf .fit (trainX .squeeze (), trainY )
690
740
end = time .time ()
691
741
print ('Training done. Took %is' % int (end - start ))
692
742
693
- n_correct = 0
743
+
744
+ predictions = np .zeros_like (valY )
694
745
for i in tqdm (range (0 ,valY .shape [0 ],bs ), desc = 'Getting Val Accuracy' ):
695
- p_label = clf .predict (valX .squeeze ()[i :i + bs ]);
696
- n_correct += (p_label == valY [i :i + bs ]).sum ()
697
- acc = float (n_correct ) / valY .shape [0 ]
698
- print ('SVM has validation accuracy %.2f' % (acc * 100 ) )
746
+ predictions [i :i + bs ] = clf .predict (valX .squeeze ()[i :i + bs ])
747
+ overall_acc = accuracy_score (valY , predictions )
748
+ C = confusion_matrix (valY , predictions ).astype (float )
749
+ per_class = np .diag (C ) / C .sum (axis = 1 )
750
+ average_acc = np .mean (per_class )
751
+ kappa = cohen_kappa_score (valY , predictions )
752
+ print ('SVM has validation OA %.2f, AA %.2f, kappa %.4f' % (overall_acc * 100 , average_acc * 100 , kappa ) )
699
753
700
754
# test everything
701
755
y_predicted = []
@@ -708,15 +762,17 @@ def svm_predict(args):
708
762
709
763
imgmatfiledata = {}
710
764
imgmatfiledata [u'imgHat' ] = pred_image
711
- groundtruthfilename = os .path .splitext (trainlabelname )[0 ]
712
- imgmatfiledata [u'groundtruthfilename' ] = '%s_%s.mat' % (groundtruthfilename , args .network )
765
+ # groundtruthfilename = os.path.splitext(trainlabelname)[0]
766
+ npzfilename = '%s_pred.npz' % args .mask_root .split ('/' )[- 1 ].split ('.' )[0 ]
767
+ # imgmatfiledata[u'groundtruthfilename'] = '%s_%s.mat' % (groundtruthfilename, args.network)
768
+ imgmatfiledata [u'groundtruthfilename' ] = '%s_pred.mat' % args .mask_root .split ('/' )[- 1 ].split ('.' )[0 ]
713
769
hdf5storage .write (imgmatfiledata ,
714
770
filename = os .path .join (args .model_root , imgmatfiledata [u'groundtruthfilename' ]),
715
771
matlab_compatible = True )
716
772
717
773
print ('Saved %s' % os .path .join (args .model_root , imgmatfiledata [u'groundtruthfilename' ]))
718
774
719
- npz_path = os .path .join (args .model_root , '%s_SVM.npz' % ( groundtruthfilename ) )
775
+ npz_path = os .path .join (args .model_root , npzfilename )
720
776
np .savez (npz_path , pred_image = pred_image )
721
777
print ('Saved %s' % npz_path )
722
778
@@ -846,7 +902,8 @@ def model_fn(features, labels, mode):
846
902
847
903
# Evaluate the accuracy of the model
848
904
acc_op = tf .metrics .accuracy (labels = labels , predictions = pred_classes )
849
-
905
+ avg_acc_op = tf .metrics .mean_per_class_accuracy (labels = labels , predictions = pred_classes , num_classes = n_classes )
906
+ kappa_op = tf .contrib .metrics .cohen_kappa (labels = labels , predictions_idx = pred_classes , num_classes = n_classes )
850
907
# tf.summary.scalar('min', loss_op)
851
908
852
909
# TF Estimators requires to return a EstimatorSpec, that specify
@@ -856,7 +913,7 @@ def model_fn(features, labels, mode):
856
913
predictions = pred_classes ,
857
914
loss = loss_op ,
858
915
train_op = train_op ,
859
- eval_metric_ops = {'accuracy' : acc_op })
916
+ eval_metric_ops = {'accuracy' : acc_op , 'avg_accuracy' : avg_acc_op , 'kappa' : kappa_op })
860
917
861
918
return estim_specs
862
919
@@ -901,6 +958,9 @@ def identity_serving_input_receiver_fn():
901
958
model .train (train_input_fn )
902
959
903
960
e = model .evaluate (eval_input_fn , name = 'eval' )
961
+ tp = float (n_eval ) / nlabeled # test percentage
962
+ avg_acc_at_best_eval_acc = 0
963
+ kappa_at_best_eval_acc = 0
904
964
905
965
if e ['accuracy' ] > best_acc :
906
966
tf .logging .info ("{:06d}: High Accuracy. Saving model with Validation Accuracy: {:.4f}" .format (i * args .eval_period , e ['accuracy' ]))
@@ -924,6 +984,8 @@ def identity_serving_input_receiver_fn():
924
984
test_e = model .evaluate (test_input_fn , name = 'test' )
925
985
if e ['accuracy' ] > best_acc :
926
986
test_acc_at_best_eval_acc = test_e ['accuracy' ]
987
+ avg_acc_at_best_eval_acc = tp * test_e ['avg_accuracy' ] + (1 - tp )* e ['avg_accuracy' ]
988
+ kappa_at_best_eval_acc = tp * test_e ['kappa' ] + (1 - tp )* e ['kappa' ]
927
989
if e ['loss' ] < best_loss :
928
990
test_acc_at_best_eval_loss = test_e ['accuracy' ]
929
991
@@ -932,13 +994,12 @@ def identity_serving_input_receiver_fn():
932
994
tf .logging .info ("{:06d}: Validation Accuracy: {:.4f} (At lowest loss: {:.4f}) (Best Ever: {:.4f})" .format (i * args .eval_period , e ['accuracy' ], acc_at_best_loss , best_acc ))
933
995
tf .logging .info ("{:06d}: Test Accuracy: Best by Eval Acc: {:.4f}. Best by Eval Loss: {:.4f}" .format (i * args .eval_period , test_acc_at_best_eval_acc , test_acc_at_best_eval_loss ))
934
996
935
- tp = float (n_eval ) / nlabeled # test percentage
936
997
overall_acc_at_best_eval_acc = tp * test_acc_at_best_eval_acc + (1 - tp )* best_acc
937
998
overall_acc_at_best_eval_loss = tp * test_acc_at_best_eval_loss + (1 - tp )* acc_at_best_loss
938
999
tf .logging .info ("{:06d}: Overall Accuracy: Best by Eval Acc: {:.4f}. Best by Eval Loss: {:.4f}" .format (i * args .eval_period , overall_acc_at_best_eval_acc , overall_acc_at_best_eval_loss ))
939
1000
940
1001
npz_path = os .path .join (args .model_root , 'results.npz' )
941
- np .savez (npz_path , results = {args .mask_root : overall_acc_at_best_eval_acc })
1002
+ np .savez (npz_path , results = {args .mask_root : ( overall_acc_at_best_eval_acc , avg_acc_at_best_eval_acc , kappa_at_best_eval_acc ) })
942
1003
print ('Saved %s' % npz_path )
943
1004
944
1005
if n_nondecreasing_evals >= args .terminate_if_n_nondecreasing_evals :
0 commit comments