Skip to content

Commit

Permalink
Update regression-example.jl (#148)
Browse files Browse the repository at this point in the history
adds batch size, selection of optimizers, possibility for initialization
  • Loading branch information
Michael Creel authored and pluskid committed Oct 4, 2016
1 parent 45c1a6c commit 8453c0a
Showing 1 changed file with 33 additions and 32 deletions.
65 changes: 33 additions & 32 deletions examples/regression-example.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,60 +3,61 @@ This script shows how a simple MLP net may be used
for regression. It shows how data in memory may be
used for training and evaluation, and how to obtain
the predictions from the trained net.
TO DO:
* specify batch size, and allow different sizes
for the training and evaluation sets
* tanh activation does not seem to work properly,
investigate
=#
using MXNet
using Distributions
using PyPlot

# data generating process for exogenous inputs
generate_inputs(media, var, tam) = rand(MvNormal(media, var), tam)

# function that maps inputs to outputs
f1(data) = sin(data[1,:]).*sin(data[2,:])./(data[1,:].*data[2,:])
# data generating process
generate_inputs(mean, var, size) = rand(MvNormal(mean, var), size)
output(data) = sin(data[1,:]).*sin(data[2,:])./(data[1,:].*data[2,:])

# parameters for input d.g.p.
# create training and evaluation data sets
mean=[0.0;0.0]
var=[1.0 0.0;0.0 1.0]

# create training and evaluation data sets
TrainInput = generate_inputs(mean, var, 5000)
TrainOutput = f1(TrainInput)
ValidationInput = generate_inputs(mean, var, 5000)
ValidationOutput = f1(ValidationInput)
samplesize = 5000
TrainInput = generate_inputs(mean, var, samplesize)
TrainOutput = output(TrainInput)
ValidationInput = generate_inputs(mean, var, samplesize)
ValidationOutput = output(ValidationInput)

# how to set up data providers using data in memory
trainprovider = mx.ArrayDataProvider(:data => TrainInput, :label => TrainOutput)
evalprovider = mx.ArrayDataProvider(:data => ValidationInput, :label => ValidationOutput)
batchsize = 100 # can adjust this later, but must be defined now for next line
trainprovider = mx.ArrayDataProvider(:data => TrainInput, batch_size=batchsize, shuffle=true, :label => TrainOutput)
evalprovider = mx.ArrayDataProvider(:data => ValidationInput, batch_size=batchsize, shuffle=true, :label => ValidationOutput)

# create a single hidden layer MPL
# create a two hidden layer MPL: try varying num_hidden, and change tanh to relu,
# or add/remove a layer
data = mx.Variable(:data)
label = mx.Variable(:label)
fc1 = mx.FullyConnected(data = data, name=:fc1, num_hidden=20)
act1 = mx.Activation(data = fc1, name=:relu, act_type=:relu)
fc2 = mx.FullyConnected(data = act1, name=:fc2, num_hidden=1)
net = @mx.chain mx.FullyConnected(data = data, num_hidden=10) =>
mx.Activation(act_type=:tanh) =>
mx.FullyConnected(num_hidden=3) =>
mx.Activation(act_type=:tanh) =>
mx.FullyConnected(num_hidden=1)

# cost is squared error loss
cost = mx.LinearRegressionOutput(data=fc2, label=label, name = :loss)
# squared error loss is appropriate for regression, don't change
cost = mx.LinearRegressionOutput(data = net, label=label)

# final model definition
# final model definition, don't change, except if using gpu
model = mx.FeedForward(cost, context=mx.cpu())

# set up the optimizer
optimizer = mx.SGD(lr=0.1, momentum=0.9, weight_decay=0.00001)
# set up the optimizer: select one, explore parameters, if desired
#optimizer = mx.SGD(lr=0.01, momentum=0.9, weight_decay=0.00001)
optimizer = mx.ADAM()

# train, reporting loss for training and evaluation sets
mx.fit(model, optimizer, eval_metric=mx.MSE(), trainprovider, eval_data=evalprovider, n_epoch = 1000)
# initial training with small batch size, to get to a good neighborhood
batchsize = 100
mx.fit(model, optimizer, initializer=mx.NormalInitializer(0.0,0.1), eval_metric=mx.MSE(), trainprovider, eval_data=evalprovider, n_epoch = 500)
# more training with the full sample
batchsize = samplesize
mx.fit(model, optimizer, eval_metric=mx.MSE(), trainprovider, eval_data=evalprovider, n_epoch = 500)

# obtain predictions
fit = mx.predict(model, evalprovider)
plotprovider = mx.ArrayDataProvider(:data => ValidationInput, :label => ValidationOutput)
fit = mx.predict(model, plotprovider)
plot(ValidationOutput,fit',".")
xlabel("true")
ylabel("predicted")
title("outputs: true versus predicted. 45º line is what we hope for")

0 comments on commit 8453c0a

Please sign in to comment.