# Path: lstm.py
# def build_model(tparams, options, maxw, training=True):
#     xc = tensor.tensor3('xc', dtype='int8')
#     mask = tensor.tensor4('mask', dtype=config.floatX)
#     y = tensor.matrix('y', dtype='int8')
#     y_mask = tensor.matrix('y_mask', dtype='int8')
# 
#     n_batch = xc.shape[2]
# 
#     emb = embeddings_layer(xc, tparams['Cemb'], options['dim_proj'])
# 
#     dist = emb
#     dist_mask = mask
# 
#     dist = dist * dist_mask
# 
#     for i in range(options['letter_layers']):
#         name = 'lstm_chars_%d' % (i + 1,)
# 
#         def _step(x_):
#             t = bidirectional_lstm_layer(tparams, x_, options, name)
#             return t
# 
#         dist, updates = theano.scan(_step, sequences=[dist], n_steps=dist.shape[0])
# 
#     proj2 = per_word_averaging_layer(dist, dist_mask)
# 
#     for i in range(options['word_layers']):
#         name = 'lstm_words_%d' % (i + 1,)
#         proj2 = bidirectional_lstm_layer(tparams, proj2, options, name)
# 
#     pred = softmax_layer(proj2, tparams['U'], tparams['b'], y_mask, maxw, training)
#     #pred = theano.printing.Print("pred", attrs=["shape"])(pred)
# 
#     f_pred_prob = theano.function([xc, mask, y_mask], pred, name='f_pred_prob', on_unused_input='ignore')
#     f_pred = theano.function([xc, mask, y_mask], pred.argmax(axis=2), name='f_pred', on_unused_input='ignore')
# 
#     def cost_scan_i(i, j, free_var):
#         return -tensor.log(i[tensor.arange(n_batch), j] + 1e-8)
# 
#     cost, _ = theano.scan(cost_scan_i, outputs_info=None, sequences=[pred, y, tensor.arange(n_batch)])
# 
#     cost = cost.mean()
# 
#     return xc, mask, y, y_mask, f_pred_prob, f_pred, cost
# 
# Path: nn_serialization.py
# def load_params(path, params):
#     logging.info("Loading model from file '%s'...", path)
#     pp = numpy.load(path)
#     for k in pp:
#         params[k] = pp[k]
#     path = "%s.pkl" % (path,)
#     logging.info("Loading model from file '%s'...", path)
#     with open(path, 'rb') as fin:
#         data = pickle.load(fin)
#         for k in ['dim_proj_chars', 'char_dict', 'pos_dict', 'word_dict']:
#             params[k] = data[k]
#     return params


from lstm import build_model
from modelio import *
from nn_params import *
from nn_optimizers import *
from nn_serialization import load_params
from flask import Flask, request, jsonify
from collections import defaultdict, Counter
import string
__author__ = 'rtownsend'


app = Flask(__name__)


model = None
max_word_count = 47#13 #get_max_word_count("Data/Gate.conll") + 12
max_word_length = get_max_word_length("Data/Gate.conll")
max_length = get_max_length("Data/Gate.conll")

def get_lstm(
    patience=10,  # Number of epoch to wait before early stop if no progress
    max_epochs=5000,  # The maximum number of epoch to run
    dispFreq=10,  # Display to stdout the training progress every N updates
    decay_c=0.0001,  # Weight decay for the classifier applied to the U weights.
    lrate=0.0001,  # Learning rate for sgd (not used for adadelta and rmsprop)
    optimizer=adadelta,  # sgd, adadelta and rmsprop available, sgd very hard to use, not recommanded (probably need momentum and decaying learning rate).
    encoder='lstm',  # TODO: can be removed must be lstm.

# Path: lstm.py
# def build_model(tparams, options, maxw, training=True):
#     xc = tensor.tensor3('xc', dtype='int8')
#     mask = tensor.tensor4('mask', dtype=config.floatX)
#     y = tensor.matrix('y', dtype='int8')
#     y_mask = tensor.matrix('y_mask', dtype='int8')
# 
#     n_batch = xc.shape[2]
# 
#     emb = embeddings_layer(xc, tparams['Cemb'], options['dim_proj'])
# 
#     dist = emb
#     dist_mask = mask
# 
#     dist = dist * dist_mask
# 
#     for i in range(options['letter_layers']):
#         name = 'lstm_chars_%d' % (i + 1,)
# 
#         def _step(x_):
#             t = bidirectional_lstm_layer(tparams, x_, options, name)
#             return t
# 
#         dist, updates = theano.scan(_step, sequences=[dist], n_steps=dist.shape[0])
# 
#     proj2 = per_word_averaging_layer(dist, dist_mask)
# 
#     for i in range(options['word_layers']):
#         name = 'lstm_words_%d' % (i + 1,)
#         proj2 = bidirectional_lstm_layer(tparams, proj2, options, name)
# 
#     pred = softmax_layer(proj2, tparams['U'], tparams['b'], y_mask, maxw, training)
#     #pred = theano.printing.Print("pred", attrs=["shape"])(pred)
# 
#     f_pred_prob = theano.function([xc, mask, y_mask], pred, name='f_pred_prob', on_unused_input='ignore')
#     f_pred = theano.function([xc, mask, y_mask], pred.argmax(axis=2), name='f_pred', on_unused_input='ignore')
# 
#     def cost_scan_i(i, j, free_var):
#         return -tensor.log(i[tensor.arange(n_batch), j] + 1e-8)
# 
#     cost, _ = theano.scan(cost_scan_i, outputs_info=None, sequences=[pred, y, tensor.arange(n_batch)])
# 
#     cost = cost.mean()
# 
#     return xc, mask, y, y_mask, f_pred_prob, f_pred, cost
# 
# Path: nn_serialization.py
# def load_params(path, params):
#     logging.info("Loading model from file '%s'...", path)
#     pp = numpy.load(path)
#     for k in pp:
#         params[k] = pp[k]
#     path = "%s.pkl" % (path,)
#     logging.info("Loading model from file '%s'...", path)
#     with open(path, 'rb') as fin:
#         data = pickle.load(fin)
#         for k in ['dim_proj_chars', 'char_dict', 'pos_dict', 'word_dict']:
#             params[k] = data[k]
#     return params


# Path: server.py
from lstm import build_model
from modelio import *
from nn_params import *
from nn_optimizers import *
from nn_serialization import load_params
from flask import Flask, request, jsonify
from collections import defaultdict, Counter
import string

__author__ = 'rtownsend'


app = Flask(__name__)


model = None
max_word_count = 47#13 #get_max_word_count("Data/Gate.conll") + 12
max_word_length = get_max_word_length("Data/Gate.conll")
max_length = get_max_length("Data/Gate.conll")

def get_lstm(
    patience=10,  # Number of epoch to wait before early stop if no progress
    max_epochs=5000,  # The maximum number of epoch to run
    dispFreq=10,  # Display to stdout the training progress every N updates
    decay_c=0.0001,  # Weight decay for the classifier applied to the U weights.
    lrate=0.0001,  # Learning rate for sgd (not used for adadelta and rmsprop)
    optimizer=adadelta,  # sgd, adadelta and rmsprop available, sgd very hard to use, not recommanded (probably need momentum and decaying learning rate).
    encoder='lstm',  # TODO: can be removed must be lstm.

    model_path='lstm_model.npz', # Where to load the model from