-
-
Notifications
You must be signed in to change notification settings - Fork 21
/
index.html
135 lines (124 loc) · 101 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
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/><style data-href="/styles.f4dbc894744c3c869f21.css" id="gatsby-global-css">@import url(https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap);.post--2021--binary-floating-point--bit-button:hover{box-shadow:0 0 5px 1px rgba(0,0,0,.2);transition:box-shadow .2s ease-in-out}input:checked~.toggle__dot{transform:translateX(100%)}input:checked~.toggle__line{background-color:#48bb78}.post--2021--water-line--gyro-cube .gyro-cube-container{height:400px;display:flex;justify-content:center;align-items:center;perspective:800px;perspective-origin:50%}.post--2021--water-line--gyro-cube .gyro-cube{position:relative;width:200px;height:200px;transform-style:preserve-3d}.post--2021--water-line--gyro-cube .gyro-cube-side{position:absolute;width:100%;height:100%;opacity:.8;border:2px solid #fff;display:flex;justify-content:center;align-items:center;color:#fff;font-weight:700;font-size:100px}.post--2021--water-line--gyro-cube .gyro-cube-front{background-color:#d50000;transform:translateZ(100px)}.post--2021--water-line--gyro-cube .gyro-cube-back{background-color:#a0f;transform:translateZ(-100px)}.post--2021--water-line--gyro-cube .gyro-cube-left{background-color:#304ffe;transform:translateX(100px) rotateY(90deg)}.post--2021--water-line--gyro-cube .gyro-cube-right{background-color:#0091ea;transform:translateX(-100px) rotateY(90deg)}.post--2021--water-line--gyro-cube .gyro-cube-top{background-color:#00bfa5;transform:translateY(-100px) rotateX(90deg)}.post--2021--water-line--gyro-cube .gyro-cube-bottom{background-color:#64dd17;transform:translateY(100px) rotateX(90deg)}.custom-fade-in-opacity{opacity:1;-webkit-animation-name:customFadeInOpacity;animation-name:customFadeInOpacity;-webkit-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-duration:.8s;animation-duration:.8s}@-webkit-keyframes customFadeInOpacity{0%{opacity:0}to{opacity:1}}@keyframes customFadeInOpacity{0%{opacity:0}to{opacity:1}}.prose blockquote p:first-of-type:before,.prose blockquote p:last-of-type:after,.prose code:after,.prose code:before{content:""!important}.prose blockquote{font-weight:400!important}.prose li code.language-text,.prose p code.language-text,.prose td code.language-text,.prose th code.language-text,.prose tr code.language-text{padding:2px 5px 1px;font-weight:400}.prose p>img{margin:auto}.prose h1>a.gatsby-remark-autolink-header-anchor,.prose h2>a.gatsby-remark-autolink-header-anchor,.prose h3>a.gatsby-remark-autolink-header-anchor,.prose h4>a.gatsby-remark-autolink-header-anchor,.prose h5>a.gatsby-remark-autolink-header-anchor{visibility:hidden;display:inline-block;margin-left:10px}.prose h1:hover>a.gatsby-remark-autolink-header-anchor,.prose h2:hover>a.gatsby-remark-autolink-header-anchor,.prose h3:hover>a.gatsby-remark-autolink-header-anchor,.prose h4:hover>a.gatsby-remark-autolink-header-anchor,.prose h5:hover>a.gatsby-remark-autolink-header-anchor{visibility:visible}
/* ! tailwindcss v2.1.2 | MIT License | https://tailwindcss.com */
/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji}hr{height:0;color:inherit}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}button{background-color:transparent;background-image:none}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}fieldset,ol,ul{margin:0;padding:0}ol,ul{list-style:none}html{font-family:Roboto,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{font-family:inherit;line-height:inherit}*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}hr{border-top-width:1px}img{border-style:solid}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input:-ms-input-placeholder,textarea:-ms-input-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button{cursor:pointer}table{border-collapse:collapse}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}button,input,optgroup,select,textarea{padding:0;line-height:inherit;color:inherit}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.prose{color:#374151;max-width:65ch}.prose [class~=lead]{color:#4b5563;font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose a{color:#dc2626;text-decoration:underline;font-weight:500}.prose a:hover{color:#ef4444}.prose strong{color:#111827;font-weight:600}.prose ol[type=A]{--list-counter-style:upper-alpha}.prose ol[type=a]{--list-counter-style:lower-alpha}.prose ol[type=I]{--list-counter-style:upper-roman}.prose ol[type=i]{--list-counter-style:lower-roman}.prose ol[type="1"]{--list-counter-style:decimal}.prose ol>li{position:relative;padding-left:1.75em}.prose ol>li:before{content:counter(list-item,var(--list-counter-style,decimal)) ".";position:absolute;font-weight:400;color:#6b7280;left:0}.prose ul>li{position:relative;padding-left:1.75em}.prose ul>li:before{content:"";position:absolute;background-color:#d1d5db;border-radius:50%;width:.375em;height:.375em;top:.6875em;left:.25em}.prose hr{border-color:#e5e7eb;border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose blockquote{font-weight:500;font-style:italic;color:#111827;border-left-width:.25rem;border-left-color:#e5e7eb;quotes:"\201C""\201D""\2018""\2019";margin-top:1.6em;margin-bottom:1.6em;padding-left:1em}.prose blockquote p:first-of-type:before{content:open-quote}.prose blockquote p:last-of-type:after{content:close-quote}.prose h1{color:#111827;font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose h2{color:#111827;font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose h3{font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose h3,.prose h4{color:#111827;font-weight:600}.prose h4{margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose figure figcaption{color:#6b7280;font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose code{color:#111827;font-weight:600;font-size:.875em}.prose code:after,.prose code:before{content:"`"}.prose a code{color:#111827}.prose pre{color:#e5e7eb;background-color:#1f2937;overflow-x:auto;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding:.8571429em 1.1428571em}.prose pre code{background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:400;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose pre code:after,.prose pre code:before{content:none}.prose table{width:100%;table-layout:auto;text-align:left;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose thead{color:#111827;font-weight:600;border-bottom-width:1px;border-bottom-color:#d1d5db}.prose thead th{vertical-align:bottom;padding-right:.5714286em;padding-bottom:.5714286em;padding-left:.5714286em}.prose tbody tr{border-bottom-width:1px;border-bottom-color:#e5e7eb}.prose tbody tr:last-child{border-bottom-width:0}.prose tbody td{vertical-align:top;padding:.5714286em}.prose{font-size:1rem;line-height:1.75}.prose p{margin-top:1.25em;margin-bottom:1.25em}.prose figure,.prose img,.prose video{margin-top:2em;margin-bottom:2em}.prose figure>*{margin-top:0;margin-bottom:0}.prose h2 code{font-size:.875em}.prose h3 code{font-size:.9em}.prose ol,.prose ul{margin-top:1.25em;margin-bottom:1.25em}.prose li{margin-top:.5em;margin-bottom:.5em}.prose>ul>li p{margin-top:.75em;margin-bottom:.75em}.prose>ul>li>:first-child{margin-top:1.25em}.prose>ul>li>:last-child{margin-bottom:1.25em}.prose>ol>li>:first-child{margin-top:1.25em}.prose>ol>li>:last-child{margin-bottom:1.25em}.prose ol ol,.prose ol ul,.prose ul ol,.prose ul ul{margin-top:.75em;margin-bottom:.75em}.prose h2+*,.prose h3+*,.prose h4+*,.prose hr+*{margin-top:0}.prose thead th:first-child{padding-left:0}.prose thead th:last-child{padding-right:0}.prose tbody td:first-child{padding-left:0}.prose tbody td:last-child{padding-right:0}.prose>:first-child{margin-top:0}.prose>:last-child{margin-bottom:0}.prose-sm{font-size:.875rem;line-height:1.7142857}.prose-sm p{margin-top:1.1428571em;margin-bottom:1.1428571em}.prose-sm [class~=lead]{font-size:1.2857143em;line-height:1.5555556;margin-top:.8888889em;margin-bottom:.8888889em}.prose-sm blockquote{margin-top:1.3333333em;margin-bottom:1.3333333em;padding-left:1.1111111em}.prose-sm h1{font-size:2.1428571em;margin-top:0;margin-bottom:.8em;line-height:1.2}.prose-sm h2{font-size:1.4285714em;margin-top:1.6em;margin-bottom:.8em;line-height:1.4}.prose-sm h3{font-size:1.2857143em;margin-top:1.5555556em;margin-bottom:.4444444em;line-height:1.5555556}.prose-sm h4{margin-top:1.4285714em;margin-bottom:.5714286em;line-height:1.4285714}.prose-sm figure,.prose-sm img,.prose-sm video{margin-top:1.7142857em;margin-bottom:1.7142857em}.prose-sm figure>*{margin-top:0;margin-bottom:0}.prose-sm figure figcaption{font-size:.8571429em;line-height:1.3333333;margin-top:.6666667em}.prose-sm code{font-size:.8571429em}.prose-sm h2 code{font-size:.9em}.prose-sm h3 code{font-size:.8888889em}.prose-sm pre{font-size:.8571429em;line-height:1.6666667;margin-top:1.6666667em;margin-bottom:1.6666667em;border-radius:.25rem;padding:.6666667em 1em}.prose-sm ol,.prose-sm ul{margin-top:1.1428571em;margin-bottom:1.1428571em}.prose-sm li{margin-top:.2857143em;margin-bottom:.2857143em}.prose-sm ol>li{padding-left:1.5714286em}.prose-sm ol>li:before{left:0}.prose-sm ul>li{padding-left:1.5714286em}.prose-sm ul>li:before{height:.3571429em;width:.3571429em;top:.67857em;left:.2142857em}.prose-sm>ul>li p{margin-top:.5714286em;margin-bottom:.5714286em}.prose-sm>ul>li>:first-child{margin-top:1.1428571em}.prose-sm>ul>li>:last-child{margin-bottom:1.1428571em}.prose-sm>ol>li>:first-child{margin-top:1.1428571em}.prose-sm>ol>li>:last-child{margin-bottom:1.1428571em}.prose-sm ol ol,.prose-sm ol ul,.prose-sm ul ol,.prose-sm ul ul{margin-top:.5714286em;margin-bottom:.5714286em}.prose-sm hr{margin-top:2.8571429em;margin-bottom:2.8571429em}.prose-sm h2+*,.prose-sm h3+*,.prose-sm h4+*,.prose-sm hr+*{margin-top:0}.prose-sm table{font-size:.8571429em;line-height:1.5}.prose-sm thead th{padding-right:1em;padding-bottom:.6666667em;padding-left:1em}.prose-sm thead th:first-child{padding-left:0}.prose-sm thead th:last-child{padding-right:0}.prose-sm tbody td{padding:.6666667em 1em}.prose-sm tbody td:first-child{padding-left:0}.prose-sm tbody td:last-child{padding-right:0}.prose-sm>:first-child{margin-top:0}.prose-sm>:last-child{margin-bottom:0}.prose-red a,.prose-red a code{color:#dc2626}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.bg-black{--tw-bg-opacity:1;background-color:rgba(0,0,0,var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgba(255,255,255,var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgba(243,244,246,var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgba(229,231,235,var(--tw-bg-opacity))}.bg-gray-400{--tw-bg-opacity:1;background-color:rgba(156,163,175,var(--tw-bg-opacity))}.bg-red-100{--tw-bg-opacity:1;background-color:rgba(254,226,226,var(--tw-bg-opacity))}.bg-blue-100{--tw-bg-opacity:1;background-color:rgba(219,234,254,var(--tw-bg-opacity))}.hover\:bg-black:hover{--tw-bg-opacity:1;background-color:rgba(0,0,0,var(--tw-bg-opacity))}.hover\:bg-white:hover{--tw-bg-opacity:1;background-color:rgba(255,255,255,var(--tw-bg-opacity))}.hover\:bg-gray-800:hover{--tw-bg-opacity:1;background-color:rgba(31,41,55,var(--tw-bg-opacity))}.hover\:bg-red-500:hover{--tw-bg-opacity:1;background-color:rgba(239,68,68,var(--tw-bg-opacity))}.bg-cover{background-size:cover}.border-black{--tw-border-opacity:1;border-color:rgba(0,0,0,var(--tw-border-opacity))}.border-white{--tw-border-opacity:1;border-color:rgba(255,255,255,var(--tw-border-opacity))}.border-gray-300{--tw-border-opacity:1;border-color:rgba(209,213,219,var(--tw-border-opacity))}.border-gray-400{--tw-border-opacity:1;border-color:rgba(156,163,175,var(--tw-border-opacity))}.border-red-500{--tw-border-opacity:1;border-color:rgba(239,68,68,var(--tw-border-opacity))}.hover\:border-white:hover{--tw-border-opacity:1;border-color:rgba(255,255,255,var(--tw-border-opacity))}.hover\:border-gray-400:hover{--tw-border-opacity:1;border-color:rgba(156,163,175,var(--tw-border-opacity))}.rounded-sm{border-radius:.125rem}.rounded{border-radius:.25rem}.rounded-md{border-radius:.375rem}.rounded-full{border-radius:9999px}.border-solid{border-style:solid}.border-dashed{border-style:dashed}.border{border-width:1px}.cursor-pointer{cursor:pointer}.cursor-not-allowed{cursor:not-allowed}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.items-stretch{align-items:stretch}.self-start{align-self:flex-start}.self-stretch{align-self:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-self-end{justify-self:end}.flex-1{flex:1 1 0%}.font-light{font-weight:300}.font-normal{font-weight:400}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.h-0{height:0}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-48{height:12rem}.h-64{height:16rem}.h-96{height:24rem}.h-0\.5{height:.125rem}.h-full{height:100%}.text-xs{font-size:.75rem;line-height:1rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.m-auto{margin:auto}.mr-0{margin-right:0}.mb-0{margin-bottom:0}.mr-1{margin-right:.25rem}.mb-1{margin-bottom:.25rem}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.mb-2{margin-bottom:.5rem}.ml-2{margin-left:.5rem}.mt-3{margin-top:.75rem}.mr-3{margin-right:.75rem}.mb-3{margin-bottom:.75rem}.ml-3{margin-left:.75rem}.mr-4{margin-right:1rem}.mb-4{margin-bottom:1rem}.ml-4{margin-left:1rem}.mr-5{margin-right:1.25rem}.ml-5{margin-left:1.25rem}.mt-6{margin-top:1.5rem}.mr-6{margin-right:1.5rem}.mb-6{margin-bottom:1.5rem}.mb-12{margin-bottom:3rem}.mt-16{margin-top:4rem}.max-w-md{max-width:28rem}.max-w-screen-xl{max-width:1280px}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.p-6{padding:1.5rem}.p-8{padding:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-12{padding-top:3rem;padding-bottom:3rem}.pb-6{padding-bottom:1.5rem}.static{position:static}.absolute{position:absolute}.relative{position:relative}.inset-y-0{top:0;bottom:0}.left-0{left:0}.resize{resize:both}*{--tw-shadow:0 0 transparent}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,0.05)}.shadow,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow)}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,0.1),0 1px 2px 0 rgba(0,0,0,0.06)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06)}.shadow-inner,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 rgba(0,0,0,0.06)}.shadow-card{--tw-shadow:0 2px 1px -1px rgba(0,0,0,0.2),0 1px 1px 0 rgba(0,0,0,0.14),0 1px 3px 0 rgba(0,0,0,0.12);box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow)}*{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,0.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent}.text-center{text-align:center}.text-black{--tw-text-opacity:1;color:rgba(0,0,0,var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgba(156,163,175,var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgba(107,114,128,var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgba(55,65,81,var(--tw-text-opacity))}.text-red-500{--tw-text-opacity:1;color:rgba(239,68,68,var(--tw-text-opacity))}.text-red-600{--tw-text-opacity:1;color:rgba(220,38,38,var(--tw-text-opacity))}.text-blue-600{--tw-text-opacity:1;color:rgba(37,99,235,var(--tw-text-opacity))}.hover\:text-black:hover{--tw-text-opacity:1;color:rgba(0,0,0,var(--tw-text-opacity))}.hover\:text-white:hover{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}.hover\:text-gray-500:hover{--tw-text-opacity:1;color:rgba(107,114,128,var(--tw-text-opacity))}.hover\:text-red-600:hover{--tw-text-opacity:1;color:rgba(220,38,38,var(--tw-text-opacity))}.uppercase{text-transform:uppercase}.underline{text-decoration:underline}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.whitespace-nowrap{white-space:nowrap}.w-1{width:.25rem}.w-2{width:.5rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-10{width:2.5rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-36{width:9rem}.w-64{width:16rem}.w-full{width:100%}.gap-12{gap:3rem}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.transform{--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;transform:translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-105:hover{--tw-scale-x:1.05;--tw-scale-y:1.05}.hover\:-translate-y-1:hover{--tw-translate-y:-0.25rem}.transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}.duration-500{transition-duration:.5s}@-webkit-keyframes spin{to{transform:rotate(1turn)}}@keyframes spin{to{transform:rotate(1turn)}}@-webkit-keyframes ping{75%,to{transform:scale(2);opacity:0}}@keyframes ping{75%,to{transform:scale(2);opacity:0}}@-webkit-keyframes pulse{50%{opacity:.5}}@keyframes pulse{50%{opacity:.5}}@-webkit-keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}.filter{--tw-blur:var(--tw-empty,/*!*/ /*!*/);--tw-brightness:var(--tw-empty,/*!*/ /*!*/);--tw-contrast:var(--tw-empty,/*!*/ /*!*/);--tw-grayscale:var(--tw-empty,/*!*/ /*!*/);--tw-hue-rotate:var(--tw-empty,/*!*/ /*!*/);--tw-invert:var(--tw-empty,/*!*/ /*!*/);--tw-saturate:var(--tw-empty,/*!*/ /*!*/);--tw-sepia:var(--tw-empty,/*!*/ /*!*/);--tw-drop-shadow:var(--tw-empty,/*!*/ /*!*/);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale:grayscale(100%)}@media (min-width:640px){.sm\:prose{color:#374151;max-width:65ch}.sm\:prose [class~=lead]{color:#4b5563;font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.sm\:prose a{color:#dc2626;text-decoration:underline;font-weight:500}.sm\:prose a:hover{color:#ef4444}.sm\:prose strong{color:#111827;font-weight:600}.sm\:prose ol[type=A]{--list-counter-style:upper-alpha}.sm\:prose ol[type=a]{--list-counter-style:lower-alpha}.sm\:prose ol[type=I]{--list-counter-style:upper-roman}.sm\:prose ol[type=i]{--list-counter-style:lower-roman}.sm\:prose ol[type="1"]{--list-counter-style:decimal}.sm\:prose ol>li{position:relative;padding-left:1.75em}.sm\:prose ol>li:before{content:counter(list-item,var(--list-counter-style,decimal)) ".";position:absolute;font-weight:400;color:#6b7280;left:0}.sm\:prose ul>li{position:relative;padding-left:1.75em}.sm\:prose ul>li:before{content:"";position:absolute;background-color:#d1d5db;border-radius:50%;width:.375em;height:.375em;top:.6875em;left:.25em}.sm\:prose hr{border-color:#e5e7eb;border-top-width:1px;margin-top:3em;margin-bottom:3em}.sm\:prose blockquote{font-weight:500;font-style:italic;color:#111827;border-left-width:.25rem;border-left-color:#e5e7eb;quotes:"\201C""\201D""\2018""\2019";margin-top:1.6em;margin-bottom:1.6em;padding-left:1em}.sm\:prose blockquote p:first-of-type:before{content:open-quote}.sm\:prose blockquote p:last-of-type:after{content:close-quote}.sm\:prose h1{color:#111827;font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.sm\:prose h2{color:#111827;font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.sm\:prose h3{font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.sm\:prose h3,.sm\:prose h4{color:#111827;font-weight:600}.sm\:prose h4{margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.sm\:prose figure figcaption{color:#6b7280;font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.sm\:prose code{color:#111827;font-weight:600;font-size:.875em}.sm\:prose code:after,.sm\:prose code:before{content:"`"}.sm\:prose a code{color:#111827}.sm\:prose pre{color:#e5e7eb;background-color:#1f2937;overflow-x:auto;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding:.8571429em 1.1428571em}.sm\:prose pre code{background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:400;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.sm\:prose pre code:after,.sm\:prose pre code:before{content:none}.sm\:prose table{width:100%;table-layout:auto;text-align:left;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.sm\:prose thead{color:#111827;font-weight:600;border-bottom-width:1px;border-bottom-color:#d1d5db}.sm\:prose thead th{vertical-align:bottom;padding-right:.5714286em;padding-bottom:.5714286em;padding-left:.5714286em}.sm\:prose tbody tr{border-bottom-width:1px;border-bottom-color:#e5e7eb}.sm\:prose tbody tr:last-child{border-bottom-width:0}.sm\:prose tbody td{vertical-align:top;padding:.5714286em}.sm\:prose{font-size:1rem;line-height:1.75}.sm\:prose p{margin-top:1.25em;margin-bottom:1.25em}.sm\:prose figure,.sm\:prose img,.sm\:prose video{margin-top:2em;margin-bottom:2em}.sm\:prose figure>*{margin-top:0;margin-bottom:0}.sm\:prose h2 code{font-size:.875em}.sm\:prose h3 code{font-size:.9em}.sm\:prose ol,.sm\:prose ul{margin-top:1.25em;margin-bottom:1.25em}.sm\:prose li{margin-top:.5em;margin-bottom:.5em}.sm\:prose>ul>li p{margin-top:.75em;margin-bottom:.75em}.sm\:prose>ul>li>:first-child{margin-top:1.25em}.sm\:prose>ul>li>:last-child{margin-bottom:1.25em}.sm\:prose>ol>li>:first-child{margin-top:1.25em}.sm\:prose>ol>li>:last-child{margin-bottom:1.25em}.sm\:prose ol ol,.sm\:prose ol ul,.sm\:prose ul ol,.sm\:prose ul ul{margin-top:.75em;margin-bottom:.75em}.sm\:prose h2+*,.sm\:prose h3+*,.sm\:prose h4+*,.sm\:prose hr+*{margin-top:0}.sm\:prose thead th:first-child{padding-left:0}.sm\:prose thead th:last-child{padding-right:0}.sm\:prose tbody td:first-child{padding-left:0}.sm\:prose tbody td:last-child{padding-right:0}.sm\:prose>:first-child{margin-top:0}.sm\:prose>:last-child{margin-bottom:0}.sm\:flex{display:flex}.sm\:flex-row{flex-direction:row}.sm\:items-start{align-items:flex-start}.sm\:items-center{align-items:center}.sm\:flex-1{flex:1 1 0%}.sm\:h-auto{height:auto}.sm\:mb-0{margin-bottom:0}.sm\:mr-6{margin-right:1.5rem}.sm\:px-12{padding-left:3rem;padding-right:3rem}.sm\:text-left{text-align:left}.sm\:w-2\/5{width:40%}.sm\:w-3\/5{width:60%}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:w-1\/4{width:25%}.lg\:w-3\/4{width:75%}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:none;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}</style><meta name="generator" content="Gatsby 3.4.0"/><title data-react-helmet="true">NanoNeuron - 7 simple JS functions that explain how machines learn | Trekhleb</title><meta data-react-helmet="true" name="description" content="The NanoNeuron.js code example contains 7 simple JavaScript functions (which touches on model prediction, cost calculation, forward/backwards propagation, and training) that will give you a feeling of how machines can actually learn. No 3rd-party libraries, no external data-sets or dependencies, only pure and simple JavaScript functions."/><meta data-react-helmet="true" name="image" content="https://trekhleb.dev/static/8c920df1600d388655fe4289a999c280/e1957/01-cover.png"/><meta data-react-helmet="true" property="og:title" content="NanoNeuron - 7 simple JS functions that explain how machines learn | Trekhleb"/><meta data-react-helmet="true" property="og:description" content="The NanoNeuron.js code example contains 7 simple JavaScript functions (which touches on model prediction, cost calculation, forward/backwards propagation, and training) that will give you a feeling of how machines can actually learn. No 3rd-party libraries, no external data-sets or dependencies, only pure and simple JavaScript functions."/><meta data-react-helmet="true" property="og:url" content="https://trekhleb.dev/blog/2019/nano-neuron/"/><meta data-react-helmet="true" property="og:image" content="https://trekhleb.dev/static/8c920df1600d388655fe4289a999c280/e1957/01-cover.png"/><meta data-react-helmet="true" property="og:type" content="article"/><meta data-react-helmet="true" name="twitter:card" content="summary_large_image"/><meta data-react-helmet="true" name="twitter:creator" content="@Trekhleb"/><meta data-react-helmet="true" name="twitter:title" content="NanoNeuron - 7 simple JS functions that explain how machines learn | Trekhleb"/><meta data-react-helmet="true" name="twitter:description" content="The NanoNeuron.js code example contains 7 simple JavaScript functions (which touches on model prediction, cost calculation, forward/backwards propagation, and training) that will give you a feeling of how machines can actually learn. No 3rd-party libraries, no external data-sets or dependencies, only pure and simple JavaScript functions."/><meta data-react-helmet="true" name="twitter:image" content="https://trekhleb.dev/static/8c920df1600d388655fe4289a999c280/e1957/01-cover.png"/><meta data-react-helmet="true" name="twitter:url" content="https://trekhleb.dev/blog/2019/nano-neuron/"/><link rel="preconnect dns-prefetch" href="https://www.google-analytics.com"/><link rel="alternate" type="application/rss+xml" title="Trekhleb.dev RSS Feed" href="/rss.xml"/><link as="script" rel="preload" href="/webpack-runtime-98886e4c056db07027a1.js"/><link as="script" rel="preload" href="/framework-d63adeb7e1b44b7b8aa5.js"/><link as="script" rel="preload" href="/app-2e0826ec06cafce3bdee.js"/><link as="script" rel="preload" href="/commons-213c962999d4e181c8a0.js"/><link as="script" rel="preload" href="/component---src-templates-post-tsx-c4045391b1a7c095d609.js"/><link as="fetch" rel="preload" href="/page-data/blog/2019/nano-neuron/page-data.json" crossorigin="anonymous"/><link as="fetch" rel="preload" href="/page-data/app-data.json" crossorigin="anonymous"/></head><body><div id="___gatsby"><div style="outline:none" tabindex="-1" id="gatsby-focus-wrapper"><main class="flex flex-col items-center"><div class="max-w-screen-xl self-stretch m-auto w-full"><header class="flex flex-row items-center px-6 sm:px-12 py-6"><div class="mr-6"><div><a class="transition duration-200 ease-in-out flex flex-row items-center hover:text-red-600 font-extrabold text-sm tracking-widest uppercase" href="/">Trekhleb</a></div></div><nav><ul class="flex flex-row"><li class="ml-5"><a class="transition duration-200 ease-in-out flex flex-row items-center hover:text-red-600 uppercase text-xs" href="/">About</a></li><li class="ml-5"><a class="transition duration-200 ease-in-out flex flex-row items-center hover:text-red-600 uppercase text-xs" href="/projects/">Projects</a></li><li class="ml-5"><a class="transition duration-200 ease-in-out flex flex-row items-center hover:text-red-600 uppercase text-xs" href="/blog/">Blog</a></li></ul></nav></header><article class="px-6 sm:px-12 py-6"><div class="flex flex-col items-center"><article class="w-full prose prose-sm sm:prose overflow-hidden prose-red" style="max-width:860px"><h1 class="text-3xl mb-6 uppercase font-extrabold ">NanoNeuron - 7 simple JS functions that explain how machines learn</h1><div class="flex flex-row items-center "><div class="flex flex-row items-center mr-6"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="mr-1" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>06 December, 2019</div><div class="flex flex-row items-center "><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="mr-1" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>8<!-- --> min to read</div></div><h2 id="tldr" style="position:relative">TL;DR<a href="#tldr" aria-label="tldr permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h2><p><a href="https://github.com/trekhleb/nano-neuron">NanoNeuron</a> is an <em>over-simplified</em> version of the Neuron concept from Neural Networks. NanoNeuron is trained to convert temperature values from Celsius to Fahrenheit.</p><p>The <a href="https://github.com/trekhleb/nano-neuron/blob/master/NanoNeuron.js">NanoNeuron.js</a> code example contains 7 simple JavaScript functions (which touches on model prediction, cost calculation, forward/backwards propagation, and training) that will give you a feeling of how machines can actually "learn". No 3rd-party libraries, no external data-sets or dependencies, only pure and simple JavaScript functions.</p><p>☝🏻These functions are <strong>NOT</strong>, by any means, a complete guide to machine learning. A lot of machine learning concepts are skipped and over-simplified! This simplification is done on purpose to give the reader a really <strong>basic</strong> understanding and feeling of how machines can learn and ultimately to make it possible for the reader to recognize that it's not "machine learning MAGIC" but rather "machine learning MATH" 🤓.</p><h2 id="what-our-nanoneuron-will-learn" style="position:relative">What our NanoNeuron will learn<a href="#what-our-nanoneuron-will-learn" aria-label="what our nanoneuron will learn permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h2><p>You've probably heard about Neurons in the context of <a href="https://en.wikipedia.org/wiki/Neural_network">Neural Networks</a>. NanoNeuron is just that but simpler and we're going to implement it from scratch. For simplicity reasons we're not even going to build a network on NanoNeurons. We will have it all working on its own, doing some magical predictions for us. Namely, we will teach this singular NanoNeuron to convert (predict) the temperature from Celsius to Fahrenheit.</p><p>By the way, the formula for converting Celsius to Fahrenheit is this:</p><p><span class="gatsby-resp-image-wrapper" style="position:relative;display:block;margin-left:auto;margin-right:auto;max-width:165px">
<span class="gatsby-resp-image-background-image" style="padding-bottom:25.454545454545457%;position:relative;bottom:0;left:0;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAgklEQVQY053PywrBYRQE8B/JrUiR+4YFsWBhYWNBnsADeP/X0L9G5LYwdfrOmTmnmY8HSi/vL1ww/CYuMPvAt7BFM3M5Jft3voIaplgVxAFL7HOwRhcjHDFHG/0YiFZHD5voZ1xlmD59oRPH4mCAcYyqSV1gh0b6WqoIMfEnTkn3hhtoJwWkHbbLjgAAAABJRU5ErkJggg==');background-size:cover;display:block"></span>
<img class="gatsby-resp-image-image" alt="Celsius to Fahrenheit" title="Celsius to Fahrenheit" src="/static/228baf7755f8ac68971b55b5b14c5ee7/04c57/02-formula-C-to-F.png" srcSet="/static/228baf7755f8ac68971b55b5b14c5ee7/04c57/02-formula-C-to-F.png 165w" sizes="(max-width: 165px) 100vw, 165px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0" loading="lazy"/>
</span></p><p>But for now our NanoNeuron doesn't know about it...</p><h3 id="the-nanoneuron-model" style="position:relative">The NanoNeuron model<a href="#the-nanoneuron-model" aria-label="the nanoneuron model permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h3><p>Let's implement our NanoNeuron model function. It implements basic linear dependency between <code class="language-text">x</code> and <code class="language-text">y</code> which looks like <code class="language-text">y = w * x + b</code>. Simply saying our NanoNeuron is a "kid" in a "school" that is being taught to draw the straight line in <code class="language-text">XY</code> coordinates.</p><p>Variables <code class="language-text">w</code>, <code class="language-text">b</code> are parameters of the model. NanoNeuron knows only about these two parameters of the linear function.
These parameters are something that NanoNeuron is going to "learn" during the training process.</p><p>The only thing that NanoNeuron can do is to imitate linear dependency. In its <code class="language-text">predict()</code> method it accepts some input <code class="language-text">x</code> and predicts the output <code class="language-text">y</code>. No magic here.</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">NanoNeuron</span><span class="token punctuation">(</span><span class="token parameter">w<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>w <span class="token operator">=</span> w<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>b <span class="token operator">=</span> b<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function-variable function">predict</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> x <span class="token operator">*</span> <span class="token keyword">this</span><span class="token punctuation">.</span>w <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>b<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre></div><p>...wait... <a href="https://en.wikipedia.org/wiki/Linear_regression">linear regression</a> is it you? 🧐</p><h3 id="celsius-to-fahrenheit-conversion" style="position:relative">Celsius to Fahrenheit conversion<a href="#celsius-to-fahrenheit-conversion" aria-label="celsius to fahrenheit conversion permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h3><p>The temperature value in Celsius can be converted to Fahrenheit using the following formula: <code class="language-text">f = 1.8 * c + 32</code>, where <code class="language-text">c</code> is a temperature in Celsius and <code class="language-text">f</code> is the calculated temperature in Fahrenheit.</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">celsiusToFahrenheit</span><span class="token punctuation">(</span><span class="token parameter">c</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> w <span class="token operator">=</span> <span class="token number">1.8</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token number">32</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> f <span class="token operator">=</span> c <span class="token operator">*</span> w <span class="token operator">+</span> b<span class="token punctuation">;</span>
<span class="token keyword">return</span> f<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div><p>Ultimately we want to teach our NanoNeuron to imitate this function (to learn that <code class="language-text">w = 1.8</code> and <code class="language-text">b = 32</code>) without knowing these parameters in advance.</p><p>This is how the Celsius to Fahrenheit conversion function looks like:</p><p><span class="gatsby-resp-image-wrapper" style="position:relative;display:block;margin-left:auto;margin-right:auto;max-width:300px">
<span class="gatsby-resp-image-background-image" style="padding-bottom:94.8%;position:relative;bottom:0;left:0;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAABYlAAAWJQFJUiTwAAABPUlEQVQ4y52U626EIBCFff+XbH9ssnQ1CsrFwsBpIItBvG4nIZDR+TKXAw1OLISw7FLKdHZSgpRafS+twYXlIKU1gveww7D4PwbmgHEc0XMOmiaQMYfZ3QYaYzB0HZzgm1bcBtZB4vmEt/Y0u9sZ0jxDMHaZ3SGwDvodekxCnA7jGFjBSGuQlNBxGG/YR8AyIO6Oc3DO0XXdZf82wLrUJGKtYYmSdP4FXKCFiJOwT27HLnCT3Tim6dZXrwTu9bMJRaPTAuCdheV8FVQCz9aubJwQCM6tfFpr3LEm9iYvqRTY4wHxw6CMSVlFvxACjLEEzf/Gc/S3bbvyN9575EVEeH1/gayFDyH5YhnzPKPv+3TO/2Z/lFTpX5XsjUF4vyaomp2nfFlyOd0okyiXPYHXQzk6L8D4Ctcv8RHwTDZ/NLjfqkMLIkMAAAAASUVORK5CYII=');background-size:cover;display:block"></span>
<img class="gatsby-resp-image-image" alt="Celsius to Fahrenheit conversion" title="Celsius to Fahrenheit conversion" src="/static/68b0d68bcc7be00ec9526867b2fcecf3/5a46d/05.png" srcSet="/static/68b0d68bcc7be00ec9526867b2fcecf3/63868/05.png 250w,/static/68b0d68bcc7be00ec9526867b2fcecf3/5a46d/05.png 300w" sizes="(max-width: 300px) 100vw, 300px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0" loading="lazy"/>
</span></p><h3 id="generating-data-sets" style="position:relative">Generating data-sets<a href="#generating-data-sets" aria-label="generating data sets permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h3><p>Before the training we need to generate <strong>training</strong> and <strong>test data-sets</strong> based on the <code class="language-text">celsiusToFahrenheit()</code> function. Data-sets consist of pairs of input values and correctly labeled output values.</p><blockquote><p>In real life, in most of cases, this data would be collected rather than generated. For example, we might have a set of images of hand-drawn numbers and the corresponding set of numbers that explains what number is written on each picture.</p></blockquote><p>We will use TRAINING example data to train our NanoNeuron. Before our NanoNeuron will grow and be able to make decisions on its own, we need to teach it what is right and what is wrong using training examples.</p><p>We will use TEST examples to evaluate how well our NanoNeuron performs on the data that it didn't see during the training. This is the point where we could see that our "kid" has grown and can make decisions on its own.</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">generateDataSets</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// xTrain -> [0, 1, 2, ...],</span>
<span class="token comment">// yTrain -> [32, 33.8, 35.6, ...]</span>
<span class="token keyword">const</span> xTrain <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> yTrain <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> x <span class="token operator"><</span> <span class="token number">100</span><span class="token punctuation">;</span> x <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> y <span class="token operator">=</span> <span class="token function">celsiusToFahrenheit</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span>
xTrain<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span>
yTrain<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// xTest -> [0.5, 1.5, 2.5, ...]</span>
<span class="token comment">// yTest -> [32.9, 34.7, 36.5, ...]</span>
<span class="token keyword">const</span> xTest <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> yTest <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">// By starting from 0.5 and using the same step of 1 as we have used for training set</span>
<span class="token comment">// we make sure that test set has different data comparing to training set.</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token number">0.5</span><span class="token punctuation">;</span> x <span class="token operator"><</span> <span class="token number">100</span><span class="token punctuation">;</span> x <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> y <span class="token operator">=</span> <span class="token function">celsiusToFahrenheit</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span>
xTest<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span>
yTest<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token punctuation">[</span>xTrain<span class="token punctuation">,</span> yTrain<span class="token punctuation">,</span> xTest<span class="token punctuation">,</span> yTest<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre></div><h3 id="the-cost-the-error-of-prediction" style="position:relative">The cost (the error) of prediction<a href="#the-cost-the-error-of-prediction" aria-label="the cost the error of prediction permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h3><p>We need to have some metric that will show us how close our model's prediction is to correct values. The calculation of the cost (the mistake) between the correct output value of <code class="language-text">y</code> and <code class="language-text">prediction</code>, that our NanoNeuron created, will be made using the following formula:</p><p><span class="gatsby-resp-image-wrapper" style="position:relative;display:block;margin-left:auto;margin-right:auto;max-width:361px">
<span class="gatsby-resp-image-background-image" style="padding-bottom:11.6%;position:relative;bottom:0;left:0;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAIAAADXZGvcAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAXUlEQVQI1yXLQQoEIQxE0b7/Bd03CCmTShCNCm4Gpv/6/Yeku9daW2uqCkBV3T0ze+/nnMx09/YPgJmJyFqL5PO+L0kRUVURIWlmEbH3BjDnjIjv+QCAMca9t5TyA3USbubA9om/AAAAAElFTkSuQmCC');background-size:cover;display:block"></span>
<img class="gatsby-resp-image-image" alt="Prediction Cost" title="Prediction Cost" src="/static/8d8e50ac12d03614e65975f7b5d36931/39d76/06.png" srcSet="/static/8d8e50ac12d03614e65975f7b5d36931/63868/06.png 250w,/static/8d8e50ac12d03614e65975f7b5d36931/39d76/06.png 361w" sizes="(max-width: 361px) 100vw, 361px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0" loading="lazy"/>
</span></p><p>This is a simple difference between two values. The closer the values are to each other, the smaller the difference. We're using a power of <code class="language-text">2</code> here just to get rid of negative numbers so that <code class="language-text">(1 - 2) ^ 2</code> would be the same as <code class="language-text">(2 - 1) ^ 2</code>. Division by <code class="language-text">2</code> is happening just to simplify further the backward propagation formula (see below).</p><p>The cost function in this case will be as simple as:</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">predictionCost</span><span class="token punctuation">(</span><span class="token parameter">y<span class="token punctuation">,</span> prediction</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>y <span class="token operator">-</span> prediction<span class="token punctuation">)</span> <span class="token operator">**</span> <span class="token number">2</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// i.e. -> 235.6</span>
<span class="token punctuation">}</span></code></pre></div><h3 id="forward-propagation" style="position:relative">Forward propagation<a href="#forward-propagation" aria-label="forward propagation permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h3><p>To do forward propagation means to do a prediction for all training examples from <code class="language-text">xTrain</code> and <code class="language-text">yTrain</code> data-sets and to calculate the average cost of those predictions along the way.</p><p>We just let our NanoNeuron say its opinion, at this point, by just allowing it to guess how to convert the temperature. It might be stupidly wrong here. The average cost will show us how wrong our model is right now. This cost value is really important since changing the NanoNeuron parameters <code class="language-text">w</code> and <code class="language-text">b</code>, and by doing the forward propagation again; we will be able to evaluate if our NanoNeuron became smarter or not after these parameters change.</p><p>The average cost will be calculated using the following formula:</p><p><span class="gatsby-resp-image-wrapper" style="position:relative;display:block;margin-left:auto;margin-right:auto;max-width:347px">
<span class="gatsby-resp-image-background-image" style="padding-bottom:16.400000000000002%;position:relative;bottom:0;left:0;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAc0lEQVQI102NSwpEIQwEvf/9FBX8zEJcGcguwbxk4AWGqWV30R3sDyJ6XsyMmQEgxggAZiYi914RUVVmdi3knPfeY4yc8+dlzomIAOD5Oaf37kJrrZQyxlhr1VqDb4gIEZnZ7xkR994ppTmn56rqrb6IyBefIalI+9WU7wAAAABJRU5ErkJggg==');background-size:cover;display:block"></span>
<img class="gatsby-resp-image-image" alt="Average Cost" title="Average Cost" src="/static/575db3e0a0c872b29582147e41231344/39e45/07.png" srcSet="/static/575db3e0a0c872b29582147e41231344/63868/07.png 250w,/static/575db3e0a0c872b29582147e41231344/39e45/07.png 347w" sizes="(max-width: 347px) 100vw, 347px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0" loading="lazy"/>
</span></p><p>Where <code class="language-text">m</code> is a number of training examples (in our case: <code class="language-text">100</code>).</p><p>Here is how we may implement it in code:</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">forwardPropagation</span><span class="token punctuation">(</span><span class="token parameter">model<span class="token punctuation">,</span> xTrain<span class="token punctuation">,</span> yTrain</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> m <span class="token operator">=</span> xTrain<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
<span class="token keyword">const</span> predictions <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> cost <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> m<span class="token punctuation">;</span> i <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> prediction <span class="token operator">=</span> nanoNeuron<span class="token punctuation">.</span><span class="token function">predict</span><span class="token punctuation">(</span>xTrain<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
cost <span class="token operator">+=</span> <span class="token function">predictionCost</span><span class="token punctuation">(</span>yTrain<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> prediction<span class="token punctuation">)</span><span class="token punctuation">;</span>
predictions<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>prediction<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// We are interested in average cost.</span>
cost <span class="token operator">/=</span> m<span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token punctuation">[</span>predictions<span class="token punctuation">,</span> cost<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre></div><h3 id="backward-propagation" style="position:relative">Backward propagation<a href="#backward-propagation" aria-label="backward propagation permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h3><p>When we know how right or wrong our NanoNeuron's predictions are (based on average cost at this point) what should we do to make the predictions more precise?</p><p>The backward propagation gives us the answer to this question. Backward propagation is the process of evaluating the cost of prediction and adjusting the NanoNeuron's parameters <code class="language-text">w</code> and <code class="language-text">b</code> so that next and future predictions would be more precise.</p><p>This is the place where machine learning looks like magic 🧞♂️. The key concept here is the <strong>derivative</strong> which shows what step to take to get closer to the cost function minimum.</p><p>Remember, finding the minimum of a cost function is the ultimate goal of the training process. If we find such values for <code class="language-text">w</code> and <code class="language-text">b</code> such that our average cost function will be small, it would mean that the NanoNeuron model does really good and precise predictions.</p><p>Derivatives are a big and separate topic that we will not cover in this article. <a href="https://www.mathsisfun.com/calculus/derivatives-introduction.html">MathIsFun</a> is a good resource to get a basic understanding of it.</p><p>One thing about derivatives that will help you to understand how backward propagation works is that the derivative, by its meaning, is a tangent line to the function curve that points toward the direction of the function minimum.</p><p><img src="/posts-assets/bb9a55828c3188edf7d48ed286135117/2.svg" alt="Derivative slope"/></p><p><em>Image source: <a href="https://www.mathsisfun.com/calculus/derivatives-introduction.html">MathIsFun</a></em></p><p>For example, on the plot above, you can see that if we're at the point of <code class="language-text">(x=2, y=4)</code> then the slope tells us to go <code class="language-text">left</code> and <code class="language-text">down</code> to get to the function minimum. Also notice that the bigger the slope, the faster we should move to the minimum.</p><p>The derivatives of our <code class="language-text">averageCost</code> function for parameters <code class="language-text">w</code> and <code class="language-text">b</code> looks like this:</p><p><span class="gatsby-resp-image-wrapper" style="position:relative;display:block;margin-left:auto;margin-right:auto;max-width:406px">
<span class="gatsby-resp-image-background-image" style="padding-bottom:13.999999999999998%;position:relative;bottom:0;left:0;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAgElEQVQI1z2OQQrEIBAE8/8HBgISUHQIepCgELRn2oUNu3WqQx1q44+1lqqSNDMA+77XWteXNzCzf2BmJDcRua4rxuicExHvfSmltXYcR0pJRACEEFJKzjnvfQgh53zfd855672TBPA8zyskxxjneYrInFNVxxiqCkBV55wA3rsPOJyq+BOe6vAAAAAASUVORK5CYII=');background-size:cover;display:block"></span>
<img class="gatsby-resp-image-image" alt="dW" title="dW" src="/static/4ccbdaba120c399c1528e2bc38cf0efd/e33ef/08.png" srcSet="/static/4ccbdaba120c399c1528e2bc38cf0efd/63868/08.png 250w,/static/4ccbdaba120c399c1528e2bc38cf0efd/e33ef/08.png 406w" sizes="(max-width: 406px) 100vw, 406px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0" loading="lazy"/>
</span></p><p><span class="gatsby-resp-image-wrapper" style="position:relative;display:block;margin-left:auto;margin-right:auto;max-width:354px">
<span class="gatsby-resp-image-background-image" style="padding-bottom:16%;position:relative;bottom:0;left:0;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAg0lEQVQI1yWNMQrFIBAFc//L2aWIG1ADidqJBKK7+/bDd4ppppitlCIiZgbAzOaczKyqZpZz3vd91QUAZhYRAKq6EdF5ns/zxBi99zHGlFIIofd+/0kplVK+7yOi67qIKIRARDnn7TiO1pqZicgYQ1UBrFut1Tn3vi8zAxhjrOHynPMHpFupew3cVWoAAAAASUVORK5CYII=');background-size:cover;display:block"></span>
<img class="gatsby-resp-image-image" alt="dB" title="dB" src="/static/e020cb125449849009a9f565a32ff46f/8f50f/09.png" srcSet="/static/e020cb125449849009a9f565a32ff46f/63868/09.png 250w,/static/e020cb125449849009a9f565a32ff46f/8f50f/09.png 354w" sizes="(max-width: 354px) 100vw, 354px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0" loading="lazy"/>
</span></p><p>Where <code class="language-text">m</code> is a number of training examples (in our case: <code class="language-text">100</code>).</p><p><em>You may read more about derivative rules and how to get a derivative of complex functions <a href="https://www.mathsisfun.com/calculus/derivatives-rules.html">here</a>.</em></p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">backwardPropagation</span><span class="token punctuation">(</span><span class="token parameter">predictions<span class="token punctuation">,</span> xTrain<span class="token punctuation">,</span> yTrain</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> m <span class="token operator">=</span> xTrain<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
<span class="token comment">// At the beginning we don't know in which way our parameters 'w' and 'b' need to be changed.</span>
<span class="token comment">// Therefore we're setting up the changing steps for each parameters to 0.</span>
<span class="token keyword">let</span> dW <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> dB <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> m<span class="token punctuation">;</span> i <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
dW <span class="token operator">+=</span> <span class="token punctuation">(</span>yTrain<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">-</span> predictions<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">*</span> xTrain<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
dB <span class="token operator">+=</span> yTrain<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">-</span> predictions<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// We're interested in average deltas for each params.</span>
dW <span class="token operator">/=</span> m<span class="token punctuation">;</span>
dB <span class="token operator">/=</span> m<span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token punctuation">[</span>dW<span class="token punctuation">,</span> dB<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre></div><h3 id="training-the-model" style="position:relative">Training the model<a href="#training-the-model" aria-label="training the model permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h3><p>Now we know how to evaluate the correctness of our model for all training set examples (<em>forward propagation</em>). We also know how to do small adjustments to parameters <code class="language-text">w</code> and <code class="language-text">b</code> of our NanoNeuron model (<em>backward propagation</em>). But the issue is that if we run forward propagation and then backward propagation only once, it won't be enough for our model to learn any laws/trends from the training data. You may compare it with attending a one day of elementary school for the kid. He/she should go to the school not once but day after day and year after year to learn something.</p><p>So we need to repeat forward and backward propagation for our model many times. That is exactly what the <code class="language-text">trainModel()</code> function does. It is like a "teacher" for our NanoNeuron model:</p><ul><li>it will spend some time (<code class="language-text">epochs</code>) with our slightly stupid NanoNeuron model and try to train/teach it,</li><li>it will use specific "books" (<code class="language-text">xTrain</code> and <code class="language-text">yTrain</code> data-sets) for training,</li><li>it will push our kid to learn harder (faster) by using a learning rate parameter <code class="language-text">alpha</code></li></ul><p>A few words about the learning rate <code class="language-text">alpha</code>. This is just a multiplier for <code class="language-text">dW</code> and <code class="language-text">dB</code> values we have calculated during the backward propagation. So, derivative pointed us toward the direction we need to take to find a minimum of the cost function (<code class="language-text">dW</code> and <code class="language-text">dB</code> sign) and it also showed us how fast we need to go in that direction (absolute values of <code class="language-text">dW</code> and <code class="language-text">dB</code>). Now we need to multiply those step sizes to <code class="language-text">alpha</code> just to adjust our movement to the minimum faster or slower. Sometimes if we use big values for <code class="language-text">alpha</code>, we might simply jump over the minimum and never find it.</p><p>The analogy with the teacher would be that the harder s/he pushes our "nano-kid" the faster our "nano-kid" will learn but if the teacher pushes too hard, the "kid" will have a nervous breakdown and won't be able to learn anything 🤯.</p><p>Here is how we're going to update our model's <code class="language-text">w</code> and <code class="language-text">b</code> params:</p><p><span class="gatsby-resp-image-wrapper" style="position:relative;display:block;margin-left:auto;margin-right:auto;max-width:199px">
<span class="gatsby-resp-image-background-image" style="padding-bottom:9.045226130653267%;position:relative;bottom:0;left:0;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAIAAADXZGvcAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAcUlEQVQI1yXLvQqFEQAA0O/938QDGDyAyUIGQhmQv1KSkNQd7tnPl1LaeyulSik5Z875vddau9ZijBFCpJQQQiFEjDHnHGN0ziGEAADfGGOt1Vo755RSjDHvPe/9nFNrTSnFGDvnhBC11t57a+3/Qwg/IRBpuEaNo00AAAAASUVORK5CYII=');background-size:cover;display:block"></span>
<img class="gatsby-resp-image-image" alt="w" title="w" src="/static/c7bdb884f2a940d62332246cdbcb44bc/3d64b/10.png" srcSet="/static/c7bdb884f2a940d62332246cdbcb44bc/3d64b/10.png 199w" sizes="(max-width: 199px) 100vw, 199px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0" loading="lazy"/>
</span></p><p><span class="gatsby-resp-image-wrapper" style="position:relative;display:block;margin-left:auto;margin-right:auto;max-width:180px">
<span class="gatsby-resp-image-background-image" style="padding-bottom:10%;position:relative;bottom:0;left:0;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAIAAADXZGvcAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAcUlEQVQI1x3BywpFERQA0PP//+ILzAwkI+UxUOyU6zGQROSMTt21HozxvRcAfn+c8zlnzrnWyhhTSlFKGWNa63OOtXbvLaUkhCCEHgA45/Te995jjFLKGKO1llLy3hNChBAxRmPM+76llLVWCME5BwAfwHdotg9If3YAAAAASUVORK5CYII=');background-size:cover;display:block"></span>
<img class="gatsby-resp-image-image" alt="b" title="b" src="/static/b576220ab6515d44255ef56699077bab/e9ff0/11.png" srcSet="/static/b576220ab6515d44255ef56699077bab/e9ff0/11.png 180w" sizes="(max-width: 180px) 100vw, 180px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0" loading="lazy"/>
</span></p><p>Here is our trainer function:</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">trainModel</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span>model<span class="token punctuation">,</span> epochs<span class="token punctuation">,</span> alpha<span class="token punctuation">,</span> xTrain<span class="token punctuation">,</span> yTrain<span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// The is the history array of how NanoNeuron learns.</span>
<span class="token keyword">const</span> costHistory <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">// Let's start counting epochs.</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> epoch <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> epoch <span class="token operator"><</span> epochs<span class="token punctuation">;</span> epoch <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Forward propagation.</span>
<span class="token keyword">const</span> <span class="token punctuation">[</span>predictions<span class="token punctuation">,</span> cost<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">forwardPropagation</span><span class="token punctuation">(</span>model<span class="token punctuation">,</span> xTrain<span class="token punctuation">,</span> yTrain<span class="token punctuation">)</span><span class="token punctuation">;</span>
costHistory<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>cost<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Backward propagation.</span>
<span class="token keyword">const</span> <span class="token punctuation">[</span>dW<span class="token punctuation">,</span> dB<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">backwardPropagation</span><span class="token punctuation">(</span>predictions<span class="token punctuation">,</span> xTrain<span class="token punctuation">,</span> yTrain<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Adjust our NanoNeuron parameters to increase accuracy of our model predictions.</span>
nanoNeuron<span class="token punctuation">.</span>w <span class="token operator">+=</span> alpha <span class="token operator">*</span> dW<span class="token punctuation">;</span>
nanoNeuron<span class="token punctuation">.</span>b <span class="token operator">+=</span> alpha <span class="token operator">*</span> dB<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> costHistory<span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre></div><h3 id="putting-all-the-pieces-together" style="position:relative">Putting all the pieces together<a href="#putting-all-the-pieces-together" aria-label="putting all the pieces together permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h3><p>Now let's use the functions we have created above.</p><p>Let's create our NanoNeuron model instance. At this moment the NanoNeuron doesn't know what values should be set for parameters <code class="language-text">w</code> and <code class="language-text">b</code>. So let's set up <code class="language-text">w</code> and <code class="language-text">b</code> randomly.</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> w <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// i.e. -> 0.9492</span>
<span class="token keyword">const</span> b <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// i.e. -> 0.4570</span>
<span class="token keyword">const</span> nanoNeuron <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">NanoNeuron</span><span class="token punctuation">(</span>w<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div><p>Generate training and test data-sets.</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token punctuation">[</span>xTrain<span class="token punctuation">,</span> yTrain<span class="token punctuation">,</span> xTest<span class="token punctuation">,</span> yTest<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">generateDataSets</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div><p>Let's train the model with small incremental (<code class="language-text">0.0005</code>) steps for <code class="language-text">70000</code> epochs. You can play with these parameters, they are being defined empirically.</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> epochs <span class="token operator">=</span> <span class="token number">70000</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> alpha <span class="token operator">=</span> <span class="token number">0.0005</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> trainingCostHistory <span class="token operator">=</span> <span class="token function">trainModel</span><span class="token punctuation">(</span><span class="token punctuation">{</span>model<span class="token operator">:</span> nanoNeuron<span class="token punctuation">,</span> epochs<span class="token punctuation">,</span> alpha<span class="token punctuation">,</span> xTrain<span class="token punctuation">,</span> yTrain<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div><p>Let's check how the cost function was changing during the training. We're expecting that the cost after the training should be much lower than before. This would mean that NanoNeuron got smarter. The opposite is also possible.</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Cost before the training:'</span><span class="token punctuation">,</span> trainingCostHistory<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// i.e. -> 4694.3335043</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Cost after the training:'</span><span class="token punctuation">,</span> trainingCostHistory<span class="token punctuation">[</span>epochs <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// i.e. -> 0.0000024</span></code></pre></div><p>This is how the training cost changes over the epochs. On the <code class="language-text">x</code> axes is the epoch number x1000.</p><p><span class="gatsby-resp-image-wrapper" style="position:relative;display:block;margin-left:auto;margin-right:auto;max-width:400px">
<span class="gatsby-resp-image-background-image" style="padding-bottom:59.199999999999996%;position:relative;bottom:0;left:0;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAABDElEQVQoz62Ty26DMBBF+f+P6qZSF11VTao+0qSkgYgGDAg/wC9uNVOB1FUV6Ehjj0f28bXHTsZxBFknO8hBcUy5KX+tJQzrOpRVCRvsDFxqDOz7Hk3TwAU3wxYrnBZKJdEN8n8UEkBrDeMMfPDrFFITQoBWiotig1tVGAbWdY2qqqCdgbFmPTCOEVppVldK8evI10LnO1RKMfjU5Jg2iTH+9GOcFf/lyUQmIFkqPvF22S+vsvcezjm0bQuKgw+429/j5uUWD6ctXr/e2bPmDGcdz6V50zpr7TwmT4wxEEIgyzJQTNX21mOze8Ljxxa78oDN+RmHS4pjeuT3Sk+MPkNRFMjzHMMw8Akp/w35tK/WM7kZgQAAAABJRU5ErkJggg==');background-size:cover;display:block"></span>
<img class="gatsby-resp-image-image" alt="Training process" title="Training process" src="/static/191860d6f0cd8cf7d24127f04f779462/e17e5/12.png" srcSet="/static/191860d6f0cd8cf7d24127f04f779462/63868/12.png 250w,/static/191860d6f0cd8cf7d24127f04f779462/e17e5/12.png 400w" sizes="(max-width: 400px) 100vw, 400px" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0" loading="lazy"/>
</span></p><p>Let's take a look at NanoNeuron parameters to see what it has learned. We expect that NanoNeuron parameters <code class="language-text">w</code> and <code class="language-text">b</code> to be similar to ones we have in the <code class="language-text">celsiusToFahrenheit()</code> function (<code class="language-text">w = 1.8</code> and <code class="language-text">b = 32</code>) since our NanoNeuron tried to imitate it.</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'NanoNeuron parameters:'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>w<span class="token operator">:</span> nanoNeuron<span class="token punctuation">.</span>w<span class="token punctuation">,</span> b<span class="token operator">:</span> nanoNeuron<span class="token punctuation">.</span>b<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// i.e. -> {w: 1.8, b: 31.99}</span></code></pre></div><p>Evaluate the model accuracy for the test data-set to see how well our NanoNeuron deals with new unknown data predictions. The cost of predictions on test sets is expected to be close to the training cost. This would mean that our NanoNeuron performs well on known and unknown data.</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token punctuation">[</span>testPredictions<span class="token punctuation">,</span> testCost<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">forwardPropagation</span><span class="token punctuation">(</span>nanoNeuron<span class="token punctuation">,</span> xTest<span class="token punctuation">,</span> yTest<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Cost on new testing data:'</span><span class="token punctuation">,</span> testCost<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// i.e. -> 0.0000023</span></code></pre></div><p>Now, since we see that our NanoNeuron "kid" has performed well in the "school" during the training and that he can convert Celsius to Fahrenheit temperatures correctly, even for the data it hasn't seen, we can call it "smart" and ask him some questions. This was the ultimate goal of the entire training process.</p><div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> tempInCelsius <span class="token operator">=</span> <span class="token number">70</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> customPrediction <span class="token operator">=</span> nanoNeuron<span class="token punctuation">.</span><span class="token function">predict</span><span class="token punctuation">(</span>tempInCelsius<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">NanoNeuron "thinks" that </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>tempInCelsius<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">°C in Fahrenheit is:</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> customPrediction<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -> 158.0002</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Correct answer is:'</span><span class="token punctuation">,</span> <span class="token function">celsiusToFahrenheit</span><span class="token punctuation">(</span>tempInCelsius<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -> 158</span></code></pre></div><p>So close! As all of us humans, our NanoNeuron is good but not ideal :)</p><p>Happy learning to you!</p><h2 id="how-to-launch-nanoneuron" style="position:relative">How to launch NanoNeuron<a href="#how-to-launch-nanoneuron" aria-label="how to launch nanoneuron permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h2><p>You may clone the repository and run it locally:</p><div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token function">git</span> clone https://github.com/trekhleb/nano-neuron.git
<span class="token builtin class-name">cd</span> nano-neuron</code></pre></div><div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash">node ./NanoNeuron.js</code></pre></div><h2 id="skipped-machine-learning-concepts" style="position:relative">Skipped machine learning concepts<a href="#skipped-machine-learning-concepts" aria-label="skipped machine learning concepts permalink" class="gatsby-remark-autolink-header-anchor after"><svg aria-hidden="true" focusable="false" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h2><p>The following machine learning concepts were skipped and simplified for simplicity of explanation.</p><p><strong>Training/testing data-set splitting</strong></p><p>Normally you have one big set of data. Depending on the number of examples in that set, you may want to split it in proportion of 70/30 for train/test sets. The data in the set should be randomly shuffled before the split. If the number of examples is big (i.e. millions) then the split might happen in proportions that are closer to 90/10 or 95/5 for train/test data-sets.</p><p><strong>The network brings the power</strong></p><p>Normally you won't notice the usage of just one standalone neuron. The power is in the <a href="https://en.wikipedia.org/wiki/Neural_network">network</a> of such neurons. The network might learn much more complex features. NanoNeuron alone looks more like a simple <a href="https://en.wikipedia.org/wiki/Linear_regression">linear regression</a> than a neural network.</p><p><strong>Input normalization</strong></p><p>Before the training, it would be better to <a href="https://www.jeremyjordan.me/batch-normalization/">normalize input values</a>.</p><p><strong>Vectorized implementation</strong></p><p>For networks, the vectorized (matrix) calculations work much faster than <code class="language-text">for</code> loops. Normally forward/backward propagation works much faster if it is implemented in vectorized form and calculated using, for example, <a href="https://numpy.org/">Numpy</a> Python library.</p><p><strong>Minimum of the cost function</strong></p><p>The cost function that we were using in this example is over-simplified. It should have <a href="https://stackoverflow.com/questions/32986123/why-the-cost-function-of-logistic-regression-has-a-logarithmic-expression/32998675">logarithmic components</a>. Changing the cost function will also change its derivatives so the back propagation step would also use different formulas.</p><p><strong>Activation function</strong></p><p>Normally the output of a neuron should be passed through an activation function like <a href="https://en.wikipedia.org/wiki/Sigmoid_function">Sigmoid</a> or <a href="https://en.wikipedia.org/wiki/Rectifier_(neural_networks)">ReLU</a> or others.</p></article></div><div class="flex flex-row justify-center items-center mt-16"><div class="max-w-md"><div class="bg-white rounded-md shadow-md p-8"><h1 class="text-grey-darkest uppercase font-bold text-xl mb-3">Subscribe to the Newsletter</h1><p class="text-sm mb-3">Get my latest posts and project updates by email</p><form action="https://dev.us1.list-manage.com/subscribe/post?u=7714f14ff32085c685da2cfaa&amp;id=53ffa81463" method="post" class="flex flex-col"><input type="text" placeholder="First Name" name="FNAME" class="border py-2 px-3 mb-3 rounded border-gray-300 border-solid appearance-none" required=""/><input type="email" placeholder="Email" name="EMAIL" class="border py-2 px-3 mb-3 rounded border-gray-300 border-solid appearance-none" required=""/><div class="hidden" aria-hidden="true"><input type="text" name="b_7714f14ff32085c685da2cfaa_53ffa81463" tabindex="-1"/></div><input type="submit" value="Subscribe" class="transition duration-200 ease-in-out bg-black text-white py-2 px-3 rounded shadow-sm cursor-pointer hover:bg-gray-800"/></form></div></div></div></article><footer class="px-6 sm:px-12 py-12"><div class="flex flex-col sm:flex-row items-center "><div style="flex:1" class="flex flex-row items-center mb-6 sm:mb-0"><a class="transition duration-200 ease-in-out flex flex-row items-center hover:text-red-600 text-xs mr-5" href="/subscribe"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024" height="20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zm-40 110.8V792H136V270.8l-27.6-21.5 39.3-50.5 42.8 33.3h643.1l42.8-33.3 39.3 50.5-27.7 21.5zM833.6 232L512 482 190.4 232l-42.8-33.3-39.3 50.5 27.6 21.5 341.6 265.6a55.99 55.99 0 0 0 68.7 0L888 270.8l27.6-21.5-39.3-50.5-42.7 33.2z"></path></svg><span class="w-2"></span>Subscribe</a><a href="https://github.com/trekhleb/trekhleb.github.io/discussions" class="transition duration-200 ease-in-out flex flex-row items-center hover:text-red-600 text-xs mr-5"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height="20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path></svg><span class="w-2"></span>Feedback</a><a class="transition duration-200 ease-in-out flex flex-row items-center hover:text-red-600 text-xs" href="/rss.xml"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height="20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="M4 11a9 9 0 0 1 9 9"></path><path d="M4 4a16 16 0 0 1 16 16"></path><circle cx="5" cy="19" r="1"></circle></svg><span class="w-2"></span>RSS</a></div><div style="flex:1" class="flex flex-row items-center justify-center"><ul class="flex flex-row flex-wrap "><li class="flex flex-row items-center last:mr-0 mr-2 ml-2"><a href="https://www.linkedin.com/in/trekhleb/" class="transition duration-200 ease-in-out flex flex-row items-center hover:text-red-600 " title="Oleksii Trekhleb on LinkedIn"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 448 512" class="w-5 h-5" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"></path></svg></a></li><li class="flex flex-row items-center last:mr-0 mr-2 ml-2"><a href="https://github.com/trekhleb" class="transition duration-200 ease-in-out flex flex-row items-center hover:text-red-600 " title="Oleksii Trekhleb on GitHub"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 496 512" class="w-5 h-5" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"></path></svg></a></li><li class="flex flex-row items-center last:mr-0 mr-2 ml-2"><a href="https://twitter.com/Trekhleb" class="transition duration-200 ease-in-out flex flex-row items-center hover:text-red-600 " title="Oleksii Trekhleb on Twitter"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" class="w-5 h-5" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"></path></svg></a></li></ul></div><div style="flex:1" class="hidden sm:flex"> </div></div></footer></div></main></div><div id="gatsby-announcer" style="position:absolute;top:0;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0" aria-live="assertive" aria-atomic="true"></div></div><script async="" src="https://www.googletagmanager.com/gtag/js?id=G-YJ73BX984Z"></script><script>
if(true) {
window.dataLayer = window.dataLayer || [];
function gtag(){window.dataLayer && window.dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-YJ73BX984Z', {"send_page_view":false});
}
</script><script id="gatsby-script-loader">/*<![CDATA[*/window.pagePath="/blog/2019/nano-neuron/";/*]]>*/</script><script id="gatsby-chunk-mapping">/*<![CDATA[*/window.___chunkMapping={"polyfill":["/polyfill-b7afeec9af34d175ba4b.js"],"app":["/app-2e0826ec06cafce3bdee.js"],"component---src-pages-404-tsx":["/component---src-pages-404-tsx-63f1eb2c9d9eccd00add.js"],"component---src-pages-blog-tsx":["/component---src-pages-blog-tsx-09e5ed745cd76684f8ac.js"],"component---src-pages-index-tsx":["/component---src-pages-index-tsx-700f213869b8e0037911.js"],"component---src-pages-projects-tsx":["/component---src-pages-projects-tsx-781dc12fd2babbe9fac0.js"],"component---src-pages-subscribe-confirm-index-tsx":["/component---src-pages-subscribe-confirm-index-tsx-7d43f1b2228f03a924f8.js"],"component---src-pages-subscribe-index-tsx":["/component---src-pages-subscribe-index-tsx-c02ecb9201e3fc4b2ce6.js"],"component---src-pages-subscribe-thanks-index-tsx":["/component---src-pages-subscribe-thanks-index-tsx-cec855950644a6361532.js"],"component---src-templates-post-tsx":["/component---src-templates-post-tsx-c4045391b1a7c095d609.js"],"component---src-templates-project-tsx":["/component---src-templates-project-tsx-d7e84ca35145045f8249.js"]};/*]]>*/</script><script src="/polyfill-b7afeec9af34d175ba4b.js" nomodule=""></script><script src="/component---src-templates-post-tsx-c4045391b1a7c095d609.js" async=""></script><script src="/commons-213c962999d4e181c8a0.js" async=""></script><script src="/app-2e0826ec06cafce3bdee.js" async=""></script><script src="/framework-d63adeb7e1b44b7b8aa5.js" async=""></script><script src="/webpack-runtime-98886e4c056db07027a1.js" async=""></script></body></html>