{"id":12522,"date":"2024-03-26T03:28:02","date_gmt":"2024-03-26T07:28:02","guid":{"rendered":"https:\/\/spinor.info\/weblog\/?p=12522"},"modified":"2024-03-26T03:28:02","modified_gmt":"2024-03-26T07:28:02","slug":"gru","status":"publish","type":"post","link":"https:\/\/spinor.info\/weblog\/?p=12522","title":{"rendered":"GRU"},"content":{"rendered":"<p>No, I am not worried about being eaten by a grue in the dark, as in the Great Underground Empire of the classic Zork text adventure games (if you ever played those games, you cannot possibly forget the ominous warning: &#8220;It is pitch black. You are likely to be eaten by a grue.&#8221;) Nor am I a secret admirer of <i lang=\"ru-Latn\">Glavnoye razvedyvatel&#8217;noye upravleniye<\/i>, the former USSR&#8217;s intelligence directorate, or its Putinist successor institution.<\/p>\n<p>Rather, I am talking about networks of gated recurrent units, a machine learning architecture that is well suited to analyze time series data. I&#8217;ve been using &#8220;black box&#8221; GRU implementations for some time in a research project, but it&#8217;s one thing to learn to use a software library, it&#8217;s another thing to understand the conceptual details.<\/p>\n<p>It is for that reason that (with the help of our sophisticated LLM friends) I embarked on a side project of building my own GRU network, in plain C++ code, without relying on other people&#8217;s solutions. That&#8217;s the best way to understand a software solution: Build your own!<\/p>\n<p>Which may explain why I get excited when I manage to produce a plot like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-12523\" src=\"https:\/\/spinor.info\/weblog\/wp-content\/uploads\/2024\/03\/GRU-example.gif\" alt=\"\" width=\"800\" height=\"600\" \/><\/p>\n<p>Nothing fancy, just an amplitude-modulated carrier (red), with a lower frequency modulating signal (green).<\/p>\n<p>But here&#8217;s the point: The GRU network doesn&#8217;t know a thing about amplitude modulation. It just learns the relationship between red and green. And learn it does: after a few passes using a training data set, it manages to reproduce the modulating signal with decent accuracy.<\/p>\n<p>My code likely still contains subtle errors, as I suspect that it can do even better. A lot also depends on the model &#8220;hyperparameters&#8221;, parameters that define the model and control the training process. Even so, I am pleased and excited: It is so much fun, seeing a creation like this &#8220;come to life&#8221;, working as it is supposed to, doing some nontrivial software magic in a mere, what, maybe 700 lines of code, but that actually even includes some commented-out lines.<\/p>\n<fb:like href='https:\/\/spinor.info\/weblog\/?p=12522' send='false' layout='button_count' show_faces='true' width='450' height='65' action='like' colorscheme='light' font='lucida grande'><\/fb:like>","protected":false},"excerpt":{"rendered":"<p>No, I am not worried about being eaten by a grue in the dark, as in the Great Underground Empire of the classic Zork text adventure games (if you ever played those games, you cannot possibly forget the ominous warning: &#8220;It is pitch black. You are likely to be eaten by a grue.&#8221;) Nor am <a href='https:\/\/spinor.info\/weblog\/?p=12522' class='excerpt-more'>[&#8230;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[58],"tags":[],"class_list":["post-12522","post","type-post","status-publish","format-standard","hentry","category-cybernetics","category-58-id","post-seq-1","post-parity-odd","meta-position-corners","fix"],"_links":{"self":[{"href":"https:\/\/spinor.info\/weblog\/index.php?rest_route=\/wp\/v2\/posts\/12522","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spinor.info\/weblog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spinor.info\/weblog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spinor.info\/weblog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/spinor.info\/weblog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12522"}],"version-history":[{"count":2,"href":"https:\/\/spinor.info\/weblog\/index.php?rest_route=\/wp\/v2\/posts\/12522\/revisions"}],"predecessor-version":[{"id":12525,"href":"https:\/\/spinor.info\/weblog\/index.php?rest_route=\/wp\/v2\/posts\/12522\/revisions\/12525"}],"wp:attachment":[{"href":"https:\/\/spinor.info\/weblog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12522"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spinor.info\/weblog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12522"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spinor.info\/weblog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12522"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}