## look at line 124:
estimator.export_saved_model(output_dir +'/saved_model', serving_input_receiver_fn)
## tensorflow tutorial:
https://www.tensorflow.org/guide/saved_model#models
```python3=
import click
from sklearn.model_selection import train_test_split
import pandas as pd
import tensorflow as tf
import tensorflow_hub as hub
from datetime import datetime
import bert
from bert import run_classifier
from bert import optimization
from bert import tokenization
import simple_data_feeder as data_feeder
import simple_model_evaluator as evaluator
from tensorflow import keras
import os
import re
import json
import mlflow
import sys
import csv
os.environ["TFHUB_CACHE_DIR"] = '/tmp/tfhub'
def run(dataset, output_dir, do_delete, max_seq_length, batch_size, learning_rate, num_train_epochs,warmup_proportion,save_checkpoints_steps,save_summary_steps, bert_model_hub, train_test_split, pre_split):
if pre_split:
train, test, tag_map = data_feeder.getDataSplitted(dataset+'/train.csv', dataset+'/train_label.csv', dataset+'/test.csv', dataset+'/test_label.csv' )
else:
train, test, tag_map= data_feeder.getData(dataset, train_test_split)
if do_delete:
try:
tf.gfile.DeleteRecursively(output_dir)
except:
# Doesn't matter if the directory didn't exist
pass
if len(train) > 10000:
train = train.sample(10000)
tf.gfile.MakeDirs(output_dir)
print('***** Model output directory: {} *****'.format(output_dir), file=sys.stderr)
tag_reverse_map = {}
for k,v in tag_map.items():
tag_reverse_map[v] = k
w = csv.writer(open(output_dir+"/labels.csv", "w"))
for key, val in tag_reverse_map.items():
w.writerow([key, val])
train['tag'] = train['label'].apply(lambda x : tag_map[x])
test['tag'] = test['label'].apply(lambda x : tag_map[x])
label_list = test['tag'].unique()
train_intent_count = getLabelCount(train)
test_intent_count = getLabelCount(test)
print('***** Training Data Set: {} *****'.format(json.dumps(train_intent_count)), file=sys.stderr)
print('***** Testing Data Set: {} *****'.format(json.dumps(test_intent_count)), file=sys.stderr)
print('***** Labels: {} *****'.format(json.dumps(tag_map)), file=sys.stderr)
tokenizer = bert.tokenization.FullTokenizer(
vocab_file='data/vocab.txt', do_lower_case=True)
print('***** preparing features *****', file=sys.stderr)
train_features = toFeature(train, label_list, max_seq_length, tokenizer)
test_features = toFeature(test, label_list, max_seq_length, tokenizer)
# Compute # train and warmup steps from batch size
num_train_steps = int(len(train_features) / batch_size * num_train_epochs)
num_warmup_steps = int(num_train_steps * warmup_proportion)
run_config = tf.estimator.RunConfig(
model_dir=output_dir,
save_summary_steps=save_summary_steps,
save_checkpoints_steps=save_checkpoints_steps)
model_fn = model_fn_builder(
bert_model_hub = bert_model_hub,
num_labels=len(label_list),
learning_rate=learning_rate,
num_train_steps=num_train_steps,
num_warmup_steps=num_warmup_steps)
estimator = tf.estimator.Estimator(
model_fn=model_fn,
config=run_config,
params={"batch_size": batch_size})
# Create an input function for training. drop_remainder = True for using TPUs.
train_input_fn = bert.run_classifier.input_fn_builder(
features=train_features,
seq_length=max_seq_length,
is_training=True,
drop_remainder=False)
print('***** start training *****', file=sys.stderr)
current_time = datetime.now()
# estimator.train(input_fn=train_input_fn, max_steps=num_train_steps)
test_input_fn = run_classifier.input_fn_builder(
features=test_features,
seq_length=max_seq_length,
is_training=False,
drop_remainder=False)
print('***** start evaluating *****', file=sys.stderr)
estimator.evaluate(input_fn=test_input_fn, steps=None)
#pred_sentences = test['text']
#predictions = getPrediction(pred_sentences, label_list, max_seq_length, tokenizer, estimator)
#accuracy, tp, fp, fn, precision, recall = evaluator.eval(test['tag'] , column(predictions, 2), label_list)
#result = parseResult(tp,fp,fn,precision, recall, tag_reverse_map)
#print(result, file=sys.stderr)
print('***** saving model *****', file=sys.stderr)
estimator.export_saved_model(output_dir +'/saved_model', serving_input_receiver_fn)
print('***** publishing result *****', file=sys.stderr)
return json.dumps({"accuracy": accuracy, "details": result})
class PredResult:
def __init__(self, tp, fp, fn, precision, recall, f1):
self.tp = tp
self.fp = fp
self.fn = fn
self.precision = precision
self.recall = recall
self.f1 = f1
def parseResult(tp, fp, fn, precision, recall, map):
result = {}
for k,v in map.items():
f1=0
if precision[k] + recall[k] != 0:
f1 = 2* precision[k] * recall[k] / (precision[k] + recall[k])
result[v] = PredResult(tp[k], fp[k], fn[k], precision[k], recall[k], f1).__dict__
return result
def column(matrix, i):
return [row[i] for row in matrix]
def analyzePredictions(predictions, class2id, id2class ):
print(predictions)
def toFeature(dataset, label_list, max_seq_length, tokenizer):
# Use the InputExample class from BERT's run_classifier code to create examples from the data
train_InputExamples = dataset.apply(lambda x: bert.run_classifier.InputExample(guid=None, # Globally unique ID for bookkeeping, unused in this example
text_a = x['text'],
text_b = None,
label = x['tag']), axis = 1)
train_features = bert.run_classifier.convert_examples_to_features(train_InputExamples, label_list, max_seq_length, tokenizer)
return train_features
def create_tokenizer_from_hub_module(bert_model_hub = "https://tfhub.dev/google/bert_uncased_L-12_H-768_A-12/1"):
print(bert_model_hub)
"""Get the vocab file and casing info from the Hub module."""
with tf.Graph().as_default():
bert_module = hub.Module(bert_model_hub)
tokenization_info = bert_module(signature="tokenization_info", as_dict=True)
with tf.Session() as sess:
vocab_file, do_lower_case = sess.run([tokenization_info["vocab_file"],
tokenization_info["do_lower_case"]])
return bert.tokenization.FullTokenizer(
vocab_file=vocab_file, do_lower_case=do_lower_case)
def getTagMap(test):
tag_set = set()
for row in test['label'] :
tag_set.add(row)
tag_map = dict()
i=0
for tag in tag_set :
tag_map[tag] = i
i=i+1
return tag_map
def getLabelCount(dataset):
tag_map = getTagMap(dataset)
intent_count = {}
for key in tag_map:
intent_count[key] =0
for intent in dataset['label'] :
intent_count[intent]+=1
return intent_count
def create_model(bert_model_hub, is_predicting, input_ids, input_mask, segment_ids, labels,
num_labels):
"""Creates a classification model."""
bert_module = hub.Module(
bert_model_hub,
trainable=True)
bert_inputs = dict(
input_ids=input_ids,
input_mask=input_mask,
segment_ids=segment_ids)
bert_outputs = bert_module(
inputs=bert_inputs,
signature="tokens",
as_dict=True)
# Use "pooled_output" for classification tasks on an entire sentence.
# Use "sequence_outputs" for token-level output.
output_layer = bert_outputs["pooled_output"]
hidden_size = output_layer.shape[-1].value
# Create our own layer to tune for politeness data.
output_weights = tf.get_variable(
"output_weights", [num_labels, hidden_size],
initializer=tf.truncated_normal_initializer(stddev=0.02))
output_bias = tf.get_variable(
"output_bias", [num_labels], initializer=tf.zeros_initializer())
with tf.variable_scope("loss"):
# Dropout helps prevent overfitting
output_layer = tf.nn.dropout(output_layer, keep_prob=0.9)
logits = tf.matmul(output_layer, output_weights, transpose_b=True)
logits = tf.nn.bias_add(logits, output_bias)
log_probs = tf.nn.log_softmax(logits, axis=-1)
# Convert labels into one-hot encoding
one_hot_labels = tf.one_hot(labels, depth=num_labels, dtype=tf.float32)
predicted_labels = tf.squeeze(tf.argmax(log_probs, axis=-1, output_type=tf.int32))
# If we're predicting, we want predicted labels and the probabiltiies.
if is_predicting:
return (predicted_labels, log_probs)
# If we're train/eval, compute loss between predicted and actual label
per_example_loss = -tf.reduce_sum(one_hot_labels * log_probs, axis=-1)
loss = tf.reduce_mean(per_example_loss)
return (loss, predicted_labels, log_probs)
# model_fn_builder actually creates our model function
# using the passed parameters for num_labels, learning_rate, etc.
def model_fn_builder(bert_model_hub, num_labels, learning_rate, num_train_steps,
num_warmup_steps):
"""Returns `model_fn` closure for TPUEstimator."""
def model_fn(features, labels, mode, params): # pylint: disable=unused-argument
"""The `model_fn` for TPUEstimator."""
input_ids = features["input_ids"]
input_mask = features["input_mask"]
segment_ids = features["segment_ids"]
label_ids = features["label_ids"]
is_predicting = (mode == tf.estimator.ModeKeys.PREDICT)
# TRAIN and EVAL
if not is_predicting:
(loss, predicted_labels, log_probs) = create_model(bert_model_hub,
is_predicting, input_ids, input_mask, segment_ids, label_ids, num_labels)
train_op = bert.optimization.create_optimizer(
loss, learning_rate, num_train_steps, num_warmup_steps, use_tpu=False)
# Calculate evaluation metrics.
def metric_fn(label_ids, predicted_labels):
accuracy = tf.metrics.accuracy(label_ids, predicted_labels)
return {
"eval_accuracy": accuracy,
}
eval_metrics = metric_fn(label_ids, predicted_labels)
if mode == tf.estimator.ModeKeys.TRAIN:
return tf.estimator.EstimatorSpec(mode=mode,
loss=loss,
train_op=train_op)
else:
return tf.estimator.EstimatorSpec(mode=mode,
loss=loss,
eval_metric_ops=eval_metrics)
else:
(predicted_labels, log_probs) = create_model(bert_model_hub,
is_predicting, input_ids, input_mask, segment_ids, label_ids, num_labels)
predictions = {
'probabilities': log_probs,
'labels': predicted_labels
}
return tf.estimator.EstimatorSpec(mode, predictions=predictions)
# Return the actual model function in the closure
return model_fn
def serving_input_receiver_fn():
"""Serving input_fn that builds features from placeholders
Returns
-------
tf.estimator.export.ServingInputReceiver
"""
input_ids = tf.placeholder(dtype=tf.int32, shape=[None, 128], name='input_ids')
input_mask = tf.placeholder(dtype=tf.int32, shape=[None, 128], name='input_mask')
segment_ids = tf.placeholder(dtype=tf.int32, shape=[None, 128], name='segment_ids')
label_ids = tf.placeholder(dtype=tf.int32, shape=[None], name='label_ids')
receiver_tensors = {'input_ids': input_ids, 'input_mask': input_mask,'segment_ids': segment_ids, 'label_ids': label_ids}
return tf.estimator.export.ServingInputReceiver(receiver_tensors, receiver_tensors)
def getPrediction(in_sentences, labels, max_seq_length, tokenizer, estimator):
input_examples = [run_classifier.InputExample(guid="", text_a = x, text_b = None, label = 0) for x in in_sentences] # here, "" is just a dummy label
input_features = run_classifier.convert_examples_to_features(input_examples, labels, max_seq_length, tokenizer)
predict_input_fn = run_classifier.input_fn_builder(features=input_features, seq_length=max_seq_length, is_training=False, drop_remainder=False)
predictions = estimator.predict(predict_input_fn)
return [(sentence, prediction['probabilities'], labels[prediction['labels']]) for sentence, prediction in zip(in_sentences, predictions)]
if __name__ == '__main__':
run()
```