Plots.jl/examples/meetup/nnet.ipynb
Thomas Breloff 20348645a3 pyplot fixes
2015-10-25 00:44:18 -04:00

702 lines
59 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"ENV[\"PYTHONPATH\"] = joinpath(Pkg.dir(\"Qwt\"), \"src\", \"python\");"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO: Recompiling stale cache file /Users/tom/.julia/lib/v0.4/Plots.ji for module Plots.\n"
]
},
{
"data": {
"text/plain": [
"gridxy (generic function with 1 method)"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"using Plots; pyplot()\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": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"target (generic function with 1 method)"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# these are the functions we want to classify\n",
"scalar = 4 # larger is harder... start with 3\n",
"f1(x) = 0.6sin(scalar * x) + 0.1\n",
"f2(x) = f1(x) - 0.2\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": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[Plots.jl] Initializing backend: pyplot"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"Plot{Plots.PyPlotPackage() n=4}"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
}
],
"source": [
"# pick the plotting limits\n",
"lim = (-1,1)\n",
"funcs = [f1, f2]\n",
"n = 40\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,[:blue :red]))\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": [
"# That looks tricky... lets build a neural net!"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO: Recompiling stale cache file /Users/tom/.julia/lib/v0.4/OnlineStats.ji for module OnlineStats.\n",
"INFO: Recompiling stale cache file /Users/tom/.julia/lib/v0.4/OnlineAI.ji for module OnlineAI.\n"
]
},
{
"data": {
"text/plain": [
"NeuralNet{\n",
" params: NetParams{OnlineAI.AdamModel(1.0e-8,0.0003,0.9,0.999,1.0e-6) NoDropout OnlineAI.L2CostModel()}\n",
" solverParams: OnlineAI.SolverParams(1000,1000,10000,-1,[:x,:xhat,:y,:Σ,:a],100,1.0e-5,OnlineAI.donothing)\n",
" layers:\n",
" NormalizedLayer{2=>2 OnlineAI.TanhActivation() p=1.0 ‖δΣ‖₁=0.0 ‖δy‖₁=0.0 }\n",
" NormalizedLayer{2=>2 OnlineAI.TanhActivation() p=1.0 ‖δΣ‖₁=0.0 ‖δy‖₁=0.0 }\n",
" NormalizedLayer{2=>2 OnlineAI.TanhActivation() p=1.0 ‖δΣ‖₁=0.0 ‖δy‖₁=0.0 }\n",
" NormalizedLayer{2=>2 OnlineAI.TanhActivation() p=1.0 ‖δΣ‖₁=0.0 ‖δy‖₁=0.0 }\n",
" NormalizedLayer{2=>1 OnlineAI.TanhActivation() p=1.0 ‖δΣ‖₁=0.0 ‖δy‖₁=0.0 }\n",
"}\n"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"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(η=3e-4)\n",
"\n",
"net = buildTanhClassificationNet(\n",
" 2, # number of inputs\n",
" 1, # number of outputs\n",
" [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": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/usr/local/lib/python2.7/site-packages/matplotlib/pyplot.py:424: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).\n",
" max_open_warning, RuntimeWarning)\n"
]
}
],
"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": 6,
"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 = plot([totalCost(net, testdata)], m=3, ylab=\"Error\")\n",
"gui(errviz)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"ename": "LoadError",
"evalue": "LoadError: KeyError: get_data not found\nwhile loading In[7], in expression starting on line 3",
"output_type": "error",
"traceback": [
"LoadError: KeyError: get_data not found\nwhile loading In[7], in expression starting on line 3",
"",
" in getindex at /Users/tom/.julia/v0.4/PyCall/src/PyCall.jl:240",
" in getindex at /Users/tom/.julia/v0.4/PyCall/src/PyCall.jl:245",
" in push! at /Users/tom/.julia/v0.4/Plots/src/utils.jl:236",
" in push! at /Users/tom/.julia/v0.4/Plots/src/utils.jl:256",
" in push! at /Users/tom/.julia/v0.4/Plots/src/utils.jl:262",
" in update! at /Users/tom/.julia/v0.4/OnlineAI/src/nnet/visualize.jl:51",
" [inlined code] from In[7]:14",
" in anonymous at no file:10"
]
}
],
"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",
" push!(errviz, totalCost(net, testdata)) |> gui\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, line=([2 2 5 5], [:blue :red], [: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 = 20)"
]
},
{
"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",
"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": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"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": [
"using Plots; immerse()\n",
"p = plot(rand(10))"
]
},
{
"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
}