{
    "version": "https://jsonfeed.org/version/1",
    "title": "a3chron's Blog",
    "home_page_url": "https://a3chron.dev/",
    "description": "Latest articles from a3chron",
    "icon": "https://a3chron.dev/a3-active.png",
    "author": {
        "name": "Kurt Schambach",
        "url": "https://a3chron.dev/"
    },
    "items": [
        {
            "id": "https://a3chron.dev/blog/stellar",
            "content_html": "<h1>stellar</h1>\n<p>After noticing that the starship theme switcher I made was actually quite useful,\nand realising, that starship hat almost 0 ecosystem, I decided, that it was again time for a new project...<br>\nIn other words, exam season -> active procrastination ^^</p>\n<p>With stellar, you can search for a config / theme you like at the <a href=\"https://stellar.a3chron.dev\">web hub</a>,\nor even upload your own config for others to use.<br>\nYou can easily download &#x26; switch between themes, whether from the community or your own local ones.</p>\n<p><img src=\"https://a3chron.dev//project-images/stellar-demo.gif\" alt=\"Starship theme switcher demo\"></p>\n<h2>Installation</h2>\n<p>Just run the <a href=\"https://raw.githubusercontent.com/a3chron/stellar/main/install.sh\">install script</a>\nwhich will download the binary and move it to <code>~/.local/bin</code></p>\n<pre><code class=\"language-bash\">curl -fsSL https://raw.githubusercontent.com/a3chron/stellar/main/install.sh | bash\n</code></pre>\n<h2>Usage</h2>\n<p>You can use this to switch quickly between starship prompts (local or community configs),\nfind themes you like, or include it in a bigger script which for example changes the\nwhole systems theme.</p>\n",
            "url": "https://a3chron.dev/blog/stellar",
            "title": "stellar",
            "summary": "A starship config / theme manager",
            "date_modified": "2026-02-09T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "Customization"
            ]
        },
        {
            "id": "https://a3chron.dev/blog/switch-to-nixos",
            "content_html": "<h1>I switched to NixOS (👾🥳)</h1>\n<p>I recently switched to NixOS, mostly because I did not want to spend\nanother time recreating my entire setup if my laptop broke again.\n(Which happenes to be expected at least every few months)</p>\n<p>The setup usually took a few hours, even with the\n<a href=\"/blog/ubuntu-setup\">customization guide</a> I wrote for the basics,\nand some things I always had not backed up anywhere or did not remember, so they were eventually lost.</p>\n<p>And I know, sure, I could have used dotfiles and all kinds of stuff to still manage that a little better,\nand I tried, but it was just too much time &#x26; energy for me, to keep everything updated,\nevery time I updated a small file somewhere, to remember to also stage the changes of this exact file,\nas of course all the config files were not in the same directory.</p>\n<p>Now with NixOS, this all works better. Everything lives in <code>/etc/nixos</code>, all my apps, packages, configs, etc.\nThe random config I totally forgot and had no time to add to my dotfiles will be just added the next time\nI change anything.</p>\n<p>I already love it, and not just because of that. For me, this is the first time my system feels quite \"clean\",\neven a few weeks after setting everything up.<br>\nThere are no hidden or forgotten installed packages, not old deprecated stuff that did somehow not get fully removed.\nQuite a good feeling.</p>\n<hr>\n<p>I'm of course working further on moving some of my old configs into the nix space,\nbut most of it is <a href=\"https://github.com/a3chron/nix-config\">already there</a>, migrated and ready for my laptop dying (please don't).</p>\n<p>Moving was actually benefitial in other parts too, I started learning vim motions, and checked out nvim,\nmight switch after I get better in the motions.<br>\nI am considering switching from fish to zsh or similar, just to have a POSIX compliant shell,\nswitched from alacritty to ghostty (not too sure about that), as alacritty refused to correctly display my custom window button menu.</p>\n<blockquote>\n<p>Little note to alacritty &#x26; ghostty, the startup time for alacritty is noticeably quicker than for ghostty,\nbut I might get used to it, and I'm quite happy about a few things at ghostty,\nfor example the great animation (<code>ghostty +boo</code>), we need more of that :)</p>\n</blockquote>\n<p>All in all, let's see how it goes</p>\n",
            "url": "https://a3chron.dev/blog/switch-to-nixos",
            "title": "Switch to NixOS",
            "summary": "Had enough of recreating my setup every time my laptop broke",
            "date_modified": "2026-01-08T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "Customization"
            ]
        },
        {
            "id": "https://a3chron.dev/blog/kaeru-kitchen-release",
            "content_html": "<h1>Kaeru's Kitchen release</h1>\n<p>For those that remember <a href=\"/projects/gith\">Gith</a>: I had exams again...</p>\n<p>For those who don't, I seem to have developed a habit during exam season -\ninstead of studying, I end up procrastinating so hard,\nI start building small life-improvements for myself that sometimes end up being\nactually useful to others too.</p>\n<p>Well, it's been a few months since the exams now,\nand finally we can see the results.</p>\n<div className=\"flex flex-col md:flex-row gap-6\">\n    <img src=\"https://a3chron.dev//project-images/kaeru-kitchen-home.jpeg\" alt=\"Preview (more visible on google play)\" className='w-full md:w-1/3 rounded-3xl border-2 border-mantle' />\n    <img src=\"https://a3chron.dev//project-images/kaeru-kitchen-settings.jpeg\" alt=\"Preview (more visible on google play)\" className='w-full md:w-1/3 rounded-3xl border-2 border-mantle' />\n</div>\n<p>This time I was desperately needing a good recipe book.\nI decided to go for an app, so I could easily share recipes with family and friends,\nand maybe easier recipe writing.<br>\nBut of course all existing options either did not have to option to create own recipes,\nonly browse them online, or they had a design,\nthat looked like it was developed before computers became a thing (or were full of ads - equally horrifying for me to look at).<br>\nThe one good looking and working app I found was too old and not available for my android version.<br>\nSo I created my own.</p>\n<p>The Android app I developed is a simple offline recipe book,\nwhich let's you save your own recipes,\nand share them with friends &#x26; family, or everyone using the app on the web-hub.</p>\n<p>You can also quickly search recipes by category,\ndepending on whether you are planning to cook dinner,\nbake a sweet dessert, or choose based on the time you have available.\nAnother filter option is custom tags, so if your best friend is allergic to pineapples,\nyou can easily filter out unsuitable recipes.</p>\n<p>After deciding for the right recipe, the app offers to calculate how much of your ingredients\nyou'll need for more or fewer servings,\nand then guide you through every step of the recipe,\nwith all ingredients needed for this step,\nas well as an optional timer, when baking muffins for 20 minutes.</p>\n<p>And for all the customization fanatics out there (myself included),\nbesides dark / light mode, Kaeru's Kitchen features three different themes to choose from: \"Material You\",\n\"Catppuccin\" with many different selectable accent colors,\nas well as a theme following the style of Nothing Technology Limited.</p>\n<p>But don't listen to me, check it out for yourself on <a href=\"https://play.google.com/store/apps/details?id=com.a3chron.nrecipe&#x26;utm_source=portfolio\">google play</a>.</p>\n<hr>\n<a href=\"https://www.producthunt.com/products/n-recipe?embed=true&utm_source=badge-featured&utm_medium=badge&utm_source=badge-n&#0045;recipe\" target=\"_blank\">\n    <img src=\"https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1032256&theme=neutral&t=1761747047783\" alt=\"Kaeru's Kitchen - Offline&#0032;recipe&#0032;book&#0032;for&#0032;android | Product Hunt\" style={{width: \"250px\", height: \"54px\"}} width=\"250\" height=\"54\" />\n</a>\n",
            "url": "https://a3chron.dev/blog/kaeru-kitchen-release",
            "title": "Kaeru's Kitchen release",
            "summary": "Released Kaeru's Kitchen, a cook book on Google Play",
            "date_modified": "2025-10-29T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "kaeru-kitchen"
            ]
        },
        {
            "id": "https://a3chron.dev/blog/gith-beta-launch",
            "content_html": "<h1>Gith Beta Launch</h1>\n<p>I had exams, so I obviously started building something instead of studying.\nGith is the result, and one I am quite proud of,\nas it can be a small life-improvement, even in it's beta phase, and with a few features missing.<br>\nBecause of this I launched a beta release on <a href=\"https://www.producthunt.com/products/gith?launch=gith-beta\">Product Hunt</a>,\njust to get some more early on feedback.<br>\nIn other words, feel free to comment any ideas for features you would like to see in the first stable release on Product Hunt,\nor create / upvote feature requests and bugs on <a href=\"https://gith.featurebase.app/\">Featurebase</a>.</p>\n<blockquote>\n<p>[!NOTE] Roadmap</p>\n<p>On <a href=\"https://gith.featurebase.app/\">Featurebase</a> you can also see the current Roadmap</p>\n</blockquote>\n<h2>Key features</h2>\n<p>Gith aims to support the most common git commands, packaged in a sleek, user-friendly interface.\nFor some of the git commands, there are even some little quality-of-life improvements, for example when adding new tags:</p>\n<p>Usually, you'd run <code>git tag &#x3C;exact-tag></code> but with gith you just run <code>gith tag</code>,\nwhich starts its interactive mode.\nGith automatically finds the latest tag and suggests new tags for patch, minor, and major updates,\nfrom which you can choose.</p>\n<p><img src=\"https://a3chron.dev//blog-images/gith-add-tag.png\" alt=\"\"></p>\n<p>Gith tries to use intuitive,\nnatural language commands, such as \"add tag\", \"push tag\", \"add remote\" etc.</p>\n<h2>Who it's for</h2>\n<p>Gith helps both beginners getting started with Git through its user-friendly interface,\nand experienced users by making everyday tasks easier.</p>\n<h2>Opensource</h2>\n<p>Gith is opensource, so feel free to check out the code at <a href=\"https://github.com/a3chron/gith/\">github</a></p>\n<p><strong>Enjoy, and don't forget to give feedback ;)</strong></p>\n<hr>\n<a href=\"https://www.producthunt.com/products/gith?embed=true&utm_source=badge-featured&utm_medium=badge&utm_source=badge-gith&#0045;beta\" target=\"_blank\">\n    <img src=\"https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1004160&theme=neutral&t=1755083014406\" alt=\"Gith&#0032;&#0040;beta&#0041; - A&#0032;Terminal&#0032;UI&#0032;for&#0032;git | Product Hunt\" style={{width: \"250px\", height: \"54px\"}} width=\"250\" height=\"54\" />\n</a>\n",
            "url": "https://a3chron.dev/blog/gith-beta-launch",
            "title": "Gith Beta Launch",
            "summary": "Launched the beta version of gith on producthunt to get some early feedback",
            "date_modified": "2025-08-14T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "gith"
            ]
        },
        {
            "id": "https://a3chron.dev/blog/ubuntu-setup",
            "content_html": "<h1>Gnome Customization</h1>\n<p>Basically my call on \"How to make Gnome look good\"™.</p>\n<p>In this tutorial I'll give a quick overview over setting up:</p>\n<ul>\n<li>GTK Theme</li>\n<li>Cursor Theme</li>\n<li>Icon Theme</li>\n<li>Fish Shell</li>\n<li>Some Gnome extensions</li>\n<li>Some catppuccin themes for various apps</li>\n<li>Starship</li>\n</ul>\n<p>I recently discovered <a href=\"https://catppuccin.com\">catppuccin</a>,\nso it'll be mostly this.</p>\n<p><img src=\"https://a3chron.dev//blog-images/example-ubuntu-customization.png\" alt=\"\">\n<img src=\"https://a3chron.dev//blog-images/example2-ubuntu-customization.png\" alt=\"\"></p>\n<hr>\n<h2>Update packages</h2>\n<p>We will need a few new packages, so make sure you are up to date:</p>\n<pre><code class=\"language-bash\">sudo apt update\nsudo apt upgrade\n</code></pre>\n<h2>Tweaks</h2>\n<p>First we'll need to install gnome-tweaks,\na tool to customize a few important settings.</p>\n<pre><code class=\"language-bash\">sudo apt install gnome-tweaks\n</code></pre>\n<h2>GTK Theme</h2>\n<p>This is just an overall catppuccin style theme replacing the default GTK theme.</p>\n<p>Download the <code>Catppuccin-Dark-B-LB.zip</code> (Mocha, Dark, Border, Legacy Buttons)\nfrom the <strong>Files tab</strong> at <a href=\"https://www.gnome-look.org/p/1715554\">gnome-look.org</a>.</p>\n<p>Create a directory for all your themes at <code>~/.themes</code>,\nand move your downloaded folder there.</p>\n<p>Now add a symlink from you gtk files (usually located at <code>~/.config/gtk-4.0</code>),\nto the respecting files in your themes directory.</p>\n<p>There should be a <code>assets</code> folder, and <code>gtk.css</code>, and <code>gtk-dark.css</code> files.</p>\n<p>You can create symlinks using the following command (replace 'username'):</p>\n<pre><code class=\"language-bash\">ln -sf /home/username/.themes/Catppuccin-Dark-Macchiato-B-LB/Catppuccin-Dark-Macchiato/gtk-4.0/assets/ ./assets/\n</code></pre>\n<h2>Cursor Theme</h2>\n<p>Now we will install a new Cursor Theme.<br>\nDownload the files at <a href=\"https://www.gnome-look.org/p/1358330/\">gnome look</a>.</p>\n<p>You shoud now have <code>01-Vimix-cursors.tar.xz</code> in your Downloads.\nExtract it, and copy the <code>dist</code> directory to <code>/usr/share/icons/vimix</code>.<br>\nOptionally you can also copy <code>dist-white</code> to <code>/usr/share/icons/vimix-white</code>.</p>\n<pre><code class=\"language-bash\">sudo mv dist \"/usr/share/icons/vimix\"\nsudo mv dist-white \"/usr/share/icons/vimix-white\"\n</code></pre>\n<p>You can now set the cursor theme in Tweaks/Appearance -> Cursor, just search for vimix.</p>\n<h2>Icon Theme</h2>\n<p>Here we will download a Icon Theme, to replace the default ubuntu one.\nIf you like others more, you can use these too, <a href=\"https://www.gnome-look.org/p/1166289/\">Papirus</a> for example is a quite common one.</p>\n<p>We will use <a href=\"https://www.gnome-look.org/p/1214931\">Flat-Remix</a> here.</p>\n<p>After downloading, you should have <code>01-Flat-Remix-GTK-Blue-20240730.tar.xz</code> (or some other icon theme) in your Downloads.</p>\n<p>Extract it, and move the <code>Flat-Remix-Blue-Dark</code> directory to <code>~/.local/share/icons</code>.</p>\n<pre><code class=\"language-bash\">mv \"Flat-Remix-Blue-Dark\" ~/.local/share/icons\n</code></pre>\n<p>You can now set the icon theme in Tweaks/Appearance -> Icons.</p>\n<h2>Fish Shell</h2>\n<p>This improvement is more about efficiency than looking good.</p>\n<p>If you are not already using fish, you can install it by running:</p>\n<pre><code class=\"language-bash\">sudo apt install fish\n</code></pre>\n<p>More info about fish: <a href=\"https://fishshell.com/\">https://fishshell.com/</a></p>\n<p>Now just run <code>fish</code> in the terminal, and try out the auto-completion\nand other features of fish, like improved reverse-search (Ctrl + R).</p>\n<blockquote>\n<p>[!NOTE] Welcome message</p>\n<p>If you want to customize the welcome message,\nyou should be able to do so in <code>/etc/fish/config.fish</code></p>\n</blockquote>\n<h2>Some Gnome extensions</h2>\n<p>Gnome extensions are just small but very useful extensions for your Desktop.</p>\n<p>To install the extension manager run:</p>\n<pre><code class=\"language-bash\">sudo apt install gnome-shell-extension-manager\n</code></pre>\n<p>You can search and view extension at <a href=\"https://extensions.gnome.org/\">extensions.gnome</a>,\nand install them in the extension manager.</p>\n<p><img src=\"https://a3chron.dev//blog-images/user-extensions.png\" alt=\"\"></p>\n<p>\"Blur my Shell\" and \"Rounded Window Corners Reborn\" are the most important here for the look and feel.</p>\n<p>Optionally, to install extensions right away from the browser,\ninstall the <a href=\"https://addons.mozilla.org/en-US/firefox/addon/gnome-shell-integration/\">gnome shell firefox addon</a>,\nand run:</p>\n<pre><code class=\"language-bash\">sudo apt install gnome-browser-connector\n</code></pre>\n<p>Now you can use the install button at an extensions page.</p>\n<h2>Some catppuccin themes for various apps</h2>\n<p>There are catppuccin themes for many apps,\nyou can view all ports at their <a href=\"https://catppuccin.com/ports/\">official site</a>.</p>\n<p>Search for any relevant apps, and follow their installation instructions.</p>\n<p>One of the bigger ports are userstyles, I have a seperate article on them: <a href=\"/blog/userstyles\">Userstyles</a></p>\n<h2>Starship</h2>\n<p>Starship is another improvement for your terminal.</p>\n<p>I have a older articel on <a href=\"/blog/starship\">Starship</a> which covers installation and configuration,\nwith a few versions of my configuration file at the end.<br>\nYou can copy the one you like most, and configure it further if you want.</p>\n<p>If you want to try out several starship prompts, or switch between them (for example based on your wallpaper)\nmake sure to try out <a href=\"github.com/a3chron/stellar\">stellar</a>, a starship config manager.</p>\n<h2>Conky</h2>\n<p>The widgets in the background on the second image at the beginning are conky,\nbut my current setup has a little bug (visible in the image, the bars at storage &#x26; eth are missing),\nso I'll be fixing that, and probably adding some more widgets.</p>\n<p>If you want to try it out yourself, I installed it via <code>sudo apt-get install conky-all</code>,\nand you can get quite decent configs at <a href=\"https://www.gnome-look.org/browse?cat=124\">gnome-look</a>.</p>\n<p>Otherwise, I'll be updating this as always when (/if) I'll finish it.</p>\n<h2>Custom window close buttons</h2>\n<p>For this one you'll need to be just a little bit more tech-savy.<br>\nYou will need to directly customize your current <code>gtk.css</code> file.</p>\n<p>If you followed this tutorial, the gtk file at <code>~/.config/gtk4.0/gtk.css</code>\nshould link to your themes <code>gtk.css</code> file, so you'll need to edit the themes <code>gtk.css</code> file.\n(probably somewhere at `~/.themes/xy)</p>\n<blockquote>\n<p>[!WARNING] This is \"beta\"\nI am planning on turning this one into an extension, so it is easier and safer to use. I'll link it here when I'm done.</p>\n<p>No warranty for this file, you can probably break your setup (mostly some things will start look really bad if somethings goes wrong)\nby doing changes in <code>gtk.css</code>.<br>\nI did not test this yet on other devices than mine, and I am not 100% sure which changes were new etc.<br>\nI'm working on it, but if you want to take the risk, feel free to take a look at the changes I think are neccassary for custom window buttons.<br>\nI would suggest making sure you can somehow revert it to the original version.</p>\n<p>In the worst case, all that can happen is, that you have to reinstall the whole theme.\nDon't edit your system <code>gtk.css</code> (if you don't know what your doing), but only the one of Themes you downloaded.</p>\n</blockquote>\n<p>To apply these styles to Flathub apps too, you'll need to give all apps access to these directories:</p>\n<p><img src=\"https://a3chron.dev//blog-images/apply-styles-to-flathub-apps.png\" alt=\"\"></p>\n<p>You can do so using an app like <a href=\"https://flathub.org/apps/com.github.tchx84.Flatseal\">Flatseal</a>.</p>\n<details>\n  <summary className='mt-6 cursor-pointer hover:underline'>(maybe) the secret to fancy window buttons</summary>\n<pre><code class=\"language-css\">windowcontrols button:not(.suggested-action):not(.destructive-action) {\n  min-height: 16px;\n  min-width: 16px;\n  padding: 0;\n  margin: 14px 0px;\n}\n\nwindowcontrols button.minimize:not(.suggested-action):not(.destructive-action), windowcontrols button.maximize:not(.suggested-action):not(.destructive-action), windowcontrols button.close:not(.suggested-action):not(.destructive-action) {\n  color: rgba(239, 241, 245, 0.7);\n  background-color: #181825; /* custom */\n  border: 2px solid #cdd6f4; /* custom */\n  border-radius: 5px; /* custom */\n  transition: all 200ms cubic-bezier(0, 0, 0.2, 1); /* custom */\n  cursor: pointer; /* custom */\n}\n\nwindowcontrols button.minimize:not(.suggested-action):not(.destructive-action) image, windowcontrols button.maximize:not(.suggested-action):not(.destructive-action) image, windowcontrols button.close:not(.suggested-action):not(.destructive-action) image {\n  padding: 0;\n  background: none;\n  display: none; /* custom */\n  opacity: 0; /* custom */\n  box-shadow: none;\n}\n\nwindowcontrols button.minimize:hover:not(.suggested-action):not(.destructive-action), windowcontrols button.maximize:hover:not(.suggested-action):not(.destructive-action), windowcontrols button.close:hover:not(.suggested-action):not(.destructive-action) {\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), inset 0 1px rgba(239, 241, 245, 0.1);\n  margin: 11px 0px; /* custom */\n  min-height: 20px; /* custom */\n}\n\nwindowcontrols button.minimize:active:not(.suggested-action):not(.destructive-action), windowcontrols button.maximize:active:not(.suggested-action):not(.destructive-action), windowcontrols button.close:active:not(.suggested-action):not(.destructive-action) {\n  color: #eff1f5;\n  background-color: #eff1f5;\n}\n\nwindowcontrols button.minimize:backdrop:not(.suggested-action):not(.destructive-action), windowcontrols button.maximize:backdrop:not(.suggested-action):not(.destructive-action), windowcontrols button.close:backdrop:not(.suggested-action):not(.destructive-action) {\n  opacity: 0.65;\n}\n\n/* custom */\n\nwindowcontrols button.minimize:not(.suggested-action):not(.destructive-action) {\n  border-color: #a6e3a1;\n}\n\nwindowcontrols button.minimize:hover:not(.suggested-action):not(.destructive-action) {\n  background-color: #a6e3a1;\n  min-height: 19px;\n}\n\nwindowcontrols button.maximize:not(.suggested-action):not(.destructive-action) {\n  border-color: #fab387;\n}\n\nwindowcontrols button.maximize:hover:not(.suggested-action):not(.destructive-action) {\n  background-color: #fab387;\n  min-height: 19px;\n}\n\nwindowcontrols button.close:not(.suggested-action):not(.destructive-action) {\n  border-color: #f38ba8;\n}\n\nwindowcontrols button.close:hover:not(.suggested-action):not(.destructive-action) {\n  background-color: #f38ba8;\n  min-height: 19px;\n}\n\n/* end custom */\n</code></pre>\n</details>\n",
            "url": "https://a3chron.dev/blog/ubuntu-setup",
            "title": "Gnome Customization",
            "summary": "Some Ubuntu >=24.04 / Gnome customizations for a catppuccin look, aestethics (and efficiency?)",
            "date_modified": "2025-04-21T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "Customization"
            ]
        },
        {
            "id": "https://a3chron.dev/blog/rl-experiment",
            "content_html": "<h1>A Reinforcement Learning Experiment</h1>\n<p>As I was studying for my endterm at university,\nI obviously searched for a lot of things to do instead of learning.\nOne of them happened to be Reinforcement Learning (RL).<br>\nI remembered an example by some university student group,\nwhere an agent was searching for food in a simulated environment.</p>\n<p>Now I wanted to build up on that, with zero to no expirience with RL...</p>\n<p>The results were obviously not really good, but anyways,\nI think I learned a little bit during improving my chatGPT boilerplate,\nand I want to share the story (mostly for my amusement in a few years),\namong with maybe later on some actually useful improvementes I made.</p>\n<blockquote>\n<p>The code is in my repo: <a href=\"https://github.com/a3chron/RL-pred-prey-sim\">RL-pred-prey-sim</a></p>\n</blockquote>\n<h2>Setup</h2>\n<p>The simulated Environment was quite simple:</p>\n<p><img src=\"https://raw.githubusercontent.com/a3chron/RL-pred-prey-sim/refs/heads/master/images/pred-prey-sim.png\" alt=\"\"></p>\n<p>There where two prey agents (green and blue circles),\nsearching for food (green dots, +1 XP) while avoiding\n\"poisonous food\" or something like that (red dots, -0.5 XP).</p>\n<p>I also added an slower predator (red circle),\nto make it a little bit harder for the prey agents,\nas I was interested in whether they would develop teaming abilities...</p>\n<p>The simulation would run for an fixed amount of frames,\nand then update the agents NNs, and start over again,\nwith each run beeing an \"episode\".</p>\n<p>It was possible to watch the simulation in realtime, 10 fps, or speed it up,\nand I also added indicator for the predator agent, which prey he is following,\nand for the prey agents, which dot is the currently nearest to them.<br>\nAdditionally I plotted a graph with MatPlotLib with the XP of both prey agents in each episode,\nlater on I added TensorBoard statistics, as it was easier to compare different runs,\nand TensorBoard also added a feature to easily smooth the graph,\nwhich was quite neccassary, because the XP per episode was heavily fluctuating.</p>\n<p>The predator was simply always going after the closest prey agent,\nas I didn't want to make it too complicated for the beginning\n(as I found out later, I made it too complicated).</p>\n<p>The prey agents both had their own Neural Net,\nwith for the beginning just two Linear Layers, and a ReLu layer in between.</p>\n<h2>First Problems</h2>\n<p>Now, in the beginning, I was just watching the simulation,<br>\nand realised, the agents are not really learning.</p>\n<p>So, first I thought, they may need more time,\nso I worked at speeding the simulation up.<br>\nI experimented with the max speedup of frames per second,\nthat would still change something at the simulation speed,\nthen I realised, that's too slow, the simulation is slowing everything down,\nand I didn't really need the simulation all the time,\nI just wanted to check in on the agents once in a while,\nto analyse strategies...</p>\n<p>So I made the simulation pausable, which heavily reduced\nthe time per episode.</p>\n<p>But the agents were still not learning.<br>\nThe <code>EPISODE_LENGTH</code> was about <code>3000</code> frames at this time,\nwhich was apparently way too much.<br>\nThe agents were running straight into one direction,\nthey ended up in some corner in maybe 20-50 frames,\nand stayed there for the following 2900 frames.</p>\n<p>Obviously they didn't learn a lot from that,\nso I reduced <code>EPISODE_LENGTH</code> to about <code>100</code>.</p>\n<p>This showed some results, as the prey agents were learning quicker,\nand the focus was more on just going straight into the\ndirection of the next green dot, and then maybe on more...</p>\n<p>At this time I thought about maybe increasing the episode length\nduring training, so that the agents would first quickly learn\nto search for the nearest greend dot, and then after some time,\nwith longer episodes, learn to search for more.<br>\nBut I left this idea for later, as the agents were still\nnot really learning in the amount that I would have liked,\ntheir behaviour was still quite random.</p>\n<p>So I thought, I will make this as easy as it could be:\nI first removed the predator agent's ability to move,\nthen I fully removed him, or at least the Xp loss\nfor the prey agents if they acidentially went right through him.</p>\n<p>I also removed all red dots, and fixed the position of the dots,\nso that they would not be randomly spread across the map after each episode.</p>\n<p>In the end, to really be sure, that it was theoretically possible\nfor them to learn, I also removed the \"eating\" effect,\nso if a prey agent ate a dot, the dot didn't get removed\n(and respawned somewhere else on the map),\nbut instead it just stayed there.<br>\nThe agents now only had to find a dot, and just stay on it,\nthey would get xp every single frame.</p>\n<p>And wow, this actually worked (Yippieh!).\nSo I started searching for good parameters with this settings,\nas it was easy to compare different runs with different setting in TensorBoard.</p>\n<p>First I found a good number of neurons in the Linear Layers,\nafterwards an good <code>EPISODE_LENGTH</code>, and number of dots.</p>\n<p>After this I slowly started making it harder for the prey agents again.\nDots would dissapear again, and get random positions every episode.</p>\n<p>This is my current state, it is less than I expected,\nbut it's useable, and I can keep improving it.</p>\n<p>I think that the next change will be adding batches,\nand updates of the NN only after batches, so a few episodes,\nbecause this should lead to better learning, and less fluctuating.</p>\n<p>With this said, I hope you will prepare better before wildly\nexperimenting like this, but I can promise you, if you are studying\nfor your endterms, it is a really fun way to loose time ;)</p>\n",
            "url": "https://a3chron.dev/blog/rl-experiment",
            "title": "A Reinforcement Learning Experiment",
            "summary": "I tried a predator-prey simulation with RL",
            "date_modified": "2025-02-27T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "AI"
            ]
        },
        {
            "id": "https://a3chron.dev/blog/neural-network-learning",
            "content_html": "<h1>Basics of Neural Networks and Deep Learning - Part 4</h1>\n<blockquote>\n<p>Course Overview: <a href=\"/blog/deep-learning-course\">Deep Learning Course - Overview</a></p>\n</blockquote>\n<p>We will learn how neural networks are learning (gradient descent),\nand how neural networks are rated.</p>\n<h2>Content of this block</h2>\n<p>The <strong>marked</strong> article is the current one.</p>\n<ul>\n<li>Our Brain and the Perceptron</li>\n<li>MNIST, and why good data is so important</li>\n<li>Structure of a Neural Network</li>\n<li><strong>A Neural Network is learning</strong></li>\n<li>Backpropagation</li>\n</ul>\n<h2>How is a Neural Network learning?</h2>\n<p>There are a few ways for a NN to learn.</p>\n<ul>\n<li>Supervised Learning</li>\n<li>Unsupervised Learning</li>\n<li>Reinforcement Learning</li>\n</ul>\n<p>We will focus on the supervised learning first,\nas we will use it in our first project,\nbut we'll also need the other ones later.</p>\n<h3>Supervised Learning</h3>\n<p><em>-> The NN gets the data and the corresponding label.</em></p>\n<p>This method is usually used for classification tasks,\ne.g. spam detection or our first project,\nwhere we will let the NN clasify images of numbers.</p>\n<blockquote>\n<p>Classification can be separated into binary and multiclass classification.</p>\n<p><strong>Binary classification</strong> is for example recognizing images of dogs:\nit's a dog (-> <code>true</code>) or not (-> <code>false</code>).</p>\n<p><strong>Multiclass classification</strong> would be assigning one of three or more labels,\ne.g. for images of animals assigning them one of the labels dog, cat, octopus, etc.</p>\n</blockquote>\n<p>Supervised learning is basically what we've been talking about all the time when talking about training.</p>\n<h3>Unsupervised Learning</h3>\n<p><em>-> The NN gets only the data.</em></p>\n<p>With this method we usually try to detect pattern in data\nand get a rule for this pattern.<br>\nThis is used in for example recommendation systems.</p>\n<h3>Reinforcement Learning</h3>\n<p><em>-> The NN gets no data, but everything the NN does in a simulated environment is rated.</em></p>\n<p>Reinforcement learning is used to get a NN to work in a real or simulated environment,\nfor example warehouse robots.</p>\n<h2>Rating our Neural Network</h2>\n<p>While training the NN, it needs to somehow know which variables (i.e. thresholds, weigths, etc.) it has to improve,\nand if it has to improve something.\nFor this we are going to calculate the loss,\ni.e. how much the calculated result is away from the right solution.\nWe will use an <strong>error function</strong>, also called <em>cost function</em> (or <em>loss function</em>).</p>\n<p>The simplest errorfunction is the following:</p>\n<p><code>loss = &#x3C;right solution> - &#x3C;calculated solution></code></p>\n<p>We usually won't use this, as it is not complicated enough for us ;)</p>\n<p>We can change this to a more interesting function when for example squaring the result.\nThis would punish errors more.</p>\n<blockquote>\n<p>In reality, it is the sum of the loss calculated with the errorfunction for every variable.</p>\n</blockquote>\n<hr>\n<p>Our goal is minimizing the errorfunction, i.e. get a small error.\nFor a normal function we could do so with the derivation.</p>\n<p>With the derivation we can get the extreme points of a function,\ni.e. the minima and maxima.<br>\n(To know whether it's a minimum or a maximum we could just insert the x-values into the function...)</p>\n<h3>Gradient Descent</h3>\n<p>With all our weights, biases and thresholds, we have much more variables than in a normal function.\nTo make all this more related to the real learning process of a NN,\nwe'll take two variables for our example errorfunction (i.e. three-dimensional space)\ninstead of only one.<br>\n<em>Yes that's not much more, but I'm sure you don't want to try to understand all the examples in the 300000-dimensional space ;)</em></p>\n<p>To find the minimum, we will use the gradient.<br>\nThe gradient gives us the way/direction of the steepest ascent.\nThat may sound cringe and unintuitive first,\nbecause why do we need the direction of the steepest ascend when we want to get down?</p>\n<p>Well, we'll just 'walk' in the opposite direction,\ni.e. we can use the negative gradient.<br>\nAs the gradient is the way of the quick increase, the negative gradient is usually the way of quickest decrease.</p>\n<blockquote>\n<p>For the gradient we'll need the partial derivation for every variable instead of the derivation of the function.</p>\n<p><em>I will explain this detailed in the backpropagation article (the next one)</em></p>\n<p>What we need to know:</p>\n<p>When a funtion has many variables and is derivated to one variable, that's a partial derivation.</p>\n</blockquote>\n<p>The gradient tells us which variables are most important / make the greatest change.</p>\n<p>Adjusting the variables with the gradient is called <strong>gradient descent</strong>.</p>\n<p><code>w' = w - n * gradient</code><br>\nwith <code>w</code>/<code>w'</code> being the variable / new variable and <code>n</code> the learning rate,\ni.e. how big the steps of our NN are when improving the variables.</p>\n<h3>Problems</h3>\n<p>There are a few important things regarding the gradient descent.<br>\nOne of them is the right learning rate.\nIf we set it too low, we will have a very long training time\nbecause our NN will improve the variables only a little bit every time.<br>\nOn the other hand we can't set it too high, because this will lead to random behaviour,\nas we would be jumping from one point to another,\nmaybe without coming closer to the minimum.</p>\n<p><img src=\"https://a3chron.dev//blog-images/learning-rate.png\" alt=\"learning-rate graphical\"></p>\n<p>Another Problem are local minima.\nWe want to find the minimal point of the whole errorfunction, i.e. the global minimum.</p>\n<p>When we take some random starting point, it can happen that the way of quickest decrease,\ni.e. gradient decent leads us to a local minimum instead of the global one.</p>\n<div className=\"invert opacity-80\">\n![local minima](/blog-images/local-minima.jpeg)\n</div>\nIn the picture the left valley is a local minimum, and the right one a global one.\n<p>In this case the gradient actually can't help us,\nbecause in a local minimum there is no way of decrease near your current point,\ni.e. the gradient descent always routes us back to the local minimum.</p>\n<p>There is no actual solution to this problem, but it's also not an really big problem,\nbecause an local minimum is usually quite good to.</p>\n<p>If not, just train your NN another time, and the result should be better.</p>\n<p>If not, it's probably somehow your fault (or my) :/<br>\nBut I test all the examples in this course, i.e. they should work.</p>\n<hr>\n<p>Another point we want to take a look into is the initialisation.</p>\n<p>An optimal point for the initialisation would be great,\ni.e. a point that is already near to a global minimum.\nSadly, we don't actually know how to do this either,\ni.e. we gotta take random values and hope the training helps.</p>\n<p>The random values should be in some specific range so we don't have some extreme random values.</p>\n<h2>Classification of Neural Networks</h2>\n<p>To classify a NN after training it,\nand compare it to other neural networks we usually take the <strong>accuracy</strong> and the <strong>loss</strong>.</p>\n<p>Accuracy is quite self-explainatory:</p>\n<p><code>accuracy = correct classifications / all classifications</code><br>\ni.e. the percentage of correctly classified data.</p>\n<p>I've already mentioned the loss, but for a clear definition:<br>\nThe \"loss\" measures how far off the network's predictions are from the actual correct answers.\nThe goal during training is to minimize (just like everything ig?) this loss.</p>\n<p>For some information while training the NN we can use small parts of the test data\nto get an accuracy / loss between epochs.</p>\n<h2>The End</h2>\n<p>In the next article we will talk about how the NN knows which variables to improve\nand how much, using the backpropagation algorithm.\nWith this we'll finish the first block.</p>\n<p>Next article: work in progress</p>\n",
            "url": "https://a3chron.dev/blog/neural-network-learning",
            "title": "A Neural Network is learning",
            "summary": "Basics of Neural Networks and Deep Learning 04",
            "date_modified": "2024-02-09T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "AI"
            ]
        },
        {
            "id": "https://a3chron.dev/blog/neural-network-structure",
            "content_html": "<h1>Basics of Neural Networks and Deep Learning - Part 3</h1>\n<blockquote>\n<p>Course Overview: <a href=\"/blog/deep-learning-course\">Deep Learning Course - Overview</a></p>\n</blockquote>\n<p>In this course, we will learn how Neural Networks look like,\nand how we transform our data, so a NN can process it.</p>\n<h2>Content of this block</h2>\n<p>The <strong>marked</strong> article is the current one.</p>\n<ul>\n<li>Our Brain and the Perceptron</li>\n<li>MNIST, and why good data is so important</li>\n<li><strong>Structure of a Neural Network</strong></li>\n<li>A Neural Network is learning</li>\n<li>Backpropagation</li>\n</ul>\n<h2>Basic Structure of a Neural Network</h2>\n<p><img src=\"https://a3chron.dev//blog-images/neural-network-structure.png\" alt=\"input, hidden and output layer\"></p>\n<p>Ok, so this is how an deep neural network looks like.\nWe have an input layer, where all our information is feeded to the NN,\nthen a hidden layer.\nIn the image we have only a few layers, but in reality there are usually more than three,\ndepending on the complexity of the problem.\n(for our first NN we are gonna only need a few layers, but big LLM for example need much much more)</p>\n<p>At the end there is the output layer, where we get the probabilities for the possible solutions.\nThis will look something like that:</p>\n<p><img src=\"https://a3chron.dev//blog-images/workflow-neural-net.png\" alt=\"image of a NN recognizing a dog\"></p>\n<h3>Output Layer</h3>\n<p><em>(I'm just starting with the detailed expl. of the output because it's easier to explain.)</em></p>\n<p>We have two output neurons, which can return a number between 0 and 1.\n(Note that the in and outputs are not binary anymore)\nEvery neuron is standing for one possible solution.</p>\n<blockquote>\n<p>You can change this, e.g. only one output neuron,\nand in another example with more outputs maybe something like\n0 for dog, 1 for cat, 2 for turtle, 3 for octopus, and so on.</p>\n<p>In our example in the picture we could also use only one output neuron,\nbut as we will use one for every solution in our first project I did it here too.</p>\n<p><a href=\"https://ai.stackexchange.com/questions/13944/one-vs-multiple-output-neurons\">Further reading</a>,\nbut we'll talk about this later too.</p>\n</blockquote>\n<h3>Input Layer</h3>\n<p>How we get data into our NN depends on the application.\nIf you're planning on coding a LLM, you'll definitly need an other input layer than for computer vision.\nRegarding our first project, we will look at computer vision here.</p>\n<p>We will have one neuron for every pixel of the image we want to feed to the NN,\ni.e. 28 x 28 = 784 (the image has 28x28 px) input neurons.\nAs the MNIST images of our first project are B&#x26;W, we have only one value between 0 and 255 for every pixel.</p>\n<p>Before giving all our data to the NN, we will normalize it.\nThis means we will take every input, and give it a value between 0 and 1.</p>\n<p>This is not too important right now,\nbut if we have different types of input, it will become important.</p>\n<p>An explanation I copied from StackOverflow:</p>\n<p><em>\"\nIn a nutshell, normalization reduces the complexity of the problem your network is trying to solve.\nThis can potentially increase the accuracy of your model and speed up the training.\nYou bring the data on the same scale and reduce variance.\nNone of the weights in the network are wasted on doing a normalization for you,\nmeaning that they can be used more efficiently to solve the actual task at hand.\n\"</em></p>\n<blockquote>\n<p>Example:</p>\n<p>A NN should decide whether a elephant is male or female.\nInputs are height in kilometers, and weight in milligrams,\ne.g. we will have sth like <code>height: 0.0043km; weight: 100000000mg</code>.</p>\n<p>This makes it very hard for the NN to balance the importance of the height/weight.\nIf we divide both values through the average value,\nthe NN won't have to use neurons for balancing the weight of the two inputs.</p>\n</blockquote>\n<p>In our first project it's going to be easier,\nas we know a minimal (<code>0</code>) and maximal (<code>255</code>) value.</p>\n<p>Because of this, we'll just divide all our inputs by 255.</p>\n<h3>Hidden Layer</h3>\n<p>This is the layer where all the magic happens,\nand also the layer we know the least about. (The name has a reason)</p>\n<p>Even if it's a crustBox, we know that there are many neurons,\nwith changing thresholds and weights,\nthat adjust parameters while training to fit the data.</p>\n<p>One of the things we can control in the hidden layers are the types of layers we use.\nWe can for example connect every neuron of one layer with every neuron of the next layer,\nor maybe only a few ones.<br>\nAlso we can take 50 neurons in the first layer and maybe 250 in the enxt one...</p>\n<p>This will look something like this later:</p>\n<pre><code class=\"language-python\">model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))\nmodel.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(10, activation='softmax'))\n</code></pre>\n<p>We'll talk more about this in the next <em>block</em> when introducing keras etc.</p>\n<h2>The End</h2>\n<p>Well, this was rather a small article, so let's jump right into the next one on NNs learning. (I'll add the link when done)</p>\n<p>Next Article: work in progress...</p>\n",
            "url": "https://a3chron.dev/blog/neural-network-structure",
            "title": "Structure of a Neural Network",
            "summary": "Basics of Neural Networks and Deep Learning 03",
            "date_modified": "2024-01-28T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "AI"
            ]
        },
        {
            "id": "https://a3chron.dev/blog/mnist-basics",
            "content_html": "<h1>Basics of Neural Networks and Deep Learning - Part 2</h1>\n<blockquote>\n<p>Course Overview: <a href=\"/blog/deep-learning-course\">Deep Learning Course - Overview</a></p>\n</blockquote>\n<p>In this course, we will learn about the MNIST dataset,\nand why good data is so important for training neural networks.</p>\n<h2>Content of this block</h2>\n<p>The <strong>marked</strong> article is the current one.</p>\n<ul>\n<li>Our Brain and the Perceptron</li>\n<li><strong>MNIST, and why good data is so important</strong></li>\n<li>Structure of a Neural Network</li>\n<li>A Neural Network is learning</li>\n<li>Backpropagation</li>\n</ul>\n<h2>What exactly do we need the Data for?</h2>\n<p>In the last article there was a little description on how a NN is trained.\nLet's make this description a little bit more detailed:</p>\n<p>When we want to train a NN, we need a bunch of data.\nThis Data is then separated in data used for training the NN (~ 75%), and data used for evaluating the NN (~ 25%).</p>\n<blockquote>\n<p>[!NOTE] One time through all training data = \"epoch\"</p>\n</blockquote>\n<p>We need this to make sure, the NN did not \"memorize\" the training data,\ni.e. it adjusted the threshold values to solve the exact problem it was given, but nothing more.\nSuch a NN could have an accuracy of probably nearly 100% on the data it was trained with,\nbut it will fail recognizing anything that was not part of the Training Data.\nThat's usually (=always) not what we want.</p>\n<blockquote>\n<p>Maybe think about why we don't want a NN that is specialized on the data it's trained on for a moment...</p>\n<p>...</p>\n<p>...</p>\n<p>Well, if we would want to assign every data-point to some label,\nyou would just take the most basic algorithm, some switch case, or a bunch of if elses,\nbut the use of Neural Networks is to recognize <em>new</em> data correctly.\n\"Never use AI if you don't have to\"\n(a standard program is usually quicker to write, takes no time and money for training, is not as complex as a NN, and you have no room for errors)</p>\n</blockquote>\n<blockquote>\n<p>This would by the way be an extreme example for <strong>overfitting</strong>, i.e. the NN getting used to the data it is trained with,\nbut it won't get better on unknown data. (That's also why more training is not equal to better accuracy)</p>\n<p><img src=\"https://a3chron.dev//blog-images/overfitting.png\" alt=\"overfitting image\"></p>\n<p>In this picture, we can see three datasets.\nLet's say, the red points are images of dogs, while the green one are cats.\n(for the light mode ppl cyan and pink).<br>\nThese points are our training data.<br>\nThe line is where our NN is separating the images.</p>\n<p>In the left image, we can see the result of a NN,\nthat was probably not trained enough (or has not enough layers etc.).<br>\n=> <strong>Underfitting</strong></p>\n<p>In the middle one, there is an <strong>overfitted</strong> NN,\nthe NN was probably trained too much.\nBecause of this, the \"function\" it developed to separate dogs and cats\nsuits the data it was trained for,\nbut it is much too specialized to fit any other data.</p>\n<p>The image on the right side shows a balanced NN.\nThis NN was trained exactly right, it's not extremely specialized,\nbut also not just a straight line through the data: It kinda \"sees\" the \"big image\",\ni.e. it will hopefully perform wonderful on new data.</p>\n</blockquote>\n<p>Because of this we check the results with the evaluation data,\nand make sure the NN will work for data it has never seen before,\ni.e. is not overfitted.</p>\n<h2>Why is good Data so important?</h2>\n<blockquote>\n<p>\"garbage in, garbage out\" - ancient chinese proverb <sup><a href=\"#user-content-fn-1\" id=\"user-content-fnref-1\" data-footnote-ref aria-describedby=\"footnote-label\">1</a></sup></p>\n</blockquote>\n<p>The Data a NN is trained with is (one of) the most important factor(s).\nYou can use wonderful algorithms, but without the right data, your NN cannot be trained properly.</p>\n<p>It is sometimes difficult to find a good dataset, and it takes even more time (much more) creating your own data,\nbut a good dataset is the first step towards a good NN.</p>\n<h2>What exactly is bad Data?</h2>\n<p>When you want to develop a NN\nwhich will recognize whether the animal in a picture is a dog or a wolve,\nbut all your training pictures of wolves are taken in the mountains (i.e. probably with snow in the background),\nthen the NN will propably classify a dog playing in the snow as a Wolve.</p>\n<p>Let's imagine this with a little kid learning. We would say:\n<em>look, this and this and this are wolves, and the other ones are dogs</em>,\nand the kid will think <em>\"If there is snow, it's a wolve, and without snow, it has to be a dog, easy\"</em>.</p>\n<p>It's the same for NN. If we label images with snow and something dog-alike as wolve, and all other images as dogs,\nthe NN will learn to classify images based on the amount of snow.</p>\n<p>Because of this we will need a lot data, and data for every possible situation, to represent the reality.\n(because in reality, there are also dogs and not only wolves in the snow.)</p>\n<p>If you'd be sure, that <em>absolutely</em> all wolves will have snow in the background, while no dog will <em>ever</em> be seen together with snow,\nit would be absolutely fine to let the NN decide based on snow.</p>\n<p>This is by the way why you should always try to <em>understand</em> your data.</p>\n<blockquote>\n<p>Little story:</p>\n<p>A group of students once tried autonomous driving, and recorded hundreds of hours of driving.\nThe AI trained with this data drove quite good, but after a while the car reached a bridge, where the car suddenly stopped.</p>\n<p>As the students found out later, in all their training data, there was grass on the side of the road,\nand so the AI did not know what to do when suddenly the grass disappeared at the bidge.</p>\n</blockquote>\n<p>This may be a small issue when recognizing dogs and wolves (depending on the application),\nbut let's imagine a scenario where your code is actually important.\nIn the best case, you're left alone with some pissed customers,\nbut you could also be responsible for much worse (self-driving cars crashing into each other, etc.).</p>\n<p>Anyway, we should <em>always</em> try to use good data,\nas our goal is to optimize our NN,\nand this starts with using good data for the training.</p>\n<hr>\n<p>That problem is one specific kind of biases. A NN with a bias basically means that the content of your data is represented in the responds the NN gives,\ne.g. the NN copies certain beliefs that are represented in the data.</p>\n<p>There are many forms of biases.\nThey can be introduced by incomplete data (e.g. you ignore for example one group of users),\nwrong data (some of your data entries are wrong) or your data is not representing the reality (dogs are playing in the snow too), etc.</p>\n<blockquote>\n<p>Example:</p>\n<p>You get your data by calling people, and asking them questions, for a product where you're not calling people.\nThe data you trained the NN is incomplete, because all the people, that hang up quick are not represented in the data.\nHowever, as the final product is used by many people - also people that would hang up the phone -\nthe NN will generate wrong responses for them.</p>\n<p>Something that - as i heard - actually happened:\nAn AI was used in court, to predict whether a suspect is innocent or not.\nAs the data it was trained on was incomplete/ not balanced, the AI started to favor quys that were white :/.</p>\n<p>TL;DR: When your data is racist, your NN will be too.</p>\n</blockquote>\n<p>Some advice when searching for good data:</p>\n<ul>\n<li>Select training data that's appropriately representative and large enough for your application.</li>\n<li>Test and validate to ensure the results of your NN don't reflect bias due to algorithms or the dataset.</li>\n<li>Understand the training data used, as the dataset could contain labels that can introduce bias.</li>\n</ul>\n<h2>Where can we get good Data?</h2>\n<p>It's quite hard getting good data, because many good/complete/normalized datasets are not available for free.\nAlso they may be not 100% suitable for your project, and so you maybe have to \"clean\" the data first.</p>\n<p>Here's a link with a few datasets for you in case you want to start your own project:</p>\n<ul>\n<li><a href=\"https://www.altexsoft.com/blog/best-public-machine-learning-datasets/\">Best public datasets</a></li>\n<li><a href=\"https://github.com/awesomedata/awesome-public-datasets\">Awesome public datasets</a></li>\n</ul>\n<p>For our first project we are gonna use a free dataset, the MNIST dataset.</p>\n<h2>MNIST</h2>\n<p>The MNIST dataset is a big collection of handwritten numbers (0 - 9).\nThey are all only 28 x 28 pixel small, i.e. increased training speed, and you don't need a graphic card for the training.</p>\n<p><img src=\"https://a3chron.dev//blog-images/mnist-example.png\" alt=\"example of the MNIST dataset\"></p>\n<p>This is a quite good dataset, the labels are good, the numbers are written by children and adults,\nthey are already separated into training and evaluation data, there is enough data (60.000 images) and so on... The perfect dataset.</p>\n<p>Additionally it's quite easy to load the data, so we won't need much code for this.</p>\n<p>The MNIST dataset is kinda the \"Hello World\" example for Deep Learning.</p>\n<h2>The End</h2>\n<p>Another article finished. In the next two articles we are going to focus more on neural networks\n(structure and learning process), so we can start developing right after the last article (backpropagation),\ni.e. in the next block on computer vision.</p>\n<p>Next Article: <a href=\"/blog/neural-network-structure\">Neural Network Structure</a></p>\n<section data-footnotes class=\"footnotes\"><h2 class=\"sr-only\" id=\"footnote-label\">Footnotes</h2>\n<ol>\n<li id=\"user-content-fn-1\">\n<p>Stole this idea from <a href=\"https://github.com/uhasker/\">mikhail berkov's</a> book on <a href=\"https://uhasker.github.io/getting-things-done-in-next-js/\">NextJS</a>. <a href=\"#user-content-fnref-1\" data-footnote-backref=\"\" aria-label=\"Back to reference 1\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>\n",
            "url": "https://a3chron.dev/blog/mnist-basics",
            "title": "MNIST, and why good data is so important",
            "summary": "Basics of Neural Networks and Deep Learning 02",
            "date_modified": "2024-01-15T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "AI"
            ]
        },
        {
            "id": "https://a3chron.dev/blog/neural-network-basics",
            "content_html": "<h1>Basics of Neural Networks and Deep Learning - Part 1</h1>\n<blockquote>\n<p>Course Overview: <a href=\"/blog/deep-learning-course\">Deep Learning Course - Overview</a></p>\n</blockquote>\n<p>In this course, we will learn the basic theory of how our brain works and how artificial neurons (=> Perceptrons) imitate it.</p>\n<h2>Content of this \"Block\"</h2>\n<p>i.e. the next few articles, the <strong>marked</strong> one is the current article.</p>\n<ul>\n<li><strong>Our Brain and the Perceptron</strong></li>\n<li>MNIST, and why good data is so important</li>\n<li>Structure of a Neural Network</li>\n<li>A Neural Network is learning</li>\n<li>Backpropagation</li>\n</ul>\n<h2>How does our Brain work?</h2>\n<p>The first question here is, why is our brain even worth looking at?</p>\n<p>Well, it is evolutionary optimized for solving specific problems.\nWe can for example distinguish quite good between a dog and a cat (usually).\nOn the other side, we are really bad in for example maths,\nbecause we never had the need to develop math skills in our evolution.</p>\n<p>If we want computers to be superior in recognizing dogs/cats,\nwe have to \"imitate\" our brain.\nFor this we need to know how it looks and works first.</p>\n<hr>\n<p>Our brain consists of millions of neurons, so it is basically a big biological neuronal network.</p>\n<blockquote>\n<p>[!NOTE]</p>\n<p>The network of neurons in our brain is called \"Neuronal\" Network, while\nartificial networks are called \"Neural\" Networks.</p>\n</blockquote>\n<p>As the whole brain is a very complex system, let's look at neurons first:</p>\n<p>Neurons take input signals, and give an output signal,\nif the sum of the input signal crosses a Threshold.</p>\n<p>One single neuron looks something like that:\n<img src=\"https://a3chron.dev//blog-images/neuron.png\" alt=\"image of a neuron\"></p>\n<p>It consists of three (or four) main parts, that are important for us:</p>\n<ul>\n<li>Dendrites</li>\n<li>Axom</li>\n<li>Soma</li>\n<li>(Synapses)</li>\n</ul>\n<p>The synapses are basically just the connection of one neurons axom to another neurons dendrites.</p>\n<p>The dendrites take the \"input signal\".\nThey are connected to other neurons through synapses,\nand when these neurons are firering (= giving an output signal),\nour neuron receives these signals over the dendrites.</p>\n<p>The axom is the part of the neuron, that transports the \"output signal\"\nto the dendrites or synapses of other neurons.</p>\n<p>The Soma is the centrum of the neuron, it's the place where all the input signal are collected,\nand where the output signal starts, when the input signals crosses a specific value.\n(A little bit simplifing biological facts)</p>\n<h2>First Models of Neurons</h2>\n<p>Now that we know how the neurons in our brain work, we gotta write code,\nthat imitates neurons. For this we have to look at more abstract models of neurons first.</p>\n<p>The perceptron is such a model, developed by Frank Rosenblatt in 1958.\nIt was heavily based on the McCulloch-Pitts neuron.</p>\n<p><img src=\"https://a3chron.dev//blog-images/mcculloch-pitts.png\" alt=\"mcculloch &#x26; pitts neuron\"></p>\n<p>The perceptron in this model has x₁ ... xₙ stimulating input signals, and\ny₁ ... yₙ suppressing input signals (the exact amount is determined by the problem we try to solve).</p>\n<blockquote>\n<p>Binary system</p>\n<p>We'll use the binary system here. Just in case you don't know it, I'll explain it real quick.\nIn the binary system (originally used for computers), we have only zeros and ones.\nThis is because communication in and between computers is using electricity.\nThe easiest transmittable format we can convert the data to is the binary system:\nwe have only zeros and ones, representing no electricity (0) versus electricity (1).</p>\n<p>In our case (and many others too):<br>\n<code>1</code> = <code>true</code><br>\n<code>0</code> = <code>false</code></p>\n<p>This should be everything we need for this course,\nbut I'll maybe add an little article about the binary and hexadecimal system,\nand add the link here when done, if you're interested and want to know more.</p>\n</blockquote>\n<p>In our perceptron, the soma is represented by a threshold, a value that determines when the neuron will fire:</p>\n<ul>\n<li>As soon as we have one (or more) suppressing signals, the output is <em>always</em> <code>0</code> (i.e. stimulating signals are ignored)</li>\n<li>If the sum of stimulating signals is equal or bigger than the Threshold, the output is <code>1</code></li>\n<li>If the sum of stimulating signals is less than the Threshold, the output is <code>0</code></li>\n</ul>\n<blockquote>\n<p>In the following I'll call stimulating input signals just input signals, because usually most of the input signals are stimulating.</p>\n</blockquote>\n<p>Our last component in the model is the output signal.\nIn this model, the input and output signals are binary (i.e. either <code>0</code> (=<code>false</code>)\nor <code>1</code> (=<code>true</code>)).</p>\n<blockquote>\n<p>This is still quite a simple and minimalistic perceptron.\nFor further reading you can check out: <a href=\"https://towardsdatascience.com/what-the-hell-is-perceptron-626217814f53\">What the hell is Perceptron?</a></p>\n</blockquote>\n<hr>\n<p>Back to our perceptron: we can already solve some easy problems with this minimalistic thing 🥳.<br>\nAs a \"developer\", lets try logic gates:</p>\n<blockquote>\n<p>If you dont know what logic gates are, please take a look into it: <a href=\"https://www.techtarget.com/whatis/definition/logic-gate-AND-OR-XOR-NOT-NAND-NOR-and-XNOR\">Logic Gates</a>.\nThe Wikipedia article is quite good too.</p>\n</blockquote>\n<h3>1. <strong>AND</strong> (two input signals, one output)</h3>\n<blockquote>\n<p>AND returns <code>true</code> (= <code>1</code>) when both input signal are <code>true</code>, and <code>false</code> (= <code>0</code>) if one or both of the input signals are <code>false</code>.</p>\n<p>Input x₁ <strong>AND</strong> input x₂ have to be <code>true</code> (<code>1</code>) to return <code>true</code> (<code>1</code>)</p>\n</blockquote>\n<p>In a table, this would look like this:</p>\n<table>\n<thead>\n<tr>\n<th>input 1</th>\n<th>input 2</th>\n<th>output</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td>0</td>\n<td><strong>0</strong></td>\n</tr>\n<tr>\n<td>0</td>\n<td>1</td>\n<td><strong>0</strong></td>\n</tr>\n<tr>\n<td>1</td>\n<td>0</td>\n<td><strong>0</strong></td>\n</tr>\n<tr>\n<td>1</td>\n<td>1</td>\n<td><strong>1</strong></td>\n</tr>\n</tbody>\n</table>\n<p>The AND function is solveable with a perceptron. We'll just set the threshold to <code>2</code>. Now we have a few possible constellations:</p>\n<ul>\n<li>both input signals are <code>0</code> -> sum = <code>0</code> -> the output of our neuron is <code>0</code></li>\n<li>one of the input signals is <code>0</code>, the other <code>1</code> -> sum = <code>1</code> -> our neuron returns <code>0</code> (the sum <code>1</code> is still smaller than our Threshold (<code>2</code>))</li>\n<li>both input signals are <code>1</code> -> sum = <code>2</code> -> the output is <code>1</code> (because sum >= Threshold)</li>\n</ul>\n<h3>2. <strong>OR</strong> (two input signals, one output)</h3>\n<blockquote>\n<p>OR returns <code>true</code> when one or both of the two input signals are <code>true</code>, and <code>false</code> if both of the input signals are <code>false</code>.</p>\n<p>Input x₁ <strong>OR</strong> input x₂ is <code>true</code>.</p>\n</blockquote>\n<table>\n<thead>\n<tr>\n<th>input 1</th>\n<th>input 2</th>\n<th>output</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td>0</td>\n<td><strong>0</strong></td>\n</tr>\n<tr>\n<td>0</td>\n<td>1</td>\n<td><strong>1</strong></td>\n</tr>\n<tr>\n<td>1</td>\n<td>0</td>\n<td><strong>1</strong></td>\n</tr>\n<tr>\n<td>1</td>\n<td>1</td>\n<td><strong>1</strong></td>\n</tr>\n</tbody>\n</table>\n<p><strong>Threshold: <code>1</code></strong></p>\n<p>If we have one or two stimulating (=<code>true</code> or <code>1</code>) inputs, the sum is bigger or equal to the threshold, and the output is <code>true</code> (<code>1</code>).</p>\n<h3>3. <strong>NOT</strong> (one <em>suppressing</em> input signal, one output)</h3>\n<blockquote>\n<p>NOT returns <code>true</code> when the input signal is <code>false</code>, and <code>false</code> if the input signal is <code>true</code>, i.e. always the opposite of the input.</p>\n<p>The Input y₁ is <strong>NOT</strong> (equal to) the Output.</p>\n</blockquote>\n<table>\n<thead>\n<tr>\n<th>input</th>\n<th>output</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>0</td>\n<td><strong>1</strong></td>\n</tr>\n<tr>\n<td>1</td>\n<td><strong>0</strong></td>\n</tr>\n</tbody>\n</table>\n<p><strong>Threshold: <code>0</code></strong></p>\n<p>Note that we have a supressing input signal here, i.e. when the input is <code>1</code>,\nthe output has to be <code>0</code>, because we have a supressing signal.</p>\n<p>On the other hand, if the input signal is <code>0</code>, i.e. we don't have a supressing signal,\nthe output will be <code>1</code>, because additionally to no supressing signal,\nthe number of input signals (<code>0</code>) is bigger or equal to the threshold (<code>0</code>).</p>\n<h3>3. <strong>XOR - exclusive OR</strong> (two input signals, one output)</h3>\n<blockquote>\n<p>XOR returns <code>true</code> when one of the two input signals is <code>true</code>, and <code>false</code> if both of the input signals are <code>false</code> or if both are <code>true</code>.</p>\n<p><strong>Either</strong> input x₁ <strong>OR</strong> input x₂ is <code>true</code>.</p>\n</blockquote>\n<p>Here we'll run into a problem. This logic gate is not solveable with a perceptron.</p>\n<p>Actually, this can be shown graphically.<br>\n<em>(green dot -> return <code>true</code>; red -> <code>false</code>)</em></p>\n<p><img src=\"https://a3chron.dev//blog-images/perceptron-graphical.png\" alt=\"perceptron graphical logic gates\"></p>\n<p>Here we can see, that XOR is not linearly separable,\ni.e. one single perceptron can't solve it.</p>\n<p>However, if we take more than one perceptron / more layers, the XOR problem becomes solveable.\nWhat you should take away from that: every problem, regardless the complexity,\ncan be solved with a finite number of perceptrons.</p>\n<p>As you could see, we have set the thresholds manually in the examples.\nThis is our next problem: getting the threshold values right for every singel perceptron.\n(usually they additionally have weights, and an activation function).</p>\n<p>With bigger NN (a few million/billion neurons) this is very hard (=not possible), and that's why NNs need to be trained.\nDuring the training, they adjust the thresholds (i.e. we don't do this manually anymore), to get better and better results.</p>\n<blockquote>\n<p>Little side note for those who don't know how an NN is trained:</p>\n<p>You take data and label it (i.e. you match every data entry with the right solution).\nAs we need much of this data, our only hope is usually that someone else has already done this\n(more about this when we come to MNIST).</p>\n<p>Now we'll give the NN one data entry, and it will generate probabilities for all possbile solutions.\nIt will suggest the most probable solution as the correct one.\nWe compare this suggestion with the corresponding label, and tell the NN whether it was right or wrong.<br>\nBased on this, the NN adjusts the thresholds (using backpropagation, we will learn about this in a extra article).</p>\n</blockquote>\n<p>Now that we know how a NN is learning, let's compare that to our brain real quick:</p>\n<p>We are basically doing exactly the same thing (adjust thresholds of neurons),\nwith the little difference, that the brain additionally adjusts the connections between neurons (topology).</p>\n<h2>This is the End... (only of this article xD)</h2>\n<p>Well, it's already the end of part one. You hopefully learned how our brain works,\nand how Neural Networks try to imitate neurons, so we can start of with neural networks and their learning procces soon.</p>\n<hr>\n<p>The next part will be a little bit smaller, we will learn about the MNIST dataset there.\nThis part is quite important too, because we need to understand a little bit about good data for our first project.</p>\n<p>Next Article: <a href=\"/blog/mnist-basics\">MNIST, and why good data is so important</a></p>\n",
            "url": "https://a3chron.dev/blog/neural-network-basics",
            "title": "Our Brain and the Perceptron",
            "summary": "Basics of Neural Networks and Deep Learning 01",
            "date_modified": "2024-01-11T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "AI"
            ]
        },
        {
            "id": "https://a3chron.dev/blog/deep-learning-course",
            "content_html": "<h1>Deep Learning / Neural Nets</h1>\n<h2>Topics / Content</h2>\n<p>In this course, we will learn about the basics of deep learning and neural networks with a few parallel coding examples (and the corresponding theory) for some different types, e.g. Computer Vision, LLM, etc.</p>\n<p>This course is meant for people that are beginners regarding deep neural networks,\nor want to know more about them / code their own one.\nWe'll need some math,\nand coding basics (for this course python would be great).</p>\n<blockquote>\n<p>If you <em>never</em> tried to code just a little, you should look into <a href=\"https://uhasker.github.io/the-python-minibook/\">The Python Minibook</a></p>\n</blockquote>\n<p>I will try to add as many examples as possible, because I think that \"theory will get you only so far\".</p>\n<p>As I will (for the beginning) not dive deep into all the types of NNs (we'll only scratch the surface), and also maybe skip some types,\nI will add a \"Further Reading\" section from time to time.</p>\n<p>The course will be separated into blocks, and these in little articles.</p>\n<blockquote>\n<p>Just for your orientation a little example:\nThe Block \"Basics of Neural Networks\" is separated into a few articles,\nvisible in the description: \"Basics of Neural Networks 01\".</p>\n<p>I will try to add a <em>Content</em> section to the beginning of all articles,\nso you can check quick if it's really the article you're searching for.</p>\n</blockquote>\n<p>I recommend reading the whole course in a chronological order,\nespecially the articles of one block, because they build up on each other.</p>\n<p>You can skip whole topics/blocks, if you are not interested in them,\nbut some blocks may introduce something new that will be important afterwards.</p>\n<h2>Basic Information</h2>\n<p>To be honest, I don't know much about Deep Learning <em>currently</em>,\nbut I hope to learn much more while writing this course.</p>\n<p>If you have problems understanding something, please\n<a href=\"https://github.com/a3chron/portfolio/issues/\">open an Issue</a>\nor write me an Email at <code>kurt.schambach@gmail.com</code>.\nI will try to fix any unclear parts.</p>\n<p>Same with spelling mistakes, I have Issue Templates (for those who know github, and have an account),\nso you basically just have to fill out a little form.\nAlso I will add a link for opening issues on every site (not mobile),\nso you won't have to come back here or search for my GitHub to open an Issue ;)</p>\n<p>Edit: The buttons on the bottom right (<strong>not on mobile</strong>) are from the top:</p>\n<ul>\n<li>Link to the code</li>\n<li>Link for reporting a Bug or any kind of malfunction (you'll need a GitHub account for that)</li>\n<li>Link for reporting spelling mistakes (Also GitHub account needed)</li>\n</ul>\n<p>If you don't have a GitHub account, just write me an informal Email.</p>\n<p><strong>Thank you for helping me improve the articles!</strong></p>\n<h2>Course Overview</h2>\n<p><em>This overview is not final.</em></p>\n<h3>Basics of Neural Networks</h3>\n<ul>\n<li><a href=\"/blog/neural-network-basics\">Our Brain and the Perceptron</a></li>\n<li><a href=\"/blog/mnist-basics\">MNIST, and why good data is so important</a></li>\n<li><a href=\"/blog/neural-network-structure\">Structure of a Neural Network</a></li>\n<li><a href=\"/blog/neural-network-learning\">A Neural Network is learning</a></li>\n<li>Backpropagation <strong>- in progress</strong></li>\n</ul>\n<p>Some possible future bigger topics are: LLMs and Reinforcement Learning.</p>\n",
            "url": "https://a3chron.dev/blog/deep-learning-course",
            "title": "Deep Learning Course - Overview",
            "summary": "A practical introduction to Deep Learning and Neural Networks",
            "date_modified": "2024-01-10T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "AI"
            ]
        },
        {
            "id": "https://a3chron.dev/blog/starship",
            "content_html": "<h1>Starship</h1>\n<p><a href=\"https://starship.rs/\">Startship</a> is a \"cross-shell prompt\", a cool way to customize the look of your shell,\nbut also good to add some helpful information, for example the current git branch, Go, Node or Python versions, and much more...</p>\n<p><img src=\"https://a3chron.dev//blog-images/starship-shell.png\" alt=\"\">\n<img src=\"https://a3chron.dev//blog-images/starship-my-shell-blue-gradient.png\" alt=\"\"></p>\n<h1>Installation</h1>\n<p>Starship is available for many operating systems:</p>\n<ul>\n<li>Android</li>\n<li>BSD</li>\n<li>Linux</li>\n<li>macOS</li>\n<li>Windows</li>\n</ul>\n<p>and even more shells:</p>\n<ul>\n<li>Bash</li>\n<li>Cmd</li>\n<li>Elvish</li>\n<li>Fish</li>\n<li>Ion</li>\n<li>Nushell</li>\n<li>PowerShell</li>\n<li>Tcsh</li>\n<li>Xonsh</li>\n<li>Zsh</li>\n</ul>\n<p>If you can't find yourself at this list, check out the <a href=\"https://starship.rs/installing/#advanced-installation\">Advanced Installation</a>.</p>\n<hr>\n<p>As the Installation Guide is quite good, I will only mention the guides for Linux and MacOS.</p>\n<p>For any other installation options, or shells, please check the <a href=\"https://starship.rs/guide/#%F0%9F%9A%80-installation\">Starship Installation Guide</a></p>\n<ol>\n<li>Install Starship</li>\n</ol>\n<pre><code class=\"language-bash\">curl -sS https://starship.rs/install.sh | sh\n</code></pre>\n<pre><code class=\"language-zsh\"># same as linux, or:\nbrew install starship\n</code></pre>\n<ol start=\"2\">\n<li>Configure the shell to start Starship</li>\n</ol>\n<p>Add these lines to your shell's configuration file:</p>\n<table>\n<thead>\n<tr>\n<th>shell</th>\n<th>location</th>\n<th>command</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>bash</td>\n<td>~/.bashrc</td>\n<td>eval \"$(starship init bash)\"</td>\n</tr>\n<tr>\n<td>fish</td>\n<td>~/.config/fish/config.fish</td>\n<td>starship init fish</td>\n</tr>\n<tr>\n<td>zsh</td>\n<td>~/.zshrc</td>\n<td>eval \"$(starship init zsh)\"</td>\n</tr>\n<tr>\n<td>Elvish</td>\n<td>~/.elvish/rc.elv</td>\n<td>eval (starship init elvish)</td>\n</tr>\n<tr>\n<td>Ion</td>\n<td>~/.config/ion/initrc</td>\n<td>eval $(starship init ion)</td>\n</tr>\n</tbody>\n</table>\n<p>When you open a new shell, you should now see the new prompt.</p>\n<ol start=\"3\">\n<li>Configure Starship</li>\n</ol>\n<p>You can now customize your prompt, with all the options at <a href=\"https://starship.rs/config/\">Starship Config</a>.</p>\n<p>the Starship configuration is done it the following file (you may need to create it first):</p>\n<p><code>~/.config/starship.toml</code></p>\n<p>If you want a quick setup, you can just paste one of my configs below in there,\nor even better, try out <a href=\"https://github.com/a3chron/stellar\">stellar</a>, a cli tool to\nget and switch between starship configs / themes quickyl.<br>\nYou can view all of the communities configs on the <a href=\"https://stellar.a3chron.dev\">stellar-hub</a>, search for one you like,\nand apply with stellar.</p>\n<h1>My Starship Configuration</h1>\n<p>Here you can copy my starship configs if you like one of them. Altough I would suggest using stellar ;)</p>\n<blockquote>\n<p>[!IMPORTANT] stellar - starhsip theme manager\nI made <a href=\"https://stellar.a3chron.dev\">stellar</a>, a starship theme manager &#x26; switcher,<br>\nyou can search for starship themes there / get my themes right from there, the setup is very quick n simple :)</p>\n<p>Feel free to upload your own starship theme for other people to use to stellar :)</p>\n</blockquote>\n<p><img src=\"https://a3chron.dev//blog-images/starship-my-shell.png\" alt=\"\"></p>\n<details>\n  <summary>starship.toml (Old)</summary>\n<pre><code class=\"language-toml\">  # custom format\n  format = '''\n  [┌── $shell─────────────── $memory_usage ──> $nodejs $python](bold green)\n  [│](bold green)$sudo$username$hostname$localip$directory$character$git_branch$git_metrics$cmd_duration\n  [└ $battery ─>](bold green) '''\n\n  #format = '$all$directory$character'\n\n  # Wait 10 milliseconds for starship to check files under the current directory.\n  scan_timeout = 10\n  command_timeout = 500\n  add_newline = true\n\n\n\n  [shell]\n  fish_indicator = 'fish'\n  bash_indicator = 'bash'\n  unknown_indicator = 'unknwn'\n  style = 'cyan bold'\n  disabled = false\n\n  [username]\n  style_user = 'green bold'\n  format = ' [$user@]($style)'\n  disabled = false\n  show_always = true\n\n  [sudo]\n  style = 'bold red'\n  format = ' [sudo](bold red)'\n  disabled = false\n\n  [python]\n  symbol = ''\n  format = 'Python [$version [\\($virtualenv\\)](dimmed yellow)](bold dimmed green)'\n  pyenv_version_name = true\n  detect_files = ['requirements.txt', '__init.py__', 'setup.py']\n  detect_extensions = ['py']\n  detect_folders = []\n\n  [nodejs]\n  format = 'Node [$version](bold dimmed green)'\n\n  [memory_usage]\n  disabled = false\n  threshold = -1\n  format = '$ram_pct'\n  symbol = ''\n  style = 'bold dimmed green'\n\n  [localip]\n  ssh_only = false\n  format = '[@$localipv4](bold yellow) '\n  disabled = false\n\n  [hostname]\n  ssh_only = false\n  ssh_symbol = 'ssh:'\n  format = '[$ssh_symbol](bold dimmed green)[$hostname](bold dimmed green)'\n  trim_at = ''\n  disabled = false\n\n  [git_metrics]\n  disabled = false\n  format = ' [+$added](bold green)[-$deleted](bold red)'\n\n  [git_branch]\n  format = '[$branch(:$remote_branch)]($style)'\n  style = 'bold purple'\n\n  [fill]\n  symbol = '-'\n  style = 'bold green'\n\n  # time of command\n  [cmd_duration]\n  min_time = 500\n  format = ' [$duration](bold yellow)'\n\n  [directory]\n  fish_style_pwd_dir_length = 5\n  disabled = false\n  truncation_length = 5\n  truncation_symbol = '…/'\n  style = 'bold blue'\n\n  # promt char\n  [character]\n  success_symbol = '[-->](bold green)'\n  error_symbol = '[-->](bold red)'\n\n  # Disable the package module, hiding it from the prompt completely\n  [package]\n  disabled = true\n\n\n  # battery\n  [battery]\n\n  full_symbol = '^'\n  charging_symbol = '+'\n  discharging_symbol = '-'\n\n  [[battery.display]]\n  threshold = 20\n  style = 'bold red'\n\n  [[battery.display]]\n  threshold = 50\n  style = 'bold orange'\n\n  [[battery.display]]\n  threshold = 100\n  style = 'bold green'\n  ```\n&#x3C;/details>\n\n---\n\n![](/blog-images/starship-my-shell-new.png)\n&#x3C;details>\n&#x3C;summary>starship.toml (New)&#x3C;/summary>\n\n```toml title=\"~/.config/starship.toml\"\n  #                                              #\n  # Starship Config by a3chron, catppuccin theme #\n  #                                              #\n\n  palette = \"catppuccin_mocha\"\n\n  # custom format\n  format = \"\"\"\n  [╭─ $shell─────────────── $memory_usage ──╌╌ $nodejs $python $fill ╌╌─╮](bold overlay0)\n  [├╌](bold overlay0)$sudo$username$hostname$localip$directory$read_only$git_branch$git_metrics [$fill $cmd_duration ┘](bold overlay0)\n  [╰─ $battery $character](bold overlay0) \"\"\"\n\n  #format = '$all$directory$character'\n\n  # Wait 10 milliseconds for starship to check files under the current directory.\n  scan_timeout = 10\n  command_timeout = 500\n  add_newline = true\n\n  # Catppuchin Theme\n\n  [palettes.catppuccin_mocha]\n  rosewater = \"#f5e0dc\"\n  flamingo = \"#f2cdcd\"\n  pink = \"#f5c2e7\"\n  mauve = \"#cba6f7\"\n  red = \"#f38ba8\"\n  maroon = \"#eba0ac\"\n  peach = \"#fab387\"\n  yellow = \"#f9e2af\"\n  green = \"#a6e3a1\"\n  teal = \"#94e2d5\"\n  sky = \"#89dceb\"\n  sapphire = \"#74c7ec\"\n  blue = \"#89b4fa\"\n  lavender = \"#b4befe\"\n  text = \"#cdd6f4\"\n  subtext1 = \"#bac2de\"\n  subtext0 = \"#a6adc8\"\n  overlay2 = \"#9399b2\"\n  overlay1 = \"#7f849c\"\n  overlay0 = \"#6c7086\"\n  surface2 = \"#585b70\"\n  surface1 = \"#45475a\"\n  surface0 = \"#313244\"\n  base = \"#1e1e2e\"\n  mantle = \"#181825\"\n  crust = \"#11111b\"\n\n\n  [shell]\n  fish_indicator = 'fish'\n  bash_indicator = 'bash'\n  unknown_indicator = 'unknwn'\n  style = 'peach'\n  disabled = false\n\n  [username]\n  style_user = 'peach bold'\n  format = ' [$user@]($style)'\n  disabled = false\n  show_always = true\n\n  [sudo]\n  format = ' [sudo](bold red)'\n  disabled = false\n\n  [python]\n  symbol = ''\n  format = '[Python](bold green) [$version [\\($virtualenv\\)](dimmed green)](bold dimmed green)'\n  pyenv_version_name = true\n  detect_files = ['requirements.txt', '__init.py__', 'setup.py']\n  detect_extensions = ['py']\n  detect_folders = []\n\n  [nodejs]\n  format = '[Node](bold lavender) [$version](bold dimmed lavender)'\n\n  [memory_usage]\n  disabled = false\n  threshold = -1\n  format = '[$ram_pct]($style)'\n  symbol = ''\n  style = 'dimmed peach'\n\n  [localip]\n  ssh_only = false\n  format = '[@$localipv4](bold overlay0) '\n  disabled = false\n\n  [hostname]\n  ssh_only = false\n  ssh_symbol = 'ssh:'\n  format = '[$ssh_symbol](bold dimmed maroon)[$hostname](bold dimmed peach)'\n  trim_at = ''\n  disabled = false\n\n  [git_metrics]\n  disabled = false\n  format = ' [+$added](bold green)[-$deleted](bold red)'\n\n  [git_branch]\n  format = '[$branch(:$remote_branch)]($style)'\n  style = 'bold mauve'\n\n  [fill]\n  symbol = ' '\n  style = 'bold base'\n\n  # time of command\n  [cmd_duration]\n  min_time = 500\n  format = ' [$duration](bold yellow)'\n\n  [directory]\n  fish_style_pwd_dir_length = 5\n  disabled = false\n  truncation_length = 5\n  truncation_symbol = '…/'\n  read_only = ' read-only'\n  read_only_style = 'bold dimmed teal'\n  style = 'bold teal'\n\n  # promt char\n  [character]\n  success_symbol = '[──╌╌](bold overlay0)'\n  error_symbol = '[──╌╌](bold red)'\n\n  # Disable the package module, hiding it from the prompt completely\n  [package]\n  disabled = true\n\n\n  # battery\n  [battery]\n\n  full_symbol = '◉ '\n  charging_symbol = '⦿ '\n  discharging_symbol = '⦾ '\n\n  [[battery.display]]\n  threshold = 20\n  style = 'red'\n\n  [[battery.display]]\n  threshold = 100\n  style = 'peach'\n  ```\n&#x3C;/details>\n\n---\n\n![](/blog-images/starship-my-shell-blue-gradient.png)\n&#x3C;details>\n&#x3C;summary>starship.toml v3 (catppuccin, blue gradient)&#x3C;/summary>\n\n```toml title=\"~/.config/starship.toml\"\n  #                                              #\n  # Starship Config by a3chron, catppuccin theme #\n  #                                              #\n\n  palette = \"catppuccin_mocha\"\n\n  # custom format\n  format = \"\"\"\n  [╭─ $shell─────────────── $memory_usage ──╌╌ $nodejs$python$ocaml $fill ╌╌─╮](overlay0)\n  [├╌](overlay0)$sudo$username$hostname$localip$directory$read_only$git_branch$git_metrics [$fill $cmd_duration ┘](overlay0)\n  [╰─ $battery $character](overlay0) \"\"\"\n\n  #format = '$all$directory$character'\n\n  # Wait 10 milliseconds for starship to check files under the current directory.\n  scan_timeout = 10\n  command_timeout = 500\n  add_newline = true\n\n  # Catppuchin Theme\n\n  [palettes.catppuccin_mocha]\n  rosewater = \"#f5e0dc\"\n  flamingo = \"#f2cdcd\"\n  pink = \"#f5c2e7\"\n  mauve = \"#cba6f7\"\n  red = \"#f38ba8\"\n  maroon = \"#eba0ac\"\n  peach = \"#fab387\"\n  yellow = \"#f9e2af\"\n  green = \"#a6e3a1\"\n  teal = \"#94e2d5\"\n  sky = \"#89dceb\"\n  sapphire = \"#74c7ec\"\n  blue = \"#89b4fa\"\n  lavender = \"#b4befe\"\n  text = \"#cdd6f4\"\n  subtext1 = \"#bac2de\"\n  subtext0 = \"#a6adc8\"\n  overlay2 = \"#9399b2\"\n  overlay1 = \"#7f849c\"\n  overlay0 = \"#6c7086\"\n  surface2 = \"#585b70\"\n  surface1 = \"#45475a\"\n  surface0 = \"#313244\"\n  base = \"#1e1e2e\"\n  mantle = \"#181825\"\n  crust = \"#11111b\"\n\n\n  [shell]\n  fish_indicator = 'fish'\n  bash_indicator = 'bash'\n  unknown_indicator = 'unknwn'\n  style = 'teal'\n  disabled = false\n\n  [username]\n  style_user = 'teal bold'\n  format = ' [$user@]($style)'\n  disabled = false\n  show_always = true\n\n  [sudo]\n  format = ' [sudo](bold red)'\n  disabled = false\n\n  [python]\n  symbol = ''\n  format = '[Python](bold mauve) [$version [\\($virtualenv\\)](dimmed mauve)](dimmed mauve)'\n  pyenv_version_name = true\n  detect_files = ['requirements.txt', '__init.py__', 'setup.py']\n  detect_extensions = ['py']\n  detect_folders = []\n\n  [nodejs]\n  format = '[Node](bold lavender) [$version](bold dimmed lavender) '\n\n  [ocaml]\n  format = '[Ocaml](bold pink) [$version](bold dimmed pink) '\n\n  [memory_usage]\n  disabled = false\n  threshold = -1\n  format = '[$ram_pct]($style)'\n  symbol = ''\n  style = 'dimmed blue'\n\n  [localip]\n  ssh_only = false\n  format = '[@$localipv4](bold dimmed blue) '\n  disabled = false\n\n  [hostname]\n  ssh_only = false\n  ssh_symbol = 'ssh:'\n  format = '[$ssh_symbol](bold dimmed maroon)[$hostname](bold dimmed sapphire)'\n  trim_at = ''\n  disabled = false\n\n  [git_metrics]\n  disabled = false\n  format = ' [+$added](bold teal)[-$deleted](bold pink)'\n\n  [git_branch]\n  format = '[$branch(:$remote_branch)]($style)'\n  style = 'bold pink'\n\n  [fill]\n  symbol = ' '\n  style = 'bold base'\n\n  # time of command\n  [cmd_duration]\n  min_time = 500\n  format = ' [$duration](bold dimmed flamingo)'\n\n  [directory]\n  fish_style_pwd_dir_length = 5\n  disabled = false\n  truncation_length = 5\n  truncation_symbol = '…/'\n  read_only = ' read-only'\n  read_only_style = 'bold dimmed mauve'\n  style = 'bold mauve'\n\n  # prompt char\n  [character]\n  success_symbol = '[──╌╌](overlay0)'\n  error_symbol = '[──╌╌](red)'\n\n  # Disable the package module, hiding it from the prompt completely\n  [package]\n  disabled = true\n\n\n  # battery\n  [battery]\n\n  full_symbol = '● '\n  charging_symbol = '◉ '\n  discharging_symbol = '◯ '\n\n  [[battery.display]]\n  threshold = 20\n  style = 'red'\n\n  [[battery.display]]\n  threshold = 100\n  style = 'teal'\n</code></pre>\n</details>\n<p>For the (as I was writing) latest v3 configuration,\nthere are several distinct themes you can use,\nlike the shown blue one, a red one, or a green one (more are probably to come).</p>\n<p>Check out my <a href=\"https://stellar.a3chron.dev/a3chron\">stellar profile</a> for the latest versions.</p>\n",
            "url": "https://a3chron.dev/blog/starship",
            "title": "Starship",
            "summary": "How to setup Starship & my current configuration",
            "date_modified": "2024-01-06T00:00:00.000Z",
            "author": {
                "name": "Kurt Schambach",
                "url": "https://a3chron.dev/"
            },
            "tags": [
                "Customization"
            ]
        }
    ]
}