def predict(self, predict_data_rows: Iterable[str]) -> List[ModelPredictionResults]: predict_input_reader = self._create_data_reader(estimator_action=EstimatorAction.Predict) input_iterator = predict_input_reader.process_and_iterate_input_from_data_lines(predict_data_rows) all_model_prediction_results = [] for input_row in input_iterator: # perform the actual prediction and get raw results. input_for_predict = input_row[0][:4] # we want only the relevant input vectors (w.o. the targets). prediction_results = self.keras_model_predict_function(input_for_predict) # make `input_row` and `prediction_results` easy to read (by accessing named fields). prediction_results = KerasPredictionModelOutput( *common.squeeze_single_batch_dimension_for_np_arrays(prediction_results)) input_row = _KerasModelInputTensorsFormer( estimator_action=EstimatorAction.Predict).from_model_input_form(input_row) input_row = ReaderInputTensors(*common.squeeze_single_batch_dimension_for_np_arrays(input_row)) # calculate the attention weight for each context attention_per_context = self._get_attention_weight_per_context( path_source_strings=input_row.path_source_token_strings, path_strings=input_row.path_strings, path_target_strings=input_row.path_target_token_strings, attention_weights=prediction_results.attention_weights ) # store the calculated prediction results in the wanted format. model_prediction_results = ModelPredictionResults( original_name=common.binary_to_string(input_row.target_string.item()), topk_predicted_words=common.binary_to_string_list(prediction_results.topk_predicted_words), topk_predicted_words_scores=prediction_results.topk_predicted_words_scores, attention_per_context=attention_per_context, code_vector=prediction_results.code_vectors) all_model_prediction_results.append(model_prediction_results) return all_model_prediction_results
def predict(self, predict_data_lines: Iterable[str]) -> List[ModelPredictionResults]: if self.predict_reader is None: self.predict_reader = PathContextReader(vocabs=self.vocabs, model_input_tensors_former=_TFEvaluateModelInputTensorsFormer(), config=self.config, estimator_action=EstimatorAction.Predict) self.predict_placeholder = tf.compat.v1.placeholder(tf.string) reader_output = self.predict_reader.process_input_row(self.predict_placeholder) self.predict_top_words_op, self.predict_top_values_op, self.predict_original_names_op, \ self.attention_weights_op, self.predict_source_string, self.predict_path_string, \ self.predict_path_target_string, self.predict_code_vectors = \ self._build_tf_test_graph(reader_output, normalize_scores=True) self._initialize_session_variables() self.saver = tf.compat.v1.train.Saver() self._load_inner_model(sess=self.sess) prediction_results: List[ModelPredictionResults] = [] for line in predict_data_lines: batch_top_words, batch_top_scores, batch_original_name, batch_attention_weights, batch_path_source_strings,\ batch_path_strings, batch_path_target_strings, batch_code_vectors = self.sess.run( [self.predict_top_words_op, self.predict_top_values_op, self.predict_original_names_op, self.attention_weights_op, self.predict_source_string, self.predict_path_string, self.predict_path_target_string, self.predict_code_vectors], feed_dict={self.predict_placeholder: line}) # shapes: # batch_top_words, top_scores: (batch, top_k) # batch_original_name: (batch, ) # batch_attention_weights: (batch, max_context, 1) # batch_path_source_strings, batch_path_strings, batch_path_target_strings: (batch, max_context) # batch_code_vectors: (batch, code_vector_size) # remove first axis: (batch=1, ...) assert all(tensor.shape[0] == 1 for tensor in (batch_top_words, batch_top_scores, batch_original_name, batch_attention_weights, batch_path_source_strings, batch_path_strings, batch_path_target_strings, batch_code_vectors)) top_words = np.squeeze(batch_top_words, axis=0) top_scores = np.squeeze(batch_top_scores, axis=0) original_name = batch_original_name[0] attention_weights = np.squeeze(batch_attention_weights, axis=0) path_source_strings = np.squeeze(batch_path_source_strings, axis=0) path_strings = np.squeeze(batch_path_strings, axis=0) path_target_strings = np.squeeze(batch_path_target_strings, axis=0) code_vectors = np.squeeze(batch_code_vectors, axis=0) top_words = common.binary_to_string_list(top_words) original_name = common.binary_to_string(original_name) attention_per_context = self._get_attention_weight_per_context( path_source_strings, path_strings, path_target_strings, attention_weights) prediction_results.append(ModelPredictionResults( original_name=original_name, topk_predicted_words=top_words, topk_predicted_words_scores=top_scores, attention_per_context=attention_per_context, code_vector=(code_vectors if self.config.EXPORT_CODE_VECTORS else None) )) return prediction_results
def evaluate(self) -> Optional[ModelEvaluationResults]: eval_start_time = time.time() if self.eval_reader is None: self.eval_reader = PathContextReader( vocabs=self.vocabs, model_input_tensors_former=_TFEvaluateModelInputTensorsFormer( ), config=self.config, estimator_action=EstimatorAction.Evaluate) input_iterator = tf.compat.v1.data.make_initializable_iterator( self.eval_reader.get_dataset()) self.eval_input_iterator_reset_op = input_iterator.initializer input_tensors = input_iterator.get_next() self.eval_top_words_op, self.eval_top_values_op, self.eval_original_names_op, _, _, _, _, _, _, \ self.eval_code_vectors = self._build_tf_test_graph(input_tensors) self.saver = tf.compat.v1.train.Saver() if self.config.MODEL_LOAD_PATH and not self.config.TRAIN_DATA_PATH_PREFIX: self._initialize_session_variables() self._load_inner_model(self.sess) if self.config.RELEASE: release_name = self.config.MODEL_LOAD_PATH + '.release' self.log('Releasing model, output model: %s' % release_name) self.saver.save(self.sess, release_name) return None # FIXME: why do we return none here? with open('log.txt', 'w') as log_output_file: if self.config.EXPORT_CODE_VECTORS: code_vectors_file = open( self.config.TEST_DATA_PATH + '.vectors', 'w') total_predictions = 0 total_prediction_batches = 0 subtokens_evaluation_metric = SubtokensEvaluationMetric( partial(common.filter_impossible_names, self.vocabs.target_vocab.special_words)) topk_accuracy_evaluation_metric = TopKAccuracyEvaluationMetric( self.config.TOP_K_WORDS_CONSIDERED_DURING_PREDICTION, partial(common.get_first_match_word_from_top_predictions, self.vocabs.target_vocab.special_words)) start_time = time.time() self.sess.run(self.eval_input_iterator_reset_op) self.log('Starting evaluation') # Run evaluation in a loop until iterator is exhausted. # Each iteration = batch. We iterate as long as the tf iterator (reader) yields batches. try: while True: top_words, top_scores, original_names, code_vectors = self.sess.run( [ self.eval_top_words_op, self.eval_top_values_op, self.eval_original_names_op, self.eval_code_vectors ], ) # shapes: # top_words: (batch, top_k); top_scores: (batch, top_k) # original_names: (batch, ); code_vectors: (batch, code_vector_size) top_words = common.binary_to_string_matrix( top_words) # (batch, top_k) original_names = common.binary_to_string_list( original_names) # (batch,) self._log_predictions_during_evaluation( zip(original_names, top_words), log_output_file) topk_accuracy_evaluation_metric.update_batch( zip(original_names, top_words)) subtokens_evaluation_metric.update_batch( zip(original_names, top_words)) total_predictions += len(original_names) total_prediction_batches += 1 if self.config.EXPORT_CODE_VECTORS: self._write_code_vectors(code_vectors_file, code_vectors) if total_prediction_batches % self.config.NUM_BATCHES_TO_LOG_PROGRESS == 0: elapsed = time.time() - start_time # start_time = time.time() self._trace_evaluation(total_predictions, elapsed) except tf.errors.OutOfRangeError: pass # reader iterator is exhausted and have no more batches to produce. self.log('Done evaluating, epoch reached') log_output_file.write( str(topk_accuracy_evaluation_metric.topk_correct_predictions) + '\n') if self.config.EXPORT_CODE_VECTORS: code_vectors_file.close() elapsed = int(time.time() - eval_start_time) self.log("Evaluation time: %sH:%sM:%sS" % ((elapsed // 60 // 60), (elapsed // 60) % 60, elapsed % 60)) return ModelEvaluationResults( topk_acc=topk_accuracy_evaluation_metric.topk_correct_predictions, subtoken_precision=subtokens_evaluation_metric.precision, subtoken_recall=subtokens_evaluation_metric.recall, subtoken_f1=subtokens_evaluation_metric.f1)