@@ -45,6 +45,8 @@ public bool Run()
4545 tf . train . import_meta_graph ( "graph/InceptionV3.meta" ) ;
4646 Tensor bottleneck_tensor = graph . OperationByName ( "module_apply_default/hub_output/feature_vector/SpatialSqueeze" ) ;
4747 Tensor resized_image_tensor = graph . OperationByName ( "Placeholder" ) ;
48+ Tensor final_tensor = graph . OperationByName ( "final_result" ) ;
49+ Tensor ground_truth_input = graph . OperationByName ( "input/GroundTruthInput" ) ;
4850
4951 var sw = new Stopwatch ( ) ;
5052
@@ -63,11 +65,45 @@ public bool Run()
6365 bottleneck_dir , jpeg_data_tensor ,
6466 decoded_image_tensor , resized_image_tensor ,
6567 bottleneck_tensor , tfhub_module ) ;
68+
69+ // Create the operations we need to evaluate the accuracy of our new layer.
70+ var ( evaluation_step , _) = add_evaluation_step ( final_tensor , ground_truth_input ) ;
71+
72+ // Merge all the summaries and write them out to the summaries_dir
73+ var merged = tf . summary . merge_all ( ) ;
6674 } ) ;
6775
6876 return false ;
6977 }
7078
79+ /// <summary>
80+ /// Inserts the operations we need to evaluate the accuracy of our results.
81+ /// </summary>
82+ /// <param name="result_tensor"></param>
83+ /// <param name="ground_truth_tensor"></param>
84+ /// <returns></returns>
85+ private ( Tensor , Tensor ) add_evaluation_step ( Tensor result_tensor , Tensor ground_truth_tensor )
86+ {
87+ Tensor evaluation_step = null , correct_prediction = null , prediction = null ;
88+
89+ with ( tf . name_scope ( "accuracy" ) , scope =>
90+ {
91+ with ( tf . name_scope ( "correct_prediction" ) , delegate
92+ {
93+ prediction = tf . argmax ( result_tensor , 1 ) ;
94+ correct_prediction = tf . equal ( prediction , ground_truth_tensor ) ;
95+ } ) ;
96+
97+ with ( tf . name_scope ( "accuracy" ) , delegate
98+ {
99+ evaluation_step = tf . reduce_mean ( tf . cast ( correct_prediction , tf . float32 ) ) ;
100+ } ) ;
101+ } ) ;
102+
103+ tf . summary . scalar ( "accuracy" , evaluation_step ) ;
104+ return ( evaluation_step , prediction ) ;
105+ }
106+
71107 /// <summary>
72108 /// Ensures all the training, testing, and validation bottlenecks are cached.
73109 /// </summary>
@@ -95,12 +131,15 @@ private void cache_bottlenecks(Session sess, Dictionary<string, Dictionary<strin
95131 get_or_create_bottleneck ( sess , image_lists , label_name , index , image_dir , category ,
96132 bottleneck_dir , jpeg_data_tensor , decoded_image_tensor ,
97133 resized_input_tensor , bottleneck_tensor , module_name ) ;
134+ how_many_bottlenecks ++ ;
135+ if ( how_many_bottlenecks % 100 == 0 )
136+ print ( $ "{ how_many_bottlenecks } bottleneck files created.") ;
98137 }
99138 }
100139 }
101140 }
102141
103- private void get_or_create_bottleneck ( Session sess , Dictionary < string , Dictionary < string , string [ ] > > image_lists ,
142+ private float [ ] get_or_create_bottleneck ( Session sess , Dictionary < string , Dictionary < string , string [ ] > > image_lists ,
104143 string label_name , int index , string image_dir , string category , string bottleneck_dir ,
105144 Tensor jpeg_data_tensor , Tensor decoded_image_tensor , Tensor resized_input_tensor ,
106145 Tensor bottleneck_tensor , string module_name )
@@ -116,6 +155,9 @@ private void get_or_create_bottleneck(Session sess, Dictionary<string, Dictionar
116155 image_dir , category , sess , jpeg_data_tensor ,
117156 decoded_image_tensor , resized_input_tensor ,
118157 bottleneck_tensor ) ;
158+ var bottleneck_string = File . ReadAllText ( bottleneck_path ) ;
159+ var bottleneck_values = Array . ConvertAll ( bottleneck_string . Split ( ',' ) , x => float . Parse ( x ) ) ;
160+ return bottleneck_values ;
119161 }
120162
121163 private void create_bottleneck_file ( string bottleneck_path , Dictionary < string , Dictionary < string , string [ ] > > image_lists ,
@@ -132,13 +174,16 @@ private void create_bottleneck_file(string bottleneck_path, Dictionary<string, D
132174 var bottleneck_values = run_bottleneck_on_image (
133175 sess , image_data , jpeg_data_tensor , decoded_image_tensor ,
134176 resized_input_tensor , bottleneck_tensor ) ;
177+ var values = bottleneck_values . Data < float > ( ) ;
178+ var bottleneck_string = string . Join ( "," , values ) ;
179+ File . WriteAllText ( bottleneck_path , bottleneck_string ) ;
135180 }
136181
137182 /// <summary>
138183 /// Runs inference on an image to extract the 'bottleneck' summary layer.
139184 /// </summary>
140185 /// <param name="sess">Current active TensorFlow Session.</param>
141- /// <param name="image_path">Path of raw JPEG data.</param>
186+ /// <param name="image_data">Data of raw JPEG data.</param>
142187 /// <param name="image_data_tensor">Input data layer in the graph.</param>
143188 /// <param name="decoded_image_tensor">Output of initial image resizing and preprocessing.</param>
144189 /// <param name="resized_input_tensor">The input node of the recognition graph.</param>
0 commit comments