Files
MNIST/docs/nbconvert/HTML_convert/02_model_training.html
T
2026-05-15 21:33:11 -05:00

2320 lines
161 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html>
<head>
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'><style type='text/css'>html {overflow-x: initial !important;}</style>
<style type='text/css' id="style-base">:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; --monospace: "Lucida Console",Consolas,"Courier",monospace; --title-bar-height: 20px; }
.mac-os-11 { --title-bar-height: 28px; }
html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, "Segoe UI Emoji", "SF Pro", sans-serif; -webkit-font-smoothing: antialiased; }
h1, h2, h3, h4, h5 { white-space: pre-wrap; }
body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857; overflow-x: hidden; background: inherit; }
iframe { margin: auto; }
a.url { word-break: break-all; }
a:active, a:hover { outline: 0px; }
.in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); }
#write { margin: 0px auto; height: auto; width: inherit; word-break: normal; overflow-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; }
#write.first-line-indent p { text-indent: 2em; }
#write.first-line-indent li p, #write.first-line-indent p *, #write.first-line-indent svg * { text-indent: 0px; }
#write.first-line-indent li { margin-left: 2em; }
.for-image #write { padding-left: 8px; padding-right: 8px; }
body.typora-export { padding-left: 30px; padding-right: 30px; }
.typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; }
.typora-export .task-list-item input { pointer-events: none; }
@media screen and (max-width: 500px) {
body.typora-export { padding-left: 0px; padding-right: 0px; }
#write { padding-left: 20px; padding-right: 20px; }
}
#write li > figure:last-child { margin-bottom: 0.5rem; }
#write ol, #write ul { position: relative; }
img { max-width: 100%; vertical-align: middle; image-orientation: from-image; }
button, input, select, textarea { color: inherit; font: inherit; }
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
*, ::after, ::before { box-sizing: border-box; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; position: relative; }
#write svg h1, #write svg h2, #write svg h3, #write svg h4, #write svg h5, #write svg h6, #write svg p { position: static; }
svg sub, svg sup { position: static; }
.nodeLabel p { padding-right: 2px; padding-left: 2px; }
.typora-export .nodeLabel p { padding-right: 0px; padding-left: 0px; }
foreignobject { overflow: visible; }
p { line-height: inherit; }
h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; }
p { orphans: 4; }
li p { orphans: 1; }
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.6rem; }
h4 { font-size: 1.4rem; }
h5 { font-size: 1.2rem; }
h6 { font-size: 1rem; }
.md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; }
.hidden { display: none; }
.md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; }
a { cursor: pointer; }
sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-radius: 4px; cursor: pointer; }
sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; }
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; }
figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; }
figure > table { margin: 0px; }
thead, tr { break-inside: avoid; break-after: auto; }
thead { display: table-header-group; }
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }
table.md-table td { min-width: 32px; }
.CodeMirror-gutters { border-right: 0px; background-color: inherit; }
.CodeMirror-linenumber { user-select: none; }
.CodeMirror { text-align: left; }
.CodeMirror-placeholder { opacity: 0.3; }
.CodeMirror pre { padding: 0px 4px; }
.CodeMirror-lines { padding: 0px; }
div.hr:focus { cursor: none; }
#write pre { white-space: pre-wrap; }
#write.fences-no-line-wrapping pre { white-space: pre; }
#write pre.ty-contain-cm { white-space: normal; }
.CodeMirror-gutters { margin-right: 4px; }
.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background: inherit; position: relative !important; }
.md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }
#write .md-fences.mock-cm { white-space: pre-wrap; }
.md-fences.md-fences-with-lineno { padding-left: 0px; }
#write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; }
.md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; }
.CodeMirror-line, twitterwidget { break-inside: avoid; }
svg { break-inside: avoid; }
.footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; }
.footnotes + .footnotes { margin-top: 0px; }
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; background: 0px 0px; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; -webkit-tap-highlight-color: transparent; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; }
li div { padding-top: 0px; }
blockquote { margin: 1rem 0px; }
li .mathjax-block, li p { margin: 0.5rem 0px; }
li blockquote { margin: 1rem 0px; }
li { margin: 0px; position: relative; }
blockquote > :last-child { margin-bottom: 0px; }
blockquote > :first-child, li > :first-child { margin-top: 0px; }
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; }
#write .footnote-line { white-space: pre-wrap; }
@media print {
body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; }
#write { margin-top: 0px; border-color: transparent !important; padding-top: 0px !important; padding-bottom: 0px !important; }
.typora-export * { -webkit-print-color-adjust: exact; }
.typora-export #write { break-after: avoid; }
.typora-export #write::after { height: 0px; }
.is-mac table { break-inside: avoid; }
#write > p:nth-child(1) { margin-top: 0px; }
.typora-export-show-outline .typora-export-sidebar { display: none; }
figure { overflow-x: visible; }
}
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
a img, img a { cursor: pointer; }
pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background: rgb(204, 204, 204); display: block; overflow-x: hidden; }
p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; }
#write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; }
p > .md-image:only-child { display: inline-block; width: 100%; }
#write .MathJax_Display { margin: 0.8em 0px 0px; }
.md-math-block { width: 100%; }
.md-math-block:not(:empty)::after { display: none; }
.MathJax_ref { fill: currentcolor; }
[contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; }
.md-task-list-item { position: relative; list-style-type: none; }
.task-list-item.md-task-list-item { padding-left: 0px; }
.md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; }
.math { font-size: 1rem; }
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-radius: 10px; }
.md-toc-content { position: relative; margin-left: 0px; }
.md-toc-content::after, .md-toc::after { display: none; }
.md-toc-item { display: block; color: rgb(65, 131, 196); }
.md-toc-item a { text-decoration: none; }
.md-toc-inner:hover { text-decoration: underline; }
.md-toc-inner { display: inline-block; cursor: pointer; }
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; }
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
@media screen and (max-width: 48em) {
.md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
.md-toc-h4 .md-toc-inner { margin-left: 5em; }
.md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
.md-toc-h6 .md-toc-inner { margin-left: 8em; }
}
a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }
.footnote-line a:not(.reversefootnote) { color: inherit; }
.reversefootnote { font-family: ui-monospace, sans-serif; }
.md-attr { display: none; }
.md-fn-count::after { content: "."; }
code, pre, samp, tt { font-family: var(--monospace); }
kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; }
.md-comment { color: rgb(162, 127, 3); opacity: 0.6; font-family: var(--monospace); }
code { text-align: left; vertical-align: initial; }
a.md-print-anchor { white-space: pre !important; border-width: initial !important; border-style: none !important; border-color: initial !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; background: 0px 0px !important; text-decoration: initial !important; text-shadow: initial !important; }
.os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; }
.md-diagram-panel > svg { max-width: 100%; }
[lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; }
[lang="mermaid"] .node text { font-size: 1rem; }
table tr th { border-bottom: 0px; }
video { max-width: 100%; display: block; margin: 0px auto; }
iframe { max-width: 100%; width: 100%; border: none; }
.highlight td, .highlight tr { border: 0px; }
mark { background: rgb(255, 255, 0); color: rgb(0, 0, 0); }
.md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; }
.md-expand mark .md-meta { opacity: 0.3 !important; }
mark .md-meta { color: rgb(0, 0, 0); }
@media print {
.typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; }
}
.md-diagram-panel .messageText { stroke: none !important; }
.md-diagram-panel .start-state { fill: var(--node-fill); }
.md-diagram-panel .edgeLabel rect { opacity: 1 !important; }
.md-fences.md-fences-math { font-size: 1em; }
.md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; }
.md-fences-advanced:not(.md-focus) { background: inherit; }
.mermaid-svg { margin: auto; }
.typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; }
.typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; }
.typora-export-show-outline #write { --webkit-flex: 2; flex: 2 1 0%; }
.typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; }
@media screen and (max-width: 1024px) {
.typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; }
}
@media screen and (max-width: 800px) {
.typora-export-sidebar { display: none; }
}
.outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; overflow-wrap: anywhere; }
.outline-content ul { margin-top: 0px; margin-bottom: 0px; }
.outline-content strong { font-weight: 400; }
.outline-expander { width: 1rem; height: 1.42857rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; }
.outline-expander::before { content: ""; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; }
.outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; }
.outline-expander:hover::before { content: ""; }
.outline-h1 > .outline-item { padding-left: 0px; }
.outline-h2 > .outline-item { padding-left: 1em; }
.outline-h3 > .outline-item { padding-left: 2em; }
.outline-h4 > .outline-item { padding-left: 3em; }
.outline-h5 > .outline-item { padding-left: 4em; }
.outline-h6 > .outline-item { padding-left: 5em; }
.outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; }
.outline-label:hover { text-decoration: underline; }
.outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); }
.outline-item:hover { margin-left: -28px; margin-right: -28px; border-left: 28px solid transparent; border-right: 28px solid transparent; }
.outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; }
.outline-item-open > .outline-item > .outline-expander::before { content: ""; }
.outline-children { display: none; }
.info-panel-tab-wrapper { display: none; }
.outline-item-open > .outline-children { display: block; }
.typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; }
.typora-export .outline-item:hover { margin-right: -8px; border-right: 8px solid transparent; }
.typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; }
.typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: "−"; }
.typora-export-collapse-outline .outline-children { display: none; }
.typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; }
.typora-export-no-collapse-outline .outline-expander::before { content: "" !important; }
.typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; }
.md-inline-math-container mjx-container { zoom: 0.95; }
mjx-container { break-inside: avoid; }
.md-alert.md-alert-note { border-left-color: rgb(9, 105, 218); }
.md-alert.md-alert-important { border-left-color: rgb(130, 80, 223); }
.md-alert.md-alert-warning { border-left-color: rgb(154, 103, 0); }
.md-alert.md-alert-tip { border-left-color: rgb(31, 136, 61); }
.md-alert.md-alert-caution { border-left-color: rgb(207, 34, 46); }
.md-alert { padding: 0px 1em; margin-bottom: 16px; color: inherit; border-left: 0.25em solid rgb(0, 0, 0); }
.md-alert-text-note { color: rgb(9, 105, 218); }
.md-alert-text-important { color: rgb(130, 80, 223); }
.md-alert-text-warning { color: rgb(154, 103, 0); }
.md-alert-text-tip { color: rgb(31, 136, 61); }
.md-alert-text-caution { color: rgb(207, 34, 46); }
.md-alert-text { font-size: 0.9rem; font-weight: 700; }
.md-alert-text svg { fill: currentcolor; position: relative; top: 0.125em; margin-right: 1ch; overflow: visible; }
.md-alert-text-container::after { content: attr(data-text); text-transform: capitalize; pointer-events: none; margin-right: 1ch; }
</style>
<style type='text/css' id="style-codemirror">.CodeMirror { height: auto; }
.CodeMirror.cm-s-inner { background: inherit; }
.CodeMirror-scroll { overflow: auto hidden; z-index: 3; }
.CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); }
.CodeMirror-gutters { border-right: 1px solid rgb(221, 221, 221); background: inherit; white-space: nowrap; }
.CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); }
.cm-s-inner .cm-keyword { color: rgb(119, 0, 136); }
.cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); }
.cm-s-inner .cm-number { color: rgb(17, 102, 68); }
.cm-s-inner .cm-def { color: rgb(0, 0, 255); }
.cm-s-inner .cm-variable { color: rgb(0, 0, 0); }
.cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); }
.cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); }
.cm-s-inner .cm-string { color: rgb(170, 17, 17); }
.cm-s-inner .cm-property { color: rgb(0, 0, 0); }
.cm-s-inner .cm-operator { color: rgb(152, 26, 26); }
.cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); }
.cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); }
.cm-s-inner .cm-meta { color: rgb(85, 85, 85); }
.cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); }
.cm-s-inner .cm-builtin { color: rgb(51, 0, 170); }
.cm-s-inner .cm-bracket { color: rgb(153, 153, 119); }
.cm-s-inner .cm-tag { color: rgb(17, 119, 0); }
.cm-s-inner .cm-attribute { color: rgb(0, 0, 204); }
.cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); }
.cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); }
.cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); }
.cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); }
.cm-negative { color: rgb(221, 68, 68); }
.cm-positive { color: rgb(34, 153, 34); }
.cm-header, .cm-strong { font-weight: 700; }
.cm-del { text-decoration: line-through; }
.cm-em { font-style: italic; }
.cm-link { text-decoration: underline; }
.cm-error { color: red; }
.cm-invalidchar { color: red; }
.cm-constant { color: rgb(38, 139, 210); }
.cm-defined { color: rgb(181, 137, 0); }
div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); }
div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); }
.cm-s-inner .CodeMirror-activeline-background { background: inherit; }
.CodeMirror { position: relative; overflow: hidden; }
.CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background: inherit; }
.CodeMirror-sizer { position: relative; }
.CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; outline: 0px; }
.CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; }
.CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: auto hidden; }
.CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; }
.CodeMirror-gutter-filler { left: 0px; bottom: 0px; }
.CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 10px; z-index: 3; overflow-y: hidden; }
.CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; }
.CodeMirror-gutter-wrapper { position: absolute; z-index: 4; background: 0px 0px !important; border: none !important; }
.CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; }
.CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; }
.CodeMirror-lines { cursor: text; }
.CodeMirror pre { border-radius: 0px; border-width: 0px; background: 0px 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; overflow-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; }
.CodeMirror-wrap pre { overflow-wrap: break-word; white-space: pre-wrap; word-break: normal; }
.CodeMirror-code pre { border-right: 30px solid transparent; width: fit-content; }
.CodeMirror-wrap .CodeMirror-code pre { border-right: none; width: auto; }
.CodeMirror-linebackground { position: absolute; inset: 0px; z-index: 0; }
.CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; }
.CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; }
.CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; }
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right: none; width: 0px; }
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
.CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; }
.cm-searching { background: rgba(255, 255, 0, 0.4); }
span.cm-underlined { text-decoration: underline; }
span.cm-strikethrough { text-decoration: line-through; }
.cm-tw-syntaxerror { color: rgb(255, 255, 255); background-color: rgb(153, 0, 0); }
.cm-tw-deleted { text-decoration: line-through; }
.cm-tw-header5 { font-weight: 700; }
.cm-tw-listitem:first-child { padding-left: 10px; }
.cm-tw-box { border-style: solid; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-color: inherit; border-top-width: 0px !important; }
.cm-tw-underline { text-decoration: underline; }
@media print {
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
}
</style>
<style type='text/css' id="style-theme_css">/*
* NOTION-STYLE TYPORA THEME - DARK MODE
* Copyright (C) 2025 Aditya Kumar Darak
* Based on original work by cayxc
* Licensed under the Apache License, Version 2.0
* http://www.apache.org/licenses/LICENSE-2.0
*/
/* =========================================================================
Table of Contents
=========================================================================
1. Theme Tokens
2. Base & Layout
3. Block Elements
4. Code & Syntax
5. Inline Elements
6. Sidebar & Navigation
7. Typora Chrome
8. Utilities & Export
========================================================================= */
/* =========================================================================
1. Theme Tokens
========================================================================= */
:root {
/* Colors */
--bg-color: rgba(25, 25, 25, 1);
--text-color: rgba(212, 212, 212, 1);
--accent-color: rgba(156, 166, 168, 1);
--accented-background-color: rgba(193, 202, 204, 1);
--title-color: rgba(212, 212, 212, 1);
--text-grey: rgba(156, 156, 156, 1);
/* Legacy Typora search highlight token. */
--color-2-0-c: rgba(156, 166, 168, 1);
/* Borders */
--border-color: rgba(61, 61, 61, 1);
/* Links and highlights */
--link-color: rgba(127, 179, 255, 1);
--link-hover-color: rgba(179, 212, 255, 1);
--link-hover-bg: rgba(127, 179, 255, 0.12);
--selection-bg: rgba(255, 238, 160, 1);
--selection-color: rgba(0, 0, 0, 1);
--highlight-bg: rgba(255, 238, 160, 1);
--search-highlight-bg: rgba(233, 188, 54, 1);
/* Headings */
--h1-color: rgba(247, 246, 243, 1);
--h2-color: rgba(232, 231, 228, 1);
--h3-color: rgba(212, 212, 212, 1);
--h4-color: rgba(192, 192, 192, 1);
--h5-color: rgba(176, 176, 176, 1);
--h6-color: rgba(160, 160, 160, 1);
/* Sidebar */
--side-bar-bg-color: rgba(32, 32, 32, 1);
--side-bar-border-color: rgba(43, 43, 43, 1);
--active-file-bg-color: rgba(44, 44, 44, 1);
/* Typography */
--body-font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei",
"Noto Sans SC", "Microsoft JhengHei", "Noto Sans TC", "Meiryo", "Yu Gothic",
"Noto Sans JP", "Malgun Gothic", "Noto Sans KR", sans-serif;
--monospace-font: "Sarasa Mono SC", "Source Han Mono", "Space Mono",
"Inconsolata", monospace;
/* Type scale */
--font-size: 16px;
--h1-fontsize: 30px;
--h2-fontsize: 24px;
--h3-fontsize: 20px;
--h4-fontsize: 18px;
--h5-fontsize: 16px;
--h6-fontsize: 16px;
--monospace-font-size: 85%;
/* Line rhythm */
--line-height: 1.6;
--monospace-line-height: normal;
--paragraph-spacing: 19.2px;
/* Layout */
--document-padding-x: 10ch;
--vertical-padding: 40px;
--main-content-max-width: 90%;
--border-radius: 2px;
--border-radius-lg: 4px;
/* Inline code */
--code-font: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
--code-bg-color: rgba(135, 131, 120, 0.15);
--code-color: rgba(235, 87, 87, 1);
--code-border-radius: 3px;
/* Code blocks */
--code-block-bg-color: rgba(32, 32, 32, 1);
--code-block-font-size: 15.2px;
--code-block-line-height: 1.65;
--code-tooltip-height: 34px;
--code-tooltip-gap: calc(var(--code-tooltip-height) + 5px);
--code-tooltip-border-color: rgba(55, 55, 55, 1);
--code-border-color: rgba(255, 255, 255, 0.12);
--code-border-hover-color: rgba(255, 255, 255, 0.2);
--code-selection-bg: rgba(255, 238, 160, 1);
--code-selection-color: rgba(0, 0, 0, 1);
/* Todo checkboxes */
--todo-bg-color: rgba(36, 131, 226, 1);
--todo-check-color: rgba(255, 255, 255, 1);
/* File tree */
--file-tree-font-size: 12px;
/* Diagrams */
--mermaid-theme: dark;
/* Performance */
--gpu-acceleration: translateZ(0);
/* Animation */
--transition-fast: 0.15s;
--transition-normal: 0.2s;
--transition-slow: 0.3s;
--easing-standard: cubic-bezier(0.4, 0, 0.2, 1);
--easing-decelerate: cubic-bezier(0, 0, 0.2, 1);
--easing-accelerate: cubic-bezier(0.4, 0, 1, 1);
}
/* =========================================================================
2. Base & Layout
========================================================================= */
/* Document base */
html {
font-size: var(--font-size);
background-color: var(--bg-color);
}
html,
body {
color: var(--text-color);
font-family: var(--body-font);
line-height: var(--line-height);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
/* Paragraph rhythm */
p {
margin: var(--paragraph-spacing) 0;
line-height: var(--line-height);
}
h1+p,
h2+p,
h3+p,
h4+p,
h5+p,
h6+p {
margin-top: 8px;
}
/* Main document container */
#write {
padding-left: var(--document-padding-x);
padding-right: var(--document-padding-x);
max-width: var(--main-content-max-width);
box-sizing: border-box;
contain: layout style;
}
/* Media */
#write img {
border-radius: 8px;
max-width: 100%;
height: auto;
display: block;
margin-left: auto;
margin-right: auto;
}
/* Image captions */
#write .md-image>.md-meta {
color: rgba(212, 212, 212, 0.7);
font-size: 14px;
font-style: italic;
margin-top: 8px;
text-align: center;
}
/* =========================================================================
3. Block Elements
========================================================================= */
/* Frontmatter (YAML) */
pre.md-meta-block {
background: rgba(32, 32, 32, 1);
color: rgba(255, 255, 255, 0.8);
padding: 12px;
border-radius: 3px;
width: 100%;
border: 1px solid rgba(255, 255, 255, 0.13);
box-shadow: none;
font-family: var(--code-font);
font-size: var(--monospace-font-size);
line-height: 1.5;
}
pre.md-meta-block .md-meta-i {
color: rgba(121, 192, 255, 1);
font-weight: 500;
}
pre.md-meta-block .md-meta-value {
color: rgba(126, 231, 135, 1);
}
/* Headings */
h1 {
margin-top: 48px;
margin-bottom: 24px;
padding-top: 8px;
font-size: var(--h1-fontsize);
font-weight: 700;
line-height: 1.3;
letter-spacing: -0.32px;
color: var(--h1-color);
}
h1:first-child {
margin-top: 16px;
}
h2 {
margin-top: 40px;
margin-bottom: 19.2px;
font-size: var(--h2-fontsize);
font-weight: 600;
line-height: 1.35;
letter-spacing: -0.16px;
color: var(--h2-color);
}
h3 {
margin-top: 32px;
margin-bottom: 16px;
font-size: var(--h3-fontsize);
font-weight: 600;
line-height: 1.4;
letter-spacing: -0.08px;
color: var(--h3-color);
}
h4 {
margin-top: 28px;
margin-bottom: 12.8px;
font-size: var(--h4-fontsize);
font-weight: 600;
line-height: 1.45;
color: var(--h4-color);
}
h5 {
margin-top: 24px;
margin-bottom: 9.6px;
font-size: var(--h5-fontsize);
font-weight: 600;
line-height: 1.5;
color: var(--h5-color);
}
h6 {
margin-top: 24px;
margin-bottom: 9.6px;
font-size: var(--h6-fontsize);
font-weight: 500;
line-height: 1.5;
font-style: italic;
color: var(--h6-color);
}
/* Tables */
#write table {
margin: 24px 0;
width: auto;
max-width: 100%;
border-collapse: separate;
border-spacing: 0;
border: 1px solid var(--border-color);
border-radius: 8px;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}
td,
th {
min-width: 120px;
max-width: 560px;
width: auto;
word-wrap: break-word;
white-space: normal;
border-right: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
padding: 12px 16px;
font-size: 15.2px;
}
td:last-child,
th:last-child {
border-right: none;
}
tbody tr:last-child td {
border-bottom: none;
}
th {
background-color: rgba(255, 255, 255, 0.08);
font-weight: 600;
text-align: left;
color: rgba(255, 255, 255, 0.9);
font-size: 14.4px;
letter-spacing: 0px;
}
tbody tr:nth-child(even) {
background-color: rgba(255, 255, 255, 0.02);
}
tbody tr {
transition: background-color 0.15s ease;
}
tbody tr:hover {
background-color: rgba(255, 255, 255, 0.06);
}
h2+table tr:first-child th,
h2+table tr:first-child td {
border-top-width: 0;
}
td[align="center"],
th[align="center"] {
text-align: center;
}
td[align="right"],
th[align="right"] {
text-align: right;
}
/* Lists */
#write ul,
#write ol {
padding-left: 0;
margin-left: 0;
}
#write ul li,
#write ol li {
padding-left: 0;
margin-left: 32px;
}
ol ol {
counter-reset: sub-counter;
list-style-type: lower-alpha;
}
ol ol ol {
counter-reset: sub-sub-counter;
list-style-type: lower-roman;
}
#write ul>li::marker {
color: var(--accent-color);
font-weight: 600;
}
#write ol>li::marker {
color: var(--accent-color);
font-weight: 600;
font-size: 15.2px;
}
#write ul ul>li::marker,
#write ol ol>li::marker {
color: rgba(156, 166, 168, 0.7);
}
#write ul ul ul>li::marker,
#write ol ol ol>li::marker {
color: rgba(156, 166, 168, 0.5);
}
li p {
margin: 0;
}
/* Task list checkboxes */
#write .md-task-list-item>input {
appearance: none;
-webkit-appearance: none;
display: inline-block;
vertical-align: middle;
position: absolute;
border: 2px solid rgba(212, 212, 212, 0.4);
margin: 3.2px 0 0 -23.2px;
height: 16px;
width: 16px;
border-radius: 3px;
background-color: rgba(0, 0, 0, 0);
cursor: pointer;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
#write .md-task-list-item>input:hover {
border-color: var(--todo-bg-color);
background-color: rgba(36, 131, 226, 0.1);
transform: scale(1.05) var(--gpu-acceleration);
}
#write .md-task-list-item>input:focus {
outline: 2px solid var(--todo-bg-color);
outline-offset: 2px;
box-shadow: 0 0 0 3px rgba(36, 131, 226, 0.1);
}
#write .md-task-list-item>input[checked] {
background: var(--todo-bg-color);
border: 2px solid var(--todo-bg-color);
animation: checkboxPop 0.2s ease-out;
}
@keyframes checkboxPop {
0% {
transform: scale(1);
}
50% {
transform: scale(1.15);
}
100% {
transform: scale(1);
}
}
#write .md-task-list-item>input[checked]::before {
content: "";
display: block;
width: 5.6px;
height: 9.6px;
background: rgba(0, 0, 0, 0);
border: 2px solid var(--todo-check-color);
border-top: none;
border-left: none;
position: absolute;
box-sizing: border-box;
top: 42%;
left: 50%;
transform: translate(-50%, -50%) rotate(45deg);
animation: checkmarkDraw 0.2s ease-out 0.1s both;
}
@keyframes checkmarkDraw {
0% {
height: 0;
width: 0;
}
50% {
height: 9.6px;
width: 0;
}
100% {
height: 9.6px;
width: 5.6px;
}
}
#write .md-task-list-item>input[checked]+label,
#write .md-task-list-item.task-list-done {
color: rgba(156, 156, 156, 0.7);
text-decoration: line-through;
text-decoration-color: rgba(156, 156, 156, 0.5);
transition: all 0.2s ease;
}
.md-image>.md-meta {
border-radius: var(--border-radius);
padding: 2px 0px 0px 4px;
font-size: 14.4px;
color: inherit;
}
/* Blockquotes and Callouts */
#write blockquote {
margin: 24px 0;
padding: 16px 20px 16px 48px;
position: relative;
border-left: 3px solid var(--accent-color);
background-color: rgba(45, 45, 45, 0.4);
border-radius: 5px;
font-style: italic;
color: rgba(212, 212, 212, 0.9);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}
#write blockquote::before {
content: '"';
position: absolute;
left: 12px;
top: 8px;
font-size: 40px;
line-height: 1;
color: var(--accent-color);
opacity: 0.3;
font-family: Georgia, serif;
}
#write blockquote p:first-child {
margin-top: 0;
}
#write blockquote p:last-child {
margin-bottom: 0;
}
.md-alert,
.admonition {
background-color: rgba(45, 45, 45, 0.4);
border-left: 3px solid var(--accent-color);
padding: 16px 20px 16px 48px;
margin: 24px 0;
border-radius: 5px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
position: relative;
}
.md-alert::before,
.admonition::before {
content: 'i';
position: absolute;
left: 14px;
top: 14px;
font-size: 24px;
line-height: 1;
color: var(--accent-color);
opacity: 0.4;
font-family: Georgia, serif;
font-style: italic;
}
.md-alert-note::before {
content: 'i';
}
.md-alert-tip::before {
content: '*';
font-style: normal;
}
.md-alert-important::before {
content: '!';
}
.md-alert-warning::before {
content: '‼';
font-style: normal;
}
.md-alert-caution::before {
content: '×';
font-style: normal;
}
.md-alert-text-container,
.md-alert-title {
display: none;
height: 0;
margin: 0;
padding: 0;
line-height: 0;
}
.md-alert p,
.admonition p {
margin: 0;
}
/* Math blocks */
.md-math-block:hover .md-math-container,
.md-math-block:hover .md-rawblock-tooltip,
.md-htmlblock:hover .md-htmlblock-container,
.md-htmlblock:hover .md-rawblock-tooltip,
.md-rawblock-on-edit:hover .md-rawblock-tooltip,
.md-rawblock-on-edit .md-mathblock-panel,
.md-rawblock-after,
.md-rawblock-before,
.md-rawblock-control:not(.md-rawblock-tooltip) {
background: var(--code-block-bg-color);
}
.md-rawblock-tooltip {
pointer-events: none;
background: var(--code-block-bg-color) !important;
}
.md-rawblock .md-rawblock-tooltip-edit-btn:hover {
background: rgba(0, 0, 0, 0);
}
/* Horizontal rules */
#write hr {
border: none;
height: 1px;
background-color: var(--border-color);
margin: 48px 0;
}
/* =========================================================================
4. Code & Syntax
========================================================================= */
/* Search highlight animation */
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
.md-search-hit,
.md-search-select {
display: inline-block !important;
border-radius: 8px !important;
padding: 0.8px 1.6px !important;
}
.md-search-hit {
color: var(--text-color) !important;
}
.md-search-select {
background: var(--search-highlight-bg) !important;
color: rgba(55, 53, 47, 1) !important;
transform-origin: center center !important;
animation: pulse 0.3s ease-in-out !important;
}
pre {
--monospace: "Cascadia Code Variable", SFMono-Regular, Menlo, Consolas,
"PT Mono", "Liberation Mono";
}
/* Code fences */
.md-fences {
position: relative;
margin: 20px 0 51.2px 0;
background: var(--code-block-bg-color);
border: 1px solid var(--code-border-color);
border-radius: 6px;
overflow: visible;
padding: 0;
font-size: var(--code-block-font-size);
transition: border-color 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease;
contain: layout style;
will-change: border-color, box-shadow;
}
#write .cm-s-inner,
.cm-s-typora-default {
background: rgba(0, 0, 0, 0);
border-radius: 0;
padding: 20px 24px;
font-size: var(--code-block-font-size);
line-height: var(--code-block-line-height);
font-family: var(--monospace-font);
border: none;
}
#write .md-fences :is(pre, code),
.cm-s-typora-default :is(pre, code) {
font-family: var(--monospace-font);
font-size: var(--code-block-font-size);
line-height: var(--code-block-line-height);
background: rgba(0, 0, 0, 0);
}
#write .md-fences pre,
.cm-s-typora-default pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
#write .md-fences code,
.cm-s-typora-default code {
display: block;
white-space: pre-wrap;
word-wrap: break-word;
word-break: break-word;
}
/* WYSIWYG mode hides gutters and line numbers. */
#write .cm-s-inner .CodeMirror-gutters {
width: 0;
opacity: 0;
pointer-events: none;
}
#write .cm-s-inner .CodeMirror-linenumber {
opacity: 0;
}
/* Source mode shows gutters and line numbers. */
.cm-s-typora-default .CodeMirror-gutters {
width: auto;
opacity: 1;
pointer-events: auto;
}
.cm-s-typora-default .CodeMirror-linenumber {
opacity: 1;
color: rgba(106, 214, 154, 1);
padding-right: 12px;
}
.cm-s-typora-default .CodeMirror-line {
padding-left: 6px;
}
#write .cm-s-inner .CodeMirror-cursor,
.cm-s-typora-default .CodeMirror-cursor {
border-left: 2px solid rgba(121, 192, 255, 1);
}
.cm-s-inner,
.cm-s-typora-default {
color: rgba(230, 237, 243, 1);
}
/* CodeMirror token colors. */
:is(.cm-s-inner, .cm-s-typora-default) :is(.cm-keyword, .cm-builtin) {
color: rgba(255, 123, 114, 1);
font-weight: 600;
}
:is(.cm-s-inner, .cm-s-typora-default) .cm-def {
color: rgba(210, 168, 255, 1);
font-weight: 600;
}
:is(.cm-s-inner, .cm-s-typora-default) :is(.cm-variable, .cm-variable-2, .cm-variable-3) {
color: rgba(255, 166, 87, 1);
}
:is(.cm-s-inner, .cm-s-typora-default) :is(.cm-number, .cm-atom) {
color: rgba(121, 192, 255, 1);
font-weight: 500;
}
:is(.cm-s-inner, .cm-s-typora-default) :is(.cm-string, .cm-string-2) {
color: rgba(165, 214, 255, 1);
}
:is(.cm-s-inner, .cm-s-typora-default) .cm-comment {
color: rgba(139, 148, 158, 1);
font-style: italic;
opacity: 0.9;
}
:is(.cm-s-inner, .cm-s-typora-default) .cm-operator {
color: rgba(255, 123, 114, 1);
}
:is(.cm-s-inner, .cm-s-typora-default) :is(.cm-property, .cm-attribute) {
color: rgba(121, 192, 255, 1);
}
:is(.cm-s-inner, .cm-s-typora-default) :is(.cm-type, .cm-tag) {
color: rgba(126, 231, 135, 1);
font-weight: 500;
}
:is(.cm-s-inner, .cm-s-typora-default) .cm-meta {
color: rgba(210, 168, 255, 1);
}
:is(.cm-s-inner, .cm-s-typora-default) .cm-qualifier {
color: rgba(255, 166, 87, 1);
font-weight: 500;
}
:is(.cm-s-inner, .cm-s-typora-default) .cm-bracket {
color: rgba(201, 209, 217, 1);
font-weight: 600;
}
:is(.cm-s-inner, .cm-s-typora-default) :is(.cm-error, .cm-invalidchar) {
color: rgba(248, 81, 73, 1);
text-decoration: wavy underline;
text-decoration-color: rgba(248, 81, 73, 1);
}
:is(.cm-s-inner, .cm-s-typora-default) .cm-header {
color: rgba(121, 192, 255, 1);
font-weight: 600;
}
:is(.cm-s-inner, .cm-s-typora-default) .cm-special {
color: rgba(210, 168, 255, 1);
}
/* Code block toolbar. */
.md-fences .code-tooltip {
background-color: rgba(0, 0, 0, 0);
border-radius: 0;
padding: 0;
height: var(--code-tooltip-height);
display: flex;
align-items: center;
border: none;
box-shadow: none;
backdrop-filter: none;
opacity: 1;
transition: opacity 0.2s ease;
position: absolute;
bottom: calc(-1 * var(--code-tooltip-gap));
right: -5px;
top: auto;
}
#write .md-diagram-panel {
margin-top: calc(var(--code-tooltip-gap) + 5px);
margin-bottom: 59.2px;
}
/* Typora lacks :has; position tooltip below diagram fences. */
#write .md-fences:is([lang="mermaid"],
[lang="flowchart"],
[lang="sequence"],
[lang="gantt"],
[lang="classDiagram"],
[lang="stateDiagram"],
[lang="erDiagram"],
[lang="journey"],
[lang="pie"],
[lang="gitGraph"],
[lang="mindmap"],
[lang="timeline"],
[lang="js-sequence-diagram"],
[lang="flow"]) .code-tooltip {
right: -5px;
bottom: auto;
top: 100%;
margin-top: 5px;
}
.md-fences .code-tooltip :is(input, span) {
padding: 6px 10px;
border-radius: 5px;
margin: 0 3px;
font-size: 13.6px;
font-weight: 500;
transition: all 0.2s ease;
}
.md-fences .code-tooltip input {
background-color: rgba(0, 0, 0, 0);
border: 1px solid rgba(0, 0, 0, 0);
color: rgba(255, 255, 255, 0.6);
}
.md-fences .code-tooltip input:hover,
.md-fences .code-tooltip input:focus {
background-color: rgba(255, 255, 255, 0.05);
border-color: rgba(255, 255, 255, 0.2);
color: rgba(255, 255, 255, 0.9);
}
.md-fences .code-tooltip span {
cursor: pointer;
color: rgba(255, 255, 255, 0.7);
background-color: rgba(255, 255, 255, 0.08);
border: 1px solid rgba(255, 255, 255, 0.15);
font-weight: 500;
}
.md-fences .code-tooltip span:hover {
background-color: rgba(255, 255, 255, 0.15);
color: rgba(255, 255, 255, 1);
border-color: rgba(255, 255, 255, 0.25);
transform: translateY(-1px);
}
.md-fences .code-tooltip span:active {
transform: translateY(0);
}
/* Autocomplete dropdown. */
.autoComplt-list {
width: 20ch !important;
border-radius: 6px !important;
background-color: rgba(43, 43, 43, 1) !important;
border: 1px solid var(--border-color) !important;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
overflow: hidden;
}
.autoComplt-hint {
background-color: rgba(0, 0, 0, 0) !important;
margin: 0 !important;
padding: 4px 12px !important;
color: var(--text-color) !important;
line-height: var(--line-height) !important;
height: auto !important;
cursor: pointer;
transition: background-color 0.15s ease;
}
.autoComplt-hint-selected {
background-color: rgba(61, 61, 61, 1) !important;
color: rgba(121, 192, 255, 1) !important;
}
/* =========================================================================
5. Inline Elements
========================================================================= */
/* Inline code. */
code {
font-family: var(--code-font);
font-size: var(--monospace-font-size);
line-height: var(--monospace-line-height);
color: var(--code-color);
background-color: var(--code-bg-color);
padding: 3.2px 6.4px;
border-radius: var(--code-border-radius);
border: none;
font-weight: 400;
}
/* Links. */
#write a {
text-decoration: none;
color: var(--link-color);
border-bottom: 1px solid rgba(0, 0, 0, 0);
padding: 0 2px;
margin: 0 -2px;
border-radius: 2px;
transition: color 0.2s ease, background-color 0.2s ease, border-color 0.2s ease;
}
#write a:hover {
color: var(--link-hover-color);
background-color: var(--link-hover-bg);
border-bottom-color: var(--link-hover-color);
}
#write a:focus {
outline: 2px solid var(--link-hover-color);
outline-offset: 2px;
background-color: var(--link-hover-bg);
}
#write a:active {
transform: translateY(1px) var(--gpu-acceleration);
}
/* Selection and marks. */
::selection {
background-color: var(--selection-bg);
color: var(--selection-color);
}
.cm-s-inner .CodeMirror-selected,
.cm-s-typora-default .CodeMirror-selected {
background: rgba(0, 0, 0, 0) !important;
}
.cm-s-inner .CodeMirror-selectedtext,
.cm-s-typora-default .CodeMirror-selectedtext {
background: var(--code-selection-bg) !important;
color: var(--code-selection-color) !important;
}
mark {
background-color: var(--highlight-bg);
color: rgba(55, 53, 47, 1);
padding: 2px 0;
border-radius: 0;
}
mark.yellow,
mark {
background-color: rgba(255, 238, 160, 1);
color: rgba(55, 53, 47, 1);
}
mark.red {
background-color: rgba(90, 44, 44, 1);
color: rgba(255, 184, 177, 1);
}
mark.blue {
background-color: rgba(43, 66, 87, 1);
color: rgba(156, 199, 232, 1);
}
mark.green {
background-color: rgba(43, 74, 63, 1);
color: rgba(147, 225, 200, 1);
}
mark.orange {
background-color: rgba(89, 74, 58, 1);
color: rgba(255, 204, 153, 1);
}
mark.purple {
background-color: rgba(68, 63, 87, 1);
color: rgba(212, 197, 249, 1);
}
mark.pink {
background-color: rgba(83, 59, 71, 1);
color: rgba(255, 184, 210, 1);
}
mark.brown {
background-color: rgba(67, 64, 64, 1);
color: rgba(212, 196, 176, 1);
}
mark.gray {
background-color: rgba(58, 58, 58, 1);
color: rgba(193, 193, 193, 1);
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
/* =========================================================================
6. Sidebar & Navigation
========================================================================= */
/* Table of contents. */
#write div.md-toc-tooltip {
background-color: var(--bg-color);
}
.md-toc {
margin-top: 40px;
}
.md-toc .md-toc-h2 {
margin-left: 16px;
}
.md-toc .md-toc-h3 {
margin-left: 32px;
}
.md-toc .md-toc-h4 {
margin-left: 48px;
}
.md-toc .md-toc-h5 {
margin-left: 64px;
}
.md-toc .md-toc-h6 {
margin-left: 80px;
}
.sidebar-footer {
border-top: 1px solid var(--side-bar-border-color);
}
.pin-outline #typora-sidebar {
box-shadow: none;
border-right: 1px solid var(--side-bar-border-color);
}
.sidebar-tabs {
border-bottom: 1px solid var(--side-bar-border-color) !important;
}
/* Outline tree. */
.outline-content {
padding: 16px;
font-size: 14px !important;
}
.outline-content li {
position: relative;
z-index: 30;
line-height: 1.3 !important;
margin-bottom: 0;
}
.outline-content li::before {
content: "";
width: 1px;
height: calc(100% + 5px);
position: absolute;
z-index: 30;
left: 0;
top: 0;
border-left: 1px solid var(--border-color);
}
.outline-content>li:first-of-type::before {
top: 0;
}
.outline-content li a {
font-size: 14px !important;
}
.outline-content li ul {
margin-left: 20px;
margin-top: 0 !important;
position: relative;
z-index: 48;
}
.outline-content ul li::before {
content: "";
width: 1px;
height: calc(100% + 10px);
top: -10px;
border-left: 1px solid var(--border-color);
}
.outline-content ul>li:last-of-type::before {
content: "";
width: 1px;
height: 10px;
top: -10px;
left: 0;
border-left: 1px solid var(--border-color);
}
.outline-content li .outline-item {
margin: 0 0 3px 7px;
padding: 4px 8px;
position: relative;
z-index: 50;
border-radius: 5px;
border: 1px solid rgba(0, 0, 0, 0);
}
.outline-item>.outline-label {
text-decoration: none;
}
.outline-content li .outline-item:hover,
.outline-content li .outline-item-active {
z-index: 70;
}
.outline-content li .outline-item::before {
content: "";
width: 12px;
height: calc(50% + 12px);
position: absolute;
z-index: 38;
left: -8px;
top: -11.5px;
background: rgba(0, 0, 0, 0);
border-left: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
}
.outline-content>li:first-of-type>.outline-item::before {
top: calc(50% - 1px) !important;
border-top: 1px solid var(--border-color);
border-bottom: none;
border-top-left-radius: 3px;
-webkit-border-top-left-radius: 3px;
border-bottom-left-radius: 0;
-webkit-border-bottom-left-radius: 0;
}
.outline-content>li:first-of-type>.outline-item::after {
content: "";
width: 1px;
height: 100%;
position: absolute;
z-index: 35;
left: -8px;
top: -2px;
border-left: 1px solid var(--bg-color);
}
.outline-content>li:last-of-type>.outline-item::before,
.outline-content>li ul>li:last-of-type>.outline-item::before {
z-index: 90;
background: rgba(0, 0, 0, 0);
border-left: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
border-top: none !important;
border-bottom-left-radius: 3px;
-webkit-border-bottom-left-radius: 3px;
border-top-left-radius: 0;
-webkit-border-top-left-radius: 0;
}
.outline-content>li:only-of-type>.outline-item::before,
.outline-content>li:last-of-type::before {
display: none;
}
.outline-content>li:only-of-type {
margin-left: -6px;
}
.outline-expander {
padding-left: 0;
width: auto;
height: 8px;
background: rgba(0, 0, 0, 0);
}
.outline-expander:before {
font-size: 10px;
padding: 0 4px 0 2px;
margin-top: -2px;
margin-left: -2px;
background: rgba(0, 0, 0, 0);
}
.outline-item:hover,
.outline-item:hover>.outline-expander:before,
.outline-item:hover>.outline-expander {
background: var(--active-file-bg-color) !important;
color: var(--text-color) !important;
}
li>.outline-item-active {
background: var(--active-file-bg-color);
}
.outline-item:hover::before,
.outline-item-active::before {
width: 7px !important;
}
.outline-item-active .outline-expander {
font-weight: 900 !important;
}
.ty-on-outline-filter .outline-content li::before,
.ty-on-outline-filter .outline-content .outline-item::before,
.ty-on-outline-filter .outline-content .outline-item::after {
display: none;
}
.ty-on-outline-filter .outline-content>li>ul,
.ty-on-outline-filter .outline-content .outline-item {
margin-left: 0;
}
/* =========================================================================
7. Typora Chrome
========================================================================= */
/* File library list and search. */
#file-library-list,
#file-library-search-result {
padding: 12px;
}
#file-library-list .file-list-item,
#file-library-search-result .ty-search-item {
margin-bottom: 8px;
border: 1px solid rgba(0, 0, 0, 0);
border-bottom-color: var(--border-color);
}
#file-library-list .file-list-item {
padding-left: 12px;
padding-right: 12px;
}
#file-library-list .file-list-item.active,
#file-library-search-result .ty-search-item.active {
border-radius: 5px;
border: 1px solid var(--text-color);
}
#file-library-list .file-list-item.active {
padding: 6px 12px;
}
#file-library-search-result .ty-search-item.active {
padding: 6px 12px 6px 0;
}
#file-library-list .file-list-item:first-of-type.active,
#file-library-search-result .ty-search-item:first-of-type.active {
margin-top: 0;
}
#file-library-list .file-list-item:hover,
#file-library-search-result .ty-search-item:hover {
border-radius: 5px;
background: var(--active-file-bg-color);
border-color: var(--border-color);
}
#file-library-search-result .ty-search-item.active {
color: var(--text-color);
}
#file-library-search-result .ty-search-item.active .ty-search-item-line {
white-space: normal;
word-break: break-word;
}
.file-list-item-time {
margin-right: 0;
padding-right: 0;
}
.file-list-item-count {
margin-right: 0;
padding: 0 6px;
border-radius: 3px;
}
#file-library-search-result .ty-search-item.active .file-list-item-count {
padding-right: 0;
}
#sidebar-loading-template {
padding: 8px;
border-radius: 5px;
margin-bottom: 5px;
display: none;
}
.ty-file-search-match-text {
background-color: var(--color-2-0-c);
}
/* File tree. */
#file-library-tree {
padding-top: 9.1424px;
padding-left: 13.7136px;
padding-right: 13.7136px;
box-sizing: border-box;
font-size: var(--file-tree-font-size);
}
.sidebar-tab-btn {
font-size: 18.2864px !important;
line-height: 22.8576px !important;
vertical-align: text-top;
margin-top: 13.7136px !important;
color: var(--title-color);
}
.ty-sidebar-search-panel .searchpanel-search-option-btn {
top: 9.1424px;
}
.file-tree-node {
position: relative;
padding-left: 0;
margin-left: 0;
}
.file-library-file-node:hover .file-node-icon:after {
width: 9.1424px !important;
}
.file-node-expanded>.file-node-children {
margin-left: 33.7136px;
}
.file-tree-node>.file-node-background {
border-radius: 5.7136px;
margin-left: -13.7136px;
border: none !important;
}
#file-library-tree .file-node-root>.file-node-content {
margin-left: -3.4288px !important;
}
#file-library-tree .file-tree-node>.file-node-content {
margin-left: -17.1424px;
}
#file-library-tree .file-node-collapsed>.file-node-content,
#file-library-tree .file-node-expanded>.file-node-content {
margin-left: -10.2864px;
}
.file-library-node:not(.file-node-root):focus>.file-node-content {
outline: none;
}
.os-windows #file-library-tree .file-node-content {
padding-right: 42.2864px;
margin-bottom: 3.4288px;
}
.file-library-node:not(.file-node-root):focus>.file-node-background,
.file-library-node.active:not(.file-node-root):focus>.file-node-background {
border: 1px dashed var(--text-color) !important;
}
.fa-folder:before,
.fa-folder:after,
.fa-caret-right,
.fa-caret-down {
color: var(--text-grey);
}
.file-node-content .file-node-title {
padding-right: 10.2864px;
}
.file-library-file-node.active .file-node-title {
font-weight: 700;
}
#file-library-tree .file-node-root>.file-node-children {
margin-left: 30.2864px;
}
#file-library-tree .file-tree-node {
position: relative;
}
.file-node-expanded>.file-node-content .fa-caret-down {
margin-right: 1.1424px;
}
#file-library-tree .file-tree-node .file-node-icon {
padding-left: 3.4288px;
}
#file-library-tree .file-node-open-state i {
position: relative;
z-index: 30;
padding-left: 4.5712px;
}
#file-library-tree .file-node-content::before {
content: "";
position: absolute;
z-index: 20;
left: -22.8576px;
top: -9.1424px;
display: block;
width: 1.1424px;
height: calc(100% + 5.7136px);
border-left: 1px solid var(--border-color);
}
#file-library-tree .file-node-content>.file-node-icon::before {
position: relative;
z-index: 35;
}
#file-library-tree .file-node-content>.file-node-icon::after {
content: "";
position: absolute;
z-index: 20;
left: -22.8576px;
top: 16px;
width: 13.7136px;
height: 18.2864px;
border-left: 1px solid var(--border-color);
border-top: 1px solid var(--border-color);
background: rgba(0, 0, 0, 0);
}
#file-library-tree .active>.file-node-content>.file-node-icon::after {
width: 9.1424px;
}
#file-library-tree .file-node-expanded>.file-node-content>.file-node-icon::after {
left: -22.8576px;
top: 17.1424px;
width: 9.1424px;
}
#file-library-tree .file-node-collapsed>.file-node-content>.file-node-icon::after {
left: -22.8576px;
top: 16px;
width: 13.7136px;
}
.os-windows #file-library-tree .file-node-collapsed>.file-node-content>.file-node-icon::after {
top: 17.1424px;
}
#file-library-tree .file-node-children>div:last-of-type>.file-node-content>.file-node-icon::after {
border-top: none;
border-bottom: 1px solid var(--border-color);
border-bottom-left-radius: 3.4288px;
top: -1.1424px;
}
#file-library-tree .file-node-children>div:last-of-type>.file-node-content::before {
height: 11.4288px;
top: -10.2864px;
}
.file-node-root>.file-node-content>.file-node-icon::after {
display: none;
}
.file-node-content {
padding: 4px 8px;
display: flex;
align-items: center;
height: 24px;
}
.file-node-background {
height: 24px;
border-radius: 4px;
}
.file-library-node {
margin: 4px 0;
}
.file-library-file-node:hover .file-node-background,
.file-library-file-node.active .file-node-background {
background: var(--active-file-bg-color);
border-radius: 4px;
height: 24px;
display: flex;
align-items: center;
}
.file-library-file-node:hover .file-node-content,
.file-library-file-node.active .file-node-content {
cursor: pointer;
}
/* =========================================================================
8. Utilities & Export
========================================================================= */
/* Print/PDF export overrides. */
@media print {
.typora-export * {
print-color-adjust: exact;
-webkit-print-color-adjust: exact;
}
:root {
--font-size: 11pt;
--bg-color: rgba(255, 255, 255, 1);
--text-color: rgba(0, 0, 0, 1);
--link-color: rgba(127, 179, 255, 1);
}
body {
max-width: 100%;
margin: 0;
padding: 0;
background: white;
color: black;
}
#write {
padding: 1cm 1.5cm;
max-width: 100%;
margin: 0;
}
#write img,
#write table,
#write blockquote,
#write .md-fences {
box-shadow: none !important;
border: 1px solid rgba(221, 221, 221, 1) !important;
}
* {
animation: none !important;
transition: none !important;
will-change: auto !important;
}
.typora-export .mermaid svg,
.typora-export .mermaid svg * {
transform-box: fill-box;
transform-origin: center;
}
.typora-export .md-diagram-panel {
background: rgba(0, 0, 0, 0) !important;
border: none !important;
box-shadow: none !important;
padding: 0 !important;
}
.typora-export .md-diagram-panel svg {
width: 100% !important;
height: auto !important;
overflow: visible !important;
}
.typora-export .md-diagram-panel svg text,
.typora-export .md-diagram-panel svg tspan {
fill: rgba(17, 17, 17, 1) !important;
}
.typora-export .md-diagram-panel svg foreignObject {
overflow: visible !important;
}
#write img,
#write .md-task-list-item>input {
will-change: auto !important;
transform: none !important;
}
#write a {
will-change: auto !important;
}
#write img {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) !important;
}
#write hr::before,
#write blockquote::before {
display: none !important;
}
#write h1 {
page-break-before: always;
break-before: page;
}
#write h1:first-of-type,
#write>h1:first-child {
page-break-before: auto;
break-before: auto;
}
#write hr {
page-break-after: always;
break-after: page;
margin-bottom: 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
page-break-after: avoid;
break-after: avoid;
page-break-inside: avoid;
break-inside: avoid;
}
#write table,
#write .md-fences,
#write blockquote,
#write img {
page-break-inside: avoid;
break-inside: avoid;
}
p,
li {
orphans: 3;
widows: 3;
}
#write a {
text-decoration: underline;
color: var(--link-color);
border: none;
background: none;
}
.code-tooltip,
.md-fences .code-tooltip,
sup.md-footnote:hover {
display: none !important;
}
#write img {
max-width: 100%;
page-break-inside: avoid;
break-inside: avoid;
display: block;
margin: 16px auto;
}
#write .md-fences {
background: rgba(248, 248, 248, 1) !important;
border: 1px solid rgba(221, 221, 221, 1) !important;
padding: 0.3cm !important;
font-size: 9pt;
page-break-inside: avoid;
}
#write .cm-s-inner {
padding: 0.3cm !important;
background: rgba(248, 248, 248, 1) !important;
}
#write .cm-s-inner .cm-keyword,
#write .cm-s-inner .cm-builtin {
color: rgba(215, 58, 73, 1) !important;
font-weight: 600;
}
#write .cm-s-inner .cm-def {
color: rgba(111, 66, 193, 1) !important;
font-weight: 600;
}
#write .cm-s-inner .cm-variable,
#write .cm-s-inner .cm-variable-2,
#write .cm-s-inner .cm-variable-3 {
color: rgba(36, 41, 46, 1) !important;
}
#write .cm-s-inner .cm-number,
#write .cm-s-inner .cm-atom {
color: rgba(0, 92, 197, 1) !important;
font-weight: 500;
}
#write .cm-s-inner .cm-string,
#write .cm-s-inner .cm-string-2 {
color: rgba(34, 134, 58, 1) !important;
}
#write .cm-s-inner .cm-comment {
color: rgba(106, 115, 125, 1) !important;
font-style: italic;
}
#write .cm-s-inner .cm-operator {
color: rgba(215, 58, 73, 1) !important;
}
#write .cm-s-inner .cm-property,
#write .cm-s-inner .cm-attribute {
color: rgba(0, 92, 197, 1) !important;
}
#write .cm-s-inner .cm-type,
#write .cm-s-inner .cm-tag {
color: rgba(34, 134, 58, 1) !important;
font-weight: 500;
}
#write .cm-s-inner .cm-meta {
color: rgba(111, 66, 193, 1) !important;
}
#write .cm-s-inner .cm-qualifier {
color: rgba(111, 66, 193, 1) !important;
font-weight: 500;
}
#write .cm-s-inner .cm-bracket {
color: rgba(36, 41, 46, 1) !important;
font-weight: 600;
}
#write .cm-s-inner .cm-error {
color: rgba(215, 58, 73, 1) !important;
background-color: rgba(215, 58, 73, 0.1) !important;
}
#write .cm-s-inner .cm-header {
color: rgba(0, 92, 197, 1) !important;
font-weight: 600;
}
#write .cm-s-inner .cm-special {
color: rgba(111, 66, 193, 1) !important;
}
#write table {
border-collapse: collapse !important;
width: 100% !important;
font-size: 10pt;
}
#write td,
#write th {
border: 1px solid rgba(221, 221, 221, 1) !important;
padding: 0.3cm !important;
}
#write blockquote {
background: rgba(245, 245, 245, 1) !important;
border-left: 4px solid rgba(102, 102, 102, 1) !important;
padding: 0.5cm !important;
page-break-inside: avoid;
}
#write blockquote::before {
display: none;
}
.sidebar,
.file-tree,
#typora-sidebar,
.outline,
.md-search-panel {
display: none !important;
}
}
/* Normalize inline-styled workflow blocks from HTML exports. */
#write .md-htmlblock-container {
background: rgba(0, 0, 0, 0) !important;
box-shadow: none !important;
border: 0 !important
}
#write div[style*="border:1px solid #ccc"][style*="padding: 15px"],
#write div[style*="background-color: #f9f9f9"],
#write div[style*="background-color:#f9f9f9"],
#write div[style*="background-color: rgb(249, 249, 249)"],
#write div[style*="background-color:rgb(249, 249, 249)"] {
background: rgba(32, 34, 37, 1) !important;
border-color: rgba(78, 78, 78, 1) !important;
color: rgba(234, 234, 234, 1) !important;
box-shadow: 0 0 0 1px rgba(0, 0, 0, .35) inset !important;
}
#write div[style*="border:1px solid #aaa"] {
background: rgba(43, 43, 44, 1) !important;
border-color: rgba(106, 106, 106, 1) !important;
color: rgba(243, 243, 243, 1) !important
}
#write [style*="background-color: #e0e0ff"],
#write [style*="background-color:#e0e0ff"],
#write [style*="background-color: rgb(224, 224, 255)"] {
background: rgba(47, 58, 122, 1) !important;
border-color: rgba(136, 146, 214, 1) !important;
color: rgba(238, 241, 255, 1) !important
}
#write [style*="background-color: #e0ffe0"],
#write [style*="background-color:#e0ffe0"],
#write [style*="background-color: rgb(224, 255, 224)"] {
background: rgba(31, 74, 31, 1) !important;
border-color: rgba(95, 201, 102, 1) !important;
color: rgba(230, 255, 230, 1) !important
}
#write div[style*="font-size: 20px"] {
background: rgba(0, 0, 0, 0) !important;
border: 0 !important;
color: rgba(207, 207, 207, 1) !important
}
#write .md-htmlblock-container *,
#write div[style*="padding: 15px"] * {
opacity: 1 !important;
filter: none !important;
mix-blend-mode: normal !important;
color: inherit !important
}
/* Strikethrough. */
s,
del,
.del {
color: rgba(212, 212, 212, 0.5);
text-decoration: line-through;
text-decoration-thickness: 2px;
text-underline-offset: 3px;
}
/* Footnote references. */
#write sup.md-footnote {
background-color: rgba(212, 212, 212, 0.9);
color: rgba(32, 32, 32, 0.95);
padding: 1px 5px;
border-radius: 3px;
margin: 0 1px;
font-weight: 600;
font-size: 0.75em;
cursor: pointer;
transition: all 0.2s ease;
border: 1px solid rgba(0, 0, 0, 0);
vertical-align: baseline;
}
#write sup.md-footnote:hover {
background-color: var(--accent-color);
color: var(--bg-color);
box-shadow: 0 1px 4px rgba(156, 166, 168, 0.3);
border-color: var(--accent-color);
}
#write .md-footnote {
font-size: inherit;
line-height: inherit;
color: inherit;
}
#write .md-footnote::before {
display: none;
}
#write .md-footnote:hover {
color: var(--accent-color);
}
#write .footnotes-sep {
display: none;
}
#write .footnotes {
margin: 0;
padding: 0;
}
#write .footnotes ol {
padding-left: 24px;
margin: 0;
}
#write .footnotes li {
margin: 0;
padding: 0;
color: rgba(212, 212, 212, 0.9);
font-size: 15px;
line-height: 1.6;
}
</style>
<style type='text/css' id="style-lp">ol, ul {padding-left: 40px}</style>
<title>02_model_training</title>
</head>
<body class='typora-export os-windows typora-export-show-outline typora-export-no-collapse-outline'><div class='typora-export-content'>
<div class="typora-export-sidebar"><div class="outline-content"><li class="outline-item-wrapper outline-h1"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#02---mnist-model-training--visualization">02 - MNIST Model Training &amp; Visualization</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1-load-data-from-duckdb">1. Load Data from DuckDB</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#2-create-pytorch-dataloaders">2. Create PyTorch DataLoaders</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#3-define-the-neural-network">3. Define the Neural Network</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#4-training-loop">4. Training Loop</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#5-training-curves">5. Training Curves</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#6-confusion-matrix">6. Confusion Matrix</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#7-misclassified-examples">7. Misclassified Examples</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#8-save-model--training-results-to-duckdb">8. Save Model &amp; Training Results to DuckDB</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#9-experiment-ideas">9. Experiment Ideas</a></div><ul class="outline-children"></ul></li></ul></li></div></div><div id='write' class=''><h1 id='02---mnist-model-training--visualization'><span>02 - MNIST Model Training &amp; Visualization</span></h1><p><span>This notebook trains a neural network on MNIST data loaded from DuckDB, then visualizes:</span></p><ul><li><p><span>Training loss &amp; accuracy curves</span></p></li><li><p><span>Confusion matrix</span></p></li><li><p><span>Per-digit accuracy</span></p></li><li><p><span>Misclassified examples</span></p></li></ul><p><strong><span>Key ML Concepts Covered:</span></strong></p><ul><li><p><span>Neural network architecture (layers, activations)</span></p></li><li><p><span>Forward/backward propagation</span></p></li><li><p><span>Loss functions &amp; optimizers</span></p></li><li><p><span>Batch training with DataLoaders</span></p></li><li><p><span>Overfitting detection (train vs validation)</span></p></li></ul><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="python"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">import</span> <span class="cm-variable">numpy</span> <span class="cm-keyword">as</span> <span class="cm-variable">np</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">import</span> <span class="cm-variable">duckdb</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">import</span> <span class="cm-variable">torch</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">import</span> <span class="cm-variable">torch</span>.<span class="cm-property">nn</span> <span class="cm-keyword">as</span> <span class="cm-variable">nn</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">from</span> <span class="cm-variable">torch</span>.<span class="cm-property">utils</span>.<span class="cm-property">data</span> <span class="cm-keyword">import</span> <span class="cm-variable">DataLoader</span>, <span class="cm-variable">TensorDataset</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">import</span> <span class="cm-variable">matplotlib</span>.<span class="cm-property">pyplot</span> <span class="cm-keyword">as</span> <span class="cm-variable">plt</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">import</span> <span class="cm-variable">seaborn</span> <span class="cm-keyword">as</span> <span class="cm-variable">sns</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">from</span> <span class="cm-variable">sklearn</span>.<span class="cm-property">metrics</span> <span class="cm-keyword">import</span> <span class="cm-variable">confusion_matrix</span>, <span class="cm-variable">classification_report</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">from</span> <span class="cm-variable">pathlib</span> <span class="cm-keyword">import</span> <span class="cm-variable">Path</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">from</span> <span class="cm-variable">tqdm</span>.<span class="cm-property">notebook</span> <span class="cm-keyword">import</span> <span class="cm-variable">tqdm</span></span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 251px;"></div><div class="CodeMirror-gutters" style="display: none; height: 251px;"></div></div></div></pre><h2 id='1-load-data-from-duckdb'><span>1. Load Data from DuckDB</span></h2><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="python"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><span><span>​</span>x</span></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">con</span> <span class="cm-operator">=</span> <span class="cm-variable">duckdb</span>.<span class="cm-property">connect</span>(<span class="cm-builtin">str</span>(<span class="cm-variable">Path</span>(<span class="cm-string">'../data/mnist.duckdb'</span>)), <span class="cm-variable">read_only</span><span class="cm-operator">=</span><span class="cm-keyword">True</span>)</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">train_data</span> <span class="cm-operator">=</span> <span class="cm-variable">con</span>.<span class="cm-property">execute</span>(<span class="cm-string">"SELECT * FROM mnist WHERE split='train'"</span>).<span class="cm-property">fetchnumpy</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">test_data</span> <span class="cm-operator">=</span> <span class="cm-variable">con</span>.<span class="cm-property">execute</span>(<span class="cm-string">"SELECT * FROM mnist WHERE split='test'"</span>).<span class="cm-property">fetchnumpy</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">con</span>.<span class="cm-property">close</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment"># Extract pixel columns and labels</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">px_cols</span> <span class="cm-operator">=</span> [<span class="cm-string">f'px</span>{<span class="cm-variable">i</span>}<span class="cm-string">'</span> <span class="cm-keyword">for</span> <span class="cm-variable">i</span> <span class="cm-keyword">in</span> <span class="cm-builtin">range</span>(<span class="cm-number">784</span>)]</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">X_train</span> <span class="cm-operator">=</span> <span class="cm-variable">np</span>.<span class="cm-property">column_stack</span>([<span class="cm-variable">train_data</span>[<span class="cm-variable">c</span>] <span class="cm-keyword">for</span> <span class="cm-variable">c</span> <span class="cm-keyword">in</span> <span class="cm-variable">px_cols</span>]).<span class="cm-property">astype</span>(<span class="cm-variable">np</span>.<span class="cm-property">float32</span>) <span class="cm-operator">/</span> <span class="cm-number">255.0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">y_train</span> <span class="cm-operator">=</span> <span class="cm-variable">train_data</span>[<span class="cm-string">'label'</span>].<span class="cm-property">astype</span>(<span class="cm-variable">np</span>.<span class="cm-property">int64</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">X_test</span> <span class="cm-operator">=</span> <span class="cm-variable">np</span>.<span class="cm-property">column_stack</span>([<span class="cm-variable">test_data</span>[<span class="cm-variable">c</span>] <span class="cm-keyword">for</span> <span class="cm-variable">c</span> <span class="cm-keyword">in</span> <span class="cm-variable">px_cols</span>]).<span class="cm-property">astype</span>(<span class="cm-variable">np</span>.<span class="cm-property">float32</span>) <span class="cm-operator">/</span> <span class="cm-number">255.0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">y_test</span> <span class="cm-operator">=</span> <span class="cm-variable">test_data</span>[<span class="cm-string">'label'</span>].<span class="cm-property">astype</span>(<span class="cm-variable">np</span>.<span class="cm-property">int64</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-builtin">print</span>(<span class="cm-string">f'Train: </span>{<span class="cm-variable">X_train</span>.<span class="cm-property">shape</span>}<span class="cm-string">, Test: </span>{<span class="cm-variable">X_test</span>.<span class="cm-property">shape</span>}<span class="cm-string">'</span>)</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 351px;"></div><div class="CodeMirror-gutters" style="display: none; height: 351px;"></div></div></div></pre><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang=""><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang=""><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Train: (60000, 784), Test: (10000, 784)</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 25px;"></div><div class="CodeMirror-gutters" style="display: none; height: 25px;"></div></div></div></pre><h2 id='2-create-pytorch-dataloaders'><span>2. Create PyTorch DataLoaders</span></h2><p><span>DataLoaders handle batching and shuffling. Batch size is a key hyperparameter:</span></p><ul><li><p><strong><span>Smaller batches</span></strong><span> → noisier gradients, can help escape local minima</span></p></li><li><p><strong><span>Larger batches</span></strong><span> → smoother gradients, faster training per epoch</span></p></li></ul><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="python"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">BATCH_SIZE</span> <span class="cm-operator">=</span> <span class="cm-number">128</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">train_ds</span> <span class="cm-operator">=</span> <span class="cm-variable">TensorDataset</span>(<span class="cm-variable">torch</span>.<span class="cm-property">tensor</span>(<span class="cm-variable">X_train</span>), <span class="cm-variable">torch</span>.<span class="cm-property">tensor</span>(<span class="cm-variable">y_train</span>))</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">test_ds</span> <span class="cm-operator">=</span> <span class="cm-variable">TensorDataset</span>(<span class="cm-variable">torch</span>.<span class="cm-property">tensor</span>(<span class="cm-variable">X_test</span>), <span class="cm-variable">torch</span>.<span class="cm-property">tensor</span>(<span class="cm-variable">y_test</span>))</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">train_loader</span> <span class="cm-operator">=</span> <span class="cm-variable">DataLoader</span>(<span class="cm-variable">train_ds</span>, <span class="cm-variable">batch_size</span><span class="cm-operator">=</span><span class="cm-variable">BATCH_SIZE</span>, <span class="cm-variable">shuffle</span><span class="cm-operator">=</span><span class="cm-keyword">True</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">test_loader</span> <span class="cm-operator">=</span> <span class="cm-variable">DataLoader</span>(<span class="cm-variable">test_ds</span>, <span class="cm-variable">batch_size</span><span class="cm-operator">=</span><span class="cm-variable">BATCH_SIZE</span>)</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 176px;"></div><div class="CodeMirror-gutters" style="display: none; height: 176px;"></div></div></div></pre><h2 id='3-define-the-neural-network'><span>3. Define the Neural Network</span></h2><p><span>Architecture: 784 → 256 → 128 → 10</span></p><p><strong><span>Key parameters to experiment with:</span></strong></p><ul><li><p><span>Hidden layer sizes (try 64, 128, 256, 512)</span></p></li><li><p><span>Number of layers (try 1-4 hidden layers)</span></p></li><li><p><span>Activation function (ReLU, Sigmoid, Tanh)</span></p></li><li><p><span>Dropout rate (regularization to prevent overfitting)</span></p></li></ul><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="python"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">class</span> <span class="cm-def">MNISTNet</span>(<span class="cm-variable">nn</span>.<span class="cm-property">Module</span>):</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">def</span> <span class="cm-def">__init__</span>(<span class="cm-variable-2">self</span>, <span class="cm-variable">hidden1</span><span class="cm-operator">=</span><span class="cm-number">256</span>, <span class="cm-variable">hidden2</span><span class="cm-operator">=</span><span class="cm-number">128</span>, <span class="cm-variable">dropout</span><span class="cm-operator">=</span><span class="cm-number">0.2</span>):</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-builtin">super</span>().<span class="cm-property">__init__</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable-2">self</span>.<span class="cm-property">net</span> <span class="cm-operator">=</span> <span class="cm-variable">nn</span>.<span class="cm-property">Sequential</span>(</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">nn</span>.<span class="cm-property">Linear</span>(<span class="cm-number">784</span>, <span class="cm-variable">hidden1</span>),</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">nn</span>.<span class="cm-property">ReLU</span>(),</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">nn</span>.<span class="cm-property">Dropout</span>(<span class="cm-variable">dropout</span>),</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">nn</span>.<span class="cm-property">Linear</span>(<span class="cm-variable">hidden1</span>, <span class="cm-variable">hidden2</span>),</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">nn</span>.<span class="cm-property">ReLU</span>(),</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">nn</span>.<span class="cm-property">Dropout</span>(<span class="cm-variable">dropout</span>),</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">nn</span>.<span class="cm-property">Linear</span>(<span class="cm-variable">hidden2</span>, <span class="cm-number">10</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; )</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">def</span> <span class="cm-def">forward</span>(<span class="cm-variable-2">self</span>, <span class="cm-variable">x</span>):</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">return</span> <span class="cm-variable-2">self</span>.<span class="cm-property">net</span>(<span class="cm-variable">x</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">device</span> <span class="cm-operator">=</span> <span class="cm-variable">torch</span>.<span class="cm-property">device</span>(<span class="cm-string">'cuda'</span> <span class="cm-keyword">if</span> <span class="cm-variable">torch</span>.<span class="cm-property">cuda</span>.<span class="cm-property">is_available</span>() <span class="cm-keyword">else</span> <span class="cm-string">'cpu'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-builtin">print</span>(<span class="cm-string">f'Using device: </span>{<span class="cm-variable">device</span>}<span class="cm-string">'</span>)</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 451px;"></div><div class="CodeMirror-gutters" style="display: none; height: 451px;"></div></div></div></pre><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang=""><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang=""><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Using device: cpu</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 25px;"></div><div class="CodeMirror-gutters" style="display: none; height: 25px;"></div></div></div></pre><h2 id='4-training-loop'><span>4. Training Loop</span></h2><p><strong><span>Hyperparameters:</span></strong></p><ul><li><p><code>lr</code><span> (learning rate): How big each optimization step is. Too high → diverges. Too low → slow.</span></p></li><li><p><code>epochs</code><span>: Number of full passes through the training data.</span></p></li><li><p><code>optimizer</code><span>: Adam adapts learning rate per-parameter. SGD is simpler but needs tuning.</span></p></li></ul><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="python"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment"># === HYPERPARAMETERS (experiment with these!) ===</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">EPOCHS</span> <span class="cm-operator">=</span> <span class="cm-number">15</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">LEARNING_RATE</span> <span class="cm-operator">=</span> <span class="cm-number">1e-3</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">HIDDEN1</span> <span class="cm-operator">=</span> <span class="cm-number">256</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">HIDDEN2</span> <span class="cm-operator">=</span> <span class="cm-number">128</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">DROPOUT</span> <span class="cm-operator">=</span> <span class="cm-number">0.2</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">model</span> <span class="cm-operator">=</span> <span class="cm-variable">MNISTNet</span>(<span class="cm-variable">HIDDEN1</span>, <span class="cm-variable">HIDDEN2</span>, <span class="cm-variable">DROPOUT</span>).<span class="cm-property">to</span>(<span class="cm-variable">device</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">criterion</span> <span class="cm-operator">=</span> <span class="cm-variable">nn</span>.<span class="cm-property">CrossEntropyLoss</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">optimizer</span> <span class="cm-operator">=</span> <span class="cm-variable">torch</span>.<span class="cm-property">optim</span>.<span class="cm-property">Adam</span>(<span class="cm-variable">model</span>.<span class="cm-property">parameters</span>(), <span class="cm-variable">lr</span><span class="cm-operator">=</span><span class="cm-variable">LEARNING_RATE</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-builtin">print</span>(<span class="cm-string">f'Model parameters: </span>{<span class="cm-builtin">sum</span>(<span class="cm-variable">p</span>.<span class="cm-property">numel</span>() <span class="cm-keyword">for</span> <span class="cm-variable">p</span> <span class="cm-keyword">in</span> <span class="cm-variable">model</span>.<span class="cm-property">parameters</span>()):,}<span class="cm-string">'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-builtin">print</span>(<span class="cm-variable">model</span>)</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 326px;"></div><div class="CodeMirror-gutters" style="display: none; height: 326px;"></div></div></div></pre><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang=""><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang=""><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Model parameters: 235,146</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">MNISTNet(</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> (net): Sequential(</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; (0): Linear(in_features=784, out_features=256, bias=True)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; (1): ReLU()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; (2): Dropout(p=0.2, inplace=False)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; (3): Linear(in_features=256, out_features=128, bias=True)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; (4): ReLU()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; (5): Dropout(p=0.2, inplace=False)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; (6): Linear(in_features=128, out_features=10, bias=True)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> )</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">)</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 301px;"></div><div class="CodeMirror-gutters" style="display: none; height: 301px;"></div></div></div></pre><p>&nbsp;</p><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="python"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment"># Training with metrics tracking</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">history</span> <span class="cm-operator">=</span> {<span class="cm-string">'train_loss'</span>: [], <span class="cm-string">'train_acc'</span>: [], <span class="cm-string">'test_loss'</span>: [], <span class="cm-string">'test_acc'</span>: []}</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">for</span> <span class="cm-variable">epoch</span> <span class="cm-keyword">in</span> <span class="cm-variable">tqdm</span>(<span class="cm-builtin">range</span>(<span class="cm-variable">EPOCHS</span>), <span class="cm-variable">desc</span><span class="cm-operator">=</span><span class="cm-string">'Training'</span>):</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment"># Train</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">model</span>.<span class="cm-property">train</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">running_loss</span>, <span class="cm-variable">correct</span>, <span class="cm-variable">total</span> <span class="cm-operator">=</span> <span class="cm-number">0.0</span>, <span class="cm-number">0</span>, <span class="cm-number">0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">for</span> <span class="cm-variable">X_batch</span>, <span class="cm-variable">y_batch</span> <span class="cm-keyword">in</span> <span class="cm-variable">train_loader</span>:</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">X_batch</span>, <span class="cm-variable">y_batch</span> <span class="cm-operator">=</span> <span class="cm-variable">X_batch</span>.<span class="cm-property">to</span>(<span class="cm-variable">device</span>), <span class="cm-variable">y_batch</span>.<span class="cm-property">to</span>(<span class="cm-variable">device</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">optimizer</span>.<span class="cm-property">zero_grad</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">outputs</span> <span class="cm-operator">=</span> <span class="cm-variable">model</span>(<span class="cm-variable">X_batch</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">loss</span> <span class="cm-operator">=</span> <span class="cm-variable">criterion</span>(<span class="cm-variable">outputs</span>, <span class="cm-variable">y_batch</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">loss</span>.<span class="cm-property">backward</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">optimizer</span>.<span class="cm-property">step</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">running_loss</span> <span class="cm-operator">+=</span> <span class="cm-variable">loss</span>.<span class="cm-property">item</span>() <span class="cm-operator">*</span> <span class="cm-builtin">len</span>(<span class="cm-variable">y_batch</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">correct</span> <span class="cm-operator">+=</span> (<span class="cm-variable">outputs</span>.<span class="cm-property">argmax</span>(<span class="cm-number">1</span>) <span class="cm-operator">==</span> <span class="cm-variable">y_batch</span>).<span class="cm-property">sum</span>().<span class="cm-property">item</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">total</span> <span class="cm-operator">+=</span> <span class="cm-builtin">len</span>(<span class="cm-variable">y_batch</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">history</span>[<span class="cm-string">'train_loss'</span>].<span class="cm-property">append</span>(<span class="cm-variable">running_loss</span> <span class="cm-operator">/</span> <span class="cm-variable">total</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">history</span>[<span class="cm-string">'train_acc'</span>].<span class="cm-property">append</span>(<span class="cm-variable">correct</span> <span class="cm-operator">/</span> <span class="cm-variable">total</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-comment"># Evaluate</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">model</span>.<span class="cm-property">eval</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">running_loss</span>, <span class="cm-variable">correct</span>, <span class="cm-variable">total</span> <span class="cm-operator">=</span> <span class="cm-number">0.0</span>, <span class="cm-number">0</span>, <span class="cm-number">0</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">with</span> <span class="cm-variable">torch</span>.<span class="cm-property">no_grad</span>():</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-keyword">for</span> <span class="cm-variable">X_batch</span>, <span class="cm-variable">y_batch</span> <span class="cm-keyword">in</span> <span class="cm-variable">test_loader</span>:</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">X_batch</span>, <span class="cm-variable">y_batch</span> <span class="cm-operator">=</span> <span class="cm-variable">X_batch</span>.<span class="cm-property">to</span>(<span class="cm-variable">device</span>), <span class="cm-variable">y_batch</span>.<span class="cm-property">to</span>(<span class="cm-variable">device</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">outputs</span> <span class="cm-operator">=</span> <span class="cm-variable">model</span>(<span class="cm-variable">X_batch</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">loss</span> <span class="cm-operator">=</span> <span class="cm-variable">criterion</span>(<span class="cm-variable">outputs</span>, <span class="cm-variable">y_batch</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">running_loss</span> <span class="cm-operator">+=</span> <span class="cm-variable">loss</span>.<span class="cm-property">item</span>() <span class="cm-operator">*</span> <span class="cm-builtin">len</span>(<span class="cm-variable">y_batch</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">correct</span> <span class="cm-operator">+=</span> (<span class="cm-variable">outputs</span>.<span class="cm-property">argmax</span>(<span class="cm-number">1</span>) <span class="cm-operator">==</span> <span class="cm-variable">y_batch</span>).<span class="cm-property">sum</span>().<span class="cm-property">item</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">total</span> <span class="cm-operator">+=</span> <span class="cm-builtin">len</span>(<span class="cm-variable">y_batch</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">history</span>[<span class="cm-string">'test_loss'</span>].<span class="cm-property">append</span>(<span class="cm-variable">running_loss</span> <span class="cm-operator">/</span> <span class="cm-variable">total</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">history</span>[<span class="cm-string">'test_acc'</span>].<span class="cm-property">append</span>(<span class="cm-variable">correct</span> <span class="cm-operator">/</span> <span class="cm-variable">total</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-builtin">print</span>(<span class="cm-string">f"Epoch </span>{<span class="cm-variable">epoch</span><span class="cm-operator">+</span><span class="cm-number">1</span>:<span class="cm-number">2</span><span class="cm-variable">d</span>}<span class="cm-string"> | Train Loss: </span>{<span class="cm-variable">history</span>[<span class="cm-string">'train_loss'</span>][<span class="cm-operator">-</span><span class="cm-number">1</span>]:<span class="cm-number">.4</span><span class="cm-variable">f</span>}<span class="cm-string"> Acc: </span>{<span class="cm-variable">history</span>[<span class="cm-string">'train_acc'</span>][<span class="cm-operator">-</span><span class="cm-number">1</span>]:<span class="cm-number">.4</span><span class="cm-variable">f</span>}<span class="cm-string"> | "</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-string">f"Test Loss: </span>{<span class="cm-variable">history</span>[<span class="cm-string">'test_loss'</span>][<span class="cm-operator">-</span><span class="cm-number">1</span>]:<span class="cm-number">.4</span><span class="cm-variable">f</span>}<span class="cm-string"> Acc: </span>{<span class="cm-variable">history</span>[<span class="cm-string">'test_acc'</span>][<span class="cm-operator">-</span><span class="cm-number">1</span>]:<span class="cm-number">.4</span><span class="cm-variable">f</span>}<span class="cm-string">"</span>)</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 928px;"></div><div class="CodeMirror-gutters" style="display: none; height: 928px;"></div></div></div></pre><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang=""><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang=""><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Training: &nbsp; 0%| &nbsp; &nbsp; &nbsp; &nbsp; | 0/15 [00:00&lt;?, ?it/s]</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 25px;"></div><div class="CodeMirror-gutters" style="display: none; height: 25px;"></div></div></div></pre><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang=""><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 1 | Train Loss: 0.3803 Acc: 0.8898 | Test Loss: 0.1511 Acc: 0.9547</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 2 | Train Loss: 0.1498 Acc: 0.9547 | Test Loss: 0.1011 Acc: 0.9693</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 3 | Train Loss: 0.1079 Acc: 0.9671 | Test Loss: 0.0837 Acc: 0.9731</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 4 | Train Loss: 0.0836 Acc: 0.9739 | Test Loss: 0.0759 Acc: 0.9762</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 5 | Train Loss: 0.0703 Acc: 0.9781 | Test Loss: 0.0729 Acc: 0.9775</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 6 | Train Loss: 0.0585 Acc: 0.9814 | Test Loss: 0.0722 Acc: 0.9782</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 7 | Train Loss: 0.0532 Acc: 0.9825 | Test Loss: 0.0709 Acc: 0.9804</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 8 | Train Loss: 0.0444 Acc: 0.9861 | Test Loss: 0.0724 Acc: 0.9783</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 9 | Train Loss: 0.0422 Acc: 0.9861 | Test Loss: 0.0615 Acc: 0.9816</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 10 | Train Loss: 0.0350 Acc: 0.9888 | Test Loss: 0.0631 Acc: 0.9828</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 11 | Train Loss: 0.0358 Acc: 0.9887 | Test Loss: 0.0622 Acc: 0.9821</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 12 | Train Loss: 0.0307 Acc: 0.9894 | Test Loss: 0.0670 Acc: 0.9817</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 13 | Train Loss: 0.0294 Acc: 0.9904 | Test Loss: 0.0677 Acc: 0.9827</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 14 | Train Loss: 0.0264 Acc: 0.9906 | Test Loss: 0.0659 Acc: 0.9818</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Epoch 15 | Train Loss: 0.0251 Acc: 0.9916 | Test Loss: 0.0653 Acc: 0.9826</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 376px;"></div><div class="CodeMirror-gutters" style="display: none; height: 376px;"></div></div></div></pre><h2 id='5-training-curves'><span>5. Training Curves</span></h2><p><strong><span>What to look for:</span></strong></p><ul><li><p><span>If test loss increases while train loss decreases → </span><strong><span>overfitting</span></strong><span> (try more dropout, fewer parameters)</span></p></li><li><p><span>If both losses plateau high → </span><strong><span>underfitting</span></strong><span> (try more parameters, lower dropout)</span></p></li><li><p><span>Gap between train/test accuracy shows generalization</span></p></li></ul><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="python"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">fig</span>, (<span class="cm-variable">ax1</span>, <span class="cm-variable">ax2</span>) <span class="cm-operator">=</span> <span class="cm-variable">plt</span>.<span class="cm-property">subplots</span>(<span class="cm-number">1</span>, <span class="cm-number">2</span>, <span class="cm-variable">figsize</span><span class="cm-operator">=</span>(<span class="cm-number">12</span>, <span class="cm-number">4</span>))</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax1</span>.<span class="cm-property">plot</span>(<span class="cm-variable">history</span>[<span class="cm-string">'train_loss'</span>], <span class="cm-variable">label</span><span class="cm-operator">=</span><span class="cm-string">'Train'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax1</span>.<span class="cm-property">plot</span>(<span class="cm-variable">history</span>[<span class="cm-string">'test_loss'</span>], <span class="cm-variable">label</span><span class="cm-operator">=</span><span class="cm-string">'Test'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax1</span>.<span class="cm-property">set_xlabel</span>(<span class="cm-string">'Epoch'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax1</span>.<span class="cm-property">set_ylabel</span>(<span class="cm-string">'Loss'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax1</span>.<span class="cm-property">set_title</span>(<span class="cm-string">'Loss Curve'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax1</span>.<span class="cm-property">legend</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax1</span>.<span class="cm-property">grid</span>(<span class="cm-keyword">True</span>, <span class="cm-variable">alpha</span><span class="cm-operator">=</span><span class="cm-number">0.3</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax2</span>.<span class="cm-property">plot</span>(<span class="cm-variable">history</span>[<span class="cm-string">'train_acc'</span>], <span class="cm-variable">label</span><span class="cm-operator">=</span><span class="cm-string">'Train'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax2</span>.<span class="cm-property">plot</span>(<span class="cm-variable">history</span>[<span class="cm-string">'test_acc'</span>], <span class="cm-variable">label</span><span class="cm-operator">=</span><span class="cm-string">'Test'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax2</span>.<span class="cm-property">set_xlabel</span>(<span class="cm-string">'Epoch'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax2</span>.<span class="cm-property">set_ylabel</span>(<span class="cm-string">'Accuracy'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax2</span>.<span class="cm-property">set_title</span>(<span class="cm-string">'Accuracy Curve'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax2</span>.<span class="cm-property">legend</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">ax2</span>.<span class="cm-property">grid</span>(<span class="cm-keyword">True</span>, <span class="cm-variable">alpha</span><span class="cm-operator">=</span><span class="cm-number">0.3</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">plt</span>.<span class="cm-property">tight_layout</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">plt</span>.<span class="cm-property">show</span>()</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 502px;"></div><div class="CodeMirror-gutters" style="display: none; height: 502px;"></div></div></div></pre><p><span> </span><br/><img src="../02_model_training_files/02_model_training_12_0.png" alt="png">
<span> </span></p><h2 id='6-confusion-matrix'><span>6. Confusion Matrix</span></h2><p><span>Shows which digits get confused with each other (e.g., 4↔9, 3↔5 are common).</span></p><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="python"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">model</span>.<span class="cm-property">eval</span>()</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">all_preds</span>, <span class="cm-variable">all_labels</span> <span class="cm-operator">=</span> [], []</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">with</span> <span class="cm-variable">torch</span>.<span class="cm-property">no_grad</span>():</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-keyword">for</span> <span class="cm-variable">X_batch</span>, <span class="cm-variable">y_batch</span> <span class="cm-keyword">in</span> <span class="cm-variable">test_loader</span>:</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">preds</span> <span class="cm-operator">=</span> <span class="cm-variable">model</span>(<span class="cm-variable">X_batch</span>.<span class="cm-property">to</span>(<span class="cm-variable">device</span>)).<span class="cm-property">argmax</span>(<span class="cm-number">1</span>).<span class="cm-property">cpu</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">all_preds</span>.<span class="cm-property">append</span>(<span class="cm-variable">preds</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">all_labels</span>.<span class="cm-property">append</span>(<span class="cm-variable">y_batch</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">all_preds</span> <span class="cm-operator">=</span> <span class="cm-variable">torch</span>.<span class="cm-property">cat</span>(<span class="cm-variable">all_preds</span>).<span class="cm-property">numpy</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">all_labels</span> <span class="cm-operator">=</span> <span class="cm-variable">torch</span>.<span class="cm-property">cat</span>(<span class="cm-variable">all_labels</span>).<span class="cm-property">numpy</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">cm</span> <span class="cm-operator">=</span> <span class="cm-variable">confusion_matrix</span>(<span class="cm-variable">all_labels</span>, <span class="cm-variable">all_preds</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">plt</span>.<span class="cm-property">figure</span>(<span class="cm-variable">figsize</span><span class="cm-operator">=</span>(<span class="cm-number">8</span>, <span class="cm-number">6</span>))</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">sns</span>.<span class="cm-property">heatmap</span>(<span class="cm-variable">cm</span>, <span class="cm-variable">annot</span><span class="cm-operator">=</span><span class="cm-keyword">True</span>, <span class="cm-variable">fmt</span><span class="cm-operator">=</span><span class="cm-string">'d'</span>, <span class="cm-variable">cmap</span><span class="cm-operator">=</span><span class="cm-string">'Blues'</span>,</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-variable">xticklabels</span><span class="cm-operator">=</span><span class="cm-builtin">range</span>(<span class="cm-number">10</span>), <span class="cm-variable">yticklabels</span><span class="cm-operator">=</span><span class="cm-builtin">range</span>(<span class="cm-number">10</span>))</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">plt</span>.<span class="cm-property">xlabel</span>(<span class="cm-string">'Predicted'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">plt</span>.<span class="cm-property">ylabel</span>(<span class="cm-string">'Actual'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">plt</span>.<span class="cm-property">title</span>(<span class="cm-string">'Confusion Matrix'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">plt</span>.<span class="cm-property">show</span>()</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 476px;"></div><div class="CodeMirror-gutters" style="display: none; height: 476px;"></div></div></div></pre><p><span> </span><br/><img src="../02_model_training_files/02_model_training_14_0.png" alt="png">
<span> </span></p><p>&nbsp;</p><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="python"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-builtin">print</span>(<span class="cm-variable">classification_report</span>(<span class="cm-variable">all_labels</span>, <span class="cm-variable">all_preds</span>, <span class="cm-variable">digits</span><span class="cm-operator">=</span><span class="cm-number">4</span>))</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 25px;"></div><div class="CodeMirror-gutters" style="display: none; height: 25px;"></div></div></div></pre><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang=""><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; precision &nbsp; recall f1-score &nbsp; support</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; 0.9798 &nbsp; 0.9908 &nbsp; 0.9853 &nbsp; &nbsp; &nbsp; 980</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; 0.9877 &nbsp; 0.9930 &nbsp; 0.9903 &nbsp; &nbsp; 1135</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; 0.9872 &nbsp; 0.9700 &nbsp; 0.9785 &nbsp; &nbsp; 1032</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp; &nbsp; 0.9861 &nbsp; 0.9832 &nbsp; 0.9846 &nbsp; &nbsp; 1010</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; 0.9825 &nbsp; 0.9725 &nbsp; 0.9775 &nbsp; &nbsp; &nbsp; 982</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 5 &nbsp; &nbsp; 0.9898 &nbsp; 0.9798 &nbsp; 0.9848 &nbsp; &nbsp; &nbsp; 892</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; 0.9864 &nbsp; 0.9875 &nbsp; 0.9870 &nbsp; &nbsp; &nbsp; 958</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 &nbsp; &nbsp; 0.9806 &nbsp; 0.9815 &nbsp; 0.9810 &nbsp; &nbsp; 1028</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; 0.9785 &nbsp; 0.9805 &nbsp; 0.9795 &nbsp; &nbsp; &nbsp; 974</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 9 &nbsp; &nbsp; 0.9679 &nbsp; 0.9861 &nbsp; 0.9769 &nbsp; &nbsp; 1009</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; accuracy &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0.9826 &nbsp; &nbsp; 10000</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; macro avg &nbsp; &nbsp; 0.9827 &nbsp; 0.9825 &nbsp; 0.9825 &nbsp; &nbsp; 10000</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">weighted avg &nbsp; &nbsp; 0.9826 &nbsp; 0.9826 &nbsp; 0.9826 &nbsp; &nbsp; 10000</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 401px;"></div><div class="CodeMirror-gutters" style="display: none; height: 401px;"></div></div></div></pre><p><span> </span></p><h2 id='7-misclassified-examples'><span>7. Misclassified Examples</span></h2><p><span>Seeing what the model gets wrong helps understand its weaknesses.</span></p><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="python"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">wrong_idx</span> <span class="cm-operator">=</span> <span class="cm-variable">np</span>.<span class="cm-property">where</span>(<span class="cm-variable">all_preds</span> <span class="cm-operator">!=</span> <span class="cm-variable">all_labels</span>)[<span class="cm-number">0</span>][:<span class="cm-number">10</span>]</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">fig</span>, <span class="cm-variable">axes</span> <span class="cm-operator">=</span> <span class="cm-variable">plt</span>.<span class="cm-property">subplots</span>(<span class="cm-number">2</span>, <span class="cm-number">5</span>, <span class="cm-variable">figsize</span><span class="cm-operator">=</span>(<span class="cm-number">12</span>, <span class="cm-number">5</span>))</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">for</span> <span class="cm-variable">i</span>, <span class="cm-variable">idx</span> <span class="cm-keyword">in</span> <span class="cm-builtin">enumerate</span>(<span class="cm-variable">wrong_idx</span>):</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">ax</span> <span class="cm-operator">=</span> <span class="cm-variable">axes</span>[<span class="cm-variable">i</span> <span class="cm-operator">//</span> <span class="cm-number">5</span>, <span class="cm-variable">i</span> <span class="cm-operator">%</span> <span class="cm-number">5</span>]</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">ax</span>.<span class="cm-property">imshow</span>(<span class="cm-variable">X_test</span>[<span class="cm-variable">idx</span>].<span class="cm-property">reshape</span>(<span class="cm-number">28</span>, <span class="cm-number">28</span>), <span class="cm-variable">cmap</span><span class="cm-operator">=</span><span class="cm-string">'gray'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">ax</span>.<span class="cm-property">set_title</span>(<span class="cm-string">f'True: </span>{<span class="cm-variable">all_labels</span>[<span class="cm-variable">idx</span>]}<span class="cm-string">\nPred: </span>{<span class="cm-variable">all_preds</span>[<span class="cm-variable">idx</span>]}<span class="cm-string">'</span>, <span class="cm-variable">color</span><span class="cm-operator">=</span><span class="cm-string">'red'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">ax</span>.<span class="cm-property">axis</span>(<span class="cm-string">'off'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">plt</span>.<span class="cm-property">suptitle</span>(<span class="cm-string">'Misclassified Examples'</span>, <span class="cm-variable">fontsize</span><span class="cm-operator">=</span><span class="cm-number">14</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">plt</span>.<span class="cm-property">tight_layout</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">plt</span>.<span class="cm-property">show</span>()</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 276px;"></div><div class="CodeMirror-gutters" style="display: none; height: 276px;"></div></div></div></pre><p><span> </span><br/><img src="../02_model_training_files/02_model_training_17_0.png" alt="png">
<span> </span></p><h2 id='8-save-model--training-results-to-duckdb'><span>8. Save Model &amp; Training Results to DuckDB</span></h2><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang="python" style="break-inside: unset;"><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang="python"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">import</span> <span class="cm-variable">pandas</span> <span class="cm-keyword">as</span> <span class="cm-variable">pd</span></span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment"># Save training history</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">history_df</span> <span class="cm-operator">=</span> <span class="cm-variable">pd</span>.<span class="cm-property">DataFrame</span>(<span class="cm-variable">history</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">history_df</span>[<span class="cm-string">'epoch'</span>] <span class="cm-operator">=</span> <span class="cm-builtin">range</span>(<span class="cm-number">1</span>, <span class="cm-variable">EPOCHS</span> <span class="cm-operator">+</span> <span class="cm-number">1</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">con</span> <span class="cm-operator">=</span> <span class="cm-variable">duckdb</span>.<span class="cm-property">connect</span>(<span class="cm-builtin">str</span>(<span class="cm-variable">Path</span>(<span class="cm-string">'../data/mnist.duckdb'</span>)))</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">con</span>.<span class="cm-property">execute</span>(<span class="cm-string">'DROP TABLE IF EXISTS training_history'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">con</span>.<span class="cm-property">execute</span>(<span class="cm-string">'CREATE TABLE training_history AS SELECT * FROM history_df'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">con</span>.<span class="cm-property">close</span>()</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="" cm-zwsp="">
</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment"># Save model weights</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">torch</span>.<span class="cm-property">save</span>(<span class="cm-variable">model</span>.<span class="cm-property">state_dict</span>(), <span class="cm-string">'../data/mnist_model.pth'</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-builtin">print</span>(<span class="cm-string">f'Model saved. Final test accuracy: </span>{<span class="cm-variable">history</span>[<span class="cm-string">"test_acc"</span>][<span class="cm-operator">-</span><span class="cm-number">1</span>]:<span class="cm-number">.4</span><span class="cm-variable">f</span>}<span class="cm-string">'</span>)</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 351px;"></div><div class="CodeMirror-gutters" style="display: none; height: 351px;"></div></div></div></pre><pre class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" lang=""><div class="CodeMirror cm-s-inner cm-s-null-scroll CodeMirror-wrap" lang=""><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 30.5391px; left: 28px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;" tabindex="0"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style="text-rendering: auto;"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">Model saved. Final test accuracy: 0.9826</span></pre></div></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 25px;"></div><div class="CodeMirror-gutters" style="display: none; height: 25px;"></div></div></div></pre><h2 id='9-experiment-ideas'><span>9. Experiment Ideas</span></h2><p><span>Try changing these parameters and re-running to see the effect:</span></p><figure class='table-figure'><table><thead><tr><th><span>Parameter</span></th><th><span>Current</span></th><th><span>Try</span></th></tr></thead><tbody><tr><td><code>LEARNING_RATE</code></td><td><span>0.001</span></td><td><span>0.01, 0.0001</span></td></tr><tr><td><code>HIDDEN1</code></td><td><span>256</span></td><td><span>64, 512</span></td></tr><tr><td><code>HIDDEN2</code></td><td><span>128</span></td><td><span>32, 256</span></td></tr><tr><td><code>DROPOUT</code></td><td><span>0.2</span></td><td><span>0.0, 0.5</span></td></tr><tr><td><code>EPOCHS</code></td><td><span>15</span></td><td><span>5, 30</span></td></tr><tr><td><code>BATCH_SIZE</code></td><td><span>128</span></td><td><span>32, 512</span></td></tr><tr><td><span>Optimizer</span></td><td><span>Adam</span></td><td><span>SGD(lr=0.01, momentum=0.9)</span></td></tr></tbody></table></figure></div></div>
<script>(function(){function e(e,n,i){document.addEventListener(e,function(e){if(!e.defaultPrevented)for(var t=e.target;t&&t!=this;t=t.parentNode)if(t.matches(n)){!1===i.call(t,e)&&(e.preventDefault(),e.stopPropagation());break}},!1)}var t=document.body.parentElement,i=[],r=null,o=document.body.classList.contains("typora-export-collapse-outline");function a(){return t.scrollTop}e("click",".outline-expander",function(e){var t=this.closest(".outline-item-wrapper").classList;return t.contains("outline-item-open")?t.remove("outline-item-open"):t.add("outline-item-open"),u(),!1}),e("click",".outline-item",function(e){var t=this.querySelector(".outline-label");location.hash=t.getAttribute("href"),o&&((t=this.closest(".outline-item-wrapper").classList).contains("outline-item-open")||t.add("outline-item-open"),d(),t.add("outline-item-active"))});function s(){var e=a();r=null;for(var t=0;t<i.length&&i[t][1]-e<60;t++)r=i[t]}function n(){c=setTimeout(function(){var n;i=[],n=a(),document.querySelector("#write").querySelectorAll("h1, h2, h3, h4, h5, h6").forEach(e=>{var t=e.getAttribute("id");i.push([t,n+e.getBoundingClientRect().y])}),s(),u()},300)}var l,c,d=function(){document.querySelectorAll(".outline-item-active").forEach(e=>e.classList.remove("outline-item-active")),document.querySelectorAll(".outline-item-single.outline-item-open").forEach(e=>e.classList.remove("outline-item-open"))},u=function(){if(r&&(d(),t=document.querySelector('.outline-label[href="#'+(CSS.escape?CSS.escape(r[0]):r[0])+'"]')))if(o){var e=t.closest(".outline-item-open>ul>.outline-item-wrapper");if(e)e.classList.add("outline-item-active");else{for(var t,n=(t=t.closest(".outline-item-wrapper")).parentElement.closest(".outline-item-wrapper");n;)n=(t=n).parentElement.closest(".outline-item-wrapper");t.classList.add("outline-item-active")}}else t.closest(".outline-item-wrapper").classList.add("outline-item-active")};window.addEventListener("scroll",function(e){l&&clearTimeout(l),l=setTimeout(function(){s(),u()},300)});window.addEventListener("resize",function(e){c&&clearTimeout(c),n()}),n()})();</script></body>
</html>