643 lines
14 KiB
Plaintext
643 lines
14 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"ENV[\"PYTHONPATH\"] = joinpath(Pkg.dir(\"Qwt\"), \"src\", \"python\");\n",
|
||
"\n",
|
||
"using Plots, Distributions; qwt()\n",
|
||
"default(size=(500,300), leg=false)\n",
|
||
"\n",
|
||
"# creates x/y vectors which can define a grid in a zig-zag pattern\n",
|
||
"function gridxy(lim, n::Int)\n",
|
||
" xs = linspace(lim..., n)\n",
|
||
" xypairs = vec([(x,y) for x in vcat(xs,reverse(xs)), y in xs])\n",
|
||
" Plots.unzip(xypairs)\n",
|
||
"end"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# The problem... can we classify the functions?"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# these are the functions we want to classify\n",
|
||
"scalar = 5 # larger is harder\n",
|
||
"noise = Distributions.Normal(0, 0.05)\n",
|
||
"\n",
|
||
"# # problem #1... non-overlapping\n",
|
||
"f1(x) = 0.6sin(scalar * x) + 0.1 + rand(noise)\n",
|
||
"f2(x) = f1(x) - 0.3\n",
|
||
"\n",
|
||
"# problem #2... overlapping\n",
|
||
"# f1(x) = 0.6sin(scalar * x)\n",
|
||
"# f2(x) = 0.6sin(scalar * (x+0.1))\n",
|
||
"\n",
|
||
"# our target function is ∈ {-1,1}\n",
|
||
"target(f) = f == f1 ? 1.0 : -1.0"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# On to the fun..."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# pick the plotting limits\n",
|
||
"lim = (-1,1)\n",
|
||
"funcs = [f1, f2]\n",
|
||
"n = 20\n",
|
||
"gridx, gridy = gridxy(lim, n)\n",
|
||
"# default(xlim = lim, ylim = lim)\n",
|
||
"\n",
|
||
"function initialize_plot(funcs, lim, gridx, gridy; kw...)\n",
|
||
" # show the grid\n",
|
||
" plot([gridx gridy], [gridy gridx], c=:black; kw...)\n",
|
||
"\n",
|
||
" # show the funcs\n",
|
||
" plot!(funcs, lim..., l=(4,[:royalblue :orangered]))\n",
|
||
"end\n",
|
||
"\n",
|
||
"# kick off an animation... we can save frames whenever we want, lets save the starting frame\n",
|
||
"function initialize_animation()\n",
|
||
" anim = Animation()\n",
|
||
" frame(anim)\n",
|
||
" anim\n",
|
||
"end\n",
|
||
"\n",
|
||
"# lets see what we're dealing with...\n",
|
||
"p = initialize_plot(funcs, lim, gridx, gridy)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Lets build a neural net!"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"using OnlineAI\n",
|
||
"\n",
|
||
"# gradientModel = SGDModel(η=1e-4, μ=0.8, λ=0)\n",
|
||
"# gradientModel = AdagradModel(η=1e-1)\n",
|
||
"# gradientModel = AdadeltaModel(η=0.1, ρ=0.99, λ=0)\n",
|
||
"# gradientModel = AdamModel(η=1e-4, λ=1e-8)\n",
|
||
"gradientModel = AdaMaxModel(η=1e-4, ρ1=0.9, ρ2=0.9)\n",
|
||
"\n",
|
||
"# learningRateModel = FixedLearningRate()\n",
|
||
"learningRateModel = AdaptiveLearningRate(gradientModel, 2e-2, 0.05, wgt=ExponentialWeighting(30))\n",
|
||
"\n",
|
||
"function OnlineAI.initialWeights(nin::Int, nout::Int, activation::Activation)\n",
|
||
" 0.1randn(nout, nin) / sqrt(nin) + eye(nout, nin)\n",
|
||
"end\n",
|
||
"\n",
|
||
"net = buildTanhClassificationNet(\n",
|
||
" 2, # number of inputs\n",
|
||
" 1, # number of outputs\n",
|
||
" [2,2,2,2,2,2], # hidden layers structure\n",
|
||
" params = NetParams(gradientModel = gradientModel)\n",
|
||
")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Update our model and the visualization"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# set up a visualization of the projections\n",
|
||
"layers = filter(l -> l.nout == 2, net.layers[1:end-1])\n",
|
||
"num_hidden_layers = length(layers)\n",
|
||
"plts = [initialize_plot(funcs, lim, gridx, gridy, title=\"Hidden Layer $i\") for i in 1:num_hidden_layers]\n",
|
||
"sz = round(Int, sqrt(num_hidden_layers) * 400)\n",
|
||
"projectionviz = subplot(plts..., n=num_hidden_layers, size=(sz,sz))\n",
|
||
"\n",
|
||
"# setup animation, then show the plots in a window\n",
|
||
"anim = initialize_animation()\n",
|
||
"gui()\n",
|
||
"\n",
|
||
"# create another visualization to track the internal progress of the neural net\n",
|
||
"progressviz = track_progress(net, fields=[:w,:b,:Σ,:a], size=(num_hidden_layers*300,800), m=2, w=0);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"dist = Distributions.Uniform(lim...)\n",
|
||
"# dist = Distributions.Uniform(-0.6,0.6)\n",
|
||
"progressgui = false\n",
|
||
"\n",
|
||
"function test_data(n, lim, funcs)\n",
|
||
" xs = linspace(lim..., n)\n",
|
||
" x1, x2 = [hcat(xs,map(f,xs)) for f in funcs]\n",
|
||
" y1, y2 = ones(n), -ones(n)\n",
|
||
" DataPoints(vcat(x1,x2), vcat(y1,y2))\n",
|
||
"end\n",
|
||
"\n",
|
||
"testn = 100\n",
|
||
"testdata = test_data(testn, lim, funcs)\n",
|
||
"\n",
|
||
"function activateHidden(net, layers, x, y, seriesidx, plts)\n",
|
||
" n = length(x)\n",
|
||
" p = length(layers)\n",
|
||
" projx, projy = zeros(n,p), zeros(n,p)\n",
|
||
" for i in 1:n\n",
|
||
" # feed the data through the neural net\n",
|
||
" OnlineAI.forward!(net, [x[i], y[i]])\n",
|
||
" \n",
|
||
" # grab the net's activations at each layer\n",
|
||
" for j in 1:p\n",
|
||
" projx[i,j], projy[i,j] = layers[j].Σ\n",
|
||
" end\n",
|
||
" end\n",
|
||
" \n",
|
||
" # now we can update the plots\n",
|
||
" for j in 1:p\n",
|
||
" plts[j][seriesidx] = (vec(projx[:,j]), vec(projy[:,j]))\n",
|
||
" end\n",
|
||
"end\n",
|
||
"\n",
|
||
"# final plot to track test error\n",
|
||
"errviz = subplot([totalCost(net, testdata) gradientModel.η], m=3, title=[\"Error\" \"η\"], n=2,nc=1, pos=(800,0))\n",
|
||
"gui(errviz)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"iterations_per_frame = 1000\n",
|
||
"total_frames = 100\n",
|
||
"for frm in 1:total_frames\n",
|
||
" # pick one of the functions at random, sample from the x line, then update the\n",
|
||
" # neural net with [x, f(x)] as the inputs\n",
|
||
" for i in 1:iterations_per_frame\n",
|
||
" f = sample(funcs)\n",
|
||
" x = rand(dist)\n",
|
||
" y = target(f)\n",
|
||
" update!(net, Float64[x, f(x)], [y])\n",
|
||
" end\n",
|
||
" \n",
|
||
" # update the progress visualization\n",
|
||
" update!(progressviz, true, show=progressgui)\n",
|
||
" \n",
|
||
" # update the error plot\n",
|
||
" err = totalCost(net, testdata)\n",
|
||
" push!(errviz.plts[1], err)\n",
|
||
" update!(learningRateModel, err)\n",
|
||
" push!(errviz.plts[2], gradientModel.η)\n",
|
||
" gui(errviz)\n",
|
||
"\n",
|
||
" # update the projections\n",
|
||
" x = linspace(lim..., 70)\n",
|
||
" for (seriesidx, (x,y)) in enumerate([(gridx,gridy), (gridy,gridx), (x,map(f1,x)), (x,map(f2,x))])\n",
|
||
" activateHidden(net, layers, x, y, seriesidx, projectionviz.plts)\n",
|
||
" end\n",
|
||
" \n",
|
||
" # show/update the plot\n",
|
||
" gui(projectionviz)\n",
|
||
" frame(anim)\n",
|
||
" sleep(0.001)\n",
|
||
"end\n",
|
||
"\n",
|
||
"# displays the progress if there's no gui\n",
|
||
"progressgui || progressviz.subplt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# # show stacked and linked histograms of the predictions for each class\n",
|
||
"xs = OnlineAI.unzip(testdata)[1]\n",
|
||
"yhat = predict(net, xs)\n",
|
||
"yhat1, yhat2 = yhat[1:testn], yhat[testn+1:end]\n",
|
||
"subplot(histogram(yhat1), histogram(yhat2), nc=1, linkx=true, title=[\"f1 prediction\" \"f2 prediction\"])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"xs = xs[1:testn]\n",
|
||
"plot(xs, hcat(map(f1,xs), map(f2,xs), yhat1, yhat2), leg=true,\n",
|
||
" line=([2 2 5 5], [:royalblue :orangered], [:solid :solid :dash :dash]))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Animate!"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"gif(anim, fps = 10)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"source": [
|
||
"# Network viz"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# show the network (uses Qwt, visualize isn't available unless you import it)\n",
|
||
"ENV[\"PYTHONPATH\"] = joinpath(Pkg.dir(\"Qwt\"), \"src\", \"python\");\n",
|
||
"import Qwt\n",
|
||
"viz = visualize(net);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# update the net representation with weights, etc\n",
|
||
"update!(viz)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"source": [
|
||
"# testing..."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"selection[3][2]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"p[4][2] |> length"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"gui(progressviz.subplt)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"histogram(yhat1)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"progressviz.subplt.plts[1].seriesargs[1][:serieshandle][:get_offsets]()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"learningRateModel"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"update!(d,5)\n",
|
||
"diff(d)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"using Plots\n",
|
||
"p1 = plot(rand(20))\n",
|
||
"p2 = plot(rand(10))\n",
|
||
"p3 = scatter(rand(100))\n",
|
||
"p4 = plot(rand(1000))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"subplot(p1,p2,p3,p4, nr=1, leg=false)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# ENV[\"MPLBACKEND\"] = \"qt4agg\"\n",
|
||
"using Plots; pyplot()\n",
|
||
"p = scatter(rand(10))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"p.seriesargs[1][:serieshandle][:get_offsets]()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"PyPlot.backend"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"gui()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"append!(p,1,rand(10))\n",
|
||
"gui()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"sp = progressviz.subplt.plts[1].o.widget[:minimumSizeHint]()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": false
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"testn = 100\n",
|
||
"xs = linspace(lim..., testn)\n",
|
||
"x1, x2 = [hcat(xs,map(f,xs)) for f in funcs]\n",
|
||
"y1, y2 = ones(testn), -ones(testn)\n",
|
||
"yhat1, yhat2 = [vec(predict(net, x)) for x in (x1,x2)]\n",
|
||
"DataPoints(vcat(x1,x2), vcat(y1,y2))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"outputs": [],
|
||
"source": []
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Julia 0.4.0",
|
||
"language": "julia",
|
||
"name": "julia-0.4"
|
||
},
|
||
"language_info": {
|
||
"file_extension": ".jl",
|
||
"mimetype": "application/julia",
|
||
"name": "julia",
|
||
"version": "0.4.0"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 0
|
||
}
|