{"id":5484,"date":"2019-02-28T08:22:23","date_gmt":"2019-02-28T07:22:23","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=5484"},"modified":"2023-08-06T21:47:30","modified_gmt":"2023-08-06T19:47:30","slug":"about-using-machine-learning-to-improve-performance-of-go-programs","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/02\/28\/about-using-machine-learning-to-improve-performance-of-go-programs\/","title":{"rendered":"About using Machine Learning to improve performance of Go programs"},"content":{"rendered":"\n<p>This Blogpost contains some thoughts on learning the sizes arrays, slices or maps are going to reach using Machine Learning (ML) to increase &nbsp;programs\u2019 performances by allocating the necessary memory in advance instead of reallocating every time new elements are appended. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What made me write this blogpost?<\/h2>\n\n\n\n<p>Well first of all I had to because it is part of the lecture Ultra Largescale Systems (ULS) I attended past winter term. But as an introduction I\u2019ll tell you what made me choose this topic: I started to learn Golang and coming from mainly Java, Python and JavaScript the concept of Arrays with fixed sizes and Slices wrapped around them for convenience was new to me. When I understood that initializing them with the correct capacity is good for performance and memory usage I always tried to so. Until I came to some use case where I could not know the capacity in advance. At almost the same time we talked about \u201c<a href=\"http:\/\/maucher.pages.mi.hdm-stuttgart.de\/ai\/res\/MLforSystems.pdf\">ML for Systems<\/a>\u201d in the ULS-lecture. There the power of ML is used to <a href=\"https:\/\/blog.acolyer.org\/2019\/01\/16\/sagedb-a-learned-database-system\/\">speed up Databases<\/a>, <a href=\"https:\/\/underthehood.meltwater.com\/blog\/2018\/09\/28\/using-machine-learning-to-load-balance-elasticsearch-queries\/\">loadbalance Elastic Search Queries<\/a> and other things. So I came up with the idea of ML for programming languages in this case for learning capacities in Golang. By the way I wanted to try out ML in Go, which is said to bring some performance advantages compared to python and is easier to deliver. But neither <a href=\"https:\/\/www.infoworld.com\/article\/3121694\/artificial-intelligence\/googles-go-language-ventures-into-machine-learning.html\">ML <\/a><strong><a href=\"https:\/\/www.infoworld.com\/article\/3121694\/artificial-intelligence\/googles-go-language-ventures-into-machine-learning.html\">in<\/a><\/strong><a href=\"https:\/\/www.infoworld.com\/article\/3121694\/artificial-intelligence\/googles-go-language-ventures-into-machine-learning.html\"> Go<\/a> (go for ML) nor <a href=\"https:\/\/medium.com\/sourcedtech\/machine-learning-on-go-code-829e85e2d2c6\">ML <\/a><strong><a href=\"https:\/\/medium.com\/sourcedtech\/machine-learning-on-go-code-829e85e2d2c6\">on<\/a><\/strong><a href=\"https:\/\/medium.com\/sourcedtech\/machine-learning-on-go-code-829e85e2d2c6\"> Go<\/a> is topic of this post, though both appear at some parts. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The goal in more detail<\/h2>\n\n\n\n<p>As explained in various blogposts like <a href=\"https:\/\/blog.golang.org\/go-slices-usage-and-internals\">here<\/a> and <a href=\"https:\/\/blog.golang.org\/slices\">there<\/a>, arrays have fixed sizes in Go. For convenient manipulation anyway they can be wrapped by slices. Thus appending to a slice that reached its capacity needs to create a new slice with a larger underling array, copy the contents of the old slice to the new one and then replace the old one by the new one. This is what the <em>append<\/em> method does. That this process is more time consuming than appending to a slice that has a sufficient capacity can be shown with some very simple code that just appends 100 times to a test slice in a loop. Once the slice is initialized with a capacity of zero and once with 100. For both cases we calculate the durations it takes and compare them. Since those durations can vary for the same kind of initialization we run this 1000 times each and calculate the average duration to get more meaningful results. The averages are calculated by the method <em>printSummary <\/em>which is left out here in order to keep track of things. However the whole code can be found on <a href=\"https:\/\/github.com\/hslr4\/uls\">GitHub<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler\"><div class=\"wp-block-embed__wrapper\">\n<style>.gist table { margin-bottom: 0; }<\/style><div style=\"tab-size: 8\" id=\"gist94869756\" class=\"gist\">\n    <div class=\"gist-file\" translate=\"no\" data-color-mode=\"light\" data-light-theme=\"light\">\n      <div class=\"gist-data\">\n        \n<div class=\"js-gist-file-update-container js-task-list-container\">\n      <div id=\"file-testsimplemakeinitialisations-go\" class=\"file my-2\">\n    \n    <div itemprop=\"text\"\n      class=\"Box-body p-0 blob-wrapper data type-go  \"\n      style=\"overflow: auto\" tabindex=\"0\" role=\"region\"\n      aria-label=\"testSimpleMakeInitialisations.go content, created by hslr4 on 06:24PM on February 26, 2019.\"\n    >\n\n        \n<div class=\"js-check-hidden-unicode js-blob-code-container blob-code-content\">\n\n  <template class=\"js-file-alert-template\">\n  <div data-view-component=\"true\" class=\"flash flash-warn flash-full d-flex flex-items-center\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n    <span>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\"Link--inTextBlock\" href=\"https:\/\/github.co\/hiddenchars\" target=\"_blank\">Learn more about bidirectional Unicode characters<\/a>\n    <\/span>\n\n\n  <div data-view-component=\"true\" class=\"flash-action\">        <a href=\"{{ revealButtonHref }}\" data-view-component=\"true\" class=\"btn-sm btn\">    Show hidden characters\n<\/a>\n<\/div>\n<\/div><\/template>\n<template class=\"js-line-alert-template\">\n  <span aria-label=\"This line has hidden Unicode characters\" data-view-component=\"true\" class=\"line-alert tooltipped tooltipped-e\">\n    <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n<\/span><\/template>\n\n  <table data-hpc class=\"highlight tab-size js-file-line-container\" data-tab-size=\"4\" data-paste-markdown-skip data-tagsearch-path=\"testSimpleMakeInitialisations.go\">\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L1\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"1\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC1\" class=\"blob-code blob-code-inner js-file-line\">func main() {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L2\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"2\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC2\" class=\"blob-code blob-code-inner js-file-line\">\ttimes := 1000<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L3\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"3\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC3\" class=\"blob-code blob-code-inner js-file-line\">\tresults := make([]time.Duration, 0, times)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L4\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"4\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC4\" class=\"blob-code blob-code-inner js-file-line\">\tfor t := 0; t &lt; times; t++ {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L5\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"5\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC5\" class=\"blob-code blob-code-inner js-file-line\">\t\tstart := time.Now()<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L6\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"6\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC6\" class=\"blob-code blob-code-inner js-file-line\">\t\t\/\/ initialize either with capacity of 0<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L7\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"7\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC7\" class=\"blob-code blob-code-inner js-file-line\">\t\t\/\/ test := make([]int, 0)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L8\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"8\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC8\" class=\"blob-code blob-code-inner js-file-line\">\t\t\/\/ or initialize with final capacity of 100<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L9\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"9\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC9\" class=\"blob-code blob-code-inner js-file-line\">\t\ttest := make([]int, 0, 100)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L10\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"10\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC10\" class=\"blob-code blob-code-inner js-file-line\">\t\tfor i := 0; i &lt; 100; i++ {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L11\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"11\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC11\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\/\/ uncomment to see how the capacity grows in larger steps<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L12\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"12\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC12\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\/\/ fmt.Println(cap(test), len(test))<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L13\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"13\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC13\" class=\"blob-code blob-code-inner js-file-line\">\t\t\ttest = append(test, i)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L14\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"14\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC14\" class=\"blob-code blob-code-inner js-file-line\">\t\t}<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L15\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"15\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC15\" class=\"blob-code blob-code-inner js-file-line\">\t\telapsed := time.Now().Sub(start)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L16\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"16\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC16\" class=\"blob-code blob-code-inner js-file-line\">\t\tresults = append(results, elapsed)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L17\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"17\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC17\" class=\"blob-code blob-code-inner js-file-line\">\t}<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L18\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"18\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC18\" class=\"blob-code blob-code-inner js-file-line\">\tprintSummary(results)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testsimplemakeinitialisations-go-L19\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"19\"><\/td>\n          <td id=\"file-testsimplemakeinitialisations-go-LC19\" class=\"blob-code blob-code-inner js-file-line\">}<\/td>\n        <\/tr>\n  <\/table>\n<\/div>\n\n\n    <\/div>\n\n  <\/div>\n\n<\/div>\n\n      <\/div>\n      <div class=\"gist-meta\">\n        <a href=\"https:\/\/gist.github.com\/hslr4\/4b069e609e6a6904685e8912a6b98c02\/raw\/c7241a86897596f8a29caff76f91328ca8c17103\/testSimpleMakeInitialisations.go\" style=\"float:right\" class=\"Link--inTextBlock\">view raw<\/a>\n        <a href=\"https:\/\/gist.github.com\/hslr4\/4b069e609e6a6904685e8912a6b98c02#file-testsimplemakeinitialisations-go\" class=\"Link--inTextBlock\">\n          testSimpleMakeInitialisations.go\n        <\/a>\n        hosted with &#10084; by <a class=\"Link--inTextBlock\" href=\"https:\/\/github.com\">GitHub<\/a>\n      <\/div>\n    <\/div>\n<\/div>\n\n<\/div><\/figure>\n\n\n\n<p>As expected the correct initialized version runs with an average of 1714ns faster than the other one with an average of 2409ns. Of course those durations are still just samples and vary if the code runs multiple times. But in over 20 runs each there is only one average value of the bad initialized slice lower than some of the good ones.<\/p>\n\n\n\n<p>If we also\ntake a look at the capacity the slower version ends up with, we see that this\nis 128 instead of the required 100. This is because append always doubles the\ncapacity if it reaches the limit.<\/p>\n\n\n\n<p>So we can see that it is worth setting the capacity correct in advance for performance and resource consumption reasons. But this is not always as easy as in the example we just saw and sometimes it is not even possible to know the length a slice will grow up to in advance. In those cases it might make sense to let the program learn the required capacities. It could be helpful at initialization with <em>make<\/em> as well as for growing with <em>append<\/em>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A basic example<br><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Setup<\/h3>\n\n\n\n<p>To check out feasibility I created a basic example that is a bit more complex than the first one but still possible to calculate as well. It iterates over index j and value s of a slice of random integer samples and for each of them the <em>test<\/em> slice is created. Then we append s times three values and one value j times. So the final length (and required capacity) of <em>test<\/em> can be calculated as s*3+j. <\/p>\n\n\n\n<p>Also in\nthis loop training data gets gathered. One sample consists of s and j as input\nand <em>len(test)<\/em> as label. Since the\nmain goal of this scenario is to check if it\u2019s worth using a trained ML model\nto predict the required capacity, this data is collected always to create equal\nconditions for every test case. Ways to avoid the time expensive training and\ndata collection at runtime are discussed later.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler\"><div class=\"wp-block-embed__wrapper\">\n<style>.gist table { margin-bottom: 0; }<\/style><div style=\"tab-size: 8\" id=\"gist94869988\" class=\"gist\">\n    <div class=\"gist-file\" translate=\"no\" data-color-mode=\"light\" data-light-theme=\"light\">\n      <div class=\"gist-data\">\n        \n<div class=\"js-gist-file-update-container js-task-list-container\">\n      <div id=\"file-testlearnedmakeinitialisations-go\" class=\"file my-2\">\n    \n    <div itemprop=\"text\"\n      class=\"Box-body p-0 blob-wrapper data type-go  \"\n      style=\"overflow: auto\" tabindex=\"0\" role=\"region\"\n      aria-label=\"testLearnedMakeInitialisations.go content, created by hslr4 on 06:38PM on February 26, 2019.\"\n    >\n\n        \n<div class=\"js-check-hidden-unicode js-blob-code-container blob-code-content\">\n\n  <template class=\"js-file-alert-template\">\n  <div data-view-component=\"true\" class=\"flash flash-warn flash-full d-flex flex-items-center\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n    <span>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\"Link--inTextBlock\" href=\"https:\/\/github.co\/hiddenchars\" target=\"_blank\">Learn more about bidirectional Unicode characters<\/a>\n    <\/span>\n\n\n  <div data-view-component=\"true\" class=\"flash-action\">        <a href=\"{{ revealButtonHref }}\" data-view-component=\"true\" class=\"btn-sm btn\">    Show hidden characters\n<\/a>\n<\/div>\n<\/div><\/template>\n<template class=\"js-line-alert-template\">\n  <span aria-label=\"This line has hidden Unicode characters\" data-view-component=\"true\" class=\"line-alert tooltipped tooltipped-e\">\n    <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n<\/span><\/template>\n\n  <table data-hpc class=\"highlight tab-size js-file-line-container\" data-tab-size=\"4\" data-paste-markdown-skip data-tagsearch-path=\"testLearnedMakeInitialisations.go\">\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L1\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"1\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC1\" class=\"blob-code blob-code-inner js-file-line\">func appendInBasicLoop(kind string) training.Examples {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L2\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"2\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC2\" class=\"blob-code blob-code-inner js-file-line\">\tsamp := getSamples(1000)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L3\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"3\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC3\" class=\"blob-code blob-code-inner js-file-line\">\tdata := make([]training.Example, 0, len(samp))<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L4\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"4\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC4\" class=\"blob-code blob-code-inner js-file-line\">\ttimes := 1000<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L5\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"5\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC5\" class=\"blob-code blob-code-inner js-file-line\">\tresults := make([]time.Duration, 0, times)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L6\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"6\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC6\" class=\"blob-code blob-code-inner js-file-line\">\tfor trys := 0; trys &lt; times; trys++ {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L7\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"7\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC7\" class=\"blob-code blob-code-inner js-file-line\">\t\tstart := time.Now()<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L8\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"8\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC8\" class=\"blob-code blob-code-inner js-file-line\">\t\tfor j, s := range samp {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L9\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"9\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC9\" class=\"blob-code blob-code-inner js-file-line\">\t\t\tvar test []int<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L10\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"10\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC10\" class=\"blob-code blob-code-inner js-file-line\">\t\t\tswitch kind {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L11\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"11\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC11\" class=\"blob-code blob-code-inner js-file-line\">\t\t\tcase &quot;zero&quot;:<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L12\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"12\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC12\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\ttest = make([]int, 0)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L13\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"13\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC13\" class=\"blob-code blob-code-inner js-file-line\">\t\t\tcase &quot;calc&quot;:<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L14\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"14\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC14\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\ttest = make([]int, 0, s*3+j)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L15\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"15\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC15\" class=\"blob-code blob-code-inner js-file-line\">\t\t\tcase &quot;func&quot;:<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L16\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"16\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC16\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\ttest = make([]int, 0, getCap(s, j))<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L17\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"17\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC17\" class=\"blob-code blob-code-inner js-file-line\">\t\t\tcase &quot;model&quot;:<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L18\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"18\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC18\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\ttest = make([]int, 0, getCapFromModel(s, j))<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L19\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"19\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC19\" class=\"blob-code blob-code-inner js-file-line\">\t\t\tcase &quot;model+1&quot;:<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L20\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"20\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC20\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\ttest = make([]int, 0, getCapFromModel(s, j)+1)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L21\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"21\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC21\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t}<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L22\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"22\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC22\" class=\"blob-code blob-code-inner js-file-line\">\t\t\tfor i := 0; i &lt; s; i++ {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L23\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"23\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC23\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\ttest = append(test, i)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L24\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"24\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC24\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\ttest = append(test, j)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L25\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"25\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC25\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\ttest = append(test, s)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L26\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"26\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC26\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t}<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L27\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"27\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC27\" class=\"blob-code blob-code-inner js-file-line\">\t\t\tfor k := 0; k &lt; j; k++ {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L28\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"28\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC28\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\ttest = append(test, k)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L29\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"29\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC29\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t}<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L30\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"30\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC30\" class=\"blob-code blob-code-inner js-file-line\">\t\t\tdata = append(data,<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L31\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"31\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC31\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\ttraining.Example{<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L32\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"32\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC32\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\t\tInput:    []float64{float64(s), float64(j)},<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L33\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"33\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC33\" class=\"blob-code blob-code-inner js-file-line\">\t\t\t\t\tResponse: []float64{float64(len(test))}})<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L34\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"34\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC34\" class=\"blob-code blob-code-inner js-file-line\">\t\t}<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L35\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"35\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC35\" class=\"blob-code blob-code-inner js-file-line\">\t\telapsed := time.Now().Sub(start)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L36\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"36\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC36\" class=\"blob-code blob-code-inner js-file-line\">\t\tresults = append(results, elapsed)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L37\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"37\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC37\" class=\"blob-code blob-code-inner js-file-line\">\t}<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L38\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"38\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC38\" class=\"blob-code blob-code-inner js-file-line\">\tprintSummary(results)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L39\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"39\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC39\" class=\"blob-code blob-code-inner js-file-line\">\treturn data<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-testlearnedmakeinitialisations-go-L40\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"40\"><\/td>\n          <td id=\"file-testlearnedmakeinitialisations-go-LC40\" class=\"blob-code blob-code-inner js-file-line\">}<\/td>\n        <\/tr>\n  <\/table>\n<\/div>\n\n\n    <\/div>\n\n  <\/div>\n\n<\/div>\n\n      <\/div>\n      <div class=\"gist-meta\">\n        <a href=\"https:\/\/gist.github.com\/hslr4\/472eaf93cc7553b5328943782ad560ae\/raw\/212c3f650cf1d5cbabae7df13b61b445d96f596f\/testLearnedMakeInitialisations.go\" style=\"float:right\" class=\"Link--inTextBlock\">view raw<\/a>\n        <a href=\"https:\/\/gist.github.com\/hslr4\/472eaf93cc7553b5328943782ad560ae#file-testlearnedmakeinitialisations-go\" class=\"Link--inTextBlock\">\n          testLearnedMakeInitialisations.go\n        <\/a>\n        hosted with &#10084; by <a class=\"Link--inTextBlock\" href=\"https:\/\/github.com\">GitHub<\/a>\n      <\/div>\n    <\/div>\n<\/div>\n\n<\/div><\/figure>\n\n\n\n<p>As implementation for the ML part I chose <a href=\"https:\/\/github.com\/patrikeh\/go-deep\">go-deep<\/a>. I picked it from this <a href=\"https:\/\/github.com\/avelino\/awesome-go#machine-learning\">list<\/a> because it looked well documented, easy to use and sufficient for my needs, though not perfect.  <\/p>\n\n\n\n<p>I used the\ncollected training data to train a MLP (Multi Layer Perceptron) with two hidden\nlayers containing two and five neurons. Of course I configured RegressionMode to\nuse Identity as activation function in the output layer and MSE (Mean Square\nError) as loss function. I also played around with some other hyperparameters but\nkept a lot from the examples provided as well, because the MSE already decreased\nvery fast and became 0.0000 after three training-iterations. This is not\nsurprising since the function to learn is very simple. Also there is no need to\navoid overfitting in this basic example. I kept some of the belonging\nhyperparameters with low values anyway. In a real world use case one would\nprobably try to keep the model as small as possible to get quickest responses.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler\"><div class=\"wp-block-embed__wrapper\">\n<style>.gist table { margin-bottom: 0; }<\/style><div style=\"tab-size: 8\" id=\"gist94870080\" class=\"gist\">\n    <div class=\"gist-file\" translate=\"no\" data-color-mode=\"light\" data-light-theme=\"light\">\n      <div class=\"gist-data\">\n        \n<div class=\"js-gist-file-update-container js-task-list-container\">\n      <div id=\"file-mlformakeinitialisations-go\" class=\"file my-2\">\n    \n    <div itemprop=\"text\"\n      class=\"Box-body p-0 blob-wrapper data type-go  \"\n      style=\"overflow: auto\" tabindex=\"0\" role=\"region\"\n      aria-label=\"MLForMakeInitialisations.go content, created by hslr4 on 06:44PM on February 26, 2019.\"\n    >\n\n        \n<div class=\"js-check-hidden-unicode js-blob-code-container blob-code-content\">\n\n  <template class=\"js-file-alert-template\">\n  <div data-view-component=\"true\" class=\"flash flash-warn flash-full d-flex flex-items-center\">\n  <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n    <span>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\"Link--inTextBlock\" href=\"https:\/\/github.co\/hiddenchars\" target=\"_blank\">Learn more about bidirectional Unicode characters<\/a>\n    <\/span>\n\n\n  <div data-view-component=\"true\" class=\"flash-action\">        <a href=\"{{ revealButtonHref }}\" data-view-component=\"true\" class=\"btn-sm btn\">    Show hidden characters\n<\/a>\n<\/div>\n<\/div><\/template>\n<template class=\"js-line-alert-template\">\n  <span aria-label=\"This line has hidden Unicode characters\" data-view-component=\"true\" class=\"line-alert tooltipped tooltipped-e\">\n    <svg aria-hidden=\"true\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n<\/span><\/template>\n\n  <table data-hpc class=\"highlight tab-size js-file-line-container\" data-tab-size=\"4\" data-paste-markdown-skip data-tagsearch-path=\"MLForMakeInitialisations.go\">\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L1\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"1\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC1\" class=\"blob-code blob-code-inner js-file-line\">var net *deep.Neural<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L2\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"2\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC2\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L3\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"3\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC3\" class=\"blob-code blob-code-inner js-file-line\">func init() {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L4\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"4\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC4\" class=\"blob-code blob-code-inner js-file-line\">\tnet = deep.NewNeural(&amp;deep.Config{<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L5\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"5\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC5\" class=\"blob-code blob-code-inner js-file-line\">\t\tInputs:     2,<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L6\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"6\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC6\" class=\"blob-code blob-code-inner js-file-line\">\t\tLayout:     []int{2, 5, 1},<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L7\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"7\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC7\" class=\"blob-code blob-code-inner js-file-line\">\t\tActivation: deep.ActivationReLU,<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L8\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"8\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC8\" class=\"blob-code blob-code-inner js-file-line\">\t\tMode:       deep.ModeRegression,<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L9\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"9\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC9\" class=\"blob-code blob-code-inner js-file-line\">\t\tWeight:     deep.NewUniform(0.1, 0.0),<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L10\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"10\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC10\" class=\"blob-code blob-code-inner js-file-line\">\t\tBias:       true,<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L11\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"11\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC11\" class=\"blob-code blob-code-inner js-file-line\">\t})<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L12\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"12\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC12\" class=\"blob-code blob-code-inner js-file-line\">}<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L13\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"13\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC13\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L14\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"14\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC14\" class=\"blob-code blob-code-inner js-file-line\">func trainModel(data training.Examples) {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L15\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"15\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC15\" class=\"blob-code blob-code-inner js-file-line\">\toptimizer := training.NewAdam(0.02, 0.9, 0.999, 1e-8)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L16\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"16\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC16\" class=\"blob-code blob-code-inner js-file-line\">\ttrainer := training.NewBatchTrainer(optimizer, 1, 200, 8)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L17\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"17\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC17\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L18\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"18\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC18\" class=\"blob-code blob-code-inner js-file-line\">\ttraining, heldout := data.Split(0.75)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L19\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"19\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC19\" class=\"blob-code blob-code-inner js-file-line\">\ttrainer.Train(net, training, heldout, 7)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L20\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"20\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC20\" class=\"blob-code blob-code-inner js-file-line\">}<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L21\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"21\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC21\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L22\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"22\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC22\" class=\"blob-code blob-code-inner js-file-line\">func getCapFromModel(s, j int) int {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L23\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"23\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC23\" class=\"blob-code blob-code-inner js-file-line\">\tp := net.Predict([]float64{float64(s), float64(j)})<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L24\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"24\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC24\" class=\"blob-code blob-code-inner js-file-line\">\treturn int(p[0])<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-mlformakeinitialisations-go-L25\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"25\"><\/td>\n          <td id=\"file-mlformakeinitialisations-go-LC25\" class=\"blob-code blob-code-inner js-file-line\">}<\/td>\n        <\/tr>\n  <\/table>\n<\/div>\n\n\n    <\/div>\n\n  <\/div>\n\n<\/div>\n\n      <\/div>\n      <div class=\"gist-meta\">\n        <a href=\"https:\/\/gist.github.com\/hslr4\/297e8608aae5116d2eadc157201dab69\/raw\/d5c4bb171a903e8e864f38996819f3a4dbcfaada\/MLForMakeInitialisations.go\" style=\"float:right\" class=\"Link--inTextBlock\">view raw<\/a>\n        <a href=\"https:\/\/gist.github.com\/hslr4\/297e8608aae5116d2eadc157201dab69#file-mlformakeinitialisations-go\" class=\"Link--inTextBlock\">\n          MLForMakeInitialisations.go\n        <\/a>\n        hosted with &#10084; by <a class=\"Link--inTextBlock\" href=\"https:\/\/github.com\">GitHub<\/a>\n      <\/div>\n    <\/div>\n<\/div>\n\n<\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Results<\/h3>\n\n\n\n<p>The\nfollowing table shows the test cases I compared along with the average\ndurations in nanoseconds calculated over 1000 tries each. Since those averages\nvary again from run to run the table contains three of them.<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-stripes\"><table><tbody><tr><td><strong>Test case<\/strong><\/td><td><strong>Avg ns run1<\/strong><\/td><td><strong>Avg ns run2<\/strong><\/td><td><strong>Avg ns run3<\/strong><\/td><\/tr><tr><td>Initialize capacity with <br>zero<\/td><td>12.790.501<\/td><td>14.267.925<\/td><td>14.321.735<\/td><\/tr><tr><td>Use s*3+j directly in <em>make<\/em><\/td><td>5.679.595<\/td><td>6.067.968<\/td><td>5.943.731<\/td><\/tr><tr><td>Use a function to <br>calculate s*3+j<\/td><td>5.242.182<\/td><td>6.012.920<\/td><td>5.515.661<\/td><\/tr><tr><td>Use the prediction of the <br>learned model<\/td><td>10.898.437<\/td><td>6.361.911<\/td><td>9.056.003<\/td><\/tr><tr><td>The model&#8217;s prediction +1<\/td><td>6.069.776<\/td><td>5.714.348<\/td><td>6.144.386<\/td><\/tr><tr><td>The model&#8217;s prediction <br>on new random data<\/td><td>10.165.764<\/td><td>6.096.929<\/td><td>9.296.384<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Even though\nthe durations vary the results show that not initializing the capacity is\nworst. Also usually it is best to calculate the capacity, if possible. It does\nnot really matter if the calculation happens in a function or directly. When I\ntook a closer look at the model\u2019s predictions I saw that they are quite often\nexactly one less than the actual capacity. This is why I also added the\nprediction+1 test case, which is almost as good as the direct calculations. So investigating\na bit deeper in what the model predicts is worth it. Maybe some finetuning on\nthe hyperparameters could also fix the problem instead of adding 1 manually.\nThe results also show that the learned model works on completely new random data\nas well as on partly known data from the training.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Conclusion<\/h3>\n\n\n\n<p>Of course creating such a model for a small performance optimization is heavy overengineered and thus not worth it. It could be worth in cases where you know you have a bottleneck at this place (because your <a href=\"https:\/\/blog.golang.org\/profiling-go-programs\">profiler<\/a> told you) and you cannot calculate the required capacity in any other way in advance. In the introduction I already mentioned that I had a use case where it is not possible to do so. In this case the length of the slice depends on a <em>sql.rows<\/em> object which doesn\u2019t tell you how many rows it contains in advance. Other examples might be conditional appends where you cannot know how many elements fulfill the condition to be appended to a slice or something else. But also in those cases the required capacity might depend on something else. For example the current time, the size of an HTTP request that caused this action or the length this slice reached the last time. In those cases using a ML model might be helpful to avoid a performance bottleneck. With dependencies to previous lengths especially RNNs (Recurrent Neural Networks) might be helpful. At least they probably could give a better guess than a developer himself. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Looking ahead<\/h2>\n\n\n\n<p>As stated\nabove in examples like this the engineering effort is too high. So ways for\nautomating would be desirable. First I thought about a one-size-fits-all\nsolution meaning one pretrained model that predicts for various <em>make<\/em>s the required capacity. But it\nwould be difficult to find good features because they could change from <em>make<\/em> to <em>make<\/em> and just using all sorts of possible features would create\nvery sparse matrices and require larger models if they could work at all.<\/p>\n\n\n\n<p>So we should stick to use case specific models that can be smaller and use meaningful features depending on their environment like lengths of arrays, slices, maps or strings \u201cclose\u201d to them or values of specific bools or integers. The drawback is that individual models need individual training maybe with production like data. Training during runtime would cause an overhead that might destroy the benefit the model could bring and slow the program down at least for a while until training can be stopped or paused because the ML model&#8217;s performance is good enough. So if possible pure online learning should be avoided and training on test stages or at times with low traffic should be preferred. If the length of a slice depends on the current traffic this is of course not possible. Then one should at least make use of dumping a model\u2019s weights from time to time to the logs to be able to reuse them when starting a new node. <\/p>\n\n\n\n<p>Still we need to solve the overengineering issue and try to build a model automatically at compile time, if the developer demands to do so for example using an additional argument in the call to <em>make<\/em>. I think that this might be another use case for <a href=\"https:\/\/medium.com\/sourcedtech\/machine-learning-on-go-code-829e85e2d2c6\">ML on code<\/a>: Finding good features and parameters to build a ML model by inspecting the code. Unfortunately I\u2019m not sure what such an ML model on code could look like and what it would require to train it. Using a GAN (Generative adversarial network) to generate the models would probably require already existing ones to train the discriminator. If the automation could be realized the use case also could get broader because then calculating the capacity would be more effort than just saying \u201clearn it\u201d.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Some final thoughts<\/h3>\n\n\n\n<p>Using ML would not magically boost performance. It would require developers to remeasure and double check if it\u2019s worth using it. For example it is not only important how often the program needs to allocate memory but also where. So stack allocation is cheap and heap allocation is expensive as explained in <a href=\"https:\/\/segment.com\/blog\/allocation-efficiency-in-high-performance-go-services\/\">this blog post<\/a>. If using ML to predict the capacity requires the program to allocate on the heap it might be slower even when the predictions are correct. In the test scenario above all the cases instead of initializing with zero escaped to the heap. There it was worth it but it needs to be measured. So the performance should be compared with and without learning for short and for longer running applications. As another example sometimes the required capacities might not be learnable because they are almost random or depend on things that cannot be used as features in an efficient way.<\/p>\n\n\n\n<p>Another\ndrawback of using ML is that your code behaves less predictable. You won\u2019t know\nwhat capacity will be estimated for a slice in advance anymore and it will be\nmuch harder to figure out why the program estimated exactly what it did\nafterwards.<\/p>\n\n\n\n<p>I also\nthought about to train the model to reduce a mix of performance and required memory\ninstead of using the final length as labels. But then it is not that easy\nanymore to get the training data. In some cases however it might also be difficult\nto get the \u201cfinal\u201d length of a slice as well.<\/p>\n\n\n\n<p>The last\nthing to remember is that it is always helpful to set a learned model some\nborders. In this case a minimum and a maximum. My test model for example\npredicted a negative capacity before I got the hyperparameters right, what made\nmy program crash. So if the model for some reason thinks this could be a great\nidea a fixed minimum of zero should prevent the worst. Also such borders make a\nprogram a bit more predictable again.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This Blogpost contains some thoughts on learning the sizes arrays, slices or maps are going to reach using Machine Learning (ML) to increase  programs\u2019 performances by allocating the necessary memory in advance instead of reallocating every time new elements are appended.<\/p>\n","protected":false},"author":911,"featured_media":5492,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1,652],"tags":[216,57,217],"ppma_author":[777],"class_list":["post-5484","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-allgemein","category-artificial-intelligence","tag-golang","tag-machine-learning","tag-uls"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/02\/fiveyears.jpg","jetpack-related-posts":[{"id":23138,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2022\/03\/31\/an-overview-of-large-scale-deep-learning\/","url_meta":{"origin":5484,"position":0},"title":"An overview of Large Scale Deep Learning","author":"mk374","date":"31. March 2022","format":false,"excerpt":"article by Annika Strau\u00df (as426) and Maximilian Kaiser (mk374) Introduction Improving Deep Learning with ULS for superior model training Single Instance Single Device (SISD) Multi Instance Single Device (MISD) Multi Instance Multi Device (MIMD) Single Instance Multi Device (SIMD) Model parallelism Data parallelism Improving ULS and its components with the\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/quantum-physics-g1357f44f5_1920-Kopie.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/quantum-physics-g1357f44f5_1920-Kopie.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/quantum-physics-g1357f44f5_1920-Kopie.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/quantum-physics-g1357f44f5_1920-Kopie.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/quantum-physics-g1357f44f5_1920-Kopie.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/quantum-physics-g1357f44f5_1920-Kopie.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":22730,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2022\/03\/09\/um-die-technik-kummern-sich-die-anderen\/","url_meta":{"origin":5484,"position":1},"title":"Um die Technik k\u00fcmmern sich die Anderen&#8230;","author":"Aliena Leonhard","date":"9. March 2022","format":false,"excerpt":"Das Ph\u00e4nomen von 'sozio-technischen Systemen' und '\u00d6kosystemen' Mammut aus Gras von Christopher Alvarenga - [4] Wenn wir uns als technisch begeisterte Computer Science Studierenden ein zu Deutsch \u201cUltra Gro\u00dfes, Skaliertes System\u201d vorstellen... Was stellen wir uns dann wirklich vor? Naja wir denken wahrscheinlich erstmal an viele Zeilen Code, Unmengen von\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/03\/christopher-alvarenga-bfqPQeidFS0-unsplash.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":24427,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/03\/03\/ai-and-scaling-the-compute-for-the-new-moores-law\/","url_meta":{"origin":5484,"position":2},"title":"AI and Scaling the Compute for the new Moore\u2019s Law","author":"Marvin Blessing","date":"3. March 2023","format":false,"excerpt":"AI and Scaling the Compute becomes more relevant as the strive for larger language models and general purpose AI continues. The future of the trend is unknown as the rate of doubling the compute outpaces Moore's Law rate of every two year to a 3.4 month doubling. IntroductionRequiring compute beyond\u2026","rel":"","context":"In &quot;Artificial Intelligence&quot;","block_context":{"text":"Artificial Intelligence","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/artificial-intelligence\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/03\/image-4.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/03\/image-4.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/03\/image-4.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/03\/image-4.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/03\/image-4.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":1017,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/07\/25\/machine-learning-in-secure-systems\/","url_meta":{"origin":5484,"position":3},"title":"Machine Learning in secure systems","author":"Claudius Messerschmidt","date":"25. July 2016","format":false,"excerpt":"Sadly today's security systems often be hacked and sensitive informations get stolen. To protect a company against cyber-attacks security experts define a \"rule set\" to detect and prevent any attack. This \u201canalyst-driven solutions\u201d are build up from human experts with their domain knowledge. This knowledge is based on experiences and\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/07\/Machine_learning_SeSy_robot_landscape.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/07\/Machine_learning_SeSy_robot_landscape.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/07\/Machine_learning_SeSy_robot_landscape.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/07\/Machine_learning_SeSy_robot_landscape.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":5576,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/03\/04\/improved-vulnerability-detection-using-deep-representation-learning\/","url_meta":{"origin":5484,"position":4},"title":"Improved Vulnerability Detection using Deep Representation Learning","author":"Daniel Bruckner","date":"4. March 2019","format":false,"excerpt":"Today's software is more vulnerable to cyber attacks than ever before. The number of recorded vulnerabilities has almost constantly increased since the early 90s. The advantage of Deep Learning algorithms is that they can learn vulnerability patterns on their own and achieve a much better vulnerability detection performance. In this\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/luca-bravo-217276-unsplash.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/luca-bravo-217276-unsplash.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/luca-bravo-217276-unsplash.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/luca-bravo-217276-unsplash.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/luca-bravo-217276-unsplash.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/luca-bravo-217276-unsplash.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":6076,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/03\/12\/large-scale-deployment-for-deep-learning-models-with-tensorflow-serving\/","url_meta":{"origin":5484,"position":5},"title":"Large Scale Deployment for Deep Learning Models with TensorFlow Serving","author":"Florian Wintel","date":"12. March 2019","format":false,"excerpt":"Image source Introduction \"How do you turn a trained model into a product, that will bring value to your enterprise?\" In recent years, serving has become a hot topic in machine learning. With the ongoing success of deep neural networks, there is a growing demand for solutions that address the\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/serving_architecture-1.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/serving_architecture-1.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/serving_architecture-1.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":777,"user_id":911,"is_guest":0,"slug":"mh313","display_name":"Marcel Heisler","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bd2af6a772c2a25bf00f13fa93eef00e7f20ee2d3f164e38194bf04d5793fe91?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/5484","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/users\/911"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=5484"}],"version-history":[{"count":6,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/5484\/revisions"}],"predecessor-version":[{"id":25453,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/5484\/revisions\/25453"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media\/5492"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=5484"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=5484"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=5484"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=5484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}