-
Notifications
You must be signed in to change notification settings - Fork 32
/
index.html
273 lines (250 loc) · 11.3 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
<!DOCTYPE html>
<html lang="en">
<head>
<title>Neural networks in 3d with webGL</title>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=yes, minimum-scale=0.3, maximum-scale=2.0">
<meta name="description" content="Visualizing neural networks in 3d">
<meta name="twitter:card" value="summary_large_image">
<meta name="twitter:title" content="Visualizing neural networks in 3d">
<meta name="twitter:description" content="Play with level surfaces of a simple neural network right in your browser">
<meta name="twitter:url" content="https://arogozhnikov.github.io/3d_nn">
<meta name="twitter:image" content="https://raw.githubusercontent.com/arogozhnikov/3d_nn/master/images/screen_capture.png">
<meta property="og:type" content="article" />
<meta property="og:title" content="Visualizing neural networks in 3d" />
<meta property="og:description" content="Play with level surfaces of a simple neural network right in your browser" />
<meta property="og:url" content="https://arogozhnikov.github.io/3d_nn" />
<meta property="og:image" content="https://raw.githubusercontent.com/arogozhnikov/3d_nn/master/images/screen_capture.png" />
<style type="text/css">
body {
background-color: black;
margin: 0;
padding: 0;
min-width: 800px;
color: #bbb;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
}
a {
color: skyblue;
}
.demo-container{
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
#canvas_container canvas{
margin: 20px;
}
.control_container{
margin-top: 20px;
text-align: center;
}
#main_controls{
margin: 10px;
}
table.control-table {
margin: 20px auto;
}
table.control-table td.weight-control{
width: 30px;
height: 30px;
border-radius: 50%;
border: 1px solid black;
vertical-align: middle;
text-align: center;
}
.button-control{
display: inline-block;
padding: 10px;
background-color: #555;
border-radius: 2px;
cursor: pointer;
font-weight: bold;
}
.button-control:hover{
background-color: #777;
}
#randomize_button{
background-color: #474;
}
#randomize_button:hover{
background-color: #696;
}
.invisible{
display: none;
}
.description{
color: #aaa;
max-width: 800px;
margin: 15px auto;
}
.control_group{
margin: 10px;
display: inline-block;
}
</style>
</head>
<body>
<div class='description'>
<h1>Marching neural network</h1>
<h2>Visualizing level surfaces of a neural network with raymarching</h2>
<p>
Artificial neural networks became very popular in recent years,
mostly because of their success in tasks of image and speech recognition.
Research in this area started more than 60 years ago and many different network architectures were
developed during first decades of research, the only architecture that became popular in applications is MLP (<a href='https://en.wikipedia.org/wiki/Multilayer_perceptron'>multilayer perceptron</a>)
— parametrized multilayer functions trained (optimized) with variations of gradient descent.
Later based on MLP approach of training application-specific architectures emerged (such as convolutional and recurrent networks).
</p>
<p>
Probably it is a good idea to understand the behavior of a neural network by visualizing it.
While dependencies modelled in machine learning, in particular by neural networks, are multidimensional,
we are limited in our visualization abilities to three dimensions.
</p>
<p>
In the demo below you can play with a very small MLP with three inputs (x, y, z) and observe resulting functions
(just to remind, MLP is a neat function) to see how flexible it is.
</p>
<p>
<strong>Visualization requires not-too-old browser and GPU acceleration. Best on laptops and PCs, but also works on modern mobile devices.</strong>
</p>
</div>
<div class='demo-container'>
<div id="canvas_container">
<div id='not_working_notification' style="font-size: 1.6em; color: #DAA; ">
<p>
If you see this message, your browser / device <br /> doesn't support this beautiful demo.
</p>
<p>
Try more powerful device!
</p>
</div>
<!-- canvas is here -->
</div>
<div class='control_container'>
<div>
<h2>Weights of the network</h2>
<small>
red is 1, blue is -1, <strong>use mouse wheel</strong> to change weights
</small>
</div>
<div id='control_container'>
</div>
<div style='text-align: center;'>
<span class='button-control' id='randomize_button'>Randomize weights!</span>
</div>
</div>
</div>
<div class='control_container'>
<label class='control_group'>
<input type="checkbox" name="show_surface_control" id="show_surface_control" checked="checked" />
show surface
</label>
<label class='control_group'>
<input type="checkbox" name="show_sparks_control" id="show_sparks_control" checked="checked" />
show sparks
</label>
<label class='control_group'>
<input type="checkbox" name="show_axes_control" id="show_axes_control" checked="checked" />
show axes
</label>
<span class='control_group'>
<div>
<input type="checkbox" checked="checked" name="animate_checkbox" id="animate_checkbox" />
<label for="animate_checkbox">animate level of surface</label>
</div>
<div class='invisible' id='surface-control-group'>
level of surface: <span id='level_display'> </span> <br />
<input type="range" name="animate_level" id="animate_level" min="0" max="1" step="0.01" />
</div>
</span>
</div>
<div class='control_container'>
<label class='control_group'>
camera azimuth <br />
<input type="range" name="camera_azimuth_control" id="camera_azimuth_control" min="-3.14" max="3.14" step="0.05" value="0.7" />
</label>
<label class='control_group'>
camera altitude <br />
<input type="range" name="camera_altitide_control" id="camera_altitide_control" min="-1.57" max="1.57" step="0.02" value='0.2' />
</label>
<span class='button-control' id='makegif_button' >Record a gif! <br/> <small>takes a while</small></span>
<span class='button-control' id='makemov_button' >Record a video! <br /> <small>chromium browsers only</small></span>
</div>
<div class='description'>
<p>
In this demonstration you can play with a simple neural network in 3 spacial dimensions
and visualize the functions the network produces (those are quite interesting despite the simplicity of a network, just click 'randomize weights' button several times).
</p>
<p>
Animated <strong>surfaces</strong> are level surfaces of a neural network.
You can stop animation and choose level of surface yourself, note that demo shows surfaces with all equidistant levels that differ by integer: <br />
f(x) = ... , level-1, level, level+1, ... <br />
that is why animation is periodic.
</p>
<p>
Sparks that are following level surfaces demonstrate the regions with rapid change (small gradient),
sparks' color demonstrates the level of surface they are following (red is higher).
As the level is changing, the color of sparks also changes (from blue to red).
</p>
<h2>Architecture of the network</h2>
<p>
Network has 4 inputs: 3 spacial inputs (x, y, z) + intercept term (1), 8 hidden neurons in a single hidden layer (h<sub>1</sub>, ..., h<sub>8</sub>) and a single output.
Weights of the network are connections between inputs and neurons in a hidden layer, and between neurons in a hidden layer and output.
Tanh is used as an activation in hidden layer.
</p>
<h2>Manipulating the network</h2>
<p>
Circles in the scheme correspond to weights (parmeters) of a network and describe the strength of connection between neurons, red is +1, blue is -1.
You can change the weights: position cursor over any circle and use mouse wheel.
</p>
<h2>Visualization technique</h2>
<p>
This demonstration employs a variation of <a href='https://en.wikipedia.org/wiki/Volume_ray_casting'>raymarching technique</a> in computer graphics
(also known as volume ray casting).
</p>
<p>
It is highly recommended to have a good GPU-acceleration to enjoy the picture,
because in raymarching everything is computed with shaders only (and neural network is calculated with shaders as well).
</p>
<p>
Update: I've simplified the technique to ray-scanning + hord-like method. It is both faster and produces visually more consistent picture.
</p>
<h2>
Inspiration
</h2>
<p>
Inspired by <a href='http://iquilezles.org/www/articles/raymarchingdf/raymarchingdf.htm'>works</a> by Inigo Quilez on raymarching singed distance fields
and his <a href='https://www.shadertoy.com/user/iq'>shadertoy</a> demos.
And also by Johann Korndorfer's <a href='https://www.youtube.com/watch?v=s8nFqwOho-s'>demo talk at NVScene</a>.
</p>
<h2>
Links
</h2>
<ul>
<li> <a href='http://cs.stanford.edu/people/karpathy/convnetjs/'>Convnet.js demonstrations</a> by Andrej Karpathy </li>
<li> <a href='http://arogozhnikov.github.io/2016/06/24/gradient_boosting_explained.html'>Gradient Boosting explained in 3d</a> </li>
<li> <a href='http://arogozhnikov.github.io/2016/12/19/markov_chain_monte_carlo.html'>Monte Carlo explained in 3d</a> </li>
<li> <a href='http://arogozhnikov.github.io/2016/04/28/demonstrations-for-ml-courses.html'>Other awesome ML demonstrations</a> </li>
</ul>
<p style="margin: 2em 0px;">
Made by <a href='http://github.com/arogozhnikov'>Alex Rogozhnikov</a> (<a href='http://arogozhnikov.github.io/'>blog</a>).
Source of this demo can be found in <a href='https://github.com/arogozhnikov/3d_nn'>repository</a>.
</p>
<!-- Buttons for github -->
<div style='display: flex; justify-content: space-evenly; padding: 30px;'>
<a class="github-button" href="https://github.com/arogozhnikov/3d_nn" data-icon="octicon-star" data-size="large" data-show-count="true" aria-label="Star arogozhnikov/3d_nn on GitHub">Star</a>
<a class="github-button" href="https://github.com/arogozhnikov/3d_nn/fork" data-icon="octicon-repo-forked" data-size="large" data-show-count="true" aria-label="Fork arogozhnikov/3d_nn on GitHub">Fork</a>
<a class="github-button" href="https://github.com/arogozhnikov" data-size="large" data-show-count="true" aria-label="Follow @arogozhnikov on GitHub">Follow @arogozhnikov</a>
</div>
</div>
<script src="utils/three.js"></script>
<script src='utils/CCapture.all.min.js' ></script>
<script src='nn3d.js' ></script>
<!-- Yandex.Metrika counter --> <script type="text/javascript"> (function (d, w, c) { (w[c] = w[c] || []).push(function() { try { w.yaCounter32426790 = new Ya.Metrika({ id:32426790, clickmap:true, trackLinks:true, accurateTrackBounce:true }); } catch(e) { } }); var n = d.getElementsByTagName("script")[0], s = d.createElement("script"), f = function () { n.parentNode.insertBefore(s, n); }; s.type = "text/javascript"; s.async = true; s.src = "https://mc.yandex.ru/metrika/watch.js"; if (w.opera == "[object Opera]") { d.addEventListener("DOMContentLoaded", f, false); } else { f(); } })(document, window, "yandex_metrika_callbacks"); </script> <noscript><div><img src="https://mc.yandex.ru/watch/32426790" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <!-- /Yandex.Metrika counter -->
<!-- Buttons: -->
<script async defer src="https://buttons.github.io/buttons.js"></script>
</body>
</html>