MLP on housing data
This example replicates the housing data example from the Knet.jl readme. Although wecould have reused more of Flux (see the mnist example), the library’s abstractions are very lightweight and don’t force you into any particular strategy.
Load the necessary packages.
using Flux, Statistics, DelimitedFiles
using Flux: Params, gradient
using Flux.Optimise: update!
using DelimitedFiles, Statistics
using Parameters: @with_kw
Struct to define hyperparameters.
@with_kw mutable struct Hyperparams
lr::Float64 = 0.1 # learning rate
split_ratio::Float64 = 0.1 # Train Test split ratio, define percentage of data to be used as Test data
end
Define the function that donwloads the housing data.
function get_processed_data(args)
isfile("housing.data") ||
download("https://raw.githubusercontent.com/MikeInnes/notebooks/master/housing.data",
"housing.data")
rawdata = readdlm("housing.data")'
# The last feature is our target -- the price of the house.
split_ratio = args.split_ratio # For the train test split
x = rawdata[1:13,:]
y = rawdata[14:14,:]
# Normalise the data
x = (x .- mean(x, dims = 2)) ./ std(x, dims = 2)
# Split into train and test sets
split_index = floor(Int,size(x,2)*split_ratio)
x_train = x[:,1:split_index]
y_train = y[:,1:split_index]
x_test = x[:,split_index+1:size(x,2)]
y_test = y[:,split_index+1:size(x,2)]
train_data = (x_train, y_train)
test_data = (x_test, y_test)
return train_data,test_data
end
Set struct to define model.
mutable struct model
W::AbstractArray
b::AbstractVector
end
Function to predict output from given parameters
predict(x, m) = m.W*x .+ m.b
Set Mean Squared Error as the loss function.
meansquarederror(ŷ, y) = sum((ŷ .- y).^2)/size(y, 2)
Define the train function.
function train(; kws...)
# Initialize the Hyperparamters
args = Hyperparams(; kws...)
# Load the data
(x_train,y_train),(x_test,y_test) = get_processed_data(args)
# The model
m = model((randn(1,13)),[0.])
loss(x, y) = meansquarederror(predict(x, m), y)
## Training
η = args.lr
θ = params([m.W, m.b])
for i = 1:500
g = gradient(() -> loss(x_train, y_train), θ)
for x in θ
update!(x, -g[x]*η)
end
if i%100==0
@show loss(x_train, y_train)
end
end
# Predict the RMSE on the test set
err = meansquarederror(predict(x_test, m),y_test)
println(err)
end
Finally, train the model.
cd(@__DIR__)
train()
Output:
loss(x_train, y_train) = 1.5581866732347647e48
loss(x_train, y_train) = 5.346256832813508e93
loss(x_train, y_train) = 1.8343413285051722e139
loss(x_train, y_train) = 6.293764431237339e184
loss(x_train, y_train) = 2.1594383826148733e230
1.7081066852828434e230