'Make a prediction, using the seq2seq model, for the given input sequence Xin.
If model is not provided, create one (or use last created instance).
Return prediction, y
prediction = array of integers, giving output prediction.  Length = out_seq_len
y = array of shape [out_seq_len, out_max_int], giving logits for output prediction'

def predict(self, Xin, model=None, model_params=None, weights_input_fn=None):

    if (not model):
        model = (self.model_instance or self.setup_model('predict', model_params, weights_input_fn))
    if self.verbose:
        print(('Xin    =    %s' % str(Xin)))
    X = np.array(Xin).astype(np.uint32)
    assert (len(X) == self.in_seq_len)
    if self.verbose:
        print(('X    Input    shape=%s,    data=%s' % (X.shape, X)))
        print(('Expected    output    =    %s' % str(self.sequence_pattern.generate_output_sequence(X))))
    Yin = ([0] * self.out_seq_len)
    XY = np.append(X, np.array(Yin).astype(np.float32))
    XY = XY.reshape([(-1), (self.in_seq_len + self.out_seq_len)])
    if (self.verbose > 1):
        print(('XY    Input    shape=%s,    data=%s' % (XY.shape, XY)))
    res = model.predict(XY)
    res = np.array(res)
    if (self.verbose > 1):
        print(('prediction    shape    =    %s' % str(res.shape)))
    y = res.reshape(self.out_seq_len, self.n_output_symbols)
    prediction = np.argmax(y, axis=1)
    if self.verbose:
        print(('Predicted    output    sequence:    %s' % str(prediction)))
    return (prediction, y)
