#!/usr/bin/env python
# encoding: utf-8

import mxnet as mx
import sys
import numpy as np
import time
from collections import namedtuple
import logging
from common import Data

def DNN_def(nLayers, nodesPerLayer):
    Param = namedtuple('Param', ["weight", "bias"]) # Currently, param(eters) are not used.
    param = []

    data = mx.sym.Variable('data')
    label = mx.sym.Variable('softmax_label')

    hidden = data
    for i in xrange(nLayers):
        #param.append(Param(weight = mx.sym.Variable("l%d_weight" % (i+1)),
        #                   bias   = mx.sym.Variable("l%d_bias" % (i+1))
        #                  ))
        #next_layer_z = mx.sym.FullyConnected(data=hidden, num_hidden=nodesPerLayer,
        #                                     weight=param[i].weight, bias=param[i].bias,
        #                                     name="Linear%d" % (i+1))
        next_layer_z = mx.sym.FullyConnected(data=hidden, num_hidden=nodesPerLayer,
                                             name="Linear%d" % (i+1))
        hidden = mx.sym.Activation(next_layer_z, act_type="sigmoid", name="Activation%d"%(i+1))

    sm = mx.sym.SoftmaxOutput(data=hidden, label=label, ignore_label=0, use_ignore=False,
                              name='softmax')
    return sm

#def get_initializer():
#    return mx.initializer.Xavier(magnitude=0.05)
#
#def do_traininit(module, data_train, data_val):
#
#    module.bind(data_shapes = data_train.provide_data,
#                label_shapes = data_train.provide_label,
#                for_training = True)
#    module.init_params(initializer=get_initializer())
#
#    module.init_optimizer(kvstore="local",
#                          optimizer="sgd",
#                          optimizer_params={'learning_rate'=0.01})
#
#    while True:
#        for data_batch in data_train:
#            module.forward_backward(data_batch)
#            module.update()


if __name__=="__main__":
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)

    # load data
    lld = Data('lld')
    lld.load_training_data()
    lld.load_test_data()

    #train_iter = mx.io.NDArrayIter(lld.feature_train, lld.label_train[:, 0], batch_size = batchsize)
    #test_iter  = mx.io.NDArrayIter(lld.feature_test, lld.label_test[:, 0], batch_size = batchsize)
    train_iter = mx.io.NDArrayIter(lld.feature_train, batch_size = batchsize)
    test_iter  = mx.io.NDArrayIter(lld.feature_test, batch_size = batchsize)
    train_iter.label = mx.io._init_data(lld.label_train[:, 0], allow_empty=True, default_name='softmax_label')
    test_iter.label  = mx.io._init_data(lld.label_test[:, 0], allow_empty=True, default_name='softmax_label')

    # Define Network Architectures
    nLayers = 3
    nodesPerLayer = 1024
    batchsize = 256
    sym = DNN_def(nLayers, nodesPerLayer)

    # Training the Model
    '''
    # To do
    #module = mx.mod.Module(sym)
    #do_training(module, data_train, data_val)
    '''
    model = mx.model.FeedForward(
        ctx = mx.cpu(0),
        symbol = sym,
        num_epoch = 10,
        learning_rate = 0.1,
        momentum = 0.9,
        wd = 0.00001,
    )
    model.fit(
        X = train_iter,
        eval_data = test_iter,
        batch_end_callback = mx.callback.Speedometer(batchsize, 200),
    )

    print model.score(test_iter)*100, "%"

@@ -1086,15 +1086,12 @@
 pe=%22
-sigmoid
+relu
 %22, n
@@ -1117,16 +1117,98 @@
 (i+1))%0A%0A
+    hidden = mx.sym.FullyConnected(data=hidden, num_hidden=5, name=%22outputLayer%22)%0A
     sm =
@@ -2166,16 +2166,398 @@
 _data()%0A
+    # Permutation%0A    np.random.seed(1234)%0A    p = np.random.permutation(lld.feature_train.shape%5B0%5D)%0A    X = lld.feature_train%5Bp%5D%0A    Y = lld.label_train%5Bp%5D%0A    lld.feature_train = X%0A    lld.label_train = Y%0A%0A    # Define Network Architectures%0A    nLayers = 3%0A    nodesPerLayer = 1024%0A    batchsize = 256%0A    sym = DNN_def(nLayers, nodesPerLayer)%0A%0A    # MXNet Iterator initialization
 %0A    #tr
@@ -3131,146 +3131,196 @@
 l')%0A
-%0A
     #
- Define Network Architectures%0A    nLayers = 3%0A    nodesPerLayer = 1024%0A    batchsize = 256%0A    sym = DNN_def(nLayers, nodesPerLayer)
+train_iter.next()%0A    #print train_iter.getdata()%5B0%5D.shape, train_iter.getlabel()%5B0%5D.shape%0A    #print train_iter.getdata()%5B0%5D.asnumpy()%5B:10,0%5D, train_iter.getlabel()%5B0%5D.asnumpy()%5B:10%5D
 %0A%0A  
@@ -3581,16 +3581,18 @@
 ate = 0.
+00
 1,%0A     
@@ -3827,8 +3827,49 @@
 00, %22%25%22%0A
+    print model.predict(test_iter).shape%0A

Fix output layer problems