# -------------------------------------------------------------
# Mxnet in R
# -------------------------------------------------------------

suppressMessages(library(mxnet))

# load train.csv
DstTrain <- read.csv('../input/train.csv', stringsAsFactors = FALSE, na.strings = c("NA", ""))
# load test.csv
DstTest  <- read.csv('../input/test.csv', stringsAsFactors = FALSE, na.strings = c("NA", ""))

# convert to matrix
DstTrain <- data.matrix(DstTrain)
DstTest <- data.matrix(DstTest)

# split x and y data
xDstTrain <- DstTrain[,-1]
yDstTrain <- DstTrain[,1]

# Normalization
xDstTrain <- t(xDstTrain/255)
DstTest <- t(DstTest/255)

# network structure
data <- mx.symbol.Variable("data")
fc1 <- mx.symbol.FullyConnected(data, name="fc1", num_hidden=128)
act1 <- mx.symbol.Activation(fc1, name="relu1", act_type="relu")
fc2 <- mx.symbol.FullyConnected(act1, name="fc2", num_hidden=64)
act2 <- mx.symbol.Activation(fc2, name="relu2", act_type="relu")
fc3 <- mx.symbol.FullyConnected(act2, name="fc3", num_hidden=10)
softmax <- mx.symbol.SoftmaxOutput(fc3, name="sm")

# training
devices <- mx.cpu()

# the mxnet model
mx.set.seed(0)
mxModel <- mx.model.FeedForward.create(softmax, 
        X=xDstTrain, 
        y=yDstTrain,
        ctx=devices, 
        num.round=10, 
        array.batch.size=100,
        learning.rate=0.07, 
        momentum=0.9,  
        eval.metric=mx.metric.accuracy,
        initializer=mx.init.uniform(0.07),
        epoch.end.callback=mx.callback.log.train.metric(100)
    )
    
# Prediction and Submitting
Prediction <- predict(mxModel, DstTest)

# get the result labels 
labelPrediction <- max.col(t(Prediction)) - 1
table(labelPrediction)

# create the submition file
result <- data.frame(ImageId=1:ncol(DstTest), Label=labelPrediction)
write.csv(result, file='result.csv', row.names=FALSE,  quote=FALSE)
