<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blog blog("Baptiste Wicht");</title><link>https://baptiste-wicht.com/</link><description>Tutorials and short posts about programming, C++, Java, Assembly, Operating Systems Development, Compilers, ...</description><atom:link href="https://baptiste-wicht.com/rss.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><lastBuildDate>Sun, 15 Feb 2026 06:57:40 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Back to Linux</title><link>https://baptiste-wicht.com/posts/2026/02/back-to-linux.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;Again, it has been too long since I posted on this blog. I am still very busy between family, work and my other blog.&lt;/p&gt;
&lt;p&gt;I wanted to post a short update on my transition back to linux. For the last 5 or 6 years of so, I have been running Windows on my desktop computers. My servers are still all on Gentoo. But it took me too much time to handle issues on the Linux desktop and time was exactly what I did not have. So, I opted out for Windows. I was also playing multiple games and it was much easier for me to do it on Windows.&lt;/p&gt;
&lt;p&gt;I was still doing development and this is something that I do on Linux. With Windows Subsystems for Linux (WSL), I felt I had found the best of both worlds. I did all my development on WSL.&lt;/p&gt;
&lt;p&gt;This is not the first time I am transitioning. I used to have Linux on my computers, then Windows again for a while. In 2013, I transitioned back to Linux and then back to Windows for simplicity.&lt;/p&gt;
&lt;p&gt;So, what changed? I got fed up with some projects and changes by Microsoft:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The idea of Windows Recall is so bad for me that it should never have made it to be a project. If you are not aware, Windows Recall is a feature that takes a screenshot of your desktop every few seconds. The stated goal is to help us remember what we do on our computer and help us troubleshoot. I cannot believe they would implementation such a stupid thing on a computer. This is a disaster for privacy even if implemented properly (and the first implementation was far from proper). I would never run a computer where Windows Recall is enabled. This was never enabled for me because my PC was apparently not Copilot+ rated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Microsoft keeps pushing for AI features into Windows. Over the years, Windows 11 has become steadily worse in my opinion. And now Microsoft is trying to push AI into the OS directly, but nobody wants that. Microsoft should push features the user wants, not force AI on everybody just because this fuels their share price.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recently, it was disclosed that Microsoft is storing Bitlocker recovery keys on their servers. Bitlocker is Microsoft solution for full-disk encryption. But if the keys are stored on their cloud, this kinds of ruins the value of full-disk encryption.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There are other small reasons, but this boils down to the fact that I lost trust in Microsoft.&lt;/p&gt;
&lt;p&gt;SO, I moved back to Linux. I pondered going back to Gentoo again, but I simply do not have enough time to tinker with it on a desktop computer where any upgrade takes forever. So, after some research, I decided to go with CachyOS, a distribution based on Arch Linux. I already have experience with Arch Linux. The focus on performance of CachyOS is talking to me. And the reviews I have read have convinced me.&lt;/p&gt;
&lt;p&gt;So far, I have converted my laptop and desktop to CachyOS and everything has been very smooth. I am also discovering btrfs which I had never used before, switched to a new bootloader (Limine) and a new desktop environment (KDE Plasma). So,  there is a lot to be learned.&lt;/p&gt;
&lt;p&gt;Overall, I have found alternatives to every software I was using on WIndows, but one. The only thing I could not do is replace Aida64 which was configuring the LCD display on my ASUS ROG AIO. But this is a small price to pay. Once I upgrade this computer, I will use an AIO that can be configured on Linux.&lt;/p&gt;
&lt;p&gt;And this time, I also tried playing games. I rarely have time for gaming, but when I do, I like to have it ready. And I was pleasantly surprised to find out that the two games I am playing (Path of Exile and Satisfactory) are both working perfectly fine on Steam on Linux.&lt;/p&gt;
&lt;p&gt;What about you? What OS do you use?&lt;/p&gt;</description><category>linux windows cachyos</category><guid>https://baptiste-wicht.com/posts/2026/02/back-to-linux.html</guid><pubDate>Sun, 15 Feb 2026 06:32:57 GMT</pubDate></item><item><title>Trying out Rust and C++26</title><link>https://baptiste-wicht.com/posts/2025/05/trying-out-rust-and-c%2B%2B26.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;It has been too long again since I wrote here. But with family, my other blog and work, I did not get a chance to write here for a while.&lt;/p&gt;
&lt;p&gt;Today is going to be a short update. I recently updated my main projects to use C++26. There is not much I can use at this point, but I have upgraded my compilers to GCC-15 and Clang-20 so that I can access most things. I will probably do some minor updates of the code in the coming weeks/months to see what I can add. What I am really waiting for is the concepts and the meta-programming, which are not yet in the base compilers. These two features are really going to make a huge difference on how we write C++ code.&lt;/p&gt;
&lt;p&gt;In the last two months, I have started learning some Rust. Since I believe the best way to learn a language is by writing code, I quickly got into coding. I have ported a (small) part of my ETL and DLL libraries to Rust. I came to the point where I can train a simple Dense Neural Network on MNIST and it works. Of course, I also tried to make it as fast as possible. Currently, it is relatively close to at about 30% slower than ETL on a CPU and without MKL.&lt;/p&gt;
&lt;p&gt;Overall, Rust is an interesting language. Its borrow checker and strong compiler contracts are definitely making the code safer. On the other hand, it also makes the code very strict. And some things that are very easy to write in C++ become very difficult to write in Rust.&lt;/p&gt;
&lt;p&gt;Here are some of the issues I found with Rust:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The generics are very limited. Compared to the level of meta-programming we can do in C++ with templates, the comparison does not even start. Everything must be tied to Traits (a bit like concepts in this case) and we can't specialize code based on the type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The SIMD library is also quite limited. I am currently using the portable-simd library from nightly Rust and it gets the job done. But we are again limited to the common interface between integers and floating points since we cannot specialize and unfortunately, some of the things are not defined for both. For instance, I could not get FMA in my code and I cannot easily tune the size of the vectors to the types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Because of the borrow-checker, we are also not allowed to do some expressions where we mix mutable and immutable references, like x = b * x + d (x is once mutable and once immutable), so we either need to do two operations (slow) or do some inplace wrappers instead of relying on expressions (ugly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Currently, there is a lot of overhead to the parallelism I used (through rayon). Compared to simply using a simple thread pool, this is quickly much more complicated and apparently much more overhead. I am using much higher thresholds for parallelizing operations in my Rust library than I am in C++.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I should still mention that this was probably not the best project to start in Rust since C++ excels at templates while Rust does not. But it was fun. And it was not that difficult for me to quickly get into Rust. But it will take a longer time to become an expert.&lt;/p&gt;
&lt;p&gt;While I enjoy writing Rust, I do enjoy writing C++ much more, so I really hope I can keep on writing C++ for a long time.&lt;/p&gt;
&lt;p&gt;What about you? Anybody tried Rust?&lt;/p&gt;</description><category>C++26 projects Rust</category><guid>https://baptiste-wicht.com/posts/2025/05/trying-out-rust-and-c%2B%2B26.html</guid><pubDate>Fri, 16 May 2025 06:20:31 GMT</pubDate></item><item><title>C++ Refresh and new technos: FP16 and AVX512</title><link>https://baptiste-wicht.com/posts/2023/12/c%2B%2B-refresh-and-new-technos-fp16-and-avx512.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;In the last few months, I have been working on refreshing my Expression Templates Library (ETL) project with modern
C++. I am happy to report that I have now finished the refresh. It took me longer than I expected and I also had less
time than I expected. But I am very happy about the result.&lt;/p&gt;
&lt;p&gt;The main change in etl is the use of concepts. Expression Templates are making heavy use of SFINAE. And I was able to
replace every single usage of SFINAE with concepts. I was also able to replace many assertions with concepts instead.&lt;/p&gt;
&lt;p&gt;In most cases, I am using concepts instead of the &lt;cite&gt;typename&lt;/cite&gt; declaration. For instance&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_79b07e2532b2496a92c01d312ef4616c-1" name="rest_code_79b07e2532b2496a92c01d312ef4616c-1" href="https://baptiste-wicht.com/posts/2023/12/c%2B%2B-refresh-and-new-technos-fp16-and-avx512.html#rest_code_79b07e2532b2496a92c01d312ef4616c-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;M&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cpp_enable_iff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_4d&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_79b07e2532b2496a92c01d312ef4616c-2" name="rest_code_79b07e2532b2496a92c01d312ef4616c-2" href="https://baptiste-wicht.com/posts/2023/12/c%2B%2B-refresh-and-new-technos-fp16-and-avx512.html#rest_code_79b07e2532b2496a92c01d312ef4616c-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;becomes&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_a5f5944915804c538950294ce12bec14-1" name="rest_code_a5f5944915804c538950294ce12bec14-1" href="https://baptiste-wicht.com/posts/2023/12/c%2B%2B-refresh-and-new-technos-fp16-and-avx512.html#rest_code_a5f5944915804c538950294ce12bec14-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;etl_4d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;M&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_a5f5944915804c538950294ce12bec14-2" name="rest_code_a5f5944915804c538950294ce12bec14-2" href="https://baptiste-wicht.com/posts/2023/12/c%2B%2B-refresh-and-new-technos-fp16-and-avx512.html#rest_code_a5f5944915804c538950294ce12bec14-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This makes the declaration much simpler to read. In some cases, I had to use &lt;cite&gt;requires&lt;/cite&gt;. For instance, here is the old definition of sub_view:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_5664db6d58f246e2bc0a1110d4475abb-1" name="rest_code_5664db6d58f246e2bc0a1110d4475abb-1" href="https://baptiste-wicht.com/posts/2023/12/c%2B%2B-refresh-and-new-technos-fp16-and-avx512.html#rest_code_5664db6d58f246e2bc0a1110d4475abb-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Aligned&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_5664db6d58f246e2bc0a1110d4475abb-2" name="rest_code_5664db6d58f246e2bc0a1110d4475abb-2" href="https://baptiste-wicht.com/posts/2023/12/c%2B%2B-refresh-and-new-technos-fp16-and-avx512.html#rest_code_5664db6d58f246e2bc0a1110d4475abb-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;sub_view&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Aligned&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;enable_if_t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="n"&gt;fast_sub_view_able&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and here is the new one:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_550637eda3c946eb90de5718e36fb13b-1" name="rest_code_550637eda3c946eb90de5718e36fb13b-1" href="https://baptiste-wicht.com/posts/2023/12/c%2B%2B-refresh-and-new-technos-fp16-and-avx512.html#rest_code_550637eda3c946eb90de5718e36fb13b-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Aligned&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_550637eda3c946eb90de5718e36fb13b-2" name="rest_code_550637eda3c946eb90de5718e36fb13b-2" href="https://baptiste-wicht.com/posts/2023/12/c%2B%2B-refresh-and-new-technos-fp16-and-avx512.html#rest_code_550637eda3c946eb90de5718e36fb13b-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;requires&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;fast_sub_view_able&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_550637eda3c946eb90de5718e36fb13b-3" name="rest_code_550637eda3c946eb90de5718e36fb13b-3" href="https://baptiste-wicht.com/posts/2023/12/c%2B%2B-refresh-and-new-technos-fp16-and-avx512.html#rest_code_550637eda3c946eb90de5718e36fb13b-3"&gt;&lt;/a&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;sub_view&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Aligned&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This also explains the requirements much better than using SFINAE. In most cases, concepts should be faster to compile
than the old enable-if stuff. However, I have not yet had time to measure that.&lt;/p&gt;
&lt;p&gt;I also made many small cleanups to the code, but they are probably not worth discussing.&lt;/p&gt;
&lt;section id="avx-512"&gt;
&lt;h2&gt;AVX-512&lt;/h2&gt;
&lt;p&gt;What is worth discussing is that I finally added support for AVX-512 into etl. Before, I was waiting until Intel would
give AVX-512F support to desktop CPU, but this is still not the case unfortunately. So I rented a VPS with AVX-512F
support.&lt;/p&gt;
&lt;p&gt;AVX512-F is able to process 512b vector operations at once, twice more than AVX-2. This makes it twice faster in theory.
I have completed the support in etl and did some extra testing as well. I wish I had a machine where to test that on
a regular basis (the VPS is pretty expensive to keep running). If I start working a lot on this project again, I will
consider having a Xeon CPU at hone.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="fp16-and-bf16"&gt;
&lt;h2&gt;FP16 and BF16&lt;/h2&gt;
&lt;p&gt;Another thing I had been wanting to work on for many years is FP16 operations on GPU. FP16 is a floating point type with
only 16b instead of the standard 32b for &lt;cite&gt;float&lt;/cite&gt;. With my new computer and new versions of CUDA, I now got a working
system to do FP16.&lt;/p&gt;
&lt;p&gt;So, I implemented support for many FP16 operations on my &lt;cite&gt;etl-gpu-blas&lt;/cite&gt; project that is used by &lt;cite&gt;etl&lt;/cite&gt; to provide GPU
operations. Thanks to operator overloading in CUDA, there is really nothing complicated about doing that.&lt;/p&gt;
&lt;p&gt;Doing so, I also added support for BF16. This is another half-precision floating point type, but the mantissa and
exponent part are different, apparently better tuned for machine learning. The support is more or less the same in CUDA,
only a different type.&lt;/p&gt;
&lt;p&gt;Currently, it is only used in etl-gpu-blas, not yet in DLL. Indeed, the problem with FP16 and BF16 is that there is no
CPU support, so it is not as easy to use. I plan to improve that support in the future so that I can use it on DLL
without even going to the CPU.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="next-steps"&gt;
&lt;h2&gt;Next steps&lt;/h2&gt;
&lt;p&gt;Another thing I want to explore in the future is FP8, which is a quarter-precision floating point. However, FP8 can only
be used for some tensor operations, through the use of tensor cores. So, I will likely only use it through CUDNN
for convolution operations.&lt;/p&gt;
&lt;p&gt;Finally, I also want to explore INT8 for neural networks. INT8 is easy to do on both CPU and GPU, but you cannot replace
all types in a neural network with INT8, a certain level of quantization is necessary and storage should still be done
in INT16 and INT32. But, that's not for tomorrow.&lt;/p&gt;
&lt;p&gt;The next immediate projec is to refresh the code of dll, with C++23. Then, I want to run some more benchmarks and see
what are my next steps to make dll faster on CPU and GPU.&lt;/p&gt;
&lt;/section&gt;</description><category>avx</category><category>C++</category><category>C++23</category><category>etl</category><category>projects</category><guid>https://baptiste-wicht.com/posts/2023/12/c%2B%2B-refresh-and-new-technos-fp16-and-avx512.html</guid><pubDate>Sun, 17 Dec 2023 08:20:55 GMT</pubDate></item><item><title>Switching from vim to neovim</title><link>https://baptiste-wicht.com/posts/2023/09/switching-from-vim-to-neovim.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;As mentioned in my last article, I am now using neovim instead of vim. I just wanted to comment shortly on this change.&lt;/p&gt;
&lt;p&gt;I have been using vim as my IDE for many years now (more than 10 years at least). But at the beginning of the year,
I switched to neovim instead.&lt;/p&gt;
&lt;p&gt;neovim is a fork of vim, so it is quite similar, but it has some very important differences. It started in 2015, after
a multithreading patch was rejected from vim.&lt;/p&gt;
&lt;p&gt;Here are some of the advantages:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Very powerful Builtin Langauge Server Protocol (LSP)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Faster startup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Builtin LUA support (the configuration can be written entirely in LUA)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asynchronous tasks (was later added to vim)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A lot of things are compatible between both editors. When I started with neovim, I simply copied over my vim
configuration and started using neovim with only very minor changes.&lt;/p&gt;
&lt;p&gt;But what really convinced me to keep using neovim was the LSP. This feature and the great plugins that make use of it
greatly simplify how to deeply integrate C++ into neovim. I am now taking advantage of the clang tooling to analyze C++
code on the fly. And I get great autocompletion as well.&lt;/p&gt;
&lt;p&gt;All of this is doable with vim as well, but the last time I tried with vim, it was a nightmware to configure. With the
help of (quite a few) plugins, I could setup automcompletion in a great way. This allows me to jump to declarations and
definitions very easily.&lt;/p&gt;
&lt;p&gt;I am far from being a neovim expert, but I am very happy with this tool. It definitely makes my life easier for
configuring complex features, compared to vim.&lt;/p&gt;
&lt;p&gt;If you are interested, you can find my neovim configuration in my &lt;cite&gt;dotfiles repository&amp;lt;https://github.com/wichtounet/dotfiles&amp;gt;&lt;/cite&gt;. It's very fresh because it was previously saved on another place and was recently copied there. I plan to improve it and little by little rewrite it in LUA. There are still some experimental stuff and it could be improved significantly. But I am really happy with the features configured.&lt;/p&gt;
&lt;p&gt;What about you? What do you think of neovim?&lt;/p&gt;</description><category>neovim</category><category>Tools</category><guid>https://baptiste-wicht.com/posts/2023/09/switching-from-vim-to-neovim.html</guid><pubDate>Wed, 20 Sep 2023 17:25:24 GMT</pubDate></item><item><title>C++23 Refresh and budgetwarrior 1.1.0</title><link>https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I am happy to announce the release of budgetwarrior 1.1.0.&lt;/p&gt;
&lt;p&gt;The last release of budgetwarrior was more than 5 years ago. So, once I finished my C++20/C++23 refresh of the code,
I decided it was a good time to generate a new release. There has been many improvements in this new version:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Many new graphs on the web interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add support for tracking stock values&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Significant speed improvements if you have a lot of data in the tool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assets can be set as inactive to be hidden&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Introduction of the FI Net Worth&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better support of asset classes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Many small bug fixes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want to use the latest version, you can now use the docker image that I am publishing frequently. This docker
image is what I use, so it should be fairly up-to-date.
* &lt;cite&gt;budgetwarrior on docker hub &amp;lt;https://hub.docker.com/r/wichtounet/budgetwarrior&amp;gt;&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;Otherwise, you can of course compile it from the sources (another docker image is available as a build image). For this,
you will need a very recent GCC (13+) or Clang (16+) compiler.&lt;/p&gt;
&lt;p&gt;Most of the new features have been implemented a while ago, for my personal usage. The main recent changes are
improvements in the code, related to using C++20 and C++23. I plan for all my projects to be compiled with C++23 by
default. The reason is mostly so I can really learn about these features, since I cannot use them all at work. On that
note, I was a bit disappointed by the support in clang, especially in libc++. I had to work around a few limitations in
order to support clang.&lt;/p&gt;
&lt;p&gt;The main C++20 feature that I am using in budgetwarrior is ranges. I have been able to improve many pieces of code from
using loops and multiple ifs, to using a range. I have implemented many transforms and filters for budgetwarrior. And
I am quite happy about the result. For instance:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_dc7ab8329cb64304befaf81121639c18-1" name="rest_code_dc7ab8329cb64304befaf81121639c18-1" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_dc7ab8329cb64304befaf81121639c18-1"&gt;&lt;/a&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;budget::account_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;a id="rest_code_dc7ab8329cb64304befaf81121639c18-2" name="rest_code_dc7ab8329cb64304befaf81121639c18-2" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_dc7ab8329cb64304befaf81121639c18-2"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;all_accounts&lt;/span&gt;&lt;span class="p"&gt;()){&lt;/span&gt;
&lt;a id="rest_code_dc7ab8329cb64304befaf81121639c18-3" name="rest_code_dc7ab8329cb64304befaf81121639c18-3" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_dc7ab8329cb64304befaf81121639c18-3"&gt;&lt;/a&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;a id="rest_code_dc7ab8329cb64304befaf81121639c18-4" name="rest_code_dc7ab8329cb64304befaf81121639c18-4" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_dc7ab8329cb64304befaf81121639c18-4"&gt;&lt;/a&gt;&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_dc7ab8329cb64304befaf81121639c18-5" name="rest_code_dc7ab8329cb64304befaf81121639c18-5" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_dc7ab8329cb64304befaf81121639c18-5"&gt;&lt;/a&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;a id="rest_code_dc7ab8329cb64304befaf81121639c18-6" name="rest_code_dc7ab8329cb64304befaf81121639c18-6" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_dc7ab8329cb64304befaf81121639c18-6"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;a id="rest_code_dc7ab8329cb64304befaf81121639c18-7" name="rest_code_dc7ab8329cb64304befaf81121639c18-7" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_dc7ab8329cb64304befaf81121639c18-7"&gt;&lt;/a&gt;
&lt;a id="rest_code_dc7ab8329cb64304befaf81121639c18-8" name="rest_code_dc7ab8329cb64304befaf81121639c18-8" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_dc7ab8329cb64304befaf81121639c18-8"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_dc7ab8329cb64304befaf81121639c18-9" name="rest_code_dc7ab8329cb64304befaf81121639c18-9" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_dc7ab8329cb64304befaf81121639c18-9"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;became:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_2a9db7738ce14d749f07b84cc7330654-1" name="rest_code_2a9db7738ce14d749f07b84cc7330654-1" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_2a9db7738ce14d749f07b84cc7330654-1"&gt;&lt;/a&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;budget::account_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;a id="rest_code_2a9db7738ce14d749f07b84cc7330654-2" name="rest_code_2a9db7738ce14d749f07b84cc7330654-2" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_2a9db7738ce14d749f07b84cc7330654-2"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ranges&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_accounts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;filter_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;a id="rest_code_2a9db7738ce14d749f07b84cc7330654-3" name="rest_code_2a9db7738ce14d749f07b84cc7330654-3" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_2a9db7738ce14d749f07b84cc7330654-3"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or here is another example of using ranges:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_7c9ad1ea8b9f42b8a75c787c9e7e5a02-1" name="rest_code_7c9ad1ea8b9f42b8a75c787c9e7e5a02-1" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_7c9ad1ea8b9f42b8a75c787c9e7e5a02-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;not_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;active_today&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;filter_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_7c9ad1ea8b9f42b8a75c787c9e7e5a02-2" name="rest_code_7c9ad1ea8b9f42b8a75c787c9e7e5a02-2" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_7c9ad1ea8b9f42b8a75c787c9e7e5a02-2"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;budget_exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"There is already an account with the name "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_7c9ad1ea8b9f42b8a75c787c9e7e5a02-3" name="rest_code_7c9ad1ea8b9f42b8a75c787c9e7e5a02-3" href="https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html#rest_code_7c9ad1ea8b9f42b8a75c787c9e7e5a02-3"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is likely the biggest change, but I have made other improvements based on recent versions of C++:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Use of std::format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use of the spaceship operator&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use of template lambdas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use of std::string_view&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use of std::filesystem&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use of std::map::contains (and other such functions)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Overall, it was a lot of fun and I could significantly improve the code by using these new features (and more).&lt;/p&gt;
&lt;p&gt;I am also taking advantage of clang-tidy now. I have added a clang-tidy configuration to my projects so that I can
quickly check everything. I have also integrated clang-tidy in neovim (yes, I switched from vim to neovim, more on that
later maybe) and this shows in real time where I could improve the code.&lt;/p&gt;
&lt;p&gt;Finally, another change is that I am now taking advantage of Github Workflows. Every time I push to the repo, everything is
compiled with the two compilers I support. This allows me to keep compatibility between both. In the future, I plan to
add a few more tools to the workflows for code analysis. This is also an opportunity for me to learn about these
workflows, which I never used before.&lt;/p&gt;
&lt;p&gt;I am quite glad to be working on these projects again eve though I do not have much time. It was really fun to use all
these new features in budgetwarrior. Next, I plan to refresh the code of ETL. And since I want to refresh my GPU skills
as well, I will also work on etl_gpu_blas.&lt;/p&gt;</description><category>budgetwarrior</category><category>C++</category><category>C++20</category><category>C++23</category><category>projects</category><guid>https://baptiste-wicht.com/posts/2023/09/c%2B%2B23-refresh-and-budgetwarrior-110.html</guid><pubDate>Sun, 10 Sep 2023 04:50:28 GMT</pubDate></item><item><title>A short update</title><link>https://baptiste-wicht.com/posts/2023/08/a-short-update.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I can't believe it's been about 5 years since the last update on this blog. For those, who are wondering what is
happening, here is a short update.&lt;/p&gt;
&lt;p&gt;About 6 years ago, I have finished my Ph.D. and about 5 years, I started to work as a software engineer, at Verisign.
I am now a Senior Software Engineer, still at Verisign. After I started working professionally, I did not spend much
time on my personal projects anymore. Before, my personal projects were part of my Ph.D., so it made sense to posts some
updates on this blog and I had time to also post other articles.&lt;/p&gt;
&lt;p&gt;But probably another bigger factor is that I started another blog in 2017, &lt;cite&gt;The Poor Swiss &amp;lt;https://thepoorswiss.com&amp;gt;&lt;/cite&gt;.
This is not a technical blog but a blog on personal finance, related to Switzerland. I have written more than 400
articles on this blog and I am still writing about one article a week these days. This takes a lot of time and made me
scale down even more on my personal projects. The only project that continued getting some improvements was budgetwarrior
since I am using it almost every day.&lt;/p&gt;
&lt;p&gt;It's obviously worth mentioning that I got married about 5 years ago and that we now have a son, almost two years old.
This obviously takes a lot of time!&lt;/p&gt;
&lt;p&gt;So, why am I posting this short update today? I recently started missing working on personal projects. And I realized
I had gotten out of touch with recent C++. It is a bit disappointing but my C++ level is becoming worse since I have
started working professionally on C++. So, I learned in details about C++20 and C++23 and decided to apply some of it to
my personal projects.&lt;/p&gt;
&lt;p&gt;I have made significant cleanups to budgetwarrior, using C++23 by default now and switching to GCC 15 and Clang 16 as
the default compilers. I plan to continue working on budgetwarrior_web, the web interface for budgetwarrior next. This
project will also be converted to C++23. After that, I will probably continue with ETL and DLL. And hopefully, I plan to
dedicate some time to adding more features to ETL and DLL as well. Thor OS is currently not on my list because I don't
have the kind of energy and time this project requires.&lt;/p&gt;
&lt;p&gt;I also hope I will be posting some more updates on this blog, but I will not adhere to any posting schedule. At least,
I will not let five years go by before the next update!&lt;/p&gt;</description><category>budgetwarrior</category><category>C++</category><category>Personal</category><category>projects</category><category>The site</category><guid>https://baptiste-wicht.com/posts/2023/08/a-short-update.html</guid><pubDate>Sun, 13 Aug 2023 06:55:40 GMT</pubDate></item><item><title>budgetwarrior 1.0.1: Allocation tracking, Retirement calculator and bug fixes</title><link>https://baptiste-wicht.com/posts/2018/04/budgetwarrior-101-allocation-tracking-retirement-calculator-bug-fixes.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I'm happy to announce the release of budgetwarrior 1.0.1. This new version
contains a series of improvement over the 1.0 version and some new features.&lt;/p&gt;
&lt;p&gt;I haven't been very active this last month. I have been working a bit on
budgetwarrior for features I needed for my budget. I've also been contacted with
questions on my thor operating system and since that point I've doing some
work on thor as well.&lt;/p&gt;
&lt;p&gt;This new version of budgetwarrior has quite a few new features even though it's
a minor version.&lt;/p&gt;
&lt;p&gt;Note: The data from all the views is totally randomized and does not make
sense ;)&lt;/p&gt;
&lt;section id="retirement-calculator"&gt;
&lt;h2&gt;Retirement Calculator&lt;/h2&gt;
&lt;p&gt;The biggest novelty in this version is the addition of a retirement calculator.
This is still very basic, but it may give information on how close (or far) you
are from early retirement. Here is what the view gives you:&lt;/p&gt;
&lt;img alt="Retirement Status" src="https://baptiste-wicht.com/images/budgetwarrior_101_retirement_status.png"&gt;
&lt;p&gt;Using your annual withdrawal rate and expected Rate Of Return, it can compute
how many years you will need to reach your goals Financial Independence (FI). It
will also gives you your FI ratio and a few more information about your savings
rate, income, expenses and so on. It's nothing very fancy but it can be very
useful.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="new-features"&gt;
&lt;h2&gt;New features&lt;/h2&gt;
&lt;p&gt;I've also added a few graphs based on the budget information. The first is the
visualization of the expenses over time:&lt;/p&gt;
&lt;img alt="Expenses over time graph" src="https://baptiste-wicht.com/images/budgetwarrior_101_expenses_over_time.png"&gt;
&lt;p&gt;This can be pretty useful to see how are your expenses going. Even if your
income is going, expenses should not necessarily go up (you should save more!).&lt;/p&gt;
&lt;p&gt;Another new view can show your asset allocation over time and the current asset
allocation of your entire net worth or specifically for your portfolio.&lt;/p&gt;
&lt;img alt="Asset allocation" src="https://baptiste-wicht.com/images/budgetwarrior_101_allocation.png"&gt;
&lt;p&gt;This is also really useful if you want to have a global view of your asset
allocation into bonds, stocks and such.&lt;/p&gt;
&lt;p&gt;There are also two other new minor features. You can now search expenses by
name. This is really useful once you start having many expenses. Another new
view is the Full aggregate view. Before, you could aggregate your expenses by
month or year, now they can be aggregate since the beginning of the budget. With
this, you can see how much you spend on coffee since you started keeping track
of your budget. For me, it's a lot! Both these features are available both in
command line and in the web interface.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="improvements"&gt;
&lt;h2&gt;Improvements&lt;/h2&gt;
&lt;p&gt;There are also a few improvements with this new version. You can now set
a default account (in the configuration file with default_account=X). It will be
set by default in both the web view and the console view. The rebalance view has
been made more clear. I've added a second batch update view with only the assets
that are being used (amount &amp;gt; 0). And lastly, the yearly overview is now
displaying correctly the previous year savings rate.&lt;/p&gt;
&lt;p&gt;Finally, there are also a few bug fixes. That is is the main reason I decided to
release now. If you were using asset with different currency, several views
where not correctly using the exchange rate to display them. Moreover, the
average expenses in the monthly overview was not correct. Finally, if you were
editing old expenses after having archived the accounts, it could be edited with
the wrong account.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="installation"&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;If you are on Gentoo, you can install it using layman:&lt;/p&gt;
&lt;pre class="literal-block"&gt;layman -a wichtounet
emerge -a budgetwarrior&lt;/pre&gt;
&lt;p&gt;If you are on Arch Linux, you can use this &lt;cite&gt;AUR repository
&amp;lt;https://github.com/StreakyCobra/aur&amp;gt;&lt;/cite&gt; (wait a few days for the new version to be
updated)_&lt;/p&gt;
&lt;p&gt;For other systems, you'll have to install from sources:&lt;/p&gt;
&lt;pre class="literal-block"&gt;git clone --recursive git://github.com/wichtounet/budgetwarrior.git
cd budgetwarrior
git checkout 1.0.1
make
sudo make install&lt;/pre&gt;
&lt;p&gt;If you want to test the server mode, the default username is admin and the
default password is 1234. You can change them in the configuration file with
web_user and web_password.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Although it's a minor version, it improves and fixes quite a few things,
especially for the web view. I encourage you to try it out. Don't hesitate to
let me a comment if you fail to use it or don't understand something ;)&lt;/p&gt;
&lt;p&gt;There are still a few things that I want to do, as I said when
&lt;a class="reference external" href="https://baptiste-wicht.com/posts/2018/01/budgetwarrior-10-web-interface-and-asset-tracking.html"&gt;I introduced the web version&lt;/a&gt;. The website still needs to be
made faster. And the communication between the console and the server can also
be improved.&lt;/p&gt;
&lt;p&gt;If you are interested by the sources, you can download them on Github:
&lt;a class="reference external" href="https://github.com/wichtounet/budgetwarrior"&gt;budgetwarrior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have a suggestion or you found a bug, please post an issue on Github.&lt;/p&gt;
&lt;p&gt;If you have any comment, don't hesitate to contact me, either by letting a
comment on this post or by email.&lt;/p&gt;
&lt;/section&gt;</description><category>budgetwarrior</category><category>C++</category><category>projects</category><category>Release</category><guid>https://baptiste-wicht.com/posts/2018/04/budgetwarrior-101-allocation-tracking-retirement-calculator-bug-fixes.html</guid><pubDate>Tue, 03 Apr 2018 08:58:47 GMT</pubDate></item><item><title>I got rid of Vivaldi browser for Google Chrome</title><link>https://baptiste-wicht.com/posts/2018/03/i-got-rid-of-vivaldi-browser-for-google-chrome.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;About a year ago, &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/01/vivaldi-vimium-finally-no-more-firefox.html"&gt;I switched from Firefox to Vivaldi&lt;/a&gt;. This week, I decided to get rid of Vivaldi and replaced with Google Chrome. In this post, I'm going to outline the reasons why I got rid of it.&lt;/p&gt;
&lt;p&gt;Before, I switched to Vivaldi because Firefox was dropping support for XUL/XPCOM
extensions and I was using Pentadactyl. In fact, Pentadactyl was the only reason
I was using Firefox. It was slow and bloated and a bit unstable, but the
extension was making it worth. Since they are dropping support for such
extensions, I did not want to use Firefox anymore. So I switched to Vivaldi with
Vimium. It's not as great as Firefox plus Pentadactyl. But it's a more
customizable version of Google Chrome on which it's based.&lt;/p&gt;
&lt;p&gt;But, in that year or so of using Vivaldi, I have had many issues. Some of them
were not too bad and there was some workarounds. But they continued to pile up
and they did not fix any of them so now, I decided it's too much.&lt;/p&gt;
&lt;p&gt;Since the beginning, it always has been slow. It's not really bad, but still
noticeable compared to Chrome. Especially opening Vivaldi is pretty bad. This is
something I can live with, but they should really do something to make it
faster.&lt;/p&gt;
&lt;p&gt;The thing that I had the most issues with is multimedia. For instance Youtube
(but all the other platforms have the same issues).&lt;/p&gt;
&lt;p&gt;The first problem with media is to get a video in fullscreen. Most of the time,
when I press the fullscreen button on Youtube, it grays out the screen and
I have to press ESC. If I do that around five to ten times, it finally goes
fullscreen. It may be because of my multi-monitor setup but Google Chrome has no
issues whatsoever with that. It's pretty painful to do, but again I could live
for since I don't use full screen a lot.&lt;/p&gt;
&lt;p&gt;A second problem I had with media is they were running too fast. I'm not
kidding, really too fast, not too slow. The media was running about twice too
fast, you could see the seconds going fast on Youtube. I never seen this issue
in any other tool, but it was happening at every start of Vivaldi. The fix was
to restart Vivaldi every time this happened and the video played normally.&lt;/p&gt;
&lt;p&gt;Another problem I had from the beginning is to make all HTML5 videos work. You
have to download the binary plugins from Chrome to let Vivaldi play all HTML5
videos. It's not a big deal, but the problem is that they are overwritten after
each update of Vivaldi. So you have to do it all the time.&lt;/p&gt;
&lt;p&gt;A new media issue I had on the last update of Vivaldi is with Flash. At the
beginning it was working even if it was outdated. I just had to confirm to run
it with a warning. But, since the last update, I only had the warning that it
was outdated. But I could not confirm to use it, the option was not here
anymore. And it was still happening after I updated Flash... The only option to
run Flash was to use a private navigation window...&lt;/p&gt;
&lt;p&gt;And finally, I had another big issue with the last version of Vivaldi as well.
The browser keeps crashing on my work computer. It can stay up a few minutes and
then crash. The complete interface is not updated. I can still press the tabs
and I can see the title of the window change, but the interface does not update.
Again, it may come from my special window manager (I use awesome), but it's the
only application not working...&lt;/p&gt;
&lt;p&gt;With all these issues and especially the last two new problems, I decided it was
time to cut the losses. So I reinstalled Google Chrome, transferred my plugins
and everything worked like a charm. I still use Vimium to use vim bindings so my
usage of the browser does not change. Of course, I don't have the customization
that I had with Vivaldi. I would really really like to get rid of the address
bar in the browser. I would also like to significantly reduce the size of the
tab bar. But I prefer to live without these improvements than with so many bugs.
I think Vivaldi is a good idea, but with a terrible implementation.&lt;/p&gt;
&lt;p&gt;I also considered qutebrowser as an alternative. But for now it's still missing
many features that I don't want to get rid of. So I will stay with Google Chrome
for the time being.&lt;/p&gt;
&lt;p&gt;What about you ? Do you have any experience with Vivaldi ?&lt;/p&gt;</description><category>Gentoo</category><category>Google</category><category>Personal</category><category>Web</category><guid>https://baptiste-wicht.com/posts/2018/03/i-got-rid-of-vivaldi-browser-for-google-chrome.html</guid><pubDate>Fri, 16 Mar 2018 07:31:45 GMT</pubDate></item><item><title>Decrease DLL neural network compilation time with C++17</title><link>https://baptiste-wicht.com/posts/2018/02/decrease-dll-neural-network-compilation-time-with-c%2B%2B17.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;Just last week, &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html"&gt;I've migrated my Expression Templates Library (ETL) library to C++17&lt;/a&gt;,
it is now also done in my Deep Learning Library (DLL) library. In ETL, this
resulted in a &lt;em&gt;much nicer code overall&lt;/em&gt;, but no real improvement in compilation
time.&lt;/p&gt;
&lt;p&gt;The objective of the migration of DLL was two-fold. First, I also wanted to
simplify some code, especially with &lt;code&gt;if constexpr&lt;/code&gt;. But I also especially
wanted to try to reduce the compilation time. In the past,
&lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/09/how-i-made-deep-learning-library-38-faster-to-compile-optimization-and-cpp17-if-constexpr.html"&gt;I've already tried a few changes with C++17&lt;/a&gt;, with good results on the compilation of the entire test suite.
While this is very good, this is not very representative of users of the library.
Indeed, normally you'll have only one network in your source file not several.
The new changes will especially help in the case of many networks, but less in
the case of a single network per source file.&lt;/p&gt;
&lt;p&gt;This time, I decided to test the compilation on the examples. I've tested the
eight official examples from the DLL library:&lt;/p&gt;
&lt;ol class="arabic simple" start="0"&gt;
&lt;li&gt;&lt;p&gt;mnist_dbn: A fully-connected Deep Belief Network (DBN) on the MNIST data set
with three layers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;char_cnn: A special CNN with embeddings and merge and group layers for text
recognition&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;imagenet_cnn: A 12 layers Convolutional Neural Network (CNN) for Imagenet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;mnist_ae: A simple two-layers auto-encoder for MNIST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;mnist_cnn: A simple 6 layers CNN for MNIST&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;mnist_deep_ae: A deep auto-encoder for MNIST, only fully-connected&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;mnist_lstm: A Recurrent Neural Network (RNN) with Long Short Term Memory
(LSTM) cells&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;mnist_mlp: A simple fully-connected network for MNIST, with dropout&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;mnist_rnn: A simple RNN with simple cells for MNIST&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is really representative of what users can do with the library and I think
it's a much better for compilation time.&lt;/p&gt;
&lt;p&gt;For reference, you can find &lt;a class="reference external" href="https://github.com/wichtounet/dll/tree/master/examples/src"&gt;the source code of all the examples online&lt;/a&gt;.&lt;/p&gt;
&lt;section id="results"&gt;
&lt;h2&gt;Results&lt;/h2&gt;
&lt;p&gt;Let's start with the results. I've tested this at different stages of the
migration with clang 5 and GCC 7.2. I tested the following steps:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The original C++14 version&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simply compiling in c++17 mode (-std=c++17)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using the C++17 version of the ETL library&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrading DLL to C++17 (without ETL)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ETL and DLL in C++17 versions&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I've compiled each example independently in release_debug mode. Here are the
results for G++ 7.2:&lt;/p&gt;
&lt;table class="align-center"&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th class="head"&gt;&lt;p&gt;Example&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;0&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;3&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;4&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;5&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;6&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;7&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;8&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;C++14&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;37.818&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;32.944&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;33.511&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;15.403&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;29.998&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;16.911&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;24.745&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;18.974&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;19.006&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;-std=c++17&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;38.358&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;32.409&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;32.707&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;15.810&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;30.042&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;16.896&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;24.635&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;19.134&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;19.027&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;ETL C++17&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;36.045&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;31.000&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;30.942&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;15.322&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;28.840&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;16.747&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;24.151&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;18.208&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;18.939&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;DLL C++17&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;35.251&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;32.577&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;32.854&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;15.653&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;29.758&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;16.851&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;24.606&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;19.098&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;19.146&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;Final C++17&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;32.289&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;31.133&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;30.939&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;15.232&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;28.753&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;16.526&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;24.326&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;18.116&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;17.819&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;Final Improvement&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;14.62%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;5.49%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;7.67%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1.11%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.15%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2.27%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1.69%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.52%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;6.24%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The difference by just enabling c++17 is not significant. On the other hand,
some significant gain can be obtained by using the C++17 version of ETL,
especially for the DBN version and for the CNN versions. Except for the DBN
case, the migration of DLL to C++17 did not bring any significant advantage.
When everything is combined, the gains are more important :) In the best case,
the example is 14.6% faster to compile.&lt;/p&gt;
&lt;p&gt;Let's see if it's the same with clang++ 5.0:&lt;/p&gt;
&lt;table class="align-center"&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th class="head"&gt;&lt;p&gt;Example&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;0&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;1&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;2&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;3&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;4&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;5&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;6&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;7&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;8&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;C++14&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;40.690&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;34.753&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;35.488&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;16.146&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;31.926&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;17.708&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;29.806&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;19.207&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;20.858&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;-std=c++17&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;40.502&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;34.664&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;34.990&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;16.027&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;31.510&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;17.630&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;29.465&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;19.161&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;20.860&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;ETL C++17&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;37.386&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;33.008&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;33.896&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;15.519&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;30.269&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;16.995&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;28.897&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;18.383&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;19.809&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;DLL C++17&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;37.252&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;34.592&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;35.250&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;16.131&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;31.782&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;17.606&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;29.595&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;19.126&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;20.782&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;Final C++17&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;34.470&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;33.154&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;33.881&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;15.415&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;30.279&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;17.078&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;28.808&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;18.497&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;19.761&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;Final Improvement&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;15.28%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.60%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.52%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4.52%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;5.15%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;3.55%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;3.34%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;3.69%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;5.25%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;First of all, as I have seen time after time, clang is still slower than GCC.
It's a not a big difference, but still significant. Overall, the gains are a bit
higher on clang than on GCC, but not by much. Interestingly, the migration of
DLL to C++17 is less interesting in terms of compilation time for clang. It
seems even to slow down compilation on some examples. On the other hand, the
migration of ETL is more important than on GCC.&lt;/p&gt;
&lt;p&gt;Overall, every example is faster to compile using both libraries in C++17, but
we don't have spectacular speed-ups. With clang, we have speedups from 3.3% to
15.3%. With GCC, we have speedup  from 1.1% to 14.6%. It's not very high, but
I'm already satisfied with these results.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="c-17-in-dll"&gt;
&lt;h2&gt;C++17 in DLL&lt;/h2&gt;
&lt;p&gt;Overall, the migration of DLL to C++17 was quite similar to that of ETL. You can
take a look at my &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html"&gt;previous article&lt;/a&gt;
if you want more details on C++17 features I've used.&lt;/p&gt;
&lt;p&gt;I've &lt;em&gt;replaced a lot of SFINAE functions&lt;/em&gt; with &lt;code&gt;if constexpr&lt;/code&gt;. I've also
replaced a lot of &lt;code&gt;statif_if&lt;/code&gt; with &lt;code&gt;if constexpr&lt;/code&gt;. There was a large
number of these in DLL's code. I also enabled all the &lt;code&gt;constexpr&lt;/code&gt; that
were commented for this exact time :)&lt;/p&gt;
&lt;p&gt;I was also thinking that I could replace a lot of meta-programming stuff with
&lt;em&gt;fold expressions&lt;/em&gt;. While I was able to replace a few of them, most of them were
harder to replace with fold expressions. Indeed, the variadic pack is often
hidden behind another class and therefore the pack is not directly usable from
the network class or the group and merge layers classes. I didn't want to start
a big refactoring just to use a C++17 feature, the current state of this code is
fine.&lt;/p&gt;
&lt;p&gt;I made some use of structured bindings as well, but again not as much as I was
thinking. In fact, a lot of time, I'm assigning the elements of a pair or tuple
to existing variables not declaring new variables and unfortunately, you can
only use structured bindings with &lt;code&gt;auto&lt;/code&gt; declaration.&lt;/p&gt;
&lt;p&gt;Overall, the &lt;em&gt;code is significantly better now&lt;/em&gt;, but there was less impact than
there was on ETL. It's also a smaller code base, so maybe this is normal and my
expectations were too high ;)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The trunk of DLL is now a C++17 library :) I think this improve the quality of
the code by a nice margin! Even though, there is still some work to be done to
improve the code, especially for the DBN pretraining code, the quality is quite
good now. Moreover, the switch to C++17 made the compilation of neural networks
using the DLL library &lt;em&gt;faster to compile&lt;/em&gt;, from 1.1% in the worst case to 15.3% in
the best case! I don't know when I will release the next version of DLL, but it
will take some time. I'll especially have to polish the RNN support and add
a sequence to sequence loss before I will release the 1.1 version of DLL.&lt;/p&gt;
&lt;p&gt;I'm quite satisfied with C++17 even if I would have liked a bit more features to
play with! I'm already a big fan of &lt;code&gt;if constexpr&lt;/code&gt;, this can make the code
much nicer and fold expressions are much more intuitive than their previous
recursive template counterpart.&lt;/p&gt;
&lt;p&gt;I may also consider migrating some parts of the cpp-utils library, but if I do,
it will only be through the use of conditionals in order not to break the other
projects that are based on the library.&lt;/p&gt;
&lt;/section&gt;</description><category>C++</category><category>C++17</category><category>clang</category><category>Compilers</category><category>Deep Learning</category><category>dll</category><category>etl</category><category>gcc</category><category>Machine Learning</category><category>Performance</category><category>projects</category><guid>https://baptiste-wicht.com/posts/2018/02/decrease-dll-neural-network-compilation-time-with-c%2B%2B17.html</guid><pubDate>Wed, 07 Feb 2018 10:39:02 GMT</pubDate></item><item><title>C++17 Migration of Expression Templates Library (ETL)</title><link>https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I've finally decided to migrate my Expression Templates Library (ETL) project to
C++17. I've talking about doing that for a long time and I've released several
releases without doing the change, but the next version will be a C++17 library.
The reason why I didn't want to rush the change was that this means the library
needs a very recent compiler that may not be available to everybody. Indeed,
after this change, the ETL library now needs at least GCC 7.1 or Clang 4.0.&lt;/p&gt;
&lt;p&gt;I've already made some previous experiments in the past. For instance,
&lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/09/how-i-made-deep-learning-library-38-faster-to-compile-optimization-and-cpp17-if-constexpr.html"&gt;by using if constexpr, I've managed to speed up compilation by 38%&lt;/a&gt; and I've also written an article about &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2015/05/cpp17-fold-expressions.html"&gt;the fold expressions introduced in C++17&lt;/a&gt;. But I haven't migrated a full library yet. This is now done with ETL. In this article, I'll try to give some example of improvements by using C++17.&lt;/p&gt;
&lt;p&gt;This will only cover the C++17 features I'm using in the updated ETL library,
I won't cover all of the new C++17 features.&lt;/p&gt;
&lt;section id="if-constexpr"&gt;
&lt;h2&gt;if constexpr&lt;/h2&gt;
&lt;p&gt;The most exciting new thing in C++17 for me is the &lt;code&gt;if constexpr&lt;/code&gt;
statement. This is a really really great thing. In essence, it's a normal
&lt;code&gt;if&lt;/code&gt; statement, but with one very important difference. The statement that
is not taken (the &lt;code&gt;else&lt;/code&gt; if the condition is true, or the &lt;code&gt;if
constexpr&lt;/code&gt; if the condition is false) is &lt;em&gt;discarded&lt;/em&gt;. And what is interesting
is what happens to &lt;em&gt;discarded&lt;/em&gt; statements:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The body of a &lt;em&gt;discarded&lt;/em&gt; statement does not participate in return type
deduction.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The discarded statement is not instantiated&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The discarded statement can &lt;em&gt;odr-use&lt;/em&gt; a variable that is not defined&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Personally, I'm especially interested by points 1 and 2. Let's start with an
example where point 1 is useful. In ETL, I have a make_temporary function. This
function either forwards an ETL container or creates a temporary container from
an ETL expression. This is based on a compile-time traits. The return type of
the function is the not the same in both cases. What you did in those case
before C++17, is use SFINAE and make two functions:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-1" name="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_d048c260ae3644b9b0a6d0e95b472d3b-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cpp_enable_iff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_dma&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-2" name="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_d048c260ae3644b9b0a6d0e95b472d3b-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;decltype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;make_temporary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-3" name="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_d048c260ae3644b9b0a6d0e95b472d3b-3"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;forward&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-4" name="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-4" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_d048c260ae3644b9b0a6d0e95b472d3b-4"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;a id="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-5" name="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-5" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_d048c260ae3644b9b0a6d0e95b472d3b-5"&gt;&lt;/a&gt;
&lt;a id="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-6" name="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-6" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_d048c260ae3644b9b0a6d0e95b472d3b-6"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cpp_enable_iff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;is_dma&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-7" name="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-7" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_d048c260ae3644b9b0a6d0e95b472d3b-7"&gt;&lt;/a&gt;&lt;span class="k"&gt;decltype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;make_temporary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-8" name="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-8" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_d048c260ae3644b9b0a6d0e95b472d3b-8"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;force_temporary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;forward&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;a id="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-9" name="rest_code_d048c260ae3644b9b0a6d0e95b472d3b-9" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_d048c260ae3644b9b0a6d0e95b472d3b-9"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;One version of the function will forward and the other version will force
a temporary and the return type can be different since these are two different
functions. This is not bad, but still requires two functions where you only want
to write one. However, in C++17, we can do much better using &lt;code&gt;if constexpr&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-1" name="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_cc4391c829bb47b3a70aeaba7245c2bc-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-2" name="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_cc4391c829bb47b3a70aeaba7245c2bc-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;decltype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;make_temporary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-3" name="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_cc4391c829bb47b3a70aeaba7245c2bc-3"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_dma&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-4" name="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-4" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_cc4391c829bb47b3a70aeaba7245c2bc-4"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;forward&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-5" name="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-5" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_cc4391c829bb47b3a70aeaba7245c2bc-5"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-6" name="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-6" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_cc4391c829bb47b3a70aeaba7245c2bc-6"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;force_temporary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;forward&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;a id="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-7" name="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-7" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_cc4391c829bb47b3a70aeaba7245c2bc-7"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;a id="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-8" name="rest_code_cc4391c829bb47b3a70aeaba7245c2bc-8" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_cc4391c829bb47b3a70aeaba7245c2bc-8"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I think this version is really superior to the previous one. We only have one
function and the logic is much clearer!&lt;/p&gt;
&lt;p&gt;Let's now see an advantage of the point 2. In ETL, there are two kinds of
matrices, matrices with compile-time dimensions (fast matrices) and matrices
with runtime dimensions (dynamic matrices). When they are used, for instance for
a matrix-multiplication, I use static assertions for fast matrices and runtime
assertions for dynamic matrices. Here is an example for the validation of the
matrix-matrix multiplication:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-1" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cpp_disable_iff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_fast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-2" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-3" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-3"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;static_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_2d&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Matrix multiplication needs matrices"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-4" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-4" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-4"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-5" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-5" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-5"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;//interior dimensions&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-6" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-6" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-6"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 1&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-7" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-7" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-7"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 2&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-8" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-8" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-8"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="s"&gt;"Invalid sizes for multiplication"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-9" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-9" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-9"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp_unused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-10" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-10" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-10"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp_unused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-11" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-11" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-11"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp_unused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-12" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-12" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-12"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-13" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-13" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-13"&gt;&lt;/a&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-14" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-14" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-14"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cpp_enable_iff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_fast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-15" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-15" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-15"&gt;&lt;/a&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-16" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-16" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-16"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;static_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_2d&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Matrix multiplication needs matrices"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-17" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-17" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-17"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;static_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-18" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-18" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-18"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;//interior dimensions&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-19" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-19" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-19"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 1&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-20" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-20" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-20"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 2&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-21" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-21" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-21"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="s"&gt;"Invalid sizes for multiplication"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-22" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-22" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-22"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp_unused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-23" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-23" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-23"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp_unused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-24" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-24" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-24"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp_unused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_8faa01fd6b58442989f5edb44c3f654a-25" name="rest_code_8faa01fd6b58442989f5edb44c3f654a-25" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_8faa01fd6b58442989f5edb44c3f654a-25"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, we use SFINAE to distinguish the two different cases. In that case, we
cannot use a normal &lt;code&gt;if&lt;/code&gt; since the value of the dimensions cannot be taken
at compile-time for dynamic matrices, more precisely, some templates cannot be
instantiated for dynamic matrices. As for the cpp_unused, we have to use for the
static version because we don't use them and for the dynamic version because
they won't be used if the assertions are not enabled. Let's use &lt;code&gt;if constexpr&lt;/code&gt; to avoid having two functions:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-1" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-2" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-3" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-3"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;static_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_2d&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Matrix multiplication needs matrices"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-4" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-4" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-4"&gt;&lt;/a&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-5" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-5" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-5"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_fast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-6" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-6" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-6"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;static_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;//interior dimensions&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-7" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-7" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-7"&gt;&lt;/a&gt;&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 1&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-8" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-8" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-8"&gt;&lt;/a&gt;&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 2&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-9" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-9" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-9"&gt;&lt;/a&gt;&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="s"&gt;"Invalid sizes for multiplication"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-10" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-10" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-10"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-11" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-11" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-11"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;cpp_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;//interior dimensions&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-12" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-12" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-12"&gt;&lt;/a&gt;&lt;span class="w"&gt;                       &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 1&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-13" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-13" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-13"&gt;&lt;/a&gt;&lt;span class="w"&gt;                       &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 2&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-14" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-14" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-14"&gt;&lt;/a&gt;&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="s"&gt;"Invalid sizes for multiplication"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-15" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-15" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-15"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-16" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-16" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-16"&gt;&lt;/a&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-17" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-17" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-17"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp_unused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-18" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-18" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-18"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp_unused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-19" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-19" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-19"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp_unused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-20" name="rest_code_b5ecdf979fac451bb2d5d62f3fff1056-20" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b5ecdf979fac451bb2d5d62f3fff1056-20"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since the &lt;em&gt;discarded&lt;/em&gt; won't be instantiated, we can now use a single function!
We also avoid some duplications of the first static assertion of the unused
statements. Pretty great, right ? But we can do better with C++17. Indeed, it
added a nice new attribute &lt;code&gt;[[maybe_unused]]&lt;/code&gt;. Let's see what this gives
us:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-1" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-2" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="n"&gt;maybe_unused&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;maybe_unused&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;maybe_unused&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-3" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-3"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;static_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_2d&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Matrix multiplication needs matrices"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-4" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-4" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-4"&gt;&lt;/a&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-5" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-5" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-5"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_fast&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-6" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-6" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-6"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;static_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;//interior dimensions&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-7" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-7" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-7"&gt;&lt;/a&gt;&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 1&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-8" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-8" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-8"&gt;&lt;/a&gt;&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 2&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-9" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-9" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-9"&gt;&lt;/a&gt;&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="s"&gt;"Invalid sizes for multiplication"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-10" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-10" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-10"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-11" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-11" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-11"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;cpp_assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;//interior dimensions&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-12" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-12" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-12"&gt;&lt;/a&gt;&lt;span class="w"&gt;                       &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 1&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-13" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-13" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-13"&gt;&lt;/a&gt;&lt;span class="w"&gt;                       &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//exterior dimension 2&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-14" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-14" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-14"&gt;&lt;/a&gt;&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="s"&gt;"Invalid sizes for multiplication"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-15" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-15" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-15"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;a id="rest_code_f5b73d78c7974a7c8449df8820c31c91-16" name="rest_code_f5b73d78c7974a7c8449df8820c31c91-16" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f5b73d78c7974a7c8449df8820c31c91-16"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No more need for &lt;code&gt;cpp_unused&lt;/code&gt; trick :) This attribute tells the compiler
that a variable or parameter can be sometimes unused and therefore does not lead
to a warning for it. Only one thing that is not great with this attribute is
that it's too long, 16 characters. It almost double the width of my check
function signature. Imagine if you have more parameters, you'll soon have to use
several lines. I wish there was a way to set an attribute for all parameters
together or a shortcut. I'm considering whether to use a short macro to use in
place of it, but haven't yet decided.&lt;/p&gt;
&lt;p&gt;Just a note, if you have &lt;code&gt;else if&lt;/code&gt; statements, you need to set them as
&lt;code&gt;constexpr&lt;/code&gt; as well! This was a bit weird for me, but you can figure it as
if the condition is &lt;code&gt;constexpr&lt;/code&gt;, then the &lt;code&gt;if&lt;/code&gt; (or &lt;code&gt;else if&lt;/code&gt;)
is &lt;code&gt;constexpr&lt;/code&gt; as well.&lt;/p&gt;
&lt;p&gt;Overall, I'm really satisfied with the new &lt;cite&gt;if constexpr&lt;/cite&gt;! This really makes the
code much nicer in many cases, especially if you abuse metaprogramming like
I do.&lt;/p&gt;
&lt;p&gt;You may remember that I've &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2015/07/simulate-static_if-with-c11c14.html"&gt;coded a version of static if in the past with C++14&lt;/a&gt; in the past. This was able to solve point 2, but not point 1 and was much uglier. Now we have a good solution to it. I've replaced two of these in the current code with the new &lt;code&gt;if constexpr&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="fold-expressions"&gt;
&lt;h2&gt;Fold expressions&lt;/h2&gt;
&lt;p&gt;For me, fold expressions is the second major feature of C++17. I wont' go into
too much details here, since
&lt;a class="reference external" href="https://baptiste-wicht.com/posts/2015/05/cpp17-fold-expressions.html"&gt;I've already talked about fold expression in the past&lt;/a&gt;
. But I'll show two examples of refactorings I've been able to do with this.&lt;/p&gt;
&lt;p&gt;Here was the size() function of a static matrix in ETL before:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_1633bf0d7c2943cfbafb5e13312fb649-1" name="rest_code_1633bf0d7c2943cfbafb5e13312fb649-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_1633bf0d7c2943cfbafb5e13312fb649-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_1633bf0d7c2943cfbafb5e13312fb649-2" name="rest_code_1633bf0d7c2943cfbafb5e13312fb649-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_1633bf0d7c2943cfbafb5e13312fb649-2"&gt;&lt;/a&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mul_all&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Dims&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_1633bf0d7c2943cfbafb5e13312fb649-3" name="rest_code_1633bf0d7c2943cfbafb5e13312fb649-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_1633bf0d7c2943cfbafb5e13312fb649-3"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The Dims parameter pack from the declaration of fast_matrix:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_74ab20596a3246a29dcf1674a4447f11-1" name="rest_code_74ab20596a3246a29dcf1674a4447f11-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_74ab20596a3246a29dcf1674a4447f11-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dims&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_74ab20596a3246a29dcf1674a4447f11-2" name="rest_code_74ab20596a3246a29dcf1674a4447f11-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_74ab20596a3246a29dcf1674a4447f11-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;fast_matrix_impl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the mul_all is a simple helper that multiplies each value of the variadic
parameter pack:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_5bb7f4c4cac8480182fdcf2acc804619-1" name="rest_code_5bb7f4c4cac8480182fdcf2acc804619-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_5bb7f4c4cac8480182fdcf2acc804619-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dims&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_5bb7f4c4cac8480182fdcf2acc804619-2" name="rest_code_5bb7f4c4cac8480182fdcf2acc804619-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_5bb7f4c4cac8480182fdcf2acc804619-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;mul_all_impl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;integral_constant&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mul_all_impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Dims&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;::&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
&lt;a id="rest_code_5bb7f4c4cac8480182fdcf2acc804619-3" name="rest_code_5bb7f4c4cac8480182fdcf2acc804619-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_5bb7f4c4cac8480182fdcf2acc804619-3"&gt;&lt;/a&gt;
&lt;a id="rest_code_5bb7f4c4cac8480182fdcf2acc804619-4" name="rest_code_5bb7f4c4cac8480182fdcf2acc804619-4" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_5bb7f4c4cac8480182fdcf2acc804619-4"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_5bb7f4c4cac8480182fdcf2acc804619-5" name="rest_code_5bb7f4c4cac8480182fdcf2acc804619-5" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_5bb7f4c4cac8480182fdcf2acc804619-5"&gt;&lt;/a&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;mul_all_impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;final&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;integral_constant&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
&lt;a id="rest_code_5bb7f4c4cac8480182fdcf2acc804619-6" name="rest_code_5bb7f4c4cac8480182fdcf2acc804619-6" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_5bb7f4c4cac8480182fdcf2acc804619-6"&gt;&lt;/a&gt;
&lt;a id="rest_code_5bb7f4c4cac8480182fdcf2acc804619-7" name="rest_code_5bb7f4c4cac8480182fdcf2acc804619-7" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_5bb7f4c4cac8480182fdcf2acc804619-7"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dims&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_5bb7f4c4cac8480182fdcf2acc804619-8" name="rest_code_5bb7f4c4cac8480182fdcf2acc804619-8" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_5bb7f4c4cac8480182fdcf2acc804619-8"&gt;&lt;/a&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mul_all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mul_all_impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dims&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;::&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Before C++17, the only way to compute this result at compilation time was to use
template recursion, either with types or with constexpr functions. I think this
is pretty heavy only for doing a multiplication sum. Now, with fold expressions,
we can manipulate the parameter pack directly and rewrite our size function:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_f909226d2c774072b07c43027cee4afd-1" name="rest_code_f909226d2c774072b07c43027cee4afd-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f909226d2c774072b07c43027cee4afd-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_f909226d2c774072b07c43027cee4afd-2" name="rest_code_f909226d2c774072b07c43027cee4afd-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f909226d2c774072b07c43027cee4afd-2"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Dims&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...);&lt;/span&gt;
&lt;a id="rest_code_f909226d2c774072b07c43027cee4afd-3" name="rest_code_f909226d2c774072b07c43027cee4afd-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_f909226d2c774072b07c43027cee4afd-3"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is much better! This clearly states that each value of the parameter should
be multiplied together. For instance &lt;code&gt;1,2,3&lt;/code&gt; will become &lt;code&gt;(1*2)*3&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Another place where I was using this was to code a traits that tests if a set of
boolean are all true at compilation-time:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_1117a5fb48184e758caed786b50e9ef1-1" name="rest_code_1117a5fb48184e758caed786b50e9ef1-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_1117a5fb48184e758caed786b50e9ef1-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_1117a5fb48184e758caed786b50e9ef1-2" name="rest_code_1117a5fb48184e758caed786b50e9ef1-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_1117a5fb48184e758caed786b50e9ef1-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;and_v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;is_same&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;a id="rest_code_1117a5fb48184e758caed786b50e9ef1-3" name="rest_code_1117a5fb48184e758caed786b50e9ef1-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_1117a5fb48184e758caed786b50e9ef1-3"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tmp_detail&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;bool_list&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_1117a5fb48184e758caed786b50e9ef1-4" name="rest_code_1117a5fb48184e758caed786b50e9ef1-4" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_1117a5fb48184e758caed786b50e9ef1-4"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cpp&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tmp_detail&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;bool_list&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;...,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;::&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I was using a nice trick here to test if all booleans are true. I don't remember
where I picked it up, but it's quite nice and very fast to compile.&lt;/p&gt;
&lt;p&gt;This was used for instance to test that a set of expressions are all
single-precision floating points:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_d7b89cc7418b4ec7967a3ce60f05afcd-1" name="rest_code_d7b89cc7418b4ec7967a3ce60f05afcd-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_d7b89cc7418b4ec7967a3ce60f05afcd-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_d7b89cc7418b4ec7967a3ce60f05afcd-2" name="rest_code_d7b89cc7418b4ec7967a3ce60f05afcd-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_d7b89cc7418b4ec7967a3ce60f05afcd-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;all_single_precision&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;and_v&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_single_precision&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)...&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, we can get rid of the and_v traits and use directly the parameter pack
directly:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_2e9c377eb341487b8d4dc0f1bc8596ff-1" name="rest_code_2e9c377eb341487b8d4dc0f1bc8596ff-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_2e9c377eb341487b8d4dc0f1bc8596ff-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_2e9c377eb341487b8d4dc0f1bc8596ff-2" name="rest_code_2e9c377eb341487b8d4dc0f1bc8596ff-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_2e9c377eb341487b8d4dc0f1bc8596ff-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;all_single_precision&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_single_precision&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I think using fold expressions results in much clearer syntax and better code
and it's a pretty nice feature overall :)&lt;/p&gt;
&lt;p&gt;As a note here, I'd like to mention, that you can also use this syntax to call
a function on each argument that you have, which makes for much nicer syntax as
well and I'll be using that in DLL once I migrate it to C++17.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="miscellaneous"&gt;
&lt;h2&gt;Miscellaneous&lt;/h2&gt;
&lt;p&gt;There are also a few more C++17 features that I've used to improve ETL, but that
have a bit less impact.&lt;/p&gt;
&lt;p&gt;A very nice feature of C++17 is the support for structured bindings. Often you
end up with a function that returns several parts of information in the form of
a pair or a tuple or even a fixed-size array. You can use an object for this,
but if you don't, you end up with code that is not terribly nice:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_28b0de5a904a4b1095556ede1fff1ab8-1" name="rest_code_28b0de5a904a4b1095556ede1fff1ab8-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_28b0de5a904a4b1095556ede1fff1ab8-1"&gt;&lt;/a&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_28b0de5a904a4b1095556ede1fff1ab8-2" name="rest_code_28b0de5a904a4b1095556ede1fff1ab8-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_28b0de5a904a4b1095556ede1fff1ab8-2"&gt;&lt;/a&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_28b0de5a904a4b1095556ede1fff1ab8-3" name="rest_code_28b0de5a904a4b1095556ede1fff1ab8-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_28b0de5a904a4b1095556ede1fff1ab8-3"&gt;&lt;/a&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_28b0de5a904a4b1095556ede1fff1ab8-4" name="rest_code_28b0de5a904a4b1095556ede1fff1ab8-4" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_28b0de5a904a4b1095556ede1fff1ab8-4"&gt;&lt;/a&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;tie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;my_function&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It's not terribly bad, but in these cases, you should be be hoping for something
better. With c++17, you can do better:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_5b13d0c8b01c4a4eba0c76d32142dc14-1" name="rest_code_5b13d0c8b01c4a4eba0c76d32142dc14-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_5b13d0c8b01c4a4eba0c76d32142dc14-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;my_function&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you can directly use auto to deduce the types of the three variables at once
and you can get all the results in the variables at once as well :) I think this
is really nice and can really profit some projects. In ETL, I've almost no use
for this, but I'm going to be using that a bit more in DLL.&lt;/p&gt;
&lt;p&gt;Something really nice to clean up the code in C++17 is the ability to declared
nested namespaces in one line. Before, you have a nested namespace
etl::impl::standard for instance, you would do:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_b389e811c69e4e6c9bd67f236efa03d4-1" name="rest_code_b389e811c69e4e6c9bd67f236efa03d4-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b389e811c69e4e6c9bd67f236efa03d4-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;etl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_b389e811c69e4e6c9bd67f236efa03d4-2" name="rest_code_b389e811c69e4e6c9bd67f236efa03d4-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b389e811c69e4e6c9bd67f236efa03d4-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;impl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_b389e811c69e4e6c9bd67f236efa03d4-3" name="rest_code_b389e811c69e4e6c9bd67f236efa03d4-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b389e811c69e4e6c9bd67f236efa03d4-3"&gt;&lt;/a&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;standard&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_b389e811c69e4e6c9bd67f236efa03d4-4" name="rest_code_b389e811c69e4e6c9bd67f236efa03d4-4" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b389e811c69e4e6c9bd67f236efa03d4-4"&gt;&lt;/a&gt;
&lt;a id="rest_code_b389e811c69e4e6c9bd67f236efa03d4-5" name="rest_code_b389e811c69e4e6c9bd67f236efa03d4-5" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b389e811c69e4e6c9bd67f236efa03d4-5"&gt;&lt;/a&gt;&lt;span class="c1"&gt;// Someting inside etl::impl::standard&lt;/span&gt;
&lt;a id="rest_code_b389e811c69e4e6c9bd67f236efa03d4-6" name="rest_code_b389e811c69e4e6c9bd67f236efa03d4-6" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b389e811c69e4e6c9bd67f236efa03d4-6"&gt;&lt;/a&gt;
&lt;a id="rest_code_b389e811c69e4e6c9bd67f236efa03d4-7" name="rest_code_b389e811c69e4e6c9bd67f236efa03d4-7" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b389e811c69e4e6c9bd67f236efa03d4-7"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// end of namespace standard&lt;/span&gt;
&lt;a id="rest_code_b389e811c69e4e6c9bd67f236efa03d4-8" name="rest_code_b389e811c69e4e6c9bd67f236efa03d4-8" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b389e811c69e4e6c9bd67f236efa03d4-8"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// end of namespace impl&lt;/span&gt;
&lt;a id="rest_code_b389e811c69e4e6c9bd67f236efa03d4-9" name="rest_code_b389e811c69e4e6c9bd67f236efa03d4-9" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_b389e811c69e4e6c9bd67f236efa03d4-9"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// end of namespace etl&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In C++17, you can do:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_9232bb817cb44fc188a23b5aaf3ec60f-1" name="rest_code_9232bb817cb44fc188a23b5aaf3ec60f-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_9232bb817cb44fc188a23b5aaf3ec60f-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;etl&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;standard&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_9232bb817cb44fc188a23b5aaf3ec60f-2" name="rest_code_9232bb817cb44fc188a23b5aaf3ec60f-2" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_9232bb817cb44fc188a23b5aaf3ec60f-2"&gt;&lt;/a&gt;
&lt;a id="rest_code_9232bb817cb44fc188a23b5aaf3ec60f-3" name="rest_code_9232bb817cb44fc188a23b5aaf3ec60f-3" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_9232bb817cb44fc188a23b5aaf3ec60f-3"&gt;&lt;/a&gt;&lt;span class="c1"&gt;// Someting inside etl::impl::standard&lt;/span&gt;
&lt;a id="rest_code_9232bb817cb44fc188a23b5aaf3ec60f-4" name="rest_code_9232bb817cb44fc188a23b5aaf3ec60f-4" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_9232bb817cb44fc188a23b5aaf3ec60f-4"&gt;&lt;/a&gt;
&lt;a id="rest_code_9232bb817cb44fc188a23b5aaf3ec60f-5" name="rest_code_9232bb817cb44fc188a23b5aaf3ec60f-5" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_9232bb817cb44fc188a23b5aaf3ec60f-5"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// end of namespace etl::impl::standard&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I think it's pretty neat :)&lt;/p&gt;
&lt;p&gt;Another very small change is the ability to use the typename keyword in place of
the class keyword when declaring template template parameters. Before, you had
to declare:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_7d0684b51552428f9869d2b46ce751f9-1" name="rest_code_7d0684b51552428f9869d2b46ce751f9-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_7d0684b51552428f9869d2b46ce751f9-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;X&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;now you can also use:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_af681ae932074853894c896784c04c4e-1" name="rest_code_af681ae932074853894c896784c04c4e-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_af681ae932074853894c896784c04c4e-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;typename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;X&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It's just some syntactic sugar, but I think it's quite nice.&lt;/p&gt;
&lt;p&gt;The last improvement that I want to talk about is one that probably very few
know about but it's pretty neat. Since C++11, you can use the &lt;code&gt;alignas(X)&lt;/code&gt;
specifier for types and objects to specify on how many bytes you want to align
these. This is pretty nice if you want to align on the stack. However, this
won't always work for dynamic memory allocation. Imagine this struct:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_c233a40a3c524a1093fadd235148b401-1" name="rest_code_c233a40a3c524a1093fadd235148b401-1" href="https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html#rest_code_c233a40a3c524a1093fadd235148b401-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;alignas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;test_struct&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you declare an object of this type on the stack, you have the guarantee that
it will be aligned on 128 bytes. However, if you use &lt;code&gt;new&lt;/code&gt; to allocate it
on the heap, you don't have such guarantee. Indeed, the problem is that 128 is
greater than the maximum default alignment. This is called an over-aligned type.
In such cases, the result will be aligned on the max alignment of your system.
Since C++17, &lt;code&gt;new&lt;/code&gt; supports aligned dynamic memory allocation of
over-aligned types. Therefore, you can use a simple &lt;code&gt;alignas&lt;/code&gt; to allocate
dynamic over-aligned types :) I need this in ETL for matrices that need to be
aligned for vectorized code. Before, I was using a larger array with some
padding in order to find an aligned element inside, but that is not very nice,
now the code is much better.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="compilation-time"&gt;
&lt;h2&gt;Compilation Time&lt;/h2&gt;
&lt;p&gt;I've done a few tests to see how much impact these news features have on
compilation time. Here, I'm doing benchmark on compiling the entire test suite
in different compilation mode, I enabled most compilation options (all GPU and
BLAS options in order to make sure almost all of the library is compiled).&lt;/p&gt;
&lt;p&gt;Since I'm a bit short on time before going to vacation, I've only gathered the
results with g++. Here are the results with G++ 7.2.0&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;debug&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;release&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;release_debug&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;C++14&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;862s&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1961s&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1718s&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;C++17&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;892s&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2018s&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;1745s&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;p&gt;Difference&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;+3.4%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;+2.9%&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;+1.5%&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Overall, I'm a bit disappointed by these results, it's around 3% slower to
compile the C++17 version than the C++14 version. I was thinking that this would
a least be as fast to compile as before. It seems that currently with G++ 7.2,
&lt;code&gt;if constexpr&lt;/code&gt; are slower to compile than the equivalent SFINAE functions.
I didn't do individual benchmarks of all the features I've migrated, therefore,
it may not be coming from &lt;code&gt;if constexpr&lt;/code&gt;, but since it's the greatest
change by far, it's the more likely candidate. Once I'll have a little more
time, after my vacations, I'll try to see if that is also the case with clang.&lt;/p&gt;
&lt;p&gt;Keep in mind that we are compiling the test suite here. The ETL test suite is
using the manual selection mode of the library in order to be able to test all
the possible implementations of each operation. This makes a considerable
difference in performance. I expect better compilation time when this is used in
automatic selection mode (the default mode). In the default mode, a lot more
code can be disabled with &lt;code&gt;if constexpr&lt;/code&gt;. I will test this next with the
DLL library which I will also migrate to C++17.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This concludes this report on the migration of my ETL library from C++14 to
C++17. Overall, I'm really satisfied with the improvement of the code, it's much
better. I'm a bit disappointed by the slight increase  (around 3%) in
compilation time, but it's not dramatic either. I'm still hoping that once it's
used in DLL, I will see a decrease in compilation, but we'll see that when I'll
be done with the migration of DLL to C++17 which may take some time since I'll
have two weeks vacation in China starting Friday.&lt;/p&gt;
&lt;p&gt;The new version is available only through the &lt;em&gt;master&lt;/em&gt; branch. It will be
released as the 1.3 version probably when I integrate some new features, but in
itself will not be released as new version. You can take a look in the
&lt;a class="reference external" href="https://github.com/wichtounet/etl"&gt;Github etl repository&lt;/a&gt; if you are interested.&lt;/p&gt;
&lt;/section&gt;</description><category>C++</category><category>C++14</category><category>C++17</category><category>etl</category><category>projects</category><guid>https://baptiste-wicht.com/posts/2018/02/c%2B%2B17-migration-of-expression-templates-library-etl.html</guid><pubDate>Fri, 02 Feb 2018 13:03:26 GMT</pubDate></item><item><title>budgetwarrior 1.0: Web interface and asset tracking!</title><link>https://baptiste-wicht.com/posts/2018/01/budgetwarrior-10-web-interface-and-asset-tracking.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I'm happy to announce the release of budgetwarrior 1.0. This is a major change
over the previous version.&lt;/p&gt;
&lt;section id="web-interface"&gt;
&lt;h2&gt;Web Interface&lt;/h2&gt;
&lt;p&gt;Until now, budgetwarrior could only be used in command line. This is fine for
me, but not for every body. Since I wanted to share my budget with my
girlfriend, I needed something less nerdy ;)&lt;/p&gt;
&lt;p&gt;Therefore, I added support for &lt;em&gt;a web interface for budgetwarrior&lt;/em&gt;. Every feature
of the console application is now available in the web version. Moreover, since
the web version offers &lt;em&gt;slightly better&lt;/em&gt; graphical capabilities, I added a few
more graphs and somewhat more information at some places. I'm not nearly an
expert in web interface, but I think I managed to get something not too bad
together. There are still some things to improve that I'll go through in the
future but so far the web interface is pretty satisfying and it is &lt;strong&gt;mobile friendly&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;The web server is coded in C++ (who would have guessed...) and is embedded in
the application, you need to use the command &lt;strong&gt;server&lt;/strong&gt; to use it:&lt;/p&gt;
&lt;pre class="literal-block"&gt;budget server&lt;/pre&gt;
&lt;p&gt;and the server will be launched (by default at localhost:8080). You can
configure the port with &lt;code&gt;server_port=X&lt;/code&gt; in the configuration file and the
listen address with &lt;code&gt;server_listen=X&lt;/code&gt;. You can access your server at
&lt;a class="reference external" href="http://localhost:8080"&gt;http://localhost:8080&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here is what this will display:&lt;/p&gt;
&lt;img alt="Web interface index" src="https://baptiste-wicht.com/images/budgetwarrior_web_index.png"&gt;
&lt;p&gt;Note: All the data is randomized&lt;/p&gt;
&lt;p&gt;The main page shows your assets, the current net worth, your monthly cash-flow
and the state of your objectives.&lt;/p&gt;
&lt;p&gt;The menu will give you access to all the features of the application. You can
add expenses and earnings, see reports, manage your assets and your objectives
and so on. Basically, you can do everything you did in the application, but you
have access to more visualization tools than you would on the console. For
instance, you can access your fortune over time:&lt;/p&gt;
&lt;img alt="Web interface fortune graph" src="https://baptiste-wicht.com/images/budgetwarrior_web_fortune.png"&gt;
&lt;p&gt;or see how your portfolio does in terms of currency:&lt;/p&gt;
&lt;img alt="Web interface portofolio currency breakdown" src="https://baptiste-wicht.com/images/budgetwarrior_web_portfolio_currency.png"&gt;
&lt;p&gt;Normally, unless I forgot something (in which case, I'll fix it), everything
should be doable from the web interface. This is simply easier people that are
not as nerdy as me for console ;)&lt;/p&gt;
&lt;p&gt;The management is still the same, the server will write to the same file the
base application uses. Therefore, you cannot use the server and the command line
application on the same machine at the same time. Nevertheless, if the server is
not running, you can still use the command line application. This could be
useful if you want to use the web visualization while still using the command
line tool for managing the budget.&lt;/p&gt;
&lt;p&gt;The default user and password is admin:1234, but you of course change it using
web_password and web_user in the configuration. You can also disable the
security if you are sure of yourself by setting &lt;code&gt;server_secure=true&lt;/code&gt; in
the configuration. The server currently does not support&lt;/p&gt;
&lt;p&gt;Currently, it does not protect against concurrent modifications of the same
data. It is very unlikely to happen with only a few people using the
applications, but I plan to improve that in the future.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="server-mode"&gt;
&lt;h2&gt;Server mode&lt;/h2&gt;
&lt;p&gt;Although it's not possible to use both the server and the command line
application at the same time, it's possible to use the command line application
in server mode. In this case, instead of reading and writing the data from the
hard disk, the application will send requests to the server to read and write
the data it needs. With this, you can use both the server and the command line
application at the same time!&lt;/p&gt;
&lt;p&gt;While running, the server exposes a simple API that can be used to get
all the information about the budget data and that can also be used to add new
expenses, earnings and so on directly to the server data. The API is also
protected by authentication.&lt;/p&gt;
&lt;p&gt;Currently, the server does not support HTTPS. However, you can run it behind
a proxy such as nginx which is running in HTTPS. This is what I'm doing. The
server mode supports SSL from the client to the server, you just have to set
&lt;code&gt;server_sll=true&lt;/code&gt; in the configuration.&lt;/p&gt;
&lt;p&gt;This is the mode I'm currently using and will continue using. With this, I can
quickly do some modifications using the command line and if I want to see
advanced visualization, I just have to open my browser and everything is
updated. Moreover, in the future, other people involved with my budget will be
able to access the web interface. This also solves the synchronization problem
in a much better way than before.&lt;/p&gt;
&lt;p&gt;Just as it was the case with the server, this is not made to be used in parallel
by different users. This should be perfectly fine for a small household.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="assets-tracking"&gt;
&lt;h2&gt;Assets Tracking&lt;/h2&gt;
&lt;p&gt;Already a few months ago, I've added &lt;cite&gt;the feature to track assets &amp;lt;https://baptiste-wicht.com/posts/2017/10/budgetwarrior-track-assets-portfolio-savings-rates-auto-completion.html&amp;gt; `_ into budgetwarrior. You can define the list of the assets you possess. The tool will then help you track the value of your assets. You can set your desired distribution of bonds, cash and stocks and the tool will help you see if you need to rebalance your assets. This will let you compute your net worth, with :code:`budget asset value&lt;/cite&gt;:&lt;/p&gt;
&lt;img alt="View of your assets" src="https://baptiste-wicht.com/images/budgetwarrior_asset_values.png"&gt;
&lt;p&gt;Moreover, you can also set a few of your assets as your portfolio assets. These
assets have a desired distribution and are handled different. These are the
assets you directly manage yourself, your investment portfolio. You can then
track their value and see if they need rebalancing. For instance, here is
a randomized rebalancing of your portfolio, with &lt;code&gt;budget asset rebalance&lt;/code&gt;:&lt;/p&gt;
&lt;img alt="View of the needed rebalance" src="https://baptiste-wicht.com/images/budgetwarrior_rebalance.png"&gt;
&lt;p&gt;All these features are now also available on the web version as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="better-console-usability"&gt;
&lt;h2&gt;Better console usability&lt;/h2&gt;
&lt;p&gt;A few months ago, I added some &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/10/budgetwarrior-track-assets-portfolio-savings-rates-auto-completion.html"&gt;quality-of-life improvements to the console appplication&lt;/a&gt;. You can now cycle through the list of possible values for accounts for instance in the console! This is down with the UP and DOWN keys. Now, I also added auto-completion with TAB key. You can write Ins&amp;lt;TAB&amp;gt; and it will complete to Insurances if you have an Insurances account in your budget. This makes it much faster to enter new expenses or to update asset values.&lt;/p&gt;
&lt;section id="installation"&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;p&gt;If you are on Gentoo, you can install it using layman:&lt;/p&gt;
&lt;pre class="literal-block"&gt;layman -a wichtounet
emerge -a budgetwarrior&lt;/pre&gt;
&lt;p&gt;If you are on Arch Linux, you can use this &lt;cite&gt;AUR repository
&amp;lt;https://github.com/StreakyCobra/aur&amp;gt;&lt;/cite&gt; (wait a few day for the new version to be
updated)_&lt;/p&gt;
&lt;p&gt;For other systems, you'll have to install from sources:&lt;/p&gt;
&lt;pre class="literal-block"&gt;git clone --recursive git://github.com/wichtounet/budgetwarrior.git
cd budgetwarrior
git checkout 1.0
make
sudo make install&lt;/pre&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Overall, even though I'm not a fan of web development, it was quite fun to add
all these features to budgetwarrior and made it much better I think. This is
a very significant change to the project since it almost doubled in number of
source lines of code, but I think it's a change that was needed.&lt;/p&gt;
&lt;p&gt;I think these changes really make budgetwarrior more useful to a wider group of
people and I'm pretty to have finally come around and implemented them. I still
have a few things I plan to improve in the near future. First, I want to make
the website a bit faster, there are many scripts and stylesheets that are being
loaded and make the site a bit bloated. I'll also enable gzip compression of the
website to speed up things. I will also ensure that the server can handle
requests concurrently without any problem of the data (should be simple since we
don't need high performance). I may also add a new module to budgetwarrior to
track your progress towards retirement if this is something you are interested
in, but I haven't decided in what form exactly. Finally, I will also try to
optimize the requests that are being done between the server and the client when
run in server mode. Indeed, it currently downloads almost all the data from the
server which is far from optimal.&lt;/p&gt;
&lt;p&gt;If you are interested by the sources, you can download them on Github:
&lt;a class="reference external" href="https://github.com/wichtounet/budgetwarrior"&gt;budgetwarrior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have a suggestion or you found a bug, please post an issue on Github.&lt;/p&gt;
&lt;p&gt;If you have any comment, don't hesitate to contact me, either by letting a
comment on this post or by email.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;</description><category>budgetwarrior</category><category>C++</category><category>projects</category><category>Release</category><guid>https://baptiste-wicht.com/posts/2018/01/budgetwarrior-10-web-interface-and-asset-tracking.html</guid><pubDate>Fri, 26 Jan 2018 11:52:31 GMT</pubDate></item><item><title>My thesis is available: Deep Learning Feature Extraction for Image Processing</title><link>https://baptiste-wicht.com/posts/2018/01/my-thesis-is-available-deep-learning-feature-extraction-for-image-processing.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I'm happy to say that I've finally put my thesis online and updated
my &lt;a class="reference external" href="https://baptiste-wicht.com/stories/publications.html"&gt;Publications&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;I should have done that earlier but it slipped my mind, so there it is!&lt;/p&gt;
&lt;p&gt;My thesis (Deep Learning Feature Extraction for Image Processing) is now
available to download.  Here is the abstract of the thesis:&lt;/p&gt;
&lt;p&gt;In this thesis, we propose to use methodologies that automatically learn how to
extract relevant features from images. We are especially interested in
evaluating how these features compare against handcrafted features. More
precisely, we are interested in the unsupervised training that is used for the
Restricted Boltzmann Machine (RBM) and Convolutional RBM (CRBM) models. These
models relaunched the Deep Learning interest of the last decade. During the time
of this thesis, the auto-encoders approach, especially Convolutional
Auto-Encoders (CAE) have been used more and more. Therefore, one objective of
this thesis is also to compare the CRBM approach with the CAE approach.&lt;/p&gt;
&lt;p&gt;The scope of this work is defined by several machine learning tasks. The first
one, handwritten digit recognition, is analysed to see how much the unsupervised
pretraining technique introduced with the Deep Belief Network (DBN) model
improves the training of neural networks. The second, detection and recognition
of Sudoku in images, is evaluating the efficiency of DBN and Convolutional DBN
(CDBN) models for classification of images of poor quality. Finally, features
are learned fully unsupervised from images for a keyword spotting task and are
compared against well-known handcrafted features. Moreover, the thesis was also
oriented around a software engineering axis. Indeed, a complete machine learning
framework was developed during this thesis to explore possible optimizations and
possible algorithms in order to train the tested models as fast as possible.&lt;/p&gt;
&lt;p&gt;If you are interested, you can:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.researchgate.net/publication/322505397_Deep_Learning_feature_Extraction_for_Image_Processing"&gt;Read it on ResearchGate&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://baptiste-wicht.com/publication_store/phd_thesis.pdf"&gt;Directly download the PDF&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope this will interest a few of you! As always, if you have any question,
don't hesitate to let me a comment ;)&lt;/p&gt;
&lt;p&gt;As for the current projects, I'm still currently working on the next version of
budgetwarrior, but I don't have any expected release date. It will depend on
much time I'm able to put to the project.&lt;/p&gt;</description><category>crbm</category><category>dll</category><category>Machine Learning</category><category>Personal</category><category>projects</category><category>publications</category><category>rbm</category><guid>https://baptiste-wicht.com/posts/2018/01/my-thesis-is-available-deep-learning-feature-extraction-for-image-processing.html</guid><pubDate>Mon, 15 Jan 2018 14:11:57 GMT</pubDate></item><item><title>Expression Templates Library 1.2.1: Faster GPU and new features</title><link>https://baptiste-wicht.com/posts/2018/01/expression-templates-library-121-faster-gpu-and-new-features.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;Happy new year to all my dear readers!&lt;/p&gt;
&lt;p&gt;It has been a while since I've posted on this blog. I've had to serve three
weeks in the army and then I had two weeks vacation. I've been actively working
on budgetwarrior with a brand new web interface! More on that later ;)&lt;/p&gt;
&lt;p&gt;Today, I'm happy to release the version 1.2.1 of my Expression Templates Library
(ETL) project. This is a minor version but with significantly better GPU support
and a few new features and bug fixes so I decided to release it now.&lt;/p&gt;
&lt;section id="faster-gpu-support"&gt;
&lt;h2&gt;Faster GPU support&lt;/h2&gt;
&lt;p&gt;Last year, I &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html"&gt;implemented the support for the detection of advanced GPU patterns in ETL&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This will significantly reduce the number of CUDA kernel calls that are being
launched. For instance, each of the following expressions will be evaluated
using a single GPU kernel:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code C++"&gt;&lt;a id="rest_code_e7535cefc1294756a6899aac35ad17bd-1" name="rest_code_e7535cefc1294756a6899aac35ad17bd-1" href="https://baptiste-wicht.com/posts/2018/01/expression-templates-library-121-faster-gpu-and-new-features.html#rest_code_e7535cefc1294756a6899aac35ad17bd-1"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;a id="rest_code_e7535cefc1294756a6899aac35ad17bd-2" name="rest_code_e7535cefc1294756a6899aac35ad17bd-2" href="https://baptiste-wicht.com/posts/2018/01/expression-templates-library-121-faster-gpu-and-new-features.html#rest_code_e7535cefc1294756a6899aac35ad17bd-2"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;a id="rest_code_e7535cefc1294756a6899aac35ad17bd-3" name="rest_code_e7535cefc1294756a6899aac35ad17bd-3" href="https://baptiste-wicht.com/posts/2018/01/expression-templates-library-121-faster-gpu-and-new-features.html#rest_code_e7535cefc1294756a6899aac35ad17bd-3"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;a id="rest_code_e7535cefc1294756a6899aac35ad17bd-4" name="rest_code_e7535cefc1294756a6899aac35ad17bd-4" href="https://baptiste-wicht.com/posts/2018/01/expression-templates-library-121-faster-gpu-and-new-features.html#rest_code_e7535cefc1294756a6899aac35ad17bd-4"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;a id="rest_code_e7535cefc1294756a6899aac35ad17bd-5" name="rest_code_e7535cefc1294756a6899aac35ad17bd-5" href="https://baptiste-wicht.com/posts/2018/01/expression-templates-library-121-faster-gpu-and-new-features.html#rest_code_e7535cefc1294756a6899aac35ad17bd-5"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This makes some operation significantly faster.&lt;/p&gt;
&lt;p&gt;Moreover, I've reduced a lot the numbers of device synchronization in the
library. Especially, I've removed almost all synchronization from the
etl-gpu-blas sub library. This means that synchronization is mostly only done
when data needs to go back to the CPU. For machine learning, this means at the
end of the epoch to compute the final error. This makes a HUGE difference in
time, I didn't realize before that I was doing way too much synchronization.&lt;/p&gt;
&lt;p&gt;With these two changes, I've been able to attain &lt;em&gt;state of the art training performance on GPU&lt;/em&gt; with my Deep Learning Library (DLL) project!&lt;/p&gt;
&lt;p&gt;Moreover, I've now added for random number generations on the GPU and for
shuffle operations as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="new-features"&gt;
&lt;h2&gt;New Features&lt;/h2&gt;
&lt;p&gt;I've also added a few new features recently. They were especially added to
support new features in DLL.&lt;/p&gt;
&lt;p&gt;Matrices and vectors can now be normalized in order to have zero-mean and
unit-variance distribution. You can also merge matrices together. For now, there
is no GPU support, so this will use CPU anyway. I plan to fix that later.&lt;/p&gt;
&lt;p&gt;In addition to bias_batch_mean that I added before, I also added bias_batch_var
now with the variance in place of the mean. This is mainly used for Batch
Normalization in machine learning, but it may have some other usages. The GPU
support has been added as well directly.&lt;/p&gt;
&lt;p&gt;And the last feature is the support for embedding and the gradients of
embedding. Again this is totally related to machine learning, but can be very
useful as well. I haven't add the time to develop the GPU version so far, but
this will come as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance"&gt;
&lt;h2&gt;Performance&lt;/h2&gt;
&lt;p&gt;Nothing fancy on the CPU performance side, I only added vectorization for
hyperbolic versions. This makes &lt;em&gt;tanh much faster on CPU&lt;/em&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="bug-fixes"&gt;
&lt;h2&gt;Bug Fixes&lt;/h2&gt;
&lt;p&gt;I fixed quite a few bugs in this version, which is one of the main reason
I released it:&lt;/p&gt;
&lt;p&gt;1. When using large fast_matrix and aliasing was detected, there was a big chance of stack overflow occurring. This is now fixed by using a dynamic temporary.
1. Some assignables such sub_view did not perform any detection for aliasing. This is now fixed and aliasing is detected everywhere.
1. fast_dyn_matrix can now be correctly used with &lt;em&gt;bool&lt;/em&gt;
1. The use of iterators was not always ensuring correct CPU/GPU consistency. This is now correctly handled.
1. The 4D convolution in GPU were not using the correct flipping
1. Fix small compilation bug with sub_matrix and GPU&lt;/p&gt;
&lt;/section&gt;
&lt;section id="what-s-next"&gt;
&lt;h2&gt;What's next ?&lt;/h2&gt;
&lt;p&gt;I don't really know what will be in the next release. This should be the release
1.3. One possible idea would be to improve and review the support for sparse
matrix which is more than  poor as of now. But I'm not really motivated to
work on that :P Moreover, I'm now &lt;em&gt;actively&lt;/em&gt; working on the next release of
budgetwarrior which will probably still come this month.&lt;/p&gt;
&lt;p&gt;I'm also still hesitating in switching to C++17 for the library to make it
faster to compile. And also to clean some parts of the code. I would be able to
remove quite some SFINAE with the new &lt;em&gt;if constexpr&lt;/em&gt;, but I'm afraid this will
make the library to difficult to use since it would need at least GCC 7 or clang
3.9.&lt;/p&gt;
&lt;section id="download-etl"&gt;
&lt;h3&gt;Download ETL&lt;/h3&gt;
&lt;p&gt;You can download ETL &lt;a class="reference external" href="https://github.com/wichtounet/etl"&gt;on Github&lt;/a&gt;. If you
only interested in the 1.2.1 version, you can look at the
&lt;a class="reference external" href="https://github.com/wichtounet/etl/releases"&gt;Releases pages&lt;/a&gt; or clone the tag
1.2.1. There are several branches:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;master&lt;/em&gt; Is the eternal development branch, may not always be stable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;stable&lt;/em&gt; Is a branch always pointing to the last tag, no development here&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the future release, there always will tags pointing to the corresponding
commits. You can also have access to previous releases on Github or via the
release tags.&lt;/p&gt;
&lt;p&gt;The documentation is still a bit sparse. There are a few examples and the Wiki,
but there still is work to be done. If you have questions on how to use or
configure the library, please don't hesitate.&lt;/p&gt;
&lt;p&gt;Don't hesitate to comment this post if you have any comment on this library or
any question. You can also open an Issue on Github if you have a problem using
this library or propose a Pull Request if you have any contribution you'd like
to make to the library.&lt;/p&gt;
&lt;p&gt;Hope this may be useful to some of you :)&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;</description><category>C++</category><category>C++14</category><category>C++17</category><category>etl</category><category>GPU</category><category>Performance</category><category>projects</category><category>Releases</category><guid>https://baptiste-wicht.com/posts/2018/01/expression-templates-library-121-faster-gpu-and-new-features.html</guid><pubDate>Tue, 09 Jan 2018 10:06:15 GMT</pubDate></item><item><title>Advanced GPU Patterns Optimization in ETL</title><link>https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;The GPU performance of my Expression Templates Library (ETL) is pretty good when
most of the time is spent inside expensive operations such as Matrix-Matrix
Multiplication or convolutions. However, when most of the time is spent in
linear kernels, performance is not great because this will invoke a lot of CUDA
kernels. Indeed, the way it is done is that each sub expressions compute its
result in a temporary GPU vector (or matrix) and these temporaries are passed
through the expressions. For instance, this expression:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code C++"&gt;&lt;a id="rest_code_46f2f90e062e4a4d8c0a3f6b428574bb-1" name="rest_code_46f2f90e062e4a4d8c0a3f6b428574bb-1" href="https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html#rest_code_46f2f90e062e4a4d8c0a3f6b428574bb-1"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;will be executed on the GPU as something like this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code C++"&gt;&lt;a id="rest_code_46f412de6c4d48c3aee31d7a73ed425e-1" name="rest_code_46f412de6c4d48c3aee31d7a73ed425e-1" href="https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html#rest_code_46f412de6c4d48c3aee31d7a73ed425e-1"&gt;&lt;/a&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;
&lt;a id="rest_code_46f412de6c4d48c3aee31d7a73ed425e-2" name="rest_code_46f412de6c4d48c3aee31d7a73ed425e-2" href="https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html#rest_code_46f412de6c4d48c3aee31d7a73ed425e-2"&gt;&lt;/a&gt;&lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;a id="rest_code_46f412de6c4d48c3aee31d7a73ed425e-3" name="rest_code_46f412de6c4d48c3aee31d7a73ed425e-3" href="https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html#rest_code_46f412de6c4d48c3aee31d7a73ed425e-3"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;that will results in three GPU kernels being invoked. In the CPU case, the
complete expression will be executed as one CPU kernel, that is constructed with
Expression Templates. Unfortunately, a CUDA kernel cannot be constructed in the
same way since the CUDA compiler does not support general template
metaprogramming. That's why I've implemented by using small kernels for each
expression.&lt;/p&gt;
&lt;p&gt;Fortunately, we can do better with a bit more meta-programming. Indeed, there
are some patterns that are repeated a lot and that easily be implemented in CUDA
kernels. I've started detecting a few of these patterns and for each of them
a single CUDA kernel is executed. For instance, each of the following
expressions can be executed with a single kernel:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code C++"&gt;&lt;a id="rest_code_dcc199d419b04cd69e08fa238cb5c8ae-1" name="rest_code_dcc199d419b04cd69e08fa238cb5c8ae-1" href="https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html#rest_code_dcc199d419b04cd69e08fa238cb5c8ae-1"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;a id="rest_code_dcc199d419b04cd69e08fa238cb5c8ae-2" name="rest_code_dcc199d419b04cd69e08fa238cb5c8ae-2" href="https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html#rest_code_dcc199d419b04cd69e08fa238cb5c8ae-2"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;a id="rest_code_dcc199d419b04cd69e08fa238cb5c8ae-3" name="rest_code_dcc199d419b04cd69e08fa238cb5c8ae-3" href="https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html#rest_code_dcc199d419b04cd69e08fa238cb5c8ae-3"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;a id="rest_code_dcc199d419b04cd69e08fa238cb5c8ae-4" name="rest_code_dcc199d419b04cd69e08fa238cb5c8ae-4" href="https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html#rest_code_dcc199d419b04cd69e08fa238cb5c8ae-4"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;a id="rest_code_dcc199d419b04cd69e08fa238cb5c8ae-5" name="rest_code_dcc199d419b04cd69e08fa238cb5c8ae-5" href="https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html#rest_code_dcc199d419b04cd69e08fa238cb5c8ae-5"&gt;&lt;/a&gt;&lt;span class="n"&gt;yy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This results in significantly performance improvement for these expressions!&lt;/p&gt;
&lt;p&gt;I have tested these new improvements in my Deep Learning Library (DLL) project
(not yet merged) and it resulted in &lt;strong&gt;25% faster momentum computation&lt;/strong&gt; and
&lt;strong&gt;17% faster Nesterov Adam (NADAM)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I'm going to continue to investigate which kernels need to be made faster for
DLL and try to improve the overall performance. Currently, the GPU performance
of DLL is very good for large convolutional networks, but could be improved for
small fully-connected networks. Indeed, in that case, quite some time is spent
outside the matrix-matrix multiplication and inside serial expressions for which
GPU could be improved. Once I'm done with my optimizations, I'll probably post
again on the blog with the latest results.&lt;/p&gt;
&lt;p&gt;All these new optimizations are now in the &lt;strong&gt;master&lt;/strong&gt; branch of the ETL
project if you want to check it out. You can access the project
&lt;a class="reference external" href="https://github.com/wichtounet/etl"&gt;on Github&lt;/a&gt;.&lt;/p&gt;</description><category>C++</category><category>dll</category><category>etl</category><category>GPU</category><category>Optimization</category><category>Performance</category><category>projects</category><guid>https://baptiste-wicht.com/posts/2017/11/advanced-gpu-patterns-optimization-in-etl.html</guid><pubDate>Sun, 26 Nov 2017 14:44:29 GMT</pubDate></item><item><title>Initial support for Long Short Term Memory (LSTM) in DLL</title><link>https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I'm really happy to announce that I just merged support for&lt;/p&gt;
&lt;p&gt;Long Short Term Memory
(LSTM) cells into my Deep Learning Library (DLL) machine learning framework. Two
weeks ago, &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html"&gt;I already merged suport for Recurrent Neural network (RNN)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It's nothing fancy yet, but forward propagation of LSTM and basic
Backpropagation Through Time (BPTT) are now supported. It was not really
complicated to implemenet the forward pass but the backward pass is much
complicated for an LSTM than for a RNN. It took me quite a long time to figure
out all the gradients formulas and the documentation on that is quite scarce.&lt;/p&gt;
&lt;p&gt;For now, still only existing classification loss is supported for RNN and LSTM.
As I said last time, I still plan to add support for sequence-to-sequence loss
in order to be able to train models able to generate characters. However, I don't
know when I'll be able to work on that. Now that I've got the code for LSTM,
I should be able to implement a GRU cell and NAS cell quite easily I believe.&lt;/p&gt;
&lt;p&gt;For example, here is a simple LSTM used on MNIST for classification:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-1" name="rest_code_440202f98df14c5cb1db75b67e65c78a-1" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-1"&gt;&lt;/a&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;"dll/neural/dense_layer.hpp"&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-2" name="rest_code_440202f98df14c5cb1db75b67e65c78a-2" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-2"&gt;&lt;/a&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;"dll/neural/lstm_layer.hpp"&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-3" name="rest_code_440202f98df14c5cb1db75b67e65c78a-3" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-3"&gt;&lt;/a&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;"dll/neural/recurrent_last_layer.hpp"&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-4" name="rest_code_440202f98df14c5cb1db75b67e65c78a-4" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-4"&gt;&lt;/a&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;"dll/network.hpp"&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-5" name="rest_code_440202f98df14c5cb1db75b67e65c78a-5" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-5"&gt;&lt;/a&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;"dll/datasets.hpp"&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-6" name="rest_code_440202f98df14c5cb1db75b67e65c78a-6" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-6"&gt;&lt;/a&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-7" name="rest_code_440202f98df14c5cb1db75b67e65c78a-7" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-7"&gt;&lt;/a&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/*argc*/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/*argv*/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-8" name="rest_code_440202f98df14c5cb1db75b67e65c78a-8" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-8"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Load the dataset&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-9" name="rest_code_440202f98df14c5cb1db75b67e65c78a-9" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-9"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;make_mnist_dataset_nc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;scale_pre&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{});&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-10" name="rest_code_440202f98df14c5cb1db75b67e65c78a-10" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-10"&gt;&lt;/a&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-11" name="rest_code_440202f98df14c5cb1db75b67e65c78a-11" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-11"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;time_steps&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-12" name="rest_code_440202f98df14c5cb1db75b67e65c78a-12" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-12"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sequence_length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-13" name="rest_code_440202f98df14c5cb1db75b67e65c78a-13" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-13"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hidden_units&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-14" name="rest_code_440202f98df14c5cb1db75b67e65c78a-14" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-14"&gt;&lt;/a&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-15" name="rest_code_440202f98df14c5cb1db75b67e65c78a-15" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-15"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Build the network&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-16" name="rest_code_440202f98df14c5cb1db75b67e65c78a-16" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-16"&gt;&lt;/a&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-17" name="rest_code_440202f98df14c5cb1db75b67e65c78a-17" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-17"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;network_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;dyn_network_desc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-18" name="rest_code_440202f98df14c5cb1db75b67e65c78a-18" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-18"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;network_layers&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-19" name="rest_code_440202f98df14c5cb1db75b67e65c78a-19" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-19"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;lstm_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;time_steps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sequence_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hidden_units&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;last_only&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-20" name="rest_code_440202f98df14c5cb1db75b67e65c78a-20" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-20"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;recurrent_last_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;time_steps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hidden_units&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-21" name="rest_code_440202f98df14c5cb1db75b67e65c78a-21" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-21"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;dense_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;hidden_units&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;softmax&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-22" name="rest_code_440202f98df14c5cb1db75b67e65c78a-22" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-22"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-23" name="rest_code_440202f98df14c5cb1db75b67e65c78a-23" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-23"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;updater&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;updater_type&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ADAM&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// Adam&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-24" name="rest_code_440202f98df14c5cb1db75b67e65c78a-24" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-24"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;                       &lt;/span&gt;&lt;span class="c1"&gt;// The mini-batch size&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-25" name="rest_code_440202f98df14c5cb1db75b67e65c78a-25" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-25"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;::&lt;/span&gt;&lt;span class="n"&gt;network_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-26" name="rest_code_440202f98df14c5cb1db75b67e65c78a-26" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-26"&gt;&lt;/a&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-27" name="rest_code_440202f98df14c5cb1db75b67e65c78a-27" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-27"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;make_unique&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;network_t&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-28" name="rest_code_440202f98df14c5cb1db75b67e65c78a-28" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-28"&gt;&lt;/a&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-29" name="rest_code_440202f98df14c5cb1db75b67e65c78a-29" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-29"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Display the network and dataset&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-30" name="rest_code_440202f98df14c5cb1db75b67e65c78a-30" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-30"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-31" name="rest_code_440202f98df14c5cb1db75b67e65c78a-31" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-31"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-32" name="rest_code_440202f98df14c5cb1db75b67e65c78a-32" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-32"&gt;&lt;/a&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-33" name="rest_code_440202f98df14c5cb1db75b67e65c78a-33" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-33"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Train the network for performance sake&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-34" name="rest_code_440202f98df14c5cb1db75b67e65c78a-34" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-34"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;fine_tune&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-35" name="rest_code_440202f98df14c5cb1db75b67e65c78a-35" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-35"&gt;&lt;/a&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-36" name="rest_code_440202f98df14c5cb1db75b67e65c78a-36" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-36"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Test the network on test set&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-37" name="rest_code_440202f98df14c5cb1db75b67e65c78a-37" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-37"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-38" name="rest_code_440202f98df14c5cb1db75b67e65c78a-38" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-38"&gt;&lt;/a&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-39" name="rest_code_440202f98df14c5cb1db75b67e65c78a-39" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-39"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_440202f98df14c5cb1db75b67e65c78a-40" name="rest_code_440202f98df14c5cb1db75b67e65c78a-40" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_440202f98df14c5cb1db75b67e65c78a-40"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The network is quite similar to the one used previously with an RNN, just
replace rnn with lstm and that's it. It starts with LSTM layer, followed by
a layer extracting the last time step and finally a dense layer with a softmax
function. The network is trained with Adam for 50 epochs. You can change the
activation function , the initializer for the weights and the biases and number
of steps for BPTT truncation.&lt;/p&gt;
&lt;p&gt;Here is the result I got on my last run:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code text"&gt;&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-1" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-1" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-1"&gt;&lt;/a&gt;------------------------------------------------------------
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-2" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-2" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-2"&gt;&lt;/a&gt;| Index | Layer                | Parameters | Output Shape |
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-3" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-3" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-3"&gt;&lt;/a&gt;------------------------------------------------------------
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-4" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-4" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-4"&gt;&lt;/a&gt;| 0     | LSTM (TANH) (dyn)    |      51200 | [Bx28x100]   |
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-5" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-5" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-5"&gt;&lt;/a&gt;| 1     | RNN(last)            |          0 | [Bx100]      |
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-6" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-6" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-6"&gt;&lt;/a&gt;| 2     | Dense(SOFTMAX) (dyn) |       1000 | [Bx10]       |
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-7" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-7" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-7"&gt;&lt;/a&gt;------------------------------------------------------------
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-8" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-8" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-8"&gt;&lt;/a&gt;              Total Parameters:      52200
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-9" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-9" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-9"&gt;&lt;/a&gt;
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-10" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-10" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-10"&gt;&lt;/a&gt;--------------------------------------------
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-11" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-11" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-11"&gt;&lt;/a&gt;| mnist | Size  | Batches | Augmented Size |
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-12" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-12" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-12"&gt;&lt;/a&gt;--------------------------------------------
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-13" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-13" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-13"&gt;&lt;/a&gt;| train | 60000 | 600     | 60000          |
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-14" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-14" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-14"&gt;&lt;/a&gt;| test  | 10000 | 100     | 10000          |
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-15" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-15" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-15"&gt;&lt;/a&gt;--------------------------------------------
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-16" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-16" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-16"&gt;&lt;/a&gt;
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-17" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-17" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-17"&gt;&lt;/a&gt;Network with 3 layers
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-18" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-18" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-18"&gt;&lt;/a&gt;    LSTM(dyn): 28x28 -&amp;gt; TANH -&amp;gt; 28x100
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-19" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-19" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-19"&gt;&lt;/a&gt;    RNN(last): 28x100 -&amp;gt; 100
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-20" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-20" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-20"&gt;&lt;/a&gt;    Dense(dyn): 100 -&amp;gt; SOFTMAX -&amp;gt; 10
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-21" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-21" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-21"&gt;&lt;/a&gt;Total parameters: 52200
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-22" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-22" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-22"&gt;&lt;/a&gt;Dataset
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-23" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-23" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-23"&gt;&lt;/a&gt;Training: In-Memory Data Generator
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-24" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-24" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-24"&gt;&lt;/a&gt;              Size: 60000
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-25" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-25" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-25"&gt;&lt;/a&gt;           Batches: 600
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-26" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-26" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-26"&gt;&lt;/a&gt;Testing: In-Memory Data Generator
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-27" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-27" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-27"&gt;&lt;/a&gt;              Size: 10000
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-28" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-28" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-28"&gt;&lt;/a&gt;           Batches: 100
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-29" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-29" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-29"&gt;&lt;/a&gt;
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-30" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-30" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-30"&gt;&lt;/a&gt;Train the network with "Stochastic Gradient Descent"
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-31" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-31" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-31"&gt;&lt;/a&gt;    Updater: ADAM
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-32" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-32" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-32"&gt;&lt;/a&gt;       Loss: CATEGORICAL_CROSS_ENTROPY
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-33" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-33" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-33"&gt;&lt;/a&gt; Early Stop: Goal(error)
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-34" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-34" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-34"&gt;&lt;/a&gt;
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-35" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-35" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-35"&gt;&lt;/a&gt;With parameters:
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-36" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-36" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-36"&gt;&lt;/a&gt;          epochs=50
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-37" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-37" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-37"&gt;&lt;/a&gt;      batch_size=100
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-38" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-38" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-38"&gt;&lt;/a&gt;   learning_rate=0.001
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-39" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-39" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-39"&gt;&lt;/a&gt;           beta1=0.9
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-40" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-40" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-40"&gt;&lt;/a&gt;           beta2=0.999
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-41" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-41" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-41"&gt;&lt;/a&gt;
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-42" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-42" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-42"&gt;&lt;/a&gt;epoch   0/50 batch  600/ 600 - error: 0.07943 loss: 0.28504 time 20910ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-43" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-43" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-43"&gt;&lt;/a&gt;epoch   1/50 batch  600/ 600 - error: 0.06683 loss: 0.24021 time 20889ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-44" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-44" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-44"&gt;&lt;/a&gt;epoch   2/50 batch  600/ 600 - error: 0.04828 loss: 0.18233 time 21061ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-45" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-45" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-45"&gt;&lt;/a&gt;epoch   3/50 batch  600/ 600 - error: 0.04407 loss: 0.16665 time 20839ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-46" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-46" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-46"&gt;&lt;/a&gt;epoch   4/50 batch  600/ 600 - error: 0.03515 loss: 0.13290 time 22108ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-47" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-47" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-47"&gt;&lt;/a&gt;epoch   5/50 batch  600/ 600 - error: 0.03207 loss: 0.12019 time 21393ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-48" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-48" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-48"&gt;&lt;/a&gt;epoch   6/50 batch  600/ 600 - error: 0.02973 loss: 0.11239 time 28199ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-49" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-49" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-49"&gt;&lt;/a&gt;epoch   7/50 batch  600/ 600 - error: 0.02653 loss: 0.10455 time 37039ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-50" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-50" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-50"&gt;&lt;/a&gt;epoch   8/50 batch  600/ 600 - error: 0.02482 loss: 0.09657 time 23127ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-51" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-51" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-51"&gt;&lt;/a&gt;epoch   9/50 batch  600/ 600 - error: 0.02177 loss: 0.08422 time 41766ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-52" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-52" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-52"&gt;&lt;/a&gt;epoch  10/50 batch  600/ 600 - error: 0.02453 loss: 0.09382 time 29765ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-53" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-53" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-53"&gt;&lt;/a&gt;epoch  11/50 batch  600/ 600 - error: 0.02575 loss: 0.09796 time 21449ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-54" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-54" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-54"&gt;&lt;/a&gt;epoch  12/50 batch  600/ 600 - error: 0.02107 loss: 0.07833 time 42056ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-55" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-55" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-55"&gt;&lt;/a&gt;epoch  13/50 batch  600/ 600 - error: 0.01877 loss: 0.07171 time 24673ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-56" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-56" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-56"&gt;&lt;/a&gt;epoch  14/50 batch  600/ 600 - error: 0.02095 loss: 0.08481 time 20878ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-57" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-57" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-57"&gt;&lt;/a&gt;epoch  15/50 batch  600/ 600 - error: 0.02040 loss: 0.07578 time 41515ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-58" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-58" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-58"&gt;&lt;/a&gt;epoch  16/50 batch  600/ 600 - error: 0.01580 loss: 0.06083 time 25705ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-59" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-59" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-59"&gt;&lt;/a&gt;epoch  17/50 batch  600/ 600 - error: 0.01945 loss: 0.07046 time 20903ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-60" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-60" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-60"&gt;&lt;/a&gt;epoch  18/50 batch  600/ 600 - error: 0.01728 loss: 0.06683 time 41828ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-61" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-61" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-61"&gt;&lt;/a&gt;epoch  19/50 batch  600/ 600 - error: 0.01577 loss: 0.05947 time 27810ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-62" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-62" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-62"&gt;&lt;/a&gt;epoch  20/50 batch  600/ 600 - error: 0.01528 loss: 0.05883 time 21477ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-63" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-63" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-63"&gt;&lt;/a&gt;epoch  21/50 batch  600/ 600 - error: 0.01345 loss: 0.05127 time 44718ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-64" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-64" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-64"&gt;&lt;/a&gt;epoch  22/50 batch  600/ 600 - error: 0.01410 loss: 0.05357 time 25174ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-65" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-65" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-65"&gt;&lt;/a&gt;epoch  23/50 batch  600/ 600 - error: 0.01268 loss: 0.04765 time 23827ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-66" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-66" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-66"&gt;&lt;/a&gt;epoch  24/50 batch  600/ 600 - error: 0.01342 loss: 0.05004 time 47232ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-67" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-67" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-67"&gt;&lt;/a&gt;epoch  25/50 batch  600/ 600 - error: 0.01730 loss: 0.06872 time 22532ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-68" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-68" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-68"&gt;&lt;/a&gt;epoch  26/50 batch  600/ 600 - error: 0.01337 loss: 0.05016 time 30114ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-69" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-69" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-69"&gt;&lt;/a&gt;epoch  27/50 batch  600/ 600 - error: 0.01842 loss: 0.07049 time 40136ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-70" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-70" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-70"&gt;&lt;/a&gt;epoch  28/50 batch  600/ 600 - error: 0.01262 loss: 0.04639 time 21793ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-71" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-71" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-71"&gt;&lt;/a&gt;epoch  29/50 batch  600/ 600 - error: 0.01403 loss: 0.05292 time 34096ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-72" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-72" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-72"&gt;&lt;/a&gt;epoch  30/50 batch  600/ 600 - error: 0.01185 loss: 0.04456 time 35420ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-73" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-73" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-73"&gt;&lt;/a&gt;epoch  31/50 batch  600/ 600 - error: 0.01098 loss: 0.04180 time 20909ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-74" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-74" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-74"&gt;&lt;/a&gt;epoch  32/50 batch  600/ 600 - error: 0.01337 loss: 0.04687 time 30113ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-75" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-75" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-75"&gt;&lt;/a&gt;epoch  33/50 batch  600/ 600 - error: 0.01415 loss: 0.05292 time 37393ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-76" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-76" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-76"&gt;&lt;/a&gt;epoch  34/50 batch  600/ 600 - error: 0.00982 loss: 0.03615 time 20962ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-77" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-77" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-77"&gt;&lt;/a&gt;epoch  35/50 batch  600/ 600 - error: 0.01178 loss: 0.04830 time 29305ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-78" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-78" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-78"&gt;&lt;/a&gt;epoch  36/50 batch  600/ 600 - error: 0.00882 loss: 0.03408 time 38293ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-79" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-79" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-79"&gt;&lt;/a&gt;epoch  37/50 batch  600/ 600 - error: 0.01148 loss: 0.04341 time 20841ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-80" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-80" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-80"&gt;&lt;/a&gt;epoch  38/50 batch  600/ 600 - error: 0.00960 loss: 0.03701 time 29204ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-81" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-81" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-81"&gt;&lt;/a&gt;epoch  39/50 batch  600/ 600 - error: 0.00850 loss: 0.03094 time 39802ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-82" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-82" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-82"&gt;&lt;/a&gt;epoch  40/50 batch  600/ 600 - error: 0.01473 loss: 0.05136 time 20831ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-83" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-83" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-83"&gt;&lt;/a&gt;epoch  41/50 batch  600/ 600 - error: 0.01007 loss: 0.03579 time 29856ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-84" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-84" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-84"&gt;&lt;/a&gt;epoch  42/50 batch  600/ 600 - error: 0.00943 loss: 0.03370 time 38200ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-85" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-85" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-85"&gt;&lt;/a&gt;epoch  43/50 batch  600/ 600 - error: 0.01205 loss: 0.04409 time 21162ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-86" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-86" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-86"&gt;&lt;/a&gt;epoch  44/50 batch  600/ 600 - error: 0.00980 loss: 0.03674 time 32279ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-87" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-87" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-87"&gt;&lt;/a&gt;epoch  45/50 batch  600/ 600 - error: 0.01068 loss: 0.04133 time 38448ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-88" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-88" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-88"&gt;&lt;/a&gt;epoch  46/50 batch  600/ 600 - error: 0.00913 loss: 0.03478 time 20797ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-89" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-89" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-89"&gt;&lt;/a&gt;epoch  47/50 batch  600/ 600 - error: 0.00985 loss: 0.03759 time 28885ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-90" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-90" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-90"&gt;&lt;/a&gt;epoch  48/50 batch  600/ 600 - error: 0.00912 loss: 0.03295 time 41120ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-91" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-91" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-91"&gt;&lt;/a&gt;epoch  49/50 batch  600/ 600 - error: 0.00930 loss: 0.03438 time 21282ms
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-92" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-92" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-92"&gt;&lt;/a&gt;Restore the best (error) weights from epoch 39
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-93" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-93" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-93"&gt;&lt;/a&gt;Training took 1460s
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-94" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-94" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-94"&gt;&lt;/a&gt;
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-95" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-95" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-95"&gt;&lt;/a&gt;Evaluation Results
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-96" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-96" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-96"&gt;&lt;/a&gt;   error: 0.02440
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-97" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-97" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-97"&gt;&lt;/a&gt;    loss: 0.11315
&lt;a id="rest_code_c5dc880eae5d4e5c84bf474d732f974f-98" name="rest_code_c5dc880eae5d4e5c84bf474d732f974f-98" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html#rest_code_c5dc880eae5d4e5c84bf474d732f974f-98"&gt;&lt;/a&gt;evaluation took 1000ms
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, nothing fancy yet, but this example has not been optimized for
performance nor for accuracy.&lt;/p&gt;
&lt;p&gt;I also made a few changes to the RNN layer. I added support for biases and
improved the code as well for performance and readability.&lt;/p&gt;
&lt;p&gt;All this support is now in the &lt;strong&gt;master&lt;/strong&gt; branch of the DLL project if you want
to check it out. You can also check out the example online:
&lt;a class="reference external" href="https://github.com/wichtounet/dll/blob/master/examples/src/mnist_lstm.cpp"&gt;mnist_lstm.cpp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can access the project &lt;a class="reference external" href="https://github.com/wichtounet/dll"&gt;on Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Currently I'm working on the GPU performance again. The performance of some is
still not as good as I want it to be, especially complex operation like used in
Adam and Nadam. Currently, there are many calls to GPU BLAS libraries and
I want to try to extract some more optimized patterns. Once it's done, I'll post
more on that later on the blog.&lt;/p&gt;</description><category>Deep Learning</category><category>dll</category><category>Machine Learning</category><category>projects</category><category>rnn</category><guid>https://baptiste-wicht.com/posts/2017/11/initial-support-for-long-short-term-memory-lstm-in-dll.html</guid><pubDate>Fri, 24 Nov 2017 14:16:37 GMT</pubDate></item><item><title>DLL: Pretty printing and live output</title><link>https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I've improved a lot the display of my Deep Learning Library (DLL). I know this
is generally not the most important point in a machine learning framework, but
the first impression being important. Therefore, I decided it was time to get
a nicer output in the console for training networks.&lt;/p&gt;
&lt;p&gt;A network or a dataset can be displayed using the &lt;code&gt;display()&lt;/code&gt; function.
I've added a &lt;code&gt;display_pretty()&lt;/code&gt; function to them to display it more
nicely. I've also added the &lt;code&gt;dll::dump_timers_nice()&lt;/code&gt; function to do the
same for &lt;code&gt;dll::dump_timers()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I've also improved the display for the results of the batches during training.
Now, the display is updated every 100ms and it also displays the current
estimated time until the end of the epoch. With that, the user should have
a much better idea on what's going on during training, especially when training
networks when the epochs are taking a long time to complete.&lt;/p&gt;
&lt;p&gt;Here is a full output of the training of fully-connected network on MNIST
(&lt;cite&gt;mnist_mlp.cpp &amp;lt;https://github.com/wichtounet/dll/blob/master/examples/src/mnist_mlp.cpp&amp;gt;&lt;/cite&gt;):&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-1" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-1" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-1"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;------------------------------------------------------------
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-2" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-2" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-2"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Index&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Layer&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Parameters&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Output&lt;span class="w"&gt; &lt;/span&gt;Shape&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-3" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-3" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-3"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;------------------------------------------------------------
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-4" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-4" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-4"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Dense&lt;span class="o"&gt;(&lt;/span&gt;SIGMOID&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;dyn&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="m"&gt;392000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;Bx500&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-5" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-5" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-5"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Dropout&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.50&lt;span class="o"&gt;)(&lt;/span&gt;dyn&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;Bx500&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-6" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-6" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-6"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Dense&lt;span class="o"&gt;(&lt;/span&gt;SIGMOID&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;dyn&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="m"&gt;125000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;Bx250&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-7" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-7" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-7"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Dropout&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.50&lt;span class="o"&gt;)(&lt;/span&gt;dyn&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;Bx250&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-8" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-8" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-8"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Dense&lt;span class="o"&gt;(&lt;/span&gt;SOFTMAX&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;dyn&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="m"&gt;2500&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;Bx10&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-9" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-9" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-9"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;------------------------------------------------------------
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-10" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-10" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-10"&gt;&lt;/a&gt;&lt;span class="w"&gt;                &lt;/span&gt;Total&lt;span class="w"&gt; &lt;/span&gt;Parameters:&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="m"&gt;519500&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-11" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-11" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-11"&gt;&lt;/a&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-12" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-12" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-12"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;--------------------------------------------
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-13" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-13" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-13"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;mnist&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Size&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Batches&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Augmented&lt;span class="w"&gt; &lt;/span&gt;Size&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-14" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-14" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-14"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;--------------------------------------------
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-15" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-15" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-15"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;train&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60000&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-16" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-16" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-16"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-17" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-17" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-17"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;--------------------------------------------
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-18" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-18" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-18"&gt;&lt;/a&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-19" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-19" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-19"&gt;&lt;/a&gt;Train&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;network&lt;span class="w"&gt; &lt;/span&gt;with&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Stochastic Gradient Descent"&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-20" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-20" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-20"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;Updater:&lt;span class="w"&gt; &lt;/span&gt;NADAM
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-21" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-21" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-21"&gt;&lt;/a&gt;&lt;span class="w"&gt;       &lt;/span&gt;Loss:&lt;span class="w"&gt; &lt;/span&gt;CATEGORICAL_CROSS_ENTROPY
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-22" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-22" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-22"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;Early&lt;span class="w"&gt; &lt;/span&gt;Stop:&lt;span class="w"&gt; &lt;/span&gt;Goal&lt;span class="o"&gt;(&lt;/span&gt;error&lt;span class="o"&gt;)&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-23" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-23" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-23"&gt;&lt;/a&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-24" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-24" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-24"&gt;&lt;/a&gt;With&lt;span class="w"&gt; &lt;/span&gt;parameters:
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-25" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-25" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-25"&gt;&lt;/a&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nv"&gt;epochs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-26" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-26" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-26"&gt;&lt;/a&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nv"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-27" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-27" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-27"&gt;&lt;/a&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nv"&gt;learning_rate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.002
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-28" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-28" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-28"&gt;&lt;/a&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="nv"&gt;beta1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.9
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-29" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-29" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-29"&gt;&lt;/a&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="nv"&gt;beta2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.999
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-30" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-30" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-30"&gt;&lt;/a&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-31" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-31" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-31"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.04623&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.15097&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3230ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-32" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-32" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-32"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.03013&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.09947&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3188ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-33" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-33" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-33"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.02048&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.06565&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3102ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-34" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-34" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-34"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01593&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.05258&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3189ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-35" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-35" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-35"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01422&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.04623&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3160ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-36" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-36" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-36"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01112&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.03660&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3131ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-37" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-37" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-37"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01078&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.03546&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3200ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-38" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-38" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-38"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;7&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01003&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.03184&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3246ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-39" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-39" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-39"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;8&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00778&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.02550&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3222ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-40" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-40" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-40"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00782&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.02505&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3119ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-41" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-41" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-41"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00578&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.02056&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3284ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-42" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-42" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-42"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;11&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00618&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.02045&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3220ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-43" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-43" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-43"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00538&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01775&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3444ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-44" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-44" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-44"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;13&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00563&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01803&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3304ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-45" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-45" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-45"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;14&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00458&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01598&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3577ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-46" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-46" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-46"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;15&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00437&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01436&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3228ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-47" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-47" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-47"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;16&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00360&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01214&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3180ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-48" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-48" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-48"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;17&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00405&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01309&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3090ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-49" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-49" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-49"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;18&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00408&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01346&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3045ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-50" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-50" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-50"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;19&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00337&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01153&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3071ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-51" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-51" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-51"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00297&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01021&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3131ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-52" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-52" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-52"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00318&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01103&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3076ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-53" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-53" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-53"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;22&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00277&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00909&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3090ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-54" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-54" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-54"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;23&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00242&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00818&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3163ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-55" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-55" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-55"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;24&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00267&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00913&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3229ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-56" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-56" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-56"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00295&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00947&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3156ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-57" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-57" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-57"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;26&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00252&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00809&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3066ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-58" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-58" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-58"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;27&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00227&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00773&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3156ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-59" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-59" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-59"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;28&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00203&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00728&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3158ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-60" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-60" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-60"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;29&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00240&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00753&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3114ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-61" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-61" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-61"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;30&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00263&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00864&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3099ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-62" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-62" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-62"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;31&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00210&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00675&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3096ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-63" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-63" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-63"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;32&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00163&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00628&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3120ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-64" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-64" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-64"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;33&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00182&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00611&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3045ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-65" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-65" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-65"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;34&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00125&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00468&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3140ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-66" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-66" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-66"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;35&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00183&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00598&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3093ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-67" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-67" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-67"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;36&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00232&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00711&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3068ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-68" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-68" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-68"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;37&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00170&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00571&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3057ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-69" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-69" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-69"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;38&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00162&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00530&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3115ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-70" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-70" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-70"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;39&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00155&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00513&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3226ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-71" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-71" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-71"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;40&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00150&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00501&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;2987ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-72" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-72" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-72"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;41&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00122&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00425&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3117ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-73" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-73" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-73"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00108&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00383&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3102ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-74" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-74" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-74"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;43&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00165&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00533&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;2977ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-75" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-75" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-75"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;44&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00142&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00469&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3009ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-76" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-76" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-76"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;45&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00098&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00356&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3055ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-77" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-77" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-77"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;46&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00127&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00409&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3076ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-78" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-78" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-78"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;47&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00132&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00438&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3068ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-79" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-79" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-79"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;48&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00130&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00459&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3045ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-80" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-80" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-80"&gt;&lt;/a&gt;epoch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;49&lt;/span&gt;/50&lt;span class="w"&gt; &lt;/span&gt;batch&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00107&lt;span class="w"&gt; &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.00365&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;3103ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-81" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-81" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-81"&gt;&lt;/a&gt;Restore&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;best&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;error&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;weights&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;epoch&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;45&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-82" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-82" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-82"&gt;&lt;/a&gt;Training&lt;span class="w"&gt; &lt;/span&gt;took&lt;span class="w"&gt; &lt;/span&gt;160s
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-83" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-83" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-83"&gt;&lt;/a&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-84" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-84" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-84"&gt;&lt;/a&gt;Evaluation&lt;span class="w"&gt; &lt;/span&gt;Results
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-85" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-85" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-85"&gt;&lt;/a&gt;&lt;span class="w"&gt;   &lt;/span&gt;error:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.01740
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-86" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-86" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-86"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;loss:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.07861
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-87" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-87" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-87"&gt;&lt;/a&gt;evaluation&lt;span class="w"&gt; &lt;/span&gt;took&lt;span class="w"&gt; &lt;/span&gt;67ms
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-88" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-88" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-88"&gt;&lt;/a&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-89" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-89" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-89"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;-----------------------------------------------------------------------------
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-90" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-90" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-90"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;%&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Timer&lt;span class="w"&gt;                         &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Count&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Total&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Average&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-91" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-91" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-91"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;-----------------------------------------------------------------------------
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-92" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-92" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-92"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;.000%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;net:train:ft&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;160&lt;/span&gt;.183s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;160&lt;/span&gt;.183s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-93" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-93" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-93"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;.000%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;net:trainer:train&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;160&lt;/span&gt;.183s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;160&lt;/span&gt;.183s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-94" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-94" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-94"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;99&lt;/span&gt;.997%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;net:trainer:train:epoch&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;160&lt;/span&gt;.178s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;.20356s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-95" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-95" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-95"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;84&lt;/span&gt;.422%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;net:trainer:train:epoch:batch&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;135&lt;/span&gt;.229s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;.50764ms&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-96" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-96" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-96"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;84&lt;/span&gt;.261%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sgd::train_batch&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;134&lt;/span&gt;.971s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;.49904ms&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-97" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-97" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-97"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;44&lt;/span&gt;.404%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sgd::grad&lt;span class="w"&gt;                     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;71&lt;/span&gt;.1271s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;.3709ms&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-98" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-98" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-98"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;35&lt;/span&gt;.453%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sgd::forward&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;56&lt;/span&gt;.7893s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;.89298ms&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-99" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-99" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-99"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;32&lt;/span&gt;.245%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sgd::update_weights&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;90000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;51&lt;/span&gt;.6505s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;573&lt;/span&gt;.894us&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-100" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-100" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-100"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;32&lt;/span&gt;.226%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sgd::apply_grad:nadam&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;180000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;51&lt;/span&gt;.6211s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;286&lt;/span&gt;.783us&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-101" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-101" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-101"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;28&lt;/span&gt;.399%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dense:dyn:forward&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;180300&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;45&lt;/span&gt;.4903s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;252&lt;/span&gt;.303us&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-102" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-102" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-102"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;17&lt;/span&gt;.642%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dropout:train:forward&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;28&lt;/span&gt;.2595s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;470&lt;/span&gt;.99us&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-103" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-103" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-103"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;13&lt;/span&gt;.707%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;net:trainer:train:epoch:error&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;.957s&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;439&lt;/span&gt;.14ms&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-104" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-104" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-104"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;.148%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dense:dyn:gradients&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;90000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;19&lt;/span&gt;.4587s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;216&lt;/span&gt;.207us&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-105" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-105" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-105"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;.299%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sgd::backward&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;.88546s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;229&lt;/span&gt;.515us&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-106" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-106" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-106"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;.301%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dense:dyn:backward&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;.28729s&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;88&lt;/span&gt;.121us&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-107" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-107" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-107"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.560%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dense:dyn:errors&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;896&lt;/span&gt;.471ms&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;14&lt;/span&gt;.941us&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-108" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-108" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-108"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.407%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dropout:backward&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;651&lt;/span&gt;.523ms&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;.858us&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-109" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-109" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-109"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.339%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dropout:test:forward&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;542&lt;/span&gt;.799ms&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;.046us&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-110" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-110" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-110"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.161%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;net:compute_loss:CCE&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60100&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;257&lt;/span&gt;.915ms&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;.291us&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-111" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-111" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-111"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.099%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sgd::error&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;30000&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;158&lt;/span&gt;.33ms&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;.277us&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;a id="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-112" name="rest_code_7f6dc94921d74486a02cbbbf1f9bb466-112" href="https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html#rest_code_7f6dc94921d74486a02cbbbf1f9bb466-112"&gt;&lt;/a&gt;&lt;span class="w"&gt; &lt;/span&gt;-----------------------------------------------------------------------------
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I hope this will make the output of the machine learning framework more useful.&lt;/p&gt;
&lt;p&gt;All this support is now in the &lt;strong&gt;master&lt;/strong&gt; branch of the DLL project if you want
to check it out. You can also check out the example online:
&lt;a class="reference external" href="https://github.com/wichtounet/dll/blob/master/examples/src/mnist_mlp.cpp"&gt;mnist_mlp.cpp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can access the project &lt;a class="reference external" href="https://github.com/wichtounet/dll"&gt;on Github&lt;/a&gt;.&lt;/p&gt;</description><category>dll</category><category>Machine Learning</category><category>projects</category><guid>https://baptiste-wicht.com/posts/2017/11/dll-pretty-printing-and-live-output.html</guid><pubDate>Sun, 19 Nov 2017 14:15:57 GMT</pubDate></item><item><title>Inventor on four new research patents</title><link>https://baptiste-wicht.com/posts/2017/11/inventor-on-four-new-research-patents.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;During the first years of my thesis I worked on CTI research project with the
American company Verisign, which has also an office near my school. A CTI
research project is a project that is partially funded by the Commission on
Innovation and Technology (CTI) where a school and a company work together.
I was quite lucky to work on this project with the awesome people at Verisign
Fribourg. After the success of the project, Verisign filled several patents
regarding various points of the projects.&lt;/p&gt;
&lt;p&gt;I'm quite happy now that these four patents are now approved and published. They
They have been approved by both the United States Patent and Trademark Office
(USPTO) and European Patent Office (EPO). The parents have been cl=¬ aimed by
Verisign, I'm only one of the inventor, I got no claim on the patent. But it's
still a great thing.&lt;/p&gt;
&lt;p&gt;Here are the names of the four patents:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Systems and methods for automatic phonetization of domain names¬&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Construction of phonetic representation of a string of characters¬&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method for writing a foreign language in a pseudo language phonetically resembling native language of the speaker¬&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Construction of a phonetic representation of a generated string of characters¬&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can take a look at them on USPTO or EPO or on Google Patents, but the way
a patent is written make it relatively hard to follow, it's more on a lawyer
level or maybe I'm simply not used to patents anymore.&lt;/p&gt;
&lt;p&gt;All these patents come from the research done during the CTI project with
Verisign. In this project, name suggestions were generated from the phonetic
sound of the name. The idea being to generate names that sounds the same as
another input (airmix could become rmix or rmics). We are using various
technologies to make this work: IG-Tree, Viterbi and HMM. And since we used
a model with an encoder and a decoder, we can also mix languages. For instance,
write something in French the way a English work would work (for instance school
could become scoule).&lt;/p&gt;
&lt;p&gt;These patents concludes a very interesting and successful project. I'm now
working on yet another CTI research project with Verisign and it will surely be
as successful as the first one.&lt;/p&gt;</description><category>Machine Learning</category><category>patents</category><category>projects</category><category>publications</category><guid>https://baptiste-wicht.com/posts/2017/11/inventor-on-four-new-research-patents.html</guid><pubDate>Fri, 17 Nov 2017 13:50:33 GMT</pubDate></item><item><title>Initial support for Recurrent Neural Network (RNN) in DLL</title><link>https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I'm happy to announce that I just merged support for Recurrent Neural Networks
(RNNs) into my Deep Learning Library (DLL) machine learning framework.&lt;/p&gt;
&lt;p&gt;It's nothing fancy yet, but forward propagation of RNN and basic Backpropagation
Through Time (BPTT) are now supported. For now, only existing classification
loss is supported for RNN. I plan to add support for sequence-to-sequence loss
in order to be able to train models able to generate characters, but I don't
know when I'll be able to work on that. I also plan to add support for other
types of cells such as LSTM and GRU (maybe NAS) in the future.&lt;/p&gt;
&lt;p&gt;For example, here is a simple RNN used on MNIST:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-1" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-1" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-1"&gt;&lt;/a&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;"dll/neural/dense_layer.hpp"&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-2" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-2" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-2"&gt;&lt;/a&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;"dll/neural/recurrent_layer.hpp"&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-3" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-3" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-3"&gt;&lt;/a&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;"dll/neural/recurrent_last_layer.hpp"&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-4" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-4" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-4"&gt;&lt;/a&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;"dll/network.hpp"&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-5" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-5" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-5"&gt;&lt;/a&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;"dll/datasets.hpp"&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-6" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-6" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-6"&gt;&lt;/a&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-7" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-7" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-7"&gt;&lt;/a&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/*argc*/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/*argv*/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-8" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-8" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-8"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Load the dataset&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-9" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-9" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-9"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;make_mnist_dataset_nc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;scale_pre&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{});&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-10" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-10" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-10"&gt;&lt;/a&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-11" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-11" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-11"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;time_steps&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-12" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-12" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-12"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sequence_length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-13" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-13" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-13"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hidden_units&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-14" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-14" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-14"&gt;&lt;/a&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-15" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-15" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-15"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Build the network&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-16" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-16" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-16"&gt;&lt;/a&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-17" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-17" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-17"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;network_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;dyn_network_desc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-18" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-18" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-18"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;network_layers&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-19" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-19" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-19"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;recurrent_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;time_steps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sequence_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hidden_units&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;last_only&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-20" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-20" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-20"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;recurrent_last_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;time_steps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hidden_units&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-21" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-21" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-21"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;dense_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;hidden_units&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;softmax&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-22" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-22" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-22"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-23" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-23" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-23"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;updater&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;updater_type&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ADAM&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// Adam&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-24" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-24" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-24"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;                       &lt;/span&gt;&lt;span class="c1"&gt;// The mini-batch size&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-25" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-25" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-25"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;::&lt;/span&gt;&lt;span class="n"&gt;network_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-26" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-26" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-26"&gt;&lt;/a&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-27" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-27" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-27"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;make_unique&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;network_t&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-28" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-28" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-28"&gt;&lt;/a&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-29" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-29" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-29"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Display the network and dataset&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-30" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-30" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-30"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-31" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-31" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-31"&gt;&lt;/a&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-32" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-32" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-32"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Train the network for performance sake&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-33" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-33" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-33"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;fine_tune&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-34" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-34" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-34"&gt;&lt;/a&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-35" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-35" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-35"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Test the network on test set&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-36" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-36" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-36"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-37" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-37" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-37"&gt;&lt;/a&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-38" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-38" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-38"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_68e3b5bb356e41f18b4636fa640f126c-39" name="rest_code_68e3b5bb356e41f18b4636fa640f126c-39" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_68e3b5bb356e41f18b4636fa640f126c-39"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The network starts with recurrent layer, followed by a layer that extracts only
the last layer and finally a dense layer with a softmax function. The recurrent
layer has support to change the activation function, change the initializer for
the two weights matrices of the RNN and the number of steps for BPTT truncation.&lt;/p&gt;
&lt;p&gt;Here is a possible result:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code text"&gt;&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-1" name="rest_code_b558f63b96924a61a4b29758d337412c-1" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-1"&gt;&lt;/a&gt;Network with 3 layers
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-2" name="rest_code_b558f63b96924a61a4b29758d337412c-2" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-2"&gt;&lt;/a&gt;    RNN(dyn): 28x28 -&amp;gt; TANH -&amp;gt; 28x100
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-3" name="rest_code_b558f63b96924a61a4b29758d337412c-3" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-3"&gt;&lt;/a&gt;    RNN(last): 28x100 -&amp;gt; 100
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-4" name="rest_code_b558f63b96924a61a4b29758d337412c-4" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-4"&gt;&lt;/a&gt;    Dense(dyn): 100 -&amp;gt; SOFTMAX -&amp;gt; 10
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-5" name="rest_code_b558f63b96924a61a4b29758d337412c-5" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-5"&gt;&lt;/a&gt;Total parameters: 13800
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-6" name="rest_code_b558f63b96924a61a4b29758d337412c-6" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-6"&gt;&lt;/a&gt;Train the network with "Stochastic Gradient Descent"
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-7" name="rest_code_b558f63b96924a61a4b29758d337412c-7" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-7"&gt;&lt;/a&gt;    Updater: ADAM
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-8" name="rest_code_b558f63b96924a61a4b29758d337412c-8" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-8"&gt;&lt;/a&gt;       Loss: CATEGORICAL_CROSS_ENTROPY
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-9" name="rest_code_b558f63b96924a61a4b29758d337412c-9" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-9"&gt;&lt;/a&gt; Early Stop: Goal(error)
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-10" name="rest_code_b558f63b96924a61a4b29758d337412c-10" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-10"&gt;&lt;/a&gt;
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-11" name="rest_code_b558f63b96924a61a4b29758d337412c-11" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-11"&gt;&lt;/a&gt;With parameters:
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-12" name="rest_code_b558f63b96924a61a4b29758d337412c-12" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-12"&gt;&lt;/a&gt;          epochs=50
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-13" name="rest_code_b558f63b96924a61a4b29758d337412c-13" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-13"&gt;&lt;/a&gt;      batch_size=100
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-14" name="rest_code_b558f63b96924a61a4b29758d337412c-14" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-14"&gt;&lt;/a&gt;   learning_rate=0.001
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-15" name="rest_code_b558f63b96924a61a4b29758d337412c-15" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-15"&gt;&lt;/a&gt;           beta1=0.9
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-16" name="rest_code_b558f63b96924a61a4b29758d337412c-16" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-16"&gt;&lt;/a&gt;           beta2=0.999
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-17" name="rest_code_b558f63b96924a61a4b29758d337412c-17" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-17"&gt;&lt;/a&gt;
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-18" name="rest_code_b558f63b96924a61a4b29758d337412c-18" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-18"&gt;&lt;/a&gt;Epoch   0/50 - Classification error: 0.11635 Loss: 0.39999 Time 4717ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-19" name="rest_code_b558f63b96924a61a4b29758d337412c-19" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-19"&gt;&lt;/a&gt;Epoch   1/50 - Classification error: 0.11303 Loss: 0.36994 Time 4702ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-20" name="rest_code_b558f63b96924a61a4b29758d337412c-20" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-20"&gt;&lt;/a&gt;Epoch   2/50 - Classification error: 0.06732 Loss: 0.23469 Time 4702ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-21" name="rest_code_b558f63b96924a61a4b29758d337412c-21" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-21"&gt;&lt;/a&gt;Epoch   3/50 - Classification error: 0.04865 Loss: 0.17091 Time 4696ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-22" name="rest_code_b558f63b96924a61a4b29758d337412c-22" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-22"&gt;&lt;/a&gt;Epoch   4/50 - Classification error: 0.05957 Loss: 0.20437 Time 4706ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-23" name="rest_code_b558f63b96924a61a4b29758d337412c-23" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-23"&gt;&lt;/a&gt;Epoch   5/50 - Classification error: 0.05022 Loss: 0.16888 Time 4696ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-24" name="rest_code_b558f63b96924a61a4b29758d337412c-24" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-24"&gt;&lt;/a&gt;Epoch   6/50 - Classification error: 0.03912 Loss: 0.13743 Time 4698ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-25" name="rest_code_b558f63b96924a61a4b29758d337412c-25" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-25"&gt;&lt;/a&gt;Epoch   7/50 - Classification error: 0.04097 Loss: 0.14509 Time 4706ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-26" name="rest_code_b558f63b96924a61a4b29758d337412c-26" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-26"&gt;&lt;/a&gt;Epoch   8/50 - Classification error: 0.03938 Loss: 0.13397 Time 4694ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-27" name="rest_code_b558f63b96924a61a4b29758d337412c-27" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-27"&gt;&lt;/a&gt;Epoch   9/50 - Classification error: 0.03525 Loss: 0.12284 Time 4706ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-28" name="rest_code_b558f63b96924a61a4b29758d337412c-28" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-28"&gt;&lt;/a&gt;Epoch  10/50 - Classification error: 0.03927 Loss: 0.13770 Time 4694ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-29" name="rest_code_b558f63b96924a61a4b29758d337412c-29" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-29"&gt;&lt;/a&gt;Epoch  11/50 - Classification error: 0.03315 Loss: 0.11315 Time 4711ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-30" name="rest_code_b558f63b96924a61a4b29758d337412c-30" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-30"&gt;&lt;/a&gt;Epoch  12/50 - Classification error: 0.05037 Loss: 0.17123 Time 4711ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-31" name="rest_code_b558f63b96924a61a4b29758d337412c-31" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-31"&gt;&lt;/a&gt;Epoch  13/50 - Classification error: 0.02927 Loss: 0.10042 Time 4780ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-32" name="rest_code_b558f63b96924a61a4b29758d337412c-32" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-32"&gt;&lt;/a&gt;Epoch  14/50 - Classification error: 0.03322 Loss: 0.11027 Time 4746ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-33" name="rest_code_b558f63b96924a61a4b29758d337412c-33" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-33"&gt;&lt;/a&gt;Epoch  15/50 - Classification error: 0.03397 Loss: 0.11585 Time 4684ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-34" name="rest_code_b558f63b96924a61a4b29758d337412c-34" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-34"&gt;&lt;/a&gt;Epoch  16/50 - Classification error: 0.02938 Loss: 0.09984 Time 4708ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-35" name="rest_code_b558f63b96924a61a4b29758d337412c-35" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-35"&gt;&lt;/a&gt;Epoch  17/50 - Classification error: 0.03262 Loss: 0.11152 Time 4690ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-36" name="rest_code_b558f63b96924a61a4b29758d337412c-36" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-36"&gt;&lt;/a&gt;Epoch  18/50 - Classification error: 0.02872 Loss: 0.09753 Time 4672ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-37" name="rest_code_b558f63b96924a61a4b29758d337412c-37" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-37"&gt;&lt;/a&gt;Epoch  19/50 - Classification error: 0.02548 Loss: 0.08605 Time 4691ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-38" name="rest_code_b558f63b96924a61a4b29758d337412c-38" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-38"&gt;&lt;/a&gt;Epoch  20/50 - Classification error: 0.02245 Loss: 0.07797 Time 4693ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-39" name="rest_code_b558f63b96924a61a4b29758d337412c-39" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-39"&gt;&lt;/a&gt;Epoch  21/50 - Classification error: 0.02705 Loss: 0.08984 Time 4684ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-40" name="rest_code_b558f63b96924a61a4b29758d337412c-40" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-40"&gt;&lt;/a&gt;Epoch  22/50 - Classification error: 0.02422 Loss: 0.08164 Time 4688ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-41" name="rest_code_b558f63b96924a61a4b29758d337412c-41" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-41"&gt;&lt;/a&gt;Epoch  23/50 - Classification error: 0.02645 Loss: 0.08804 Time 4690ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-42" name="rest_code_b558f63b96924a61a4b29758d337412c-42" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-42"&gt;&lt;/a&gt;Epoch  24/50 - Classification error: 0.02927 Loss: 0.09739 Time 4715ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-43" name="rest_code_b558f63b96924a61a4b29758d337412c-43" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-43"&gt;&lt;/a&gt;Epoch  25/50 - Classification error: 0.02578 Loss: 0.08669 Time 4702ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-44" name="rest_code_b558f63b96924a61a4b29758d337412c-44" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-44"&gt;&lt;/a&gt;Epoch  26/50 - Classification error: 0.02785 Loss: 0.09368 Time 4700ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-45" name="rest_code_b558f63b96924a61a4b29758d337412c-45" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-45"&gt;&lt;/a&gt;Epoch  27/50 - Classification error: 0.02472 Loss: 0.08237 Time 4695ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-46" name="rest_code_b558f63b96924a61a4b29758d337412c-46" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-46"&gt;&lt;/a&gt;Epoch  28/50 - Classification error: 0.02125 Loss: 0.07324 Time 4690ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-47" name="rest_code_b558f63b96924a61a4b29758d337412c-47" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-47"&gt;&lt;/a&gt;Epoch  29/50 - Classification error: 0.01977 Loss: 0.06635 Time 4688ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-48" name="rest_code_b558f63b96924a61a4b29758d337412c-48" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-48"&gt;&lt;/a&gt;Epoch  30/50 - Classification error: 0.03635 Loss: 0.12140 Time 4689ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-49" name="rest_code_b558f63b96924a61a4b29758d337412c-49" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-49"&gt;&lt;/a&gt;Epoch  31/50 - Classification error: 0.02862 Loss: 0.09704 Time 4698ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-50" name="rest_code_b558f63b96924a61a4b29758d337412c-50" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-50"&gt;&lt;/a&gt;Epoch  32/50 - Classification error: 0.02463 Loss: 0.08158 Time 4686ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-51" name="rest_code_b558f63b96924a61a4b29758d337412c-51" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-51"&gt;&lt;/a&gt;Epoch  33/50 - Classification error: 0.02565 Loss: 0.08771 Time 4697ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-52" name="rest_code_b558f63b96924a61a4b29758d337412c-52" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-52"&gt;&lt;/a&gt;Epoch  34/50 - Classification error: 0.02278 Loss: 0.07634 Time 4718ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-53" name="rest_code_b558f63b96924a61a4b29758d337412c-53" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-53"&gt;&lt;/a&gt;Epoch  35/50 - Classification error: 0.02105 Loss: 0.07075 Time 4697ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-54" name="rest_code_b558f63b96924a61a4b29758d337412c-54" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-54"&gt;&lt;/a&gt;Epoch  36/50 - Classification error: 0.02770 Loss: 0.09358 Time 4711ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-55" name="rest_code_b558f63b96924a61a4b29758d337412c-55" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-55"&gt;&lt;/a&gt;Epoch  37/50 - Classification error: 0.02627 Loss: 0.08805 Time 4742ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-56" name="rest_code_b558f63b96924a61a4b29758d337412c-56" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-56"&gt;&lt;/a&gt;Epoch  38/50 - Classification error: 0.02282 Loss: 0.07712 Time 4708ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-57" name="rest_code_b558f63b96924a61a4b29758d337412c-57" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-57"&gt;&lt;/a&gt;Epoch  39/50 - Classification error: 0.02305 Loss: 0.07661 Time 4697ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-58" name="rest_code_b558f63b96924a61a4b29758d337412c-58" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-58"&gt;&lt;/a&gt;Epoch  40/50 - Classification error: 0.02243 Loss: 0.07773 Time 4700ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-59" name="rest_code_b558f63b96924a61a4b29758d337412c-59" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-59"&gt;&lt;/a&gt;Epoch  41/50 - Classification error: 0.02467 Loss: 0.08234 Time 4712ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-60" name="rest_code_b558f63b96924a61a4b29758d337412c-60" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-60"&gt;&lt;/a&gt;Epoch  42/50 - Classification error: 0.01808 Loss: 0.06186 Time 4691ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-61" name="rest_code_b558f63b96924a61a4b29758d337412c-61" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-61"&gt;&lt;/a&gt;Epoch  43/50 - Classification error: 0.02388 Loss: 0.07917 Time 4681ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-62" name="rest_code_b558f63b96924a61a4b29758d337412c-62" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-62"&gt;&lt;/a&gt;Epoch  44/50 - Classification error: 0.02162 Loss: 0.07508 Time 4699ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-63" name="rest_code_b558f63b96924a61a4b29758d337412c-63" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-63"&gt;&lt;/a&gt;Epoch  45/50 - Classification error: 0.01877 Loss: 0.06289 Time 4735ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-64" name="rest_code_b558f63b96924a61a4b29758d337412c-64" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-64"&gt;&lt;/a&gt;Epoch  46/50 - Classification error: 0.02263 Loss: 0.07969 Time 4764ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-65" name="rest_code_b558f63b96924a61a4b29758d337412c-65" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-65"&gt;&lt;/a&gt;Epoch  47/50 - Classification error: 0.02100 Loss: 0.07207 Time 4684ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-66" name="rest_code_b558f63b96924a61a4b29758d337412c-66" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-66"&gt;&lt;/a&gt;Epoch  48/50 - Classification error: 0.02425 Loss: 0.08076 Time 4752ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-67" name="rest_code_b558f63b96924a61a4b29758d337412c-67" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-67"&gt;&lt;/a&gt;Epoch  49/50 - Classification error: 0.02328 Loss: 0.07803 Time 4718ms
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-68" name="rest_code_b558f63b96924a61a4b29758d337412c-68" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-68"&gt;&lt;/a&gt;Restore the best (error) weights from epoch 42
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-69" name="rest_code_b558f63b96924a61a4b29758d337412c-69" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-69"&gt;&lt;/a&gt;Training took 235s
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-70" name="rest_code_b558f63b96924a61a4b29758d337412c-70" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-70"&gt;&lt;/a&gt;Evaluation Results
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-71" name="rest_code_b558f63b96924a61a4b29758d337412c-71" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-71"&gt;&lt;/a&gt;   error: 0.03000
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-72" name="rest_code_b558f63b96924a61a4b29758d337412c-72" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-72"&gt;&lt;/a&gt;    loss: 0.12260
&lt;a id="rest_code_b558f63b96924a61a4b29758d337412c-73" name="rest_code_b558f63b96924a61a4b29758d337412c-73" href="https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html#rest_code_b558f63b96924a61a4b29758d337412c-73"&gt;&lt;/a&gt;evaluation took 245ms
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nothing fancy, but this example is not necessarily optimized.&lt;/p&gt;
&lt;p&gt;All this support is now in the &lt;strong&gt;master&lt;/strong&gt; branch of the DLL project if you want
to check it out. You can also check out the example online:
&lt;a class="reference external" href="https://github.com/wichtounet/dll/blob/master/examples/src/mnist_rnn.cpp"&gt;mnist_rnn.cpp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can access the project &lt;a class="reference external" href="https://github.com/wichtounet/dll"&gt;on Github&lt;/a&gt;.&lt;/p&gt;</description><category>Deep Learning</category><category>dll</category><category>Machine Learning</category><category>projects</category><category>rnn</category><guid>https://baptiste-wicht.com/posts/2017/11/initial-support-for-recurrent-neural-network-rnn-in-dll.html</guid><pubDate>Sun, 12 Nov 2017 14:22:44 GMT</pubDate></item><item><title>DLL New Features: Embeddings and Merge layers</title><link>https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I've just finished integrating new features into DLL, my deep learning library.
I've added support for an embeddings layer, a group layer and a merge layer.
This is not yet released, but available in the master branch.&lt;/p&gt;
&lt;p&gt;Embeddings are used more and more these days to learn dense representation of
characters or word. An embedding layer in a neural network transform labels into
a vector. It's generally used as the first layer of the network. The embedding
are learned as part of the network.&lt;/p&gt;
&lt;p&gt;The merge layer allows to create branches in the network. The input is passed to
each sub layer and then the output of each layer is concatenated to form the
output of the merged layers. This can be very useful to use different
convolutional filter sizes.&lt;/p&gt;
&lt;p&gt;The group layer is a simple utility to group layers together. This is mostly to
use with merge layers to form several branches.&lt;/p&gt;
&lt;p&gt;I've put together a new example to use these features on text classification.
The dataset is totally synthetic for now, but this can easily be reproduced with
a normal text classification dataset. This kind of model is called a Character
Convolutional Neural Network.&lt;/p&gt;
&lt;p&gt;Here is the code for example:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-1" name="rest_code_21af2587003d47fea6be105f1565773e-1" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// The length of the embedding vector&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-2" name="rest_code_21af2587003d47fea6be105f1565773e-2" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-2"&gt;&lt;/a&gt;&lt;span class="k"&gt;constexpr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// The word (or sequence) length&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-3" name="rest_code_21af2587003d47fea6be105f1565773e-3" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-3"&gt;&lt;/a&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-4" name="rest_code_21af2587003d47fea6be105f1565773e-4" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-4"&gt;&lt;/a&gt;&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding_network_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;dyn_network_desc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-5" name="rest_code_21af2587003d47fea6be105f1565773e-5" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-5"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;network_layers&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-6" name="rest_code_21af2587003d47fea6be105f1565773e-6" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-6"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// The embedding layer&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-7" name="rest_code_21af2587003d47fea6be105f1565773e-7" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-7"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;embedding_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-8" name="rest_code_21af2587003d47fea6be105f1565773e-8" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-8"&gt;&lt;/a&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-9" name="rest_code_21af2587003d47fea6be105f1565773e-9" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-9"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// The convolutional layers&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-10" name="rest_code_21af2587003d47fea6be105f1565773e-10" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-10"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;merge_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-11" name="rest_code_21af2587003d47fea6be105f1565773e-11" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-11"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-12" name="rest_code_21af2587003d47fea6be105f1565773e-12" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-12"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;group_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-13" name="rest_code_21af2587003d47fea6be105f1565773e-13" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-13"&gt;&lt;/a&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;conv_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-14" name="rest_code_21af2587003d47fea6be105f1565773e-14" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-14"&gt;&lt;/a&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mp_2d_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-15" name="rest_code_21af2587003d47fea6be105f1565773e-15" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-15"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-16" name="rest_code_21af2587003d47fea6be105f1565773e-16" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-16"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;group_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-17" name="rest_code_21af2587003d47fea6be105f1565773e-17" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-17"&gt;&lt;/a&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;conv_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-18" name="rest_code_21af2587003d47fea6be105f1565773e-18" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-18"&gt;&lt;/a&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mp_2d_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-19" name="rest_code_21af2587003d47fea6be105f1565773e-19" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-19"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-20" name="rest_code_21af2587003d47fea6be105f1565773e-20" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-20"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;group_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-21" name="rest_code_21af2587003d47fea6be105f1565773e-21" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-21"&gt;&lt;/a&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;conv_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-22" name="rest_code_21af2587003d47fea6be105f1565773e-22" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-22"&gt;&lt;/a&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mp_2d_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-23" name="rest_code_21af2587003d47fea6be105f1565773e-23" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-23"&gt;&lt;/a&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-24" name="rest_code_21af2587003d47fea6be105f1565773e-24" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-24"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-25" name="rest_code_21af2587003d47fea6be105f1565773e-25" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-25"&gt;&lt;/a&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-26" name="rest_code_21af2587003d47fea6be105f1565773e-26" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-26"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// The final softmax layer&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-27" name="rest_code_21af2587003d47fea6be105f1565773e-27" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-27"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;dense_layer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;softmax&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-28" name="rest_code_21af2587003d47fea6be105f1565773e-28" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-28"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-29" name="rest_code_21af2587003d47fea6be105f1565773e-29" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-29"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;updater&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;updater_type&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NADAM&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="c1"&gt;// Nesterov Adam (NADAM)&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-30" name="rest_code_21af2587003d47fea6be105f1565773e-30" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-30"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="c1"&gt;// The mini-batch size&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-31" name="rest_code_21af2587003d47fea6be105f1565773e-31" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-31"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dll&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;shuffle&lt;/span&gt;&lt;span class="w"&gt;                               &lt;/span&gt;&lt;span class="c1"&gt;// Shuffle before each epoch&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-32" name="rest_code_21af2587003d47fea6be105f1565773e-32" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-32"&gt;&lt;/a&gt;&lt;span class="o"&gt;&amp;gt;::&lt;/span&gt;&lt;span class="n"&gt;network_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-33" name="rest_code_21af2587003d47fea6be105f1565773e-33" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-33"&gt;&lt;/a&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-34" name="rest_code_21af2587003d47fea6be105f1565773e-34" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-34"&gt;&lt;/a&gt;&lt;span class="k"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;make_unique&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;embedding_network_t&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-35" name="rest_code_21af2587003d47fea6be105f1565773e-35" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-35"&gt;&lt;/a&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-36" name="rest_code_21af2587003d47fea6be105f1565773e-36" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-36"&gt;&lt;/a&gt;&lt;span class="c1"&gt;// Display the network and dataset&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-37" name="rest_code_21af2587003d47fea6be105f1565773e-37" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-37"&gt;&lt;/a&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-38" name="rest_code_21af2587003d47fea6be105f1565773e-38" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-38"&gt;&lt;/a&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-39" name="rest_code_21af2587003d47fea6be105f1565773e-39" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-39"&gt;&lt;/a&gt;&lt;span class="c1"&gt;// Train the network for performance sake&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-40" name="rest_code_21af2587003d47fea6be105f1565773e-40" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-40"&gt;&lt;/a&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;fine_tune&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;samples&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-41" name="rest_code_21af2587003d47fea6be105f1565773e-41" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-41"&gt;&lt;/a&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-42" name="rest_code_21af2587003d47fea6be105f1565773e-42" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-42"&gt;&lt;/a&gt;&lt;span class="c1"&gt;// Test the network on train set&lt;/span&gt;
&lt;a id="rest_code_21af2587003d47fea6be105f1565773e-43" name="rest_code_21af2587003d47fea6be105f1565773e-43" href="https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html#rest_code_21af2587003d47fea6be105f1565773e-43"&gt;&lt;/a&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;samples&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The network starts with an embedding layer. The embedding is then passed to
three convolutional layers with different filter sizes, each followed by
a pooling layer. The outputs of the three layers are merged at the end of the
merge layer. Finally, a softmax layer is used for classification.&lt;/p&gt;
&lt;p&gt;This kind of model can be very powerful and is used regularly. These new
features make for a much larger variety of models that can be build with the DLL
library.&lt;/p&gt;
&lt;p&gt;The full code with the dataset generation can be found online:
&lt;a class="reference external" href="https://github.com/wichtounet/dll/blob/master/examples/src/char_cnn.cpp"&gt;char_cnn.cpp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The next feature I want to focus on is recurrent neural networks. I'll probably
try a single RNN layer first and then upgrade to multi-layers and LSTM and maybe
GRU.&lt;/p&gt;</description><category>C++</category><category>Deep Learning</category><category>dll</category><category>Machine Learning</category><category>projects</category><guid>https://baptiste-wicht.com/posts/2017/10/dll-new-features-embeddings-and-merge-layers.html</guid><pubDate>Tue, 17 Oct 2017 17:50:40 GMT</pubDate></item><item><title>I successfully defended my Ph.D.</title><link>https://baptiste-wicht.com/posts/2017/10/i-successfully-defended-my-phd.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I'm happy to announce that I've successfully defended my thesis "Deep Learning
Features for Image Processing". After four years, I've defended it officially in
front of the thesis committed last Friday and then again two days ago I've
successfully publicly defended in front of my friends, family and colleagues.&lt;/p&gt;
&lt;p&gt;I'm now a "Doctor of Philosophy in Computer Science :)&lt;/p&gt;
&lt;p&gt;I will update my thesis with the last comments in November and send the final
version to the university. At which point, I'll publish it on this website as
well.&lt;/p&gt;</description><category>Machine Learning</category><category>Personal</category><category>thesis</category><guid>https://baptiste-wicht.com/posts/2017/10/i-successfully-defended-my-phd.html</guid><pubDate>Sun, 15 Oct 2017 15:16:29 GMT</pubDate></item><item><title>Budgetwarrior: Track assets and portfolio, savings rates and auto-completion</title><link>https://baptiste-wicht.com/posts/2017/10/budgetwarrior-track-assets-portfolio-savings-rates-auto-completion.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;This last month, I've been reading quite a few blogs about personal finance and
I've decided to integrate more features into budgetwarrior. This post is about
three new features that I've integrated. It's not yet a new release, so if you
want to test this version, you'll have to compile it from the &lt;em&gt;master&lt;/em&gt; branch on
Git.&lt;/p&gt;
&lt;p&gt;As it was last time, the values on my screenshots have all been randomized.&lt;/p&gt;
&lt;p&gt;If you have several assets with different distributions, I believe it is a great
value to have them all shown at the same time. Especially if you want to change
the distribution of your portfolio or if you plan big changes in it.&lt;/p&gt;
&lt;section id="track-assets"&gt;
&lt;h2&gt;Track assets&lt;/h2&gt;
&lt;p&gt;The first feature I've added is a feature to precisely track each of your assets
independently. And you can also track the allocation of your portfolio in terms
of stocks, bonds and cash. The tool also lets you set the desired distribution
of your assets and will compute the difference that you should make in order to
comply to your desired distribution.&lt;/p&gt;
&lt;p&gt;First, you need to define all your asset classes (your accounts, funds, and
stocks, ...) and their distribution with &lt;code&gt;budget asset add&lt;/code&gt;. It also
supports to set a currency. The default currency is now CHF, but you can set it
in the configuration file, for instance &lt;code&gt;default_currency=USD&lt;/code&gt;. You can
see your assets using &lt;code&gt;budget asset&lt;/code&gt;:&lt;/p&gt;
&lt;img alt="View of your assets" src="https://baptiste-wicht.com/images/budgetwarrior_assets.png"&gt;
&lt;p&gt;You can then set the value of your assets using &lt;code&gt;budget asset value add&lt;/code&gt;.
The system will save all the values of your assets. For now, only the last value
is used in the application to display. In the future, I plan to add new reports
for evolution of the portfolio over time. You can see your current net worth
with the &lt;code&gt;budget asset value&lt;/code&gt;:&lt;/p&gt;
&lt;img alt="View of your portfolio" src="https://baptiste-wicht.com/images/budgetwarrior_asset_values.png"&gt;
&lt;p&gt;The different currencies will all be converted to the default currency.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="savings-rate"&gt;
&lt;h2&gt;Savings rate&lt;/h2&gt;
&lt;p&gt;The second change I did is to compute the savings rate of each month and year.
The savings rate is simply the portion of your income that you are able to save
each month. The savings rate for a year is simple the average of the savings
rate of each month.&lt;/p&gt;
&lt;p&gt;The savings rate of the month can be seen with &lt;code&gt;budget overview month&lt;/code&gt;:&lt;/p&gt;
&lt;img alt="Savings rate of the month" src="https://baptiste-wicht.com/images/budgetwarrior_savings_rate.png"&gt;
&lt;p&gt;The saving rates of each month can also be seen in the overview of the year with
&lt;code&gt;budget overview year&lt;/code&gt;:&lt;/p&gt;
&lt;img alt="Savings rate of the year" src="https://baptiste-wicht.com/images/budgetwarrior_savings_rate_year.png"&gt;
&lt;p&gt;This shows the savings rate of each month, the average of the year and the
average of the current year up to the current month.&lt;/p&gt;
&lt;p&gt;The savings rate is a very important metric of your budget. In my case, it's
currently way too low and made me realize I really need to save more. Any
savings rate below 10% is too low. There are no rule as too much it should be,
but I'd like to augment mine to at least 20% next year.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="auto-completion"&gt;
&lt;h2&gt;Auto-completion&lt;/h2&gt;
&lt;p&gt;The last feature is mostly some quality-of-life improvement. Some of the inputs
in the console can now be completed. It's not really auto-completion per se, but
you can cycle through the list of possible values using the UP and DOWN.&lt;/p&gt;
&lt;p&gt;This makes it much easier to set some values such as asset names (in
&lt;code&gt;budget asset value add&lt;/code&gt; for instance), account names and objective types
and sources. I'm trying to make the input of values easier.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I don't know exactly what else will be integrated in this feature, but I may
already improve some visualization for asset values. If I learn something new
about personal finance that I may integrate in the tool, I'll do it as well.&lt;/p&gt;
&lt;p&gt;If you are interested by the sources or want to install this version,
you can download them on Github:
&lt;a class="reference external" href="https://github.com/wichtounet/budgetwarrior"&gt;budgetwarrior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The new features are in the &lt;em&gt;master&lt;/em&gt; branch.&lt;/p&gt;
&lt;p&gt;If you have a suggestion for a new features or you found a bug, please post an
issue on Github, I'd be glad to help you.&lt;/p&gt;
&lt;p&gt;If you have any comment, don't hesitate to contact me, either by letting a
comment on this post or by email.&lt;/p&gt;
&lt;/section&gt;</description><category>budgetwarrior</category><category>C++</category><category>Linux</category><guid>https://baptiste-wicht.com/posts/2017/10/budgetwarrior-track-assets-portfolio-savings-rates-auto-completion.html</guid><pubDate>Thu, 12 Oct 2017 17:40:14 GMT</pubDate></item><item><title>Deep Learning Library 1.0 - Fast Neural Network Library</title><link>https://baptiste-wicht.com/posts/2017/10/deep-learning-library-10-fast-neural-network-library.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;div&gt;&lt;img alt="DLL Logo" class="align-center" src="https://baptiste-wicht.com/images/dll_logo.png"&gt;
&lt;p&gt;I'm very happy to announce the release of the first version of Deep Learning
Library (DLL) 1.0. DLL is a neural network library with a focus on speed and
ease of use.&lt;/p&gt;
&lt;p&gt;I started working on this library about 4 years ago for my Ph.D. thesis.
I needed a good library to train and use Restricted Boltzmann Machines (RBMs)
and at this time there was no good support for it. Therefore, I decided to write
my own. It now has very complete support for the RBM and the Convolutional RBM
(CRBM) models. Stacks of RBMs (or Deep Belief Networks (DBNs)) can be pretrained
using Contrastive Divergence and then either fine-tuned with mini-batch gradient
descent or Conjugate Gradient or used as a feature extractor. Over the years,
the library has been extended to handle Artificial Neural Networks (ANNs) and
Convolutional Neural Networks (CNNs). The network is also able to train regular
auto-encoders. Several advanced layers such as Dropout or Batch Normalization
are also available as well as adaptive learning rates techniques such as
Adadelta and Adam. The library also has integrated support for a few datasets:
MNIST, CIFAR-10 and ImageNet.&lt;/p&gt;
&lt;p&gt;This library can be used using a C++ interface. The library is fully
header-only. It requires a C++14 compiler, which means a minimum of clang 3.9 or
GCC 6.3.&lt;/p&gt;
&lt;p&gt;In this post, I'm going to present a few examples on using the library and give
some information about the performance of the library and the roadmap for the
project.&lt;/p&gt;
&lt;p class="more"&gt;&lt;a href="https://baptiste-wicht.com/posts/2017/10/deep-learning-library-10-fast-neural-network-library.html"&gt;Read more…&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;</description><category>C++</category><category>dll</category><category>etl</category><category>GPU</category><category>Machine Learning</category><category>Performances</category><category>Releases</category><guid>https://baptiste-wicht.com/posts/2017/10/deep-learning-library-10-fast-neural-network-library.html</guid><pubDate>Sat, 07 Oct 2017 13:42:16 GMT</pubDate></item><item><title>Expression Templates Library (ETL) 1.2 - Complete GPU support</title><link>https://baptiste-wicht.com/posts/2017/10/expression-templates-library-etl-1-2-complete-gpu-support.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;img alt="ETL Logo" class="align-center" src="https://baptiste-wicht.com/images/logo.png"&gt;
&lt;p&gt;I'm happy to announce the version 1.2 of my Expression Templates Library (ETL):
ETL 1.2, two months after &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/08/expression-templates-library-etl-11.html"&gt;I released the version 1.1&lt;/a&gt;.
This version features much better GPU Support, a few new features and a lot of
changes in the internal code.&lt;/p&gt;
&lt;section id="gpu-support"&gt;
&lt;h2&gt;GPU Support&lt;/h2&gt;
&lt;p&gt;Before, only algorithms such as 4D convolution or matrix-matrix multiplication
were computed in the GPU and lots of operations were causing copies between CPU
and GPU version. Now, the support for basic operations has also been completed
and therefore, expressions like this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_4880248f581649aeb00f8e807dac13ba-1" name="rest_code_4880248f581649aeb00f8e807dac13ba-1" href="https://baptiste-wicht.com/posts/2017/10/expression-templates-library-etl-1-2-complete-gpu-support.html#rest_code_4880248f581649aeb00f8e807dac13ba-1"&gt;&lt;/a&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sigmoid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Can be computed entirely on GPU.&lt;/p&gt;
&lt;p&gt;Each matrix and vector containers have a secondary GPU memory space.  During the
execution, the status of both memory spaces is being managed and when necessary,
copies are made between two spaces. In the best case, there should only be
initial copies to the GPU and then everything should be done on the GPU. I've
also considered using Unified Memory in place of this system, but this is
a problem for fast matrix and I'd rather not have two different systems.&lt;/p&gt;
&lt;p&gt;If you have an expression such as &lt;code&gt;c = a + b * 2&lt;/code&gt;, it can be entirely computed
on GPU, however, it will be computed in two GPU operations such as:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code cpp"&gt;&lt;a id="rest_code_f699b25ff2a042f3887ee554c01bd8f9-1" name="rest_code_f699b25ff2a042f3887ee554c01bd8f9-1" href="https://baptiste-wicht.com/posts/2017/10/expression-templates-library-etl-1-2-complete-gpu-support.html#rest_code_f699b25ff2a042f3887ee554c01bd8f9-1"&gt;&lt;/a&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;a id="rest_code_f699b25ff2a042f3887ee554c01bd8f9-2" name="rest_code_f699b25ff2a042f3887ee554c01bd8f9-2" href="https://baptiste-wicht.com/posts/2017/10/expression-templates-library-etl-1-2-complete-gpu-support.html#rest_code_f699b25ff2a042f3887ee554c01bd8f9-2"&gt;&lt;/a&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is not perfect in terms of performance but this will be done without any
copies between CPU and GPU memory. I plan to improve this system with a bit more
complex operations to avoid too many GPU operations, but there will always be
more operations than in CPU where this can easily be done in one go.&lt;/p&gt;
&lt;p&gt;There are a few expressions that are not computable on the GPU, such as random
generations. A few transformations are also not fully compatible with GPU.
Moreover, if you access an element with operators &lt;code&gt;[]&lt;/code&gt; or &lt;code&gt;()&lt;/code&gt;, this
will invalidate the GPU memory and force an update to the CPU memory.&lt;/p&gt;
&lt;p&gt;GPU operations are not implemented directly in ETL, there are coming from
various libraries. ETL is using NVIDIA CUDNN, CUFFT and CUDNN for most
algorithms. Moreover, for other operations, I've implemented a libraries with
simple GPU operations: ETL-GPU-BLAS (EGBLAS). You can have a look at
&lt;a class="reference external" href="https://github.com/wichtounet/etl-gpu-blas"&gt;egblas&lt;/a&gt; if you are interested.&lt;/p&gt;
&lt;p&gt;My Deep Learning Library (DLL) project is based on ETL and its performances are
mostly dependent on ETL's performances. Now that ETL fully supports GPU, the
GPU performance of DLL is much improved. You may remember a few weeks ago
I posted &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/08/dll-blazing-fast-neural-network-library.html"&gt;very high CPU performance of DLL&lt;/a&gt;.
Now, I've run again the tests to see the GPU performance with DLL. Here is the
performance for training a small CNN on the MNIST data set:&lt;/p&gt;
&lt;img alt="Performances for training a Convolutional Neural Network on MNIST" class="align-center" src="https://baptiste-wicht.com/images/etl_12_dll_gpu_mnist.png"&gt;
&lt;p&gt;As you can see, the performances on GPU are now excellent. DLL's performances
are on par with Tensorflow and Keras!&lt;/p&gt;
&lt;p&gt;The next results are for training a much larger CNN on ImageNet, with the time
necessary to train a single batch:&lt;/p&gt;
&lt;img alt="Performances for training a Convolutional Neural Network on Imagenet" class="align-center" src="https://baptiste-wicht.com/images/etl_12_dll_gpu_imagenet.png"&gt;
&lt;p&gt;Again, using the new version of ETL inside DLL has led to excellent performance.
The framework is again on par with TensorFlow and Keras and faster than all the
other frameworks. The large difference between DLL and Tensorflow and Keras is
due to the inefficiency of reading the dataset in the two frameworks, so the
performance of the three framework themselves are about the same.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-changes"&gt;
&lt;h2&gt;Other Changes&lt;/h2&gt;
&lt;p&gt;The library also has a few other new features. Logarithms of base 2 and base 10
are now supported in complement to the base e that was already available before.
Categorical Cross Entropy (CCE) computation is also available now, the CCE loss
and error can be computed for one or many samples. Convolutions have also been
improved in that you can use mixed types in both the image and the kernel and
different storage order as well. Nevertheless, the most optimized version
remains the version with the same storage order and the same data type.&lt;/p&gt;
&lt;p&gt;I've also made a major change in the way implementations are selected for each
operation. The tests and the benchmark are using a system to force the selection
of an algorithm. This system is now disabled by default. This makes the
compilation much faster by default. Since it's not necessary in most cases, this
will help regular use cases of the library by compiling much faster.&lt;/p&gt;
&lt;p&gt;Overall, the support for complex numbers has been improved in ETL. There are
more routines that are supported and &lt;code&gt;etl::complex&lt;/code&gt; is better supported
throughout the code. I'll still work on this in the future to make it totally
complete.&lt;/p&gt;
&lt;p&gt;The internal code also has a few new changes. First, all traits have been
rewritten to use variable templates instead of struct traits. This makes the
code much nicer in my opinion. Moreover, I've started experimenting with C++17
&lt;code&gt;if constexpr&lt;/code&gt;. Most of the if conditions that can be transformed to if
constexpr have been annotated with comments that I can quickly enable or disable
so that I can test the impact of C++17, especially on compilation time.&lt;/p&gt;
&lt;p&gt;Finally, a few bugs have been fixed. ETL is now working better with parallel
BLAS library. There should not be issues with double parallelization in ETL and
BLAS. There was a slight bug in the Column-Major matrix-matrix multiplication
kernel. Binary operations with different types in the left and right hand sides
was also problematic with vectorization. The last bug was about GPU status in
case ETL containers were moved.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="what-s-next"&gt;
&lt;h2&gt;What's next ?&lt;/h2&gt;
&lt;p&gt;I don't yet know exactly on which features I'm going to focus for the next
version of ETL. I plan to focus a bit more in the near future on Deep Learning
Library (DLL) for which I should release the version 1.0 soon. I also plan to
start support for Recurrent Neural Networks on it, so that will take me quite
some time.&lt;/p&gt;
&lt;p&gt;Nevertheless, I'm still planning to consider the switch to C++17, since it is
&lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/09/how-i-made-deep-learning-library-38-faster-to-compile-optimization-and-cpp17-if-constexpr.html"&gt;a bit faster to compile ETL with if constexpr&lt;/a&gt;. The next version of ETL will also probably have GPU-support for
integers, at least in the cases that depend on the etl-gpu-blas library, which
is the standard operators. I also plan to improve the support for complex
numbers, especially in terms of performance and tests. Hopefully, I will have also time (and motivation)
to start working on  the sparse capabilities of ETL. It really needs much more
unit tests and the performance should be improved as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="download-etl"&gt;
&lt;h2&gt;Download ETL&lt;/h2&gt;
&lt;p&gt;You can download ETL &lt;a class="reference external" href="https://github.com/wichtounet/etl"&gt;on Github&lt;/a&gt;. If you
only interested in the 1.2 version, you can look at the
&lt;a class="reference external" href="https://github.com/wichtounet/etl/releases"&gt;Releases pages&lt;/a&gt; or clone the tag
1.2. There are several branches:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;master&lt;/em&gt; Is the eternal development branch, may not always be stable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;stable&lt;/em&gt; Is a branch always pointing to the last tag, no development here&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the future release, there always will tags pointing to the corresponding
commits. You can also have access to previous releases on Github or via the
release tags.&lt;/p&gt;
&lt;p&gt;The documentation is still a bit sparse. There are a few examples and the Wiki,
but there still is work to be done. If you have questions on how to use or
configure the library, please don't hesitate.&lt;/p&gt;
&lt;p&gt;Don't hesitate to comment this post if you have any comment on this library or
any question. You can also open an Issue on Github if you have a problem using
this library or propose a Pull Request if you have any contribution you'd like
to make to the library.&lt;/p&gt;
&lt;p&gt;Hope this may be useful to some of you :)&lt;/p&gt;
&lt;/section&gt;</description><category>C++</category><category>C++14</category><category>C++17</category><category>Compilers</category><category>dll</category><category>etl</category><category>GPU</category><category>Performance</category><category>projects</category><category>Release</category><guid>https://baptiste-wicht.com/posts/2017/10/expression-templates-library-etl-1-2-complete-gpu-support.html</guid><pubDate>Mon, 02 Oct 2017 08:49:02 GMT</pubDate></item><item><title>C++11 Performance tip: Update on when to use std::pow ?</title><link>https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;A few days ago, I published a post comparing the
&lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-when-to-use-std-pow.html"&gt;performance of std::pow against direct multiplications&lt;/a&gt;. When not compiling with -ffast-math, direct multiplication was significantly faster than &lt;code&gt;std::pow&lt;/code&gt;, around two orders of magnitude faster when comparing &lt;code&gt;x * x * x&lt;/code&gt; and &lt;code&gt;code:std::pow(x, 3)&lt;/code&gt;.
One comment that I've got was to test for which &lt;code&gt;n&lt;/code&gt; is
&lt;code&gt;code:std::pow(x, n)&lt;/code&gt; becoming faster than multiplying in a loop. Since
std::pow is using a special algorithm to perform the computation rather than be
simply loop-based multiplications, there may be a point after which it's more interesting to use the
algorithm rather than a loop. So I decided to do the tests. You can also find
the result in the original article, which I've updated.&lt;/p&gt;
&lt;p&gt;First, our pow function:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code c++"&gt;&lt;a id="rest_code_7108cb7dee0c48eba724db26a71df046-1" name="rest_code_7108cb7dee0c48eba724db26a71df046-1" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html#rest_code_7108cb7dee0c48eba724db26a71df046-1"&gt;&lt;/a&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;my_pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;a id="rest_code_7108cb7dee0c48eba724db26a71df046-2" name="rest_code_7108cb7dee0c48eba724db26a71df046-2" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html#rest_code_7108cb7dee0c48eba724db26a71df046-2"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_7108cb7dee0c48eba724db26a71df046-3" name="rest_code_7108cb7dee0c48eba724db26a71df046-3" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html#rest_code_7108cb7dee0c48eba724db26a71df046-3"&gt;&lt;/a&gt;
&lt;a id="rest_code_7108cb7dee0c48eba724db26a71df046-4" name="rest_code_7108cb7dee0c48eba724db26a71df046-4" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html#rest_code_7108cb7dee0c48eba724db26a71df046-4"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;a id="rest_code_7108cb7dee0c48eba724db26a71df046-5" name="rest_code_7108cb7dee0c48eba724db26a71df046-5" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html#rest_code_7108cb7dee0c48eba724db26a71df046-5"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_7108cb7dee0c48eba724db26a71df046-6" name="rest_code_7108cb7dee0c48eba724db26a71df046-6" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html#rest_code_7108cb7dee0c48eba724db26a71df046-6"&gt;&lt;/a&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_7108cb7dee0c48eba724db26a71df046-7" name="rest_code_7108cb7dee0c48eba724db26a71df046-7" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html#rest_code_7108cb7dee0c48eba724db26a71df046-7"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;a id="rest_code_7108cb7dee0c48eba724db26a71df046-8" name="rest_code_7108cb7dee0c48eba724db26a71df046-8" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html#rest_code_7108cb7dee0c48eba724db26a71df046-8"&gt;&lt;/a&gt;
&lt;a id="rest_code_7108cb7dee0c48eba724db26a71df046-9" name="rest_code_7108cb7dee0c48eba724db26a71df046-9" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html#rest_code_7108cb7dee0c48eba724db26a71df046-9"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_7108cb7dee0c48eba724db26a71df046-10" name="rest_code_7108cb7dee0c48eba724db26a71df046-10" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html#rest_code_7108cb7dee0c48eba724db26a71df046-10"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now, let's see the performance. I've compiled my benchmark with GCC 4.9.3
and running on my old Sandy Bridge processor. Here are the results for 1000
calls to each functions:&lt;/p&gt;
&lt;div id="graph_std_pow_my_pow_1" style="width: 700px; height: 400px;"&gt;&lt;/div&gt;&lt;p&gt;We can see that between &lt;code&gt;n=100&lt;/code&gt; and &lt;code&gt;n=110&lt;/code&gt;, &lt;code&gt;std::pow(x, n)&lt;/code&gt;
starts to be faster than &lt;code&gt;my_pow(x, n)&lt;/code&gt;. At this point, you should only
use &lt;code&gt;std::pow(x, n)&lt;/code&gt;.  Interestingly too, the time for &lt;code&gt;std::pow(x,
n)&lt;/code&gt; is decreasing. Let's see how is the performance with higher range of
&lt;code&gt;n&lt;/code&gt;:&lt;/p&gt;
&lt;div id="graph_std_pow_my_pow_2" style="width: 700px; height: 400px;"&gt;&lt;/div&gt;&lt;p&gt;We can see that the pow function time still remains stable while our loop-based
pow function still increases linearly. At &lt;code&gt;n=1000&lt;/code&gt;, &lt;code&gt;std::pow&lt;/code&gt; is
one order of magnitude faster than &lt;code&gt;my_pow&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Overall, if you do not care much about extreme accuracy, you may consider using
you own pow function for small-ish (integer) &lt;code&gt;n&lt;/code&gt; values. After
&lt;code&gt;n=100&lt;/code&gt;, it becomes more interesting to use &lt;code&gt;std::pow&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you want more results on the subject, you take a look at the
&lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-when-to-use-std-pow.html"&gt;original article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you are interested in the code of this benchmark, it's available online:
&lt;a class="reference external" href="https://github.com/wichtounet/articles/blob/master/src/bench_pow_my_pow.cpp"&gt;bench_pow_my_pow.cpp&lt;/a&gt;&lt;/p&gt;
&lt;script type="text/javascript" src="https://www.google.com/jsapi"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;google.load('visualization', '1.0', {'packages':['corechart']});&lt;/script&gt;
&lt;script type="text/javascript"&gt;
function draw_graph_pow_my_pow_1(){
var data = google.visualization.arrayToDataTable([
['n', 'my_pow(x, n)', 'std::pow(x, n)'],
['10',   2,     127],
['20',   17,     123],
['30',   26,     127],
['40',   36,     123],
['50',   43,     123],
['60',   55,     123],
['70',   72,     123],
['80',   85,     123],
['90',   102,    126],
['100',  114,    125],
['110',  131,    115],
['120',  144,    111],
['130',  165,    111],
['140',  173,    108],
['150',  189,    107],
['160',  202,    112],
['170',  219,    106],
['180',  232,    105],
['190',  249,    108],
['200',  261,    105],
]);
var graph = new google.visualization.LineChart(document.getElementById('graph_std_pow_my_pow_1'));
var options = {curveType: "function",title: "std::pow(x, 2) (float)",animation: {duration:1200, easing:"in"},width: 700, height: 400,hAxis: {title:"Number of elements", slantedText:true},vAxis: {viewWindow: {min:0}, title:"us"}};
graph.draw(data, options);
}
function draw_graph_pow_my_pow_2(){
var data = google.visualization.arrayToDataTable([
['n', 'my_pow(x, n)', 'std::pow(x, n)'],
['100',  114,    125],
['200',  261,    105],
['300',  410,    104],
['400',  558,    104],
['500',  708,    104],
['600',  855,    104],
['700',  1002,   104],
['800',  1148,   104],
['900',  1300,   104],
['1000', 1442,   104],
]);
var graph = new google.visualization.LineChart(document.getElementById('graph_std_pow_my_pow_2'));
var options = {curveType: "function",title: "std::pow(x, 2) (float)",animation: {duration:1200, easing:"in"},width: 700, height: 400,hAxis: {title:"Number of elements", slantedText:true},vAxis: {viewWindow: {min:0}, title:"us"}};
graph.draw(data, options);
}
function draw_all(){
draw_graph_pow_my_pow_1();
draw_graph_pow_my_pow_2();
}
google.setOnLoadCallback(draw_all);
&lt;/script&gt;</description><category>Benchmark</category><category>C++</category><category>C++11</category><category>Performances</category><category>Tip</category><guid>https://baptiste-wicht.com/posts/2017/09/cpp11-performance-tip-update-when-to-use-std-pow.html</guid><pubDate>Fri, 22 Sep 2017 09:21:07 GMT</pubDate></item><item><title>How I made my Deep Learning Library 38% faster to compile (Optimization and C++17 if constexpr)</title><link>https://baptiste-wicht.com/posts/2017/09/how-i-made-deep-learning-library-38-faster-to-compile-optimization-and-cpp17-if-constexpr.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;div&gt;&lt;p&gt;My Deep Learning Library (DLL) project is a C++ library for training and using
artificial neural networks (you can take a look at
&lt;a class="reference external" href="https://baptiste-wicht.com/posts/2017/07/update-on-deep-learning-library-dll-dropout-batch-normalization-adaptive-learning-rates.html"&gt;this post about DLL&lt;/a&gt;
if you want more information).&lt;/p&gt;
&lt;p&gt;While I made a lot of effort to make it as fast as possible to train and run
neural networks, the compilation time has been steadily going up and is becoming
quite annoying. This library is heavily templated and all the matrix operations
are done using my Expression Templates Library (ETL) which is more than
template-heavy itself.&lt;/p&gt;
&lt;p&gt;In this post, I'll present two techniques with which I've been able to reduce
the total compilation of the DLL unit tests by up to 38%.&lt;/p&gt;
&lt;p class="more"&gt;&lt;a href="https://baptiste-wicht.com/posts/2017/09/how-i-made-deep-learning-library-38-faster-to-compile-optimization-and-cpp17-if-constexpr.html"&gt;Read more…&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;</description><category>C++</category><category>C++17</category><category>clang</category><category>Compilers</category><category>dll</category><category>etl</category><category>gcc</category><category>Performance</category><category>projects</category><guid>https://baptiste-wicht.com/posts/2017/09/how-i-made-deep-learning-library-38-faster-to-compile-optimization-and-cpp17-if-constexpr.html</guid><pubDate>Thu, 21 Sep 2017 17:44:34 GMT</pubDate></item></channel></rss>