<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Random Thoughts</title>
<link>https://blog.brunk.io/</link>
<atom:link href="https://blog.brunk.io/index.xml" rel="self" type="application/rss+xml"/>
<description>Machine learning, Scala, and interactive computing</description>
<generator>quarto-1.5.57</generator>
<lastBuildDate>Sun, 11 Aug 2024 22:00:00 GMT</lastBuildDate>
<item>
  <title>DuckDB.mojo at the MAX &amp; Mojo Community Meeting</title>
  <link>https://blog.brunk.io/posts/mojo-community-meeting-duckdb/</link>
  <description><![CDATA[ 





<p>I gave a short presentation at the 6th Max + Mojo Community Meeting‍ about <a href="https://github.com/sbrunk/duckdb.mojo">DuckDB.mojo</a>, the <a href="https://www.modular.com/mojo">Mojo</a> <a href="https://duckdb.org/">DuckDB</a> bindings I’m working on:</p>
<div class="quarto-video ratio ratio-16x9"><iframe data-external="1" src="https://www.youtube.com/embed/6huytcgQgk8?start=784" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></div>
<p><a href="../../slides/2024-08-12-mojo-community-meeting-duckdb/index.html" target="_blank">View slides in fullscreen</a></p>
<iframe class="slide-deck" style="width: 100%; aspect-ratio: 1050/700;" src="../../slides/2024-08-12-mojo-community-meeting-duckdb/index.html">
</iframe>



 ]]></description>
  <category>mojo</category>
  <category>duckdb</category>
  <guid>https://blog.brunk.io/posts/mojo-community-meeting-duckdb/</guid>
  <pubDate>Sun, 11 Aug 2024 22:00:00 GMT</pubDate>
  <media:content url="https://blog.brunk.io/posts/mojo-community-meeting-duckdb/mojo_loves_duckdb.png" medium="image" type="image/png" height="102" width="144"/>
</item>
<item>
  <title>Using DuckDB for Embeddings and Vector Search</title>
  <link>https://blog.brunk.io/posts/similarity-search-with-duckdb/</link>
  <description><![CDATA[ 





<p><a href="https://duckdb.org/">DuckDB</a>, with version <a href="https://duckdb.org/2024/06/03/announcing-duckdb-100">1.0.0</a> released just last week, emphasizing API/format stability and backwards compatibility, is one of my favorite systems for doing data analysis. It’s blazingly fast, helps you avoid running out of memory even when dealing with larger datasets on a single machine and, quoting Hannes Mühleisen, one of its creators, it “doesn’t suck” when it comes to non-core database things like importing CSV or having a decent CLI. Last but not least, SQL is clearly undefeated:</p>
<div class="centered">
<iframe src="https://hachyderm.io/@forrestbrazeal/112553276907862881/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="400" allowfullscreen="allowfullscreen">
</iframe>
<script src="https://hachyderm.io/embed.js" async="async"></script>
</div>
<p>Just in case you feel offended by this diagram: I’m a software engineer and I have trained and deployed generative language models with actual business value since 2021. So I’m in two circles here and I still think there’s a lot of truth in it.</p>
<p>Since I’m working on neural information retrieval use-cases, I was very excited when I heard that DuckDB has <a href="https://duckdb.org/docs/sql/data_types/array">array support</a> including distance functions like dot product and cosine and that it also got a <a href="https://duckdb.org/2024/05/03/vector-similarity-search-vss.html">vector similarity search extension</a> recently. Equipped with these tools, we can use DuckDB to work with <strong>embeddings</strong>.</p>
<section id="embeddings" class="level2">
<h2 class="anchored" data-anchor-id="embeddings">Embeddings</h2>
<p>An embedding is a <em>vector representation</em> of data like a text or an image mapped into a vector space in some meaningful way, i.e.&nbsp;data points that are similar in some sense should be close to each other in that vector space. Embeddings are kind of a by-product of training neural networks, because they are an internal representation of the data inside the model. But we can also use their properties for <strong>search</strong> or <strong>recommendation</strong>: if we’re able to obtain useful embeddings, we can search for similar content, or for documents that are similar to a query, by searching for documents with similar embedding vectors.</p>
<p>I don’t want to go into more details here about embeddings. If you want to learn more, there are plenty of good explanations. Two articles that I found helpful are</p>
<ul>
<li><a href="https://vickiboykis.com/what_are_embeddings/">What are embeddings?</a> by Vicky Boykis.</li>
<li><a href="https://simonwillison.net/2023/Oct/23/embeddings/">Embeddings: What they are and why they matter</a> by Simon Willison.</li>
</ul>
<p>Instead, I want to show you how to store embeddings along with their documents in DuckDB, how to integrate with an embedding model running locally, and how to do vector search with DuckDB.</p>
<p>The examples are in Python, so if you want to follow along, install the required dependencies:</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">pip</span> install duckdb transformers FlagEmbedding polars</span></code></pre></div>
<p>We start by creating a database on disk and connecting to it:</p>
<div id="cell-2" class="cell" data-execution_count="3">
<div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> duckdb</span>
<span id="cb2-2"></span>
<span id="cb2-3">conn <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> duckdb.<span class="ex" style="color: null;
background-color: null;
font-style: inherit;">connect</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"embeddings.db"</span>)</span></code></pre></div>
</div>
</section>
<section id="loading-data-into-duckdb" class="level2">
<h2 class="anchored" data-anchor-id="loading-data-into-duckdb">Loading Data into DuckDB</h2>
<p>In order to do vector search, we need some content first, so let’s download some documents and store them in our database. To keep things simple, we’ll use the <a href="https://huggingface.co/datasets/wikimedia/wikipedia">pre-processed Wikipedia dataset</a> provided by the Wikimedia Foundation as a set of Parquet files. To test the multilingual capabilities of our embedding model, we’ll use the German Wikipedia subset <code>20231101.de</code>. You can get a nice preview of the data using the <a href="https://huggingface.co/datasets/wikimedia/wikipedia/viewer/20231101.de">Hugging Face dataset viewer</a>:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://blog.brunk.io/posts/similarity-search-with-duckdb/hf-dataset-viewer.png" class="img-fluid figure-img"></p>
<figcaption>Wikipedia in the Hugging Face dataset viewer</figcaption>
</figure>
</div>
<p>We can use the new DuckDB <a href="https://huggingface.co/docs/hub/datasets-duckdb">integration with Huggingface Datasets</a> that was just <a href="https://duckdb.org/2024/05/29/access-150k-plus-datasets-from-hugging-face-with-duckdb.html">announced</a> to fetch the data directly from the hub. Let’s try to verify the 2.85M rows the viewer reports for the German subset with a DuckDB query:</p>
<div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">FROM</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'hf://datasets/wikimedia/wikipedia/20231101.de/*.parquet'</span></span>
<span id="cb3-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">SELECT</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</span>(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">AS</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</span>;</span></code></pre></div>
<div id="cell-5" class="cell" data-execution_count="3">
<div class="cell-output cell-output-display">
<script type="application/vnd.jupyter.widget-view+json">
{"model_id":"680139e0bc0b43199d9f5381cb62f7bf","version_major":2,"version_minor":0,"quarto_mimetype":"application/vnd.jupyter.widget-view+json"}
</script>
</div>
<div class="cell-output cell-output-display" data-execution_count="3">
<div>

<table class="dataframe caption-top table table-sm table-striped small" data-quarto-postprocess="true" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th">count</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>2845308</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>The count looks close enough. I was surprised though that it took only a few seconds to run this query on my machine, even though the German Wikipedia subset is more than 5GB compressed data spread over 20 Parquet files. How is that possible?</p>
<p>The reason is that DuckDB supports <a href="https://duckdb.org/docs/data/parquet/overview#partial-reading">partial reading</a> of Parquet files, which means that if your query states that you only need a part of the data (filter or projection), or even just metadata, DuckDB can optimize the reads and only read what it really needs from disk. Even more amazingly, it also works with Parquet files served over HTTP if your webserver supports <a href="https://duckdb.org/docs/extensions/httpfs/https">HTTP range requests</a>. Read more about how DuckDB can efficiently perform queries on Parquet in this <a href="https://duckdb.org/2021/06/25/querying-parquet.html">blog post</a>.</p>
<p>Let’s fetch the first 10 entries to have a quick look:</p>
<div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">FROM</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'hf://datasets/wikimedia/wikipedia/20231101.de/*.parquet'</span></span>
<span id="cb4-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">SELECT</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">LIMIT</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>;</span></code></pre></div>
<div id="cell-7" class="cell" data-execution_count="4">
<div class="cell-output cell-output-display">
<script type="application/vnd.jupyter.widget-view+json">
{"model_id":"6c62648163e54369afd3bc170a594fe6","version_major":2,"version_minor":0,"quarto_mimetype":"application/vnd.jupyter.widget-view+json"}
</script>
</div>
<div class="cell-output cell-output-display" data-execution_count="4">
<div>

<table class="dataframe caption-top table table-sm table-striped small" data-quarto-postprocess="true" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th">id</th>
<th data-quarto-table-cell-role="th">url</th>
<th data-quarto-table-cell-role="th">title</th>
<th data-quarto-table-cell-role="th">text</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>"1"</td>
<td>"https://de.wikipedia.org/wiki/…</td>
<td>"Alan Smithee"</td>
<td>"Alan Smithee steht als Pseudon…</td>
</tr>
<tr class="even">
<td>"3"</td>
<td>"https://de.wikipedia.org/wiki/…</td>
<td>"Actinium"</td>
<td>"Actinium ist ein radioaktives …</td>
</tr>
<tr class="odd">
<td>"5"</td>
<td>"https://de.wikipedia.org/wiki/…</td>
<td>"Ang Lee"</td>
<td>"Ang Lee (; * 23. Oktober 1954 …</td>
</tr>
<tr class="even">
<td>"7"</td>
<td>"https://de.wikipedia.org/wiki/…</td>
<td>"Anschluss (Luhmann)"</td>
<td>"Anschluss ist in der Soziologi…</td>
</tr>
<tr class="odd">
<td>"10"</td>
<td>"https://de.wikipedia.org/wiki/…</td>
<td>"Aussagenlogik"</td>
<td>"Die Aussagenlogik ist ein Teil…</td>
</tr>
<tr class="even">
<td>"13"</td>
<td>"https://de.wikipedia.org/wiki/…</td>
<td>"Liste von Autoren/A"</td>
<td>" Aa Bertus Aafjes (1914–199…</td>
</tr>
<tr class="odd">
<td>"14"</td>
<td>"https://de.wikipedia.org/wiki/…</td>
<td>"Liste von Autoren/H"</td>
<td>" Ha Haa–Han Ha Song-ran (19…</td>
</tr>
<tr class="even">
<td>"15"</td>
<td>"https://de.wikipedia.org/wiki/…</td>
<td>"Liste von Autoren/C"</td>
<td>" Ca Cab–Cap Fernán Caballe…</td>
</tr>
<tr class="odd">
<td>"16"</td>
<td>"https://de.wikipedia.org/wiki/…</td>
<td>"Liste von Autoren/I"</td>
<td>" I Yi I (1536–1584) Ia I…</td>
</tr>
<tr class="even">
<td>"17"</td>
<td>"https://de.wikipedia.org/wiki/…</td>
<td>"Liste von Autoren/K"</td>
<td>" Ka Dieter B. Kabus (1941–19…</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>Note that this also only takes a few seconds for the reason explained above. Depending on your query, it could of course take longer as DuckDB has to fetch more data.</p>
<p>Finally, let’s create a table directly from this query, with a few more articles:</p>
<div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">CREATE</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">TABLE</span> wikipedia <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">AS</span></span>
<span id="cb5-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">FROM</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'hf://datasets/wikimedia/wikipedia/20231101.de/*.parquet'</span></span>
<span id="cb5-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">SELECT</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">limit</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">200</span>;</span></code></pre></div>
<p>Now we have 200 entries in our local database which means we can query them much faster:</p>
<div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">SELECT</span> text <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">FROM</span> wikipedia <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">LIMIT</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>;</span></code></pre></div>
<div id="cell-11" class="cell" data-execution_count="106">
<div class="cell-output cell-output-display" data-execution_count="106">
<div>

<table class="dataframe caption-top table table-sm table-striped small" data-quarto-postprocess="true" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th">text</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>"Alan Smithee steht als Pseudonym für einen fiktiven Regisseur, der Filme verantwortet, bei denen der…</td>
</tr>
<tr class="even">
<td>"Actinium ist ein radioaktives chemisches Element mit dem Elementsymbol Ac und der Ordnungszahl 89. I…</td>
</tr>
<tr class="odd">
<td>"Ang Lee (; * 23. Oktober 1954 in Chaozhou, Landkreis Pingtung, Taiwan) ist ein taiwanischer Filmregi…</td>
</tr>
<tr class="even">
<td>"Anschluss ist in der Soziologie ein Fachbegriff aus der Systemtheorie von Niklas Luhmann und bezeich…</td>
</tr>
<tr class="odd">
<td>"Die Aussagenlogik ist ein Teilgebiet der Logik, das sich mit Aussagen und deren Verknüpfung durch Ju…</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
<section id="loading-an-embedding-model" class="level2">
<h2 class="anchored" data-anchor-id="loading-an-embedding-model">Loading an Embedding Model</h2>
<p>In order to create our vectors for our documents, we need an <strong>embedding model</strong>. While we could use an embedding as a service provider like Cohere, OpenAI or Google, I want to use an open model that we can run locally without any subscription.</p>
<p><a href="https://arxiv.org/abs/2402.03216">BGE-M3</a> from Chen et al.&nbsp;is an interesting choice due to its multi-lingual capabilities and that it can produce not only dense embeddings, but also multi-vector term embeddings for late interaction as popularized by <a href="https://github.com/stanford-futuredata/ColBERT">ColBERT</a>. We can even ask the model to output sparse vectors to help with traditional TF/IDF or BM-25 like search with an inverted index. In this example we’re just using dense, single vector embeddings though.</p>
<p>The <a href="https://huggingface.co/BAAI/bge-m3">BGE-M3 weights</a> are available on Hugging Face as well and we can load the model as follows:</p>
<div id="cell-13" class="cell" data-execution_count="6">
<div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> FlagEmbedding <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> BGEM3FlagModel</span>
<span id="cb7-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> torch</span>
<span id="cb7-3"></span>
<span id="cb7-4">device <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cpu"</span></span>
<span id="cb7-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># use a GPU if available to speed up the embedding computation</span></span>
<span id="cb7-6"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> torch.cuda.is_available(): device <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cuda"</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Nvidia GPU</span></span>
<span id="cb7-7"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> torch.backends.mps.is_available(): device <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mps"</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Apple silicon GPU</span></span>
<span id="cb7-8"></span>
<span id="cb7-9">model <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> BGEM3FlagModel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'BAAI/bge-m3'</span>, use_fp16<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, device<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>device)</span></code></pre></div>
<div class="cell-output cell-output-display">
<script type="application/vnd.jupyter.widget-view+json">
{"model_id":"e28f0ebcc3e0405192e980a01ad55258","version_major":2,"version_minor":0,"quarto_mimetype":"application/vnd.jupyter.widget-view+json"}
</script>
</div>
</div>
<p>We can run the model on a few inputs, get the dense embeddings and compute similarities with the dot product:</p>
<div id="cell-15" class="cell" data-execution_count="8">
<div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1">queries <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"What is BGE M3?"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"What is DuckDB?"</span>]</span>
<span id="cb8-2">documents <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [</span>
<span id="cb8-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"BGE M3 is an embedding model supporting dense retrieval, lexical matching and multi-vector interaction."</span>,</span>
<span id="cb8-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"DuckDB is a fast in-process analytical database. It supports a feature-rich SQL dialect complemented with deep integrations into client APIs"</span>,</span>
<span id="cb8-5">]</span>
<span id="cb8-6"></span>
<span id="cb8-7">query_embeddings <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model.encode(queries)[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dense_vecs"</span>]</span>
<span id="cb8-8">document_embeddings <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model.encode(documents)[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dense_vecs"</span>]</span>
<span id="cb8-9"></span>
<span id="cb8-10">similarity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> query_embeddings <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@</span> document_embeddings.T</span>
<span id="cb8-11">similarity</span></code></pre></div>
<div class="cell-output cell-output-display" data-execution_count="8">
<pre><code>array([[0.626 , 0.1918],
       [0.3362, 0.732 ]], dtype=float16)</code></pre>
</div>
</div>
</section>
<section id="creating-embeddings-for-wikipedia-articles" class="level2">
<h2 class="anchored" data-anchor-id="creating-embeddings-for-wikipedia-articles">Creating Embeddings for Wikipedia Articles</h2>
<p>Now that we have a few documents and a model, we can create embeddings for each document and store them in our database as well. We create an embeddings table with two columns: One to store our vectors we get from our model, <code>float</code> arrays of size 1024 in this case. And another for the document id to link back to our table with the Wikipedia pages:</p>
<div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb10-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">CREATE</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">TABLE</span> embeddings(</span>
<span id="cb10-2">     doc_id <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">VARCHAR</span>,</span>
<span id="cb10-3">     embedding <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">FLOAT</span>[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1024</span>]</span>
<span id="cb10-4">);</span></code></pre></div>
<p>There are multiple ways to create our embeddings. For example, we could</p>
<ol type="1">
<li>Loop through batches of inputs in Python, call the embedding model and store each batch in the database.</li>
<li>Create a custom DuckDB function (UDF) to call the model and write the embeddings in a single SQL statement.</li>
<li>Use another library like Hugging Face <a href="https://huggingface.co/docs/datasets/index">Datasets</a> for batch processing and then write the results to our database.</li>
</ol>
<section id="looping-through-arrow-batches" class="level3">
<h3 class="anchored" data-anchor-id="looping-through-arrow-batches">Looping through Arrow Batches</h3>
<p>Let’s go with the first option here: Fetch batches as Arrow records via the <a href="https://duckdb.org/docs/guides/python/export_arrow">DuckDB Apache Arrow</a> integration and write back batches of embeddings. We’ll see an example of the second option later when we create a UDF to compute the query embedding. First, we need to create a reader that will return an Arrow <a href="https://arrow.apache.org/docs/python/generated/pyarrow.RecordBatch.html#pyarrow-recordbatch"><code>RecordBatch</code></a> iterator from our query result, with each batch containing 100 records:</p>
<div id="cell-19" class="cell" data-execution_count="42">
<div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1">reader <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> conn.execute(</span>
<span id="cb11-2">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"FROM wikipedia SELECT id, text WHERE id NOT IN (FROM embeddings select doc_id);"</span></span>
<span id="cb11-3">).fetch_record_batch(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span>)</span></code></pre></div>
</div>
<p>We can iterate over these batches and call the model to compute embeddings for each batch. Note that here we are reading batches of size 100 from the database into main memory, and then smaller batches of size 4 into GPU memory (if our model runs on the GPU). Once we have a batch of 100 embeddings, we put them into an Arrow table, write them back to the database using the <a href="https://duckdb.org/docs/guides/python/import_arrow">Arrow import feature</a>, and fetch the next batch. We also convert our embeddings back to float32 because DuckDB doesn’t currently support 16 bit floats.</p>
<div id="cell-21" class="cell" data-execution_count="43">
<div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pyarrow <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pa</span>
<span id="cb12-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb12-3"></span>
<span id="cb12-4"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> batch <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> reader: <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 100 records per batch</span></span>
<span id="cb12-5">     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 4 records per GPU batch</span></span>
<span id="cb12-6">    embeddings <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model.encode(batch[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"text"</span>].tolist(), batch_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>)[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"dense_vecs"</span>].astype(np.float32)</span>
<span id="cb12-7">     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># add our embeddings to the batch</span></span>
<span id="cb12-8">    batch <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> batch.add_column(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"embedding"</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>(embeddings))</span>
<span id="cb12-9">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># we need an Arrow table for the DuckDB replacement scan to work</span></span>
<span id="cb12-10">    batch_table <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pa.Table.from_batches([batch])</span>
<span id="cb12-11">    conn.cursor().execute(</span>
<span id="cb12-12">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"INSERT INTO embeddings FROM (FROM batch_table SELECT id, embedding);"</span>)</span></code></pre></div>
<div class="cell-output cell-output-display">
<script type="application/vnd.jupyter.widget-view+json">
{"model_id":"7f6453fdf972479e881fbd83ef6a427c","version_major":2,"version_minor":0,"quarto_mimetype":"application/vnd.jupyter.widget-view+json"}
</script>
</div>
</div>
<p>You will probably want to run this on a GPU for more than a few dozen documents, or it will take a long time. You may also want to change <code>batch_size</code> depending on the size of your GPU memory.</p>
<p>Let’s have a look at our embeddings:</p>
<div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb13-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">FROM</span> wikipedia <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">JOIN</span> embeddings <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">ON</span> (wikipedia.<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">id</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> embeddings.doc_id)</span>
<span id="cb13-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">SELECT</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb13-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">LIMIT</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>;</span></code></pre></div>
<div id="cell-23" class="cell" data-execution_count="202">
<div class="cell-output cell-output-display" data-execution_count="202">
<div>

<table class="dataframe caption-top table table-sm table-striped small" data-quarto-postprocess="true" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th">text</th>
<th data-quarto-table-cell-role="th">embedding</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>"Actinium ist ein radioaktives chemisches Element mit dem Elementsymbol Ac und der Ordnungszahl 89. I…</td>
<td>[0.026413, -0.018646, -0.0625, 0.037933, -0.010872, … 0.013496]</td>
</tr>
<tr class="even">
<td>"Ang Lee (; * 23. Oktober 1954 in Chaozhou, Landkreis Pingtung, Taiwan) ist ein taiwanischer Filmregi…</td>
<td>[-0.067383, -0.025024, -0.012299, 0.01944, -0.008987, … -0.01368]</td>
</tr>
<tr class="odd">
<td>"Anschluss ist in der Soziologie ein Fachbegriff aus der Systemtheorie von Niklas Luhmann und bezeich…</td>
<td>[-0.030182, 0.01799, -0.018402, 0.031464, -0.013596, … 0.020737]</td>
</tr>
<tr class="even">
<td>"Die Aussagenlogik ist ein Teilgebiet der Logik, das sich mit Aussagen und deren Verknüpfung durch Ju…</td>
<td>[0.007038, 0.014084, -0.012436, 0.007843, -0.010979, … -0.058868]</td>
</tr>
<tr class="odd">
<td>" Ha Haa–Han Ha Song-ran (1967) Alban Haas (1877–1968) Rudolf Haas (1877–1943) Wolf Haas (1960) He…</td>
<td>[-0.066101, 0.001437, -0.023911, -0.034119, 0.011597, … -0.013344]</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>DuckDB being a real database gives us a lot of flexibility to store our embeddings and join them back with the documents or chunks they are generated from. This is even more powerful if we take into account the numerous data source <a href="https://duckdb.org/docs/extensions/official_extensions">extensions</a>. While we’re reading from remote Parquet files here, we could just as easily fetch our data from Postgres using DuckDB’s Postgres reader, a CSV in some bucket, or even a combination of different sources.</p>
</section>
</section>
<section id="running-vector-similarity-search" class="level2">
<h2 class="anchored" data-anchor-id="running-vector-similarity-search">Running Vector Similarity Search</h2>
<p>We’re almost there! Now we just need to embed our queries as well before we can do a similarity search. To do this, let’s see another DuckDB feature in action: We’ll create a user-defined function (UDF) <code>embed</code> using the <a href="https://duckdb.org/docs/api/python/function">Python Function API</a> to call our model:</p>
<div id="cell-26" class="cell" data-execution_count="9">
<div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> duckdb.typing <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> VARCHAR</span>
<span id="cb14-2"></span>
<span id="cb14-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> embed(sentence: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> np.ndarray:</span>
<span id="cb14-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> model.encode(sentence)[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'dense_vecs'</span>]</span>
<span id="cb14-5"></span>
<span id="cb14-6">conn.create_function(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"embed"</span>, embed, [VARCHAR], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'FLOAT[1024]'</span>)</span></code></pre></div>
</div>
<p>Once we’ve registered the function with DuckDB, we can use in like any native function as part of our SQL query:</p>
<div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb15-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">SELECT</span> embed(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Who was the first human on the moon?'</span>) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">AS</span> query_embedding;</span></code></pre></div>
<div id="cell-28" class="cell" data-execution_count="203">
<div class="cell-output cell-output-display" data-execution_count="203">
<div>

<table class="dataframe caption-top table table-sm table-striped small" data-quarto-postprocess="true" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th">query_embedding</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>[0.011353, 0.010292, -0.058899, -0.044098, 0.015778, … -0.033691]</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>Equipped with our embedding UDF, we can use a array distance function like <code>array_cosine_similarity</code>, or just <code>array_inner_product</code> for normalized vectors to find the most similar documents to our query based on their embedding vectors. Let’s define a small <code>search</code> function that given a query, returns the most similar Wikipedia articles:</p>
<div id="cell-30" class="cell" data-execution_count="171">
<div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb16-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> search(q: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>):</span>
<span id="cb16-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> conn.execute(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb16-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">        FROM embeddings JOIN wikipedia ON (wikipedia.id = embeddings.doc_id)</span></span>
<span id="cb16-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">        SELECT wikipedia.id, title, array_inner_product(embedding, embed($q)) AS similarity</span></span>
<span id="cb16-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">        ORDER BY similarity DESC</span></span>
<span id="cb16-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">        LIMIT 5"""</span>,</span>
<span id="cb16-7">        {<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"q"</span>: q}</span>
<span id="cb16-8">    ).pl()</span>
<span id="cb16-9"></span>
<span id="cb16-10">search(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Who was the first human on the moon?'</span>)</span></code></pre></div>
<div class="cell-output cell-output-display">
<script type="application/vnd.jupyter.widget-view+json">
{"model_id":"72cf8bc7cbcc4091b56afdeda5d382cd","version_major":2,"version_minor":0,"quarto_mimetype":"application/vnd.jupyter.widget-view+json"}
</script>
</div>
<div class="cell-output cell-output-display" data-execution_count="171">
<div>

<table class="dataframe caption-top table table-sm table-striped small" data-quarto-postprocess="true" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th">id</th>
<th data-quarto-table-cell-role="th">title</th>
<th data-quarto-table-cell-role="th">similarity</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>"207"</td>
<td>"Apollo-Programm"</td>
<td>0.591756</td>
</tr>
<tr class="even">
<td>"256"</td>
<td>"Apollo 11"</td>
<td>0.576521</td>
</tr>
<tr class="odd">
<td>"22"</td>
<td>"Liste von Autoren/B"</td>
<td>0.485747</td>
</tr>
<tr class="even">
<td>"26"</td>
<td>"Liste von Autoren/M"</td>
<td>0.481897</td>
</tr>
<tr class="odd">
<td>"16"</td>
<td>"Liste von Autoren/I"</td>
<td>0.465602</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>Here we can see the capabilities of a multilingual model like BGE-M3 in action. Even though our query is in English and our documents are German, articles with relevant information to answer the question have a high similarity. If we ask the question in German as well, the result is almost the same.</p>
<div id="cell-32" class="cell" data-execution_count="172">
<div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb17-1">search(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Wer war der erste Mensch auf dem Mond?'</span>)</span></code></pre></div>
<div class="cell-output cell-output-display">
<script type="application/vnd.jupyter.widget-view+json">
{"model_id":"296337c4509a47dd882d28377e7f5e78","version_major":2,"version_minor":0,"quarto_mimetype":"application/vnd.jupyter.widget-view+json"}
</script>
</div>
<div class="cell-output cell-output-display" data-execution_count="172">
<div>

<table class="dataframe caption-top table table-sm table-striped small" data-quarto-postprocess="true" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th">id</th>
<th data-quarto-table-cell-role="th">title</th>
<th data-quarto-table-cell-role="th">similarity</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>"207"</td>
<td>"Apollo-Programm"</td>
<td>0.608182</td>
</tr>
<tr class="even">
<td>"256"</td>
<td>"Apollo 11"</td>
<td>0.602915</td>
</tr>
<tr class="odd">
<td>"26"</td>
<td>"Liste von Autoren/M"</td>
<td>0.483409</td>
</tr>
<tr class="even">
<td>"16"</td>
<td>"Liste von Autoren/I"</td>
<td>0.458147</td>
</tr>
<tr class="odd">
<td>"22"</td>
<td>"Liste von Autoren/B"</td>
<td>0.450969</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>Note that the model was trained on Wikipedia (among others) so this would not be a good dataset for actually validating how well the model performs. The interesting question you have to ask yourself is how well it works, in <strong>your domain</strong>, on <strong>your data</strong>.</p>
</section>
<section id="using-an-hnsw-index" class="level2">
<h2 class="anchored" data-anchor-id="using-an-hnsw-index">Using an HNSW Index</h2>
<p>By default DuckDB has to compare a query embedding with <strong>all</strong> document embeddings to find the most similar ones. With our small sample of 200 documents that’s not an issue, but if you’re trying to find the most similar ones among millions of documents, comparing the query vector with each document vector will become expensive in terms of computation and latency.</p>
<p>To speed up vector search (at the cost of some accuracy), we can use an approximate nearest neighbor (ANN) method. A popular approach for ANN is the <a href="https://en.wikipedia.org/wiki/Hierarchical_navigable_small_world">Hierarchical Navigable Small World (HNSW) algorithm</a>. DuckDB supports HNSW through its <a href="https://duckdb.org/2024/05/03/vector-similarity-search-vss.html">vector similarity search extension</a>.</p>
<p>Let’s load the vss extension and create an index on our embedding table:</p>
<div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb18-1">INSTALL vss;</span>
<span id="cb18-2">LOAD vss;</span>
<span id="cb18-3"> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-- required for persistent databases as of DuckDB 1.0.0</span></span>
<span id="cb18-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">SET</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">GLOBAL</span> hnsw_enable_experimental_persistence <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span>;</span>
<span id="cb18-5"></span>
<span id="cb18-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">CREATE</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">INDEX</span> ip_idx <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">ON</span> embeddings <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">USING</span> HNSW (embedding)</span>
<span id="cb18-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">WITH</span> (metric <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ip'</span>);</span></code></pre></div>
<p>Now we can use the index for our vector search. Note that currently, the index is only used when our similarity search looks like in the <code>top_k</code> common table expression, so we can’t combine it i.e.&nbsp;with a <code>WHERE</code> clause for filtering or a join immediately. We can use the results to filter and join as we like though:</p>
<div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb19-1">q <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Who was the first human on the moon?"</span></span></code></pre></div>
<div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb20-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">WITH</span> top_k <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">AS</span> (</span>
<span id="cb20-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">FROM</span> embeddings <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">SELECT</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb20-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">ORDER</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">BY</span> array_inner_product(embedding, embed($q))</span>
<span id="cb20-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">LIMIT</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span>
<span id="cb20-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">FROM</span> top_k <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">JOIN</span> wikipedia <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">ON</span> (wikipedia.<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">id</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> top_k.doc_id)</span>
<span id="cb20-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">SELECT</span> wikipedia.<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">id</span>, title, array_inner_product(embedding, embed($q)) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">AS</span> similarity</span>
<span id="cb20-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">ORDER</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">BY</span> similarity <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">DESC</span></span></code></pre></div>
<div id="cell-36" class="cell" data-scrolled="true" data-execution_count="194">
<div class="cell-output cell-output-display" data-execution_count="194">
<div>

<table class="dataframe caption-top table table-sm table-striped small" data-quarto-postprocess="true" data-border="1">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th">id</th>
<th data-quarto-table-cell-role="th">title</th>
<th data-quarto-table-cell-role="th">similarity</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>"207"</td>
<td>"Apollo-Programm"</td>
<td>0.591756</td>
</tr>
<tr class="even">
<td>"256"</td>
<td>"Apollo 11"</td>
<td>0.576521</td>
</tr>
<tr class="odd">
<td>"22"</td>
<td>"Liste von Autoren/B"</td>
<td>0.485747</td>
</tr>
<tr class="even">
<td>"26"</td>
<td>"Liste von Autoren/M"</td>
<td>0.481897</td>
</tr>
<tr class="odd">
<td>"16"</td>
<td>"Liste von Autoren/I"</td>
<td>0.465602</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>The result looks still good, but, depending on your <a href="https://duckdb.org/docs/extensions/vss#index-options">HNSW index settings</a>, accuracy will not be as good as comparing all vectors. This trade-off might be necessary to achieve faster performance though.</p>
<p>We can also check if the index is used by putting <code>EXPLAIN</code> statement in front of the SQL query:</p>
<div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb21-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">EXPLAIN</span></span>
<span id="cb21-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">SELECT</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb21-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">FROM</span> embeddings</span>
<span id="cb21-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">ORDER</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">BY</span> array_inner_product(embedding, embed(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'some text'</span>))</span>
<span id="cb21-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">LIMIT</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>;</span></code></pre></div>
<div id="cell-39" class="cell" data-execution_count="14">
<div class="cell-output cell-output-stdout">
<pre><code>┌───────────────────────────┐
│         PROJECTION        │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─   │
│             #0            │
│             #1            │
└─────────────┬─────────────┘                             
┌─────────────┴─────────────┐
│         PROJECTION        │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─   │
│         embedding         │
│           doc_id          │
│            NULL           │
└─────────────┬─────────────┘                             
┌─────────────┴─────────────┐
│      HNSW_INDEX_SCAN      │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─   │
│embeddings (HNSW INDEX SCAN│
│          : ip_idx)        │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─   │
│         embedding         │
│           doc_id          │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─   │
│           EC: 5           │
└───────────────────────────┘                             
</code></pre>
</div>
</div>
<p>Since HNSW is experimental for persistent databases as of DuckDB 1.0.0, let’s remove the index again or we might run into WAL issues when loading the database from disk next time.</p>
<div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb23-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">DROP</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">INDEX</span> ip_idx;</span></code></pre></div>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>This article has demonstrated the power and flexibility of DuckDB for handling embeddings and performing vector search. We’ve leveraged DuckDB’s efficient Parquet handling to load data from large datasets, integrated a PyTorch embedding model seamlessly using both batch processing and UDFs, and performed vector similarity search with and without an HNSW index.</p>
<p>The ability to store embeddings along with your data directly in DuckDB, coupled with its extensive data source connectivity, opens up a wide range of possibilities for complex analysis and retrieval.</p>
<p>We have barely scratched the surface of what is possible with DuckDB, and there is much more to explore. In an upcoming article, we are going to work with slightly more complex vector operations and see if we can do simple <strong>ColBERT</strong>-style late interaction by implementing the <em>MaxSim</em> operator using only native DuckDB functions.</p>
<hr>
<p>I hope you enjoyed reading this article. If you have have questions, corrections or any other feedback, don’t hesitate to contact me through any of the channels linked on the <a href="../../about.html">about page</a>.</p>


</section>

 ]]></description>
  <category>duckdb</category>
  <category>embeddings</category>
  <category>python</category>
  <guid>https://blog.brunk.io/posts/similarity-search-with-duckdb/</guid>
  <pubDate>Thu, 13 Jun 2024 22:00:00 GMT</pubDate>
  <media:content url="https://blog.brunk.io/posts/similarity-search-with-duckdb/DuckDB_Logo.png" medium="image" type="image/png" height="111" width="144"/>
</item>
<item>
  <title>Storch - GPU Accelerated Deep Learning for Scala 3</title>
  <link>https://blog.brunk.io/posts/storch-gpu-accelerated-deep-learning-for-scala-3-talk/</link>
  <description><![CDATA[ 





<p>Slides and recording from my <a href="https://scaladays.org/madrid-2023/storch-gpu-accelerated-deep-learning-for-scala-3">Scala Days Madrid talk</a> about <a href="https://storch.dev">Storch</a>.</p>
<p><strong>Update</strong>: The recording is now available.</p>
<div class="quarto-video ratio ratio-16x9"><iframe data-external="1" src="https://www.youtube.com/embed/ZoJanBS9kw8" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></div>
<p><a href="../../slides/scaladays-2023-storch/index.html" target="_blank">View slides in fullscreen</a></p>
<!-- <p style="text-align: center;">[View in fullscreen](/slides/scaladays-2023-storch/index.ipynb){target="_blank"}</p> -->
<iframe class="slide-deck" style="width: 100%; aspect-ratio: 1050/700;" src="../../slides/scaladays-2023-storch/index.html">
</iframe>



 ]]></description>
  <category>scala</category>
  <category>deep-learning</category>
  <category>storch</category>
  <category>pytorch</category>
  <guid>https://blog.brunk.io/posts/storch-gpu-accelerated-deep-learning-for-scala-3-talk/</guid>
  <pubDate>Tue, 12 Sep 2023 22:00:00 GMT</pubDate>
  <media:content url="https://blog.brunk.io/posts/storch-gpu-accelerated-deep-learning-for-scala-3-talk/SpeakerCard-SorenBrunk-1920x1080.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Talk: Interactive Computing with Jupyter and almond</title>
  <link>https://blog.brunk.io/posts/interactive-computing-with-jupyter-and-almond-talk/</link>
  <description><![CDATA[ 





<p>Recording of my talk at Scala Days 2019 in Lausanne.</p>
<div class="quarto-video ratio ratio-16x9"><iframe data-external="1" src="https://www.youtube.com/embed/DLdJ4EFqkf8" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></div>
<p>The slides are available as <strong><a href="https://mybinder.org/v2/gh/sbrunk/scaladays-2019/master?filepath=slides.ipynb" target="_blank">interactive Jupyter notebook that runs in your browser</a></strong>. It allows you to run all the examples yourself <strong>within</strong> the slides! Powered by <a href="https://mybinder.org" target="_blank">binder</a>. The slide source notebook is also<a href="https://github.com/sbrunk/scaladays-2019" target="_blank"> available.</a></p>



 ]]></description>
  <category>jupyter</category>
  <category>scala</category>
  <category>interactive computing</category>
  <guid>https://blog.brunk.io/posts/interactive-computing-with-jupyter-and-almond-talk/</guid>
  <pubDate>Sun, 04 Aug 2019 22:00:00 GMT</pubDate>
  <media:content url="https://img.youtube.com/vi/DLdJ4EFqkf8/0.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Interactive Computing in Scala with Jupyter and almond</title>
  <link>https://blog.brunk.io/posts/interactive-computing-with-jupyter-and-almond/</link>
  <description><![CDATA[ 





<p>The <a href="https://docs.scala-lang.org/overviews/repl/overview.html">Scala REPL</a> is a great tool for trying out code interactively. It lets you write expressions in a terminal window, and immediately prints the return value as well as any outputs to the console. Whether you’re learning the language, exploring an API, or sketching out a new idea, the immediate feedback after evaluating an expression is a great enabler for hands-on learning and rapid prototyping.</p>
<p>The easiest way to get started is the default REPL because it’s part of the Scala distribution and is also available in any SBT project as the <code>console</code> command. The default REPL lacks many convenience features though.</p>
<section id="ammonite" class="level3">
<h3 class="anchored" data-anchor-id="ammonite">Ammonite</h3>
<p><a href="http://ammonite.io/#Ammonite-REPL">Ammonite</a> is a modern REPL implementation created by Li Haoyi. It comes with many features that make working in the REPL more convenient. Probably the most important one is dynamic maven dependency loading in the REPL itself (through <a href="https://coursier.github.io/coursier/snapshot/docs/intro">Coursier</a>), which allows you to import and immediately use almost any published Scala or Java library. It also has many others convenience features, such as * multi line editing support * better syntax highlighting. i.e.&nbsp;inputs are highlighted as you type * much better autocompletion * pretty printed, nicely formatted outputs * undo/redo, session handling and more</p>
<p>If you know Python, Ammonite (roughly) is to the default Scala REPL what the <a href="https://ipython.org/">IPython</a> shell is to the default Python shell. Parts of Ammonite are also used in the default dotty REPL, which means they will be available in Scala 3.</p>
<p>While Ammonite has many improvements compared to the default REPL, the basic execution model is still the same. You enter an expression (or multiple expressions in a block). You press enter to have it evaluated to immediately see the output below your input. You then repeat with a new expression or by refining the previous one and executing it again. As a result, your inputs are interleaved with the computed output values.</p>
<p><img src="https://ammonite.io/GettingStarted.png" class="img-fluid" alt="Ammonite"> <em>The Ammonite REPL (Source: ammonite.io)</em></p>
<p>This model of interaction helps you to iterate fast due to the immediate feedback, but it also has some drawbacks: * Seeing multiple inputs at once can be hard, because they are interleaved with their outputs, especially if the outputs are long. * It also makes it harder to copy multiple consecutive inputs into an editor. * Finding and changing older inputs often means scrolling back or searching the history because they are far away or in the console window completely gone due to newer outputs. * Selectively replaying multiple expressions after changes in an earlier input or after a REPL restart can be tedious.</p>
<p>You can show the history of inputs using <code>:history</code> in the default REPL or <code>repl.history</code> in Ammonite. While the history can be helpful, it is often cluttered with refinement attempts, which you still need to filter out.</p>
<p>An interesting REPL variant that addresses some of these issues are worksheets.</p>
</section>
<section id="worksheets" class="level3">
<h3 class="anchored" data-anchor-id="worksheets">Worksheets</h3>
<p>From the Dotty documentation:</p>
<blockquote class="blockquote">
<p>A worksheet is a Scala file that is evaluated on save, and the result of each expression is shown in a column to the right of your program. Worksheets are like a REPL session on steroids, and enjoy 1st class editor support: completion, hyperlinking, interactive errors-as-you-type, etc.</p>
</blockquote>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://dotty.epfl.ch/images/worksheets/worksheet-demo.gif" class="img-fluid figure-img"></p>
<figcaption>Worksheet support in Dotty IDE</figcaption>
</figure>
</div>
<p><em>Worksheet example in Dotty IDE / Visual Studio Code. (source: <a href="https://dotty.epfl.ch/docs/usage/worksheet-mode.html">Dotty documentation</a>)</em></p>
<p>Let’s go through this definition to explain how worksheets differ from the REPL:</p>
<p>First of all, worksheets are files. That means we can put them under version control and share them with others more easily.</p>
<p>Second, we enter our expressions into an editor window. In most cases, the input editor is on the left while the output is shown to the right. This layout makes it easier to see multiple expressions at once, because they are not interleaved with their outputs. It also makes it easier to write multi line expressions and to edit expressions.</p>
<p>Third, a worksheet is evaluated on save. More specifically, <strong>all</strong> expressions are recomputed every time we save the worksheet. The advantage of this behaviour is that it’s easy to change an earlier expression because all dependent values are automatically recomputed. The drawback is that you lose control over which expressions are evaluated so it’s not very well suited for things that take longer than a few seconds like loading large datasets or running complex computations.</p>
<p>The fourth point about editor support is mostly IDE dependent. Dotty IDE worksheet support looks very nice, but most of us are still stuck with Scala 2. I’ve tried IntelliJ worksheets a few times but they didn’t work very well for me. Eclipse based Scala IDE had good worksheet support last time I tried it but isn’t widely used for other reasons. There’s also an online worksheet variant called <a href="https://scastie.scala-lang.org/">Scastie</a> that only requires a browser and makes it very easy to share worksheets online.</p>
<p>So worksheets solve some of the issues of REPLs mentioned above. Their layout and their execution model makes multiple expressions easier to read and to change, even if their outputs are shown. However, the execution model also introduces new issues.</p>
<p>So the natural question that follows is: Could we combine the advantages of REPL and worksheets somehow? Interestingly, there is a technology that does have most of the advantages of both (and more): <em>Jupyter notebooks</em>.</p>
</section>
<section id="jupyter-notebooks" class="level3">
<h3 class="anchored" data-anchor-id="jupyter-notebooks">Jupyter Notebooks</h3>
<p><a href="https://jupyter.org/">Jupyter notebooks</a> are interactive, web based documents that can contain executable code. Interactive notebooks are nothing new. In science, they’re in use since the 80s and many different flavours exist.</p>
<p>As of today though, Jupyter notebooks are by far the most successful and flexible variant. Some reasons for their success are that they’re open-source, programming language agnostic, provide a modular architecture and a web-based frontend. That’s why we will use Jupyter as an example to explain the basic concepts behind interactive notebooks. In fact, this article itself is written as a Jupyter notebook.</p>
<p>A Jupyter notebook is made of editable input cells. Cells can be of different types. By default, two cell types are available:</p>
<ul>
<li><strong>Documentation cells</strong>, which are written in Markdown and rendered to HTML when we run them, using JavaScript directly in the browser. For instance, this text was written as a Markdown cell, and you see the HTML output.</li>
<li><strong>Code cells</strong>, which allow you to write and execute code.</li>
</ul>
<p>Here’s a simple example of a Scala code cell:</p>
<div id="cell-2" class="cell" data-execution_count="1">
<div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">println</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hello notebook!"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span></span></code></pre></div>
<div class="cell-output cell-output-stdout">
<pre><code>Hello notebook!</code></pre>
</div>
<div class="cell-output cell-output-display" data-execution_count="1">
<div class="ansi-escaped-output">
<pre><span class="ansi-cyan-fg">x</span>: <span class="ansi-green-fg">Int</span> = <span class="ansi-green-fg">42</span></pre>
</div>
</div>
</div>
<p>Code cells are executed by so called <strong>kernels</strong>. A kernel is basically an interpreter process that executes the code of a code cell in the backend. Once you run a code cell, the frontend sends the current cell content to the kernel for processing. The kernel’s output is then sent back to the frontend and written below the code cell. Later cells can access the variable state of previous cells as long as the kernel is still running.</p>
<div id="cell-4" class="cell" data-execution_count="2">
<div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb3-1">x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span></code></pre></div>
<div class="cell-output cell-output-display" data-execution_count="2">
<div class="ansi-escaped-output">
<pre><span class="ansi-cyan-fg">res1</span>: <span class="ansi-green-fg">Int</span> = <span class="ansi-green-fg">23</span></pre>
</div>
</div>
</div>
<p>Jupyter Kernels can be implemented in any language as long as they follow the <a href="http://zeromq.org/">ZeroMQ</a> based Jupyter communication protocol. IPython is the most popular kernel and is included by default. That’s no surprise since Jupyter (<strong>Ju</strong>lia, <strong>Pyt</strong>hon, <strong>R</strong>) is derived from the IPython project. It is a result of separating the language independent part from the IPython kernel to make it work with other languages. Now there are kernels for over 100 programming languages available.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://jupyter.readthedocs.io/en/latest/_images/notebook_components.png" class="img-fluid figure-img"></p>
<figcaption>Jupyter components</figcaption>
</figure>
</div>
<p><em>High level overview of the Jupyter components (source: <a href="https://jupyter.readthedocs.io/en/latest/architecture/how_jupyter_ipython_work.html#id5">Jupyter documentation</a>)</em></p>
<p>The Jupyter frontend renders the notebook and lets you interact with it. It provides editing capabilies, lets you create notebooks, execute cells and so on. The default frontend Jupyter classic is made of HTML &amp; JavaScript and runs in the browser. In 2018, a modern, more flexible and modular frontend implementation called <a href="https://jupyterlab.readthedocs.io/en/stable/">JupyterLab</a> was published as “the next-generation web-based user interface for Project Jupyter”.</p>
<p><img src="https://jupyterlab.readthedocs.io/en/stable/_images/jupyterlab.png" alt="JupyterLab" width="80%"></p>
<p><em>The JupyterLab interface (source: <a href="https://jupyterlab.readthedocs.io/en/stable/">JupyterLab documentation</a>)</em></p>
<p>The modular architecture of Jupyter allows you to run kernels anywhere: On your laptop, in the cloud, or on a powerful GPU machine for deep learning. The frontend on the other hand even runs on a tablet. You only need a modern web-browser.</p>
<p>There are also desktop frontends with additional features like <a href="https://nteract.io/">nteract</a>. A large ecosystem around Jupyter provides various extensions like git integration, specialized widgets etc.</p>
<p>Besides kernel and frontend, a Jupyter installation consists of the language agnostic backend part that manages kernels, notebooks and the communication with the frontend. This component is called the Jupyter server. Notebooks are stored in .ipynb files, encoded in a Json format on the server. The Json based format allows storing cells inputs, outputs and metadata in a structured way. Binary output data is base64encoded. The disadvantage is that the json makes diff and merge harder, compared to line based text formats. You can export notebooks into other formats such as Markdown, Scala (contains only code input cells), or HTML like this article.</p>
</section>
<section id="jupyter-and-scala" class="level3">
<h3 class="anchored" data-anchor-id="jupyter-and-scala">Jupyter and Scala</h3>
<p>How does support for Jupyter look like in Scala? There’s actually a number of different Scala kernels available. If you look closer though, many of them are somewhat limited in features, have scalability issues or have even been abandoned. Others are focused exclusively on Spark rather than Scala in general and other frameworks.</p>
<p>One reason for that is that almost all existing kernels build on top of the default REPL. Due to its limitations, they customize and extend it to add their own features such as dependency management or framework support. Some kernels also use the Spark Shell which is basically a fork of the Scala REPL customized for Spark support. This all leads to fragmentation, difficulty of reuse and duplication of work, making it harder to create a kernel that is on par with other languages.</p>
<p>For a more detailed discussion about some of the reasons check out this talk at JupyterCon 2017 by Alexandre Archambault:</p>
<div style="text-align:center;">
<a href="https://www.youtube.com/watch?v=pgVtdveelAQ"><img src="https://img.youtube.com/vi/pgVtdveelAQ/hqdefault.jpg" alt="Scala: Why hasn't an Official Scala Kernel for Jupyter emerged yet?"></a>
</div>
</section>
<section id="the-almond-scala-kernel" class="level3">
<h3 class="anchored" data-anchor-id="the-almond-scala-kernel">The almond Scala Kernel</h3>
<p>Fortunately, recent developments have changed the situation. We’ve already talked about Ammonite and the improvements it has over the default REPL. Couldn’t we leverage some of Ammonite’s features for a Scala kernel as well? And that’s exactly what <strong><a href="https://-sh.github.io/almond/stable">almond</a></strong> (formerly called jupyter-scala) by Alexandre Archambault does. By building on top of Ammonite, almond can directly benefit from many of its features.</p>
<p>For instance, dynamic dependency resolution works exactly the same way as in Ammonite:</p>
<div id="cell-6" class="cell" data-execution_count="3">
<div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> $ivy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>`org<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>typelevel<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>cats<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>core<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.0</span>`</span>
<span id="cb4-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> cats<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>syntax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>semigroup<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_ <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// for |+|</span></span>
<span id="cb4-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> cats<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>instances<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// for Monoid</span></span>
<span id="cb4-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> cats<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>instances<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>option<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_ <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// for Monoid</span></span>
<span id="cb4-5"></span>
<span id="cb4-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Option</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|+|</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Option</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<div class="cell-output cell-output-display" data-execution_count="3">
<div class="ansi-escaped-output">
<pre><span class="ansi-green-fg">import </span><span class="ansi-cyan-fg">$ivy.$                               
</span><span class="ansi-green-fg">import </span><span class="ansi-cyan-fg">cats.syntax.semigroup._ // for |+|
</span><span class="ansi-green-fg">import </span><span class="ansi-cyan-fg">cats.instances.int._    // for Monoid
</span><span class="ansi-green-fg">import </span><span class="ansi-cyan-fg">cats.instances.option._ // for Monoid
</span><span class="ansi-cyan-fg">res2_4</span>: <span class="ansi-green-fg">Option</span>[<span class="ansi-green-fg">Int</span>] = <span class="ansi-yellow-fg">Some</span>(<span class="ansi-green-fg">3</span>)</pre>
</div>
</div>
</div>
<p>The same is true for syntax highlighting, pretty printing and autocompletion.</p>
<div id="cell-8" class="cell" data-execution_count="4">
<div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb5-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fill</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fill</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Foo"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span></code></pre></div>
<div class="cell-output cell-output-display" data-execution_count="4">
<div class="ansi-escaped-output">
<pre><span class="ansi-cyan-fg">res3</span>: <span class="ansi-green-fg">Seq</span>[<span class="ansi-green-fg">Seq</span>[<span class="ansi-green-fg">String</span>]] = <span class="ansi-yellow-fg">List</span>(
  <span class="ansi-yellow-fg">List</span>(<span class="ansi-green-fg">"Foo"</span>, <span class="ansi-green-fg">"Foo"</span>, <span class="ansi-green-fg">"Foo"</span>),
  <span class="ansi-yellow-fg">List</span>(<span class="ansi-green-fg">"Foo"</span>, <span class="ansi-green-fg">"Foo"</span>, <span class="ansi-green-fg">"Foo"</span>),
  <span class="ansi-yellow-fg">List</span>(<span class="ansi-green-fg">"Foo"</span>, <span class="ansi-green-fg">"Foo"</span>, <span class="ansi-green-fg">"Foo"</span>),
  <span class="ansi-yellow-fg">List</span>(<span class="ansi-green-fg">"Foo"</span>, <span class="ansi-green-fg">"Foo"</span>, <span class="ansi-green-fg">"Foo"</span>),
  <span class="ansi-yellow-fg">List</span>(<span class="ansi-green-fg">"Foo"</span>, <span class="ansi-green-fg">"Foo"</span>, <span class="ansi-green-fg">"Foo"</span>)
)</pre>
</div>
</div>
</div>
<p>Building on Ammonite also highlights a more general design principle of almond. It tries to delegate as much functionality as possible to existing components instead of reinventing the wheel. Doing so allows it to stay more lightweight, easier to understand, and to better focus on its core functionality as a kernel. While almond has used a forked version of Ammonite for some time, the changes have been upstreamed and it now includes stock Ammonite. This is unlike other kernels which have often heavily customized and extended the Scala REPL to fit their needs.</p>
<p>almond is not tied to a specific big-data framework like Spark. That doesn’t mean we can’t have framework integrations, quite on the contrary. But the idea is to do bridging and integration in more standardized way instead of having to customize the REPL or the kernel itself. Ideally, the integration is done as a module or a separate library that talks to the kernel via well defined APIs. For interfacing with a Spark cluster for instance, almond relies on <a href="https://github.com/alexarchambault/ammonite-spark">ammonite-spark</a> in combination with providing a Jupyter specific Spark module.</p>
<p>Due to its modular design and well defined interfaces, almond even makes it easy to create your <a href="https://almond-sh.github.io/almond/stable/docs/dev-custom-kernel">own custom kernel</a>. For more info about almond’s features, check out its <a href="https://almond-sh.github.io/almond/stable/docs/intro">project website</a>.</p>
<p>almond development (through its creator and main developer) is currently funded by the Scala Center but there’s still a lot to be done, like adding more integrations or improving the code editor experience for Scala. If you’d like to contribute, PRs are very much welcome!</p>
</section>
<section id="combining-the-advantages-of-repls-and-worksheets" class="level3">
<h3 class="anchored" data-anchor-id="combining-the-advantages-of-repls-and-worksheets">Combining the Advantages of REPLs and Worksheets</h3>
<p>Let’s now get back to the question how Jupyter notebooks combine the advantages of REPLs &amp; worksheets. In a sense, you can think of a notebook as a REPL of worksheets (cells).</p>
<p>Each code cell roughly corresponds to a worksheet. You have an editor window to enter your expressions, and once you hit run, <strong>all</strong> expressions in a cell are evaluated in one go and the outputs are shown below. Since notebooks are files, you can also save them, share them and put them under version control like worksheets. So the behaviour inside a cell is basically worksheet like, except that by default, the output is not on the right hand side but below the cell.</p>
<p>A Jupyter notebook can have as many cells as you like, though, and at the document level it behaves more like a REPL. You enter one or more expressions in a cell, run it, perhaps refine and run again a few times until you’re happy. Then you create a new cell below the current one (which may depend on values from the cell above) and repeat the process. The way you can control which cell will be executed is actually even more flexible. You can, for instance * select any cell and (re-)run it * Run all cells, or all cells above/below the currently selected cell * Insert a new cell anywhere, or delete an existing one * copy and paste cells * easily rearrange cells as you like * merge or split cells</p>
<p>That’s a very powerful toolbox for experimentation. Because you can execute and rearrange cells arbitrarily, sometimes you end up with cells containing expressions which depend on values from cells below. This can be very confusing so you should make sure that your code runs fine when executing your notebook in linear order, especially if you want to share it. There’s a talk called <a href="https://youtu.be/7jiPeIFXb6U">I Don’t Like Notebooks</a> by Joel Grus about those traps and about Jupyter notebooks from a Software Engineering perspective.</p>
<div class="center">
<img src="https://blog.brunk.io/posts/interactive-computing-with-jupyter-and-almond/jh_jupyter_productivity.png" alt="Jupyter Notebooks productivity" width="550px">
</div>
<p>Since cells in one notebook share the same kernel and its interpreter variable state, they can depend on values computed by other cells executed earlier. So you could have a cell on top of your notebook that loads a large dataset or runs a complex computation and the results will be cached and available to all cells executed later, as long as the kernel isn’t restarted. In essence, notebooks defuse the main disadvantage of worksheets by combining its execution model with the one of the REPL.</p>
<p>While outputs are shown below a cell by default, interleaving of input and output is between cells, not between single expressions as in The REPL. That means you can always see the code of a cell as a whole. You can also easily clear the output of a cell or of all cells to see all your inputs more clearly. Last but not least can you also export your notebook as a Scala file containing all your code input cells.</p>
</section>
<section id="rich-interactive-computing-in-your-browser" class="level3">
<h3 class="anchored" data-anchor-id="rich-interactive-computing-in-your-browser">Rich, Interactive Computing in your Browser</h3>
<p>Another very important reason why Jupyter notebooks are so successful is their web based frontend and how we can interact with it. As we’ve already seen, we can add documentation cells with Markdown formatting including images or other HTML elements. But what makes notebooks <strong>really</strong> powerful is that the Jupyter API allows us to send rich outputs from the kernel to the frontend.</p>
<p>We can generate generate dynamic web content on the fly in our code, accessing any data source available and send it to the frontend. That way, we can display basically anything the browser supports such as <em>tables</em>, <em>images</em>, <em>charts</em> etc. straight from our code. We can even send JavaScript from the kernel that will be executed in our frontend. And that JavaScript can communicate with the kernel through the Jupyter API i.e.&nbsp;for interactive input widgets.</p>
<p>This powerful idea is best illustrated with a few examples:</p>
<div id="cell-10" class="cell" data-execution_count="5">
<div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> almond<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>interpreter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>api<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>DisplayData</span>
<span id="cb6-2"></span>
<span id="cb6-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">display</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb6-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">DisplayData</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb6-5">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb6-6">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"text/html"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Some &lt;b&gt;HTML&lt;/b&gt;"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)))</span></span></code></pre></div>
<div class="cell-output cell-output-display">
Some <b>HTML</b>
</div>
<div class="cell-output cell-output-display" data-execution_count="5">
<div class="ansi-escaped-output">
<pre><span class="ansi-green-fg">import </span><span class="ansi-cyan-fg">almond.interpreter.api.DisplayData
</span></pre>
</div>
</div>
</div>
<p>The kernel API provides a <code>display</code> method that takes expects our content, together with its mime-type. We can also send <em>multiple representations</em> of the data we want to display (keyed by mime-type), and the frontend will pick and show the most specific one it supports:</p>
<div id="cell-12" class="cell" data-execution_count="6">
<div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb7-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">display</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb7-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">DisplayData</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb7-3">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb7-4">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"text/plain"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Some text"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-5">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"text/html"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Some &lt;b&gt;HTML&lt;/b&gt;"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)))</span></span></code></pre></div>
<div class="cell-output cell-output-display">
Some <b>HTML</b>
</div>
</div>
<p>almond provides and automatically imports some convenience helper methods for common mime-types in <code>almond.api.helpers.Display</code>:</p>
<div id="cell-14" class="cell" data-execution_count="7">
<div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb8-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">html</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Some &lt;b&gt;HTML&lt;/b&gt;"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<div class="cell-output cell-output-display">
Some <b>HTML</b>
</div>
<div class="cell-output cell-output-display" data-execution_count="7">
<div class="ansi-escaped-output">
<pre><span class="ansi-cyan-fg">res6</span>: <span class="ansi-green-fg">almond</span>.<span class="ansi-green-fg">api</span>.<span class="ansi-green-fg">helpers</span>.<span class="ansi-green-fg">Display</span> = text/html #e207fdff-f77e-464b-acb7-3c2a882d6292</pre>
</div>
</div>
</div>
<p>You can also register a <code>Displayer</code> for any type via <a href="https://github.com/jupyter/jvm-repr">JVM Repr</a>, a project for “standardizing object representation and inspection across JVM kernels (Scala, Clojure, Groovy, …)”.</p>
<p>Let’s see how a list of <code>people</code> is displayed by default:</p>
<div id="cell-16" class="cell" data-execution_count="8">
<div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb9-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Person</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">String</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> age<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb9-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">People</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>people<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>Person<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">])</span></span>
<span id="cb9-3"></span>
<span id="cb9-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> people <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">People</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb9-5">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb9-6">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Person</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"alice"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">29</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb9-7">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Person</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bob"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb9-8">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Person</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"charlie"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">34</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb9-9">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb9-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<div class="cell-output cell-output-display" data-execution_count="8">
<div class="ansi-escaped-output">
<pre>defined <span class="ansi-green-fg">class</span> <span class="ansi-cyan-fg">Person</span>
defined <span class="ansi-green-fg">class</span> <span class="ansi-cyan-fg">People</span>
<span class="ansi-cyan-fg">people</span>: <span class="ansi-green-fg">People</span> = <span class="ansi-yellow-fg">People</span>(
  <span class="ansi-yellow-fg">List</span>(<span class="ansi-yellow-fg">Person</span>(<span class="ansi-green-fg">"alice"</span>, <span class="ansi-green-fg">29</span>), <span class="ansi-yellow-fg">Person</span>(<span class="ansi-green-fg">"bob"</span>, <span class="ansi-green-fg">23</span>), <span class="ansi-yellow-fg">Person</span>(<span class="ansi-green-fg">"charlie"</span>, <span class="ansi-green-fg">34</span>))
)</pre>
</div>
</div>
</div>
<p>Now let’s add a displayer for <code>People</code> and see how it is displayed:</p>
<div id="cell-18" class="cell" data-execution_count="9">
<div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb10-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> $ivy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>`com<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>lihaoyi<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>scalatags<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.7</span>`</span>
<span id="cb10-2"></span>
<span id="cb10-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> jupyter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Displayer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> jupyter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Displayers</span>
<span id="cb10-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> scala<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>collection<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>JavaConverters<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_</span>
<span id="cb10-5"></span>
<span id="cb10-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Note that as of now this approach doesn't seem to work with parameterized types like Seq[Person]</span></span>
<span id="cb10-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// which is probably due to type erasure.</span></span>
<span id="cb10-8">Displayers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">register</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>classOf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>People<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>people<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> People<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-9">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> scalatags<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Text</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>all<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_</span>
<span id="cb10-10">  <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb10-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"text/html"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-12">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>cls<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"table"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)(</span></span>
<span id="cb10-13">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">th</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Name"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">th</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Age"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)),</span></span>
<span id="cb10-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Person</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> age<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;-</span> people<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>people<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">yield</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb10-15">          <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">td</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb10-16">          <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">td</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>age<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb10-17">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb10-18">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>render</span>
<span id="cb10-19">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-20">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>asJava</span>
<span id="cb10-21"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">})</span></span>
<span id="cb10-22"></span>
<span id="cb10-23">people</span></code></pre></div>
<div class="cell-output cell-output-display">
<table class="table caption-top table-sm table-striped small" data-quarto-postprocess="true">
<tbody>
<tr class="odd">
<td data-quarto-table-cell-role="th">Name</td>
<td data-quarto-table-cell-role="th">Age</td>
</tr>
<tr class="even">
<td>alice</td>
<td>29</td>
</tr>
<tr class="odd">
<td>bob</td>
<td>23</td>
</tr>
<tr class="even">
<td>charlie</td>
<td>34</td>
</tr>
</tbody>
</table>
</div>
<div class="cell-output cell-output-display" data-execution_count="9">
<div class="ansi-escaped-output">
<pre><span class="ansi-green-fg">import </span><span class="ansi-cyan-fg">$ivy.$                             
</span><span class="ansi-green-fg">import </span><span class="ansi-cyan-fg">jupyter.Displayer, jupyter.Displayers
</span><span class="ansi-green-fg">import </span><span class="ansi-cyan-fg">scala.collection.JavaConverters._
</span>// Note that as of now this approach doesn't seem to work with parameterized types like Seq[Person]
// which is probably due to type erasure.
</pre>
</div>
</div>
</div>
<p>Pretty neat huh?</p>
<p>The idea is that library authors can provide <code>Displayers</code> for types i.e.&nbsp;for a Spark <code>DataFrame</code> and once you have it imported it you will get a nicely formatted representation of your data.</p>
<p>There are also helpers for images.</p>
<div id="cell-20" class="cell" data-execution_count="10">
<div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb11-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Image</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fromUrl</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://scala-lang.org/resources/img/frontpage/scala-spiral.png"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Some</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"50"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span></code></pre></div>
<div class="cell-output cell-output-display">
<img src="https://scala-lang.org/resources/img/frontpage/scala-spiral.png" width="50/">
</div>
<div class="cell-output cell-output-display" data-execution_count="10">
<div class="ansi-escaped-output">
<pre><span class="ansi-cyan-fg">res9</span>: <span class="ansi-green-fg">almond</span>.<span class="ansi-green-fg">api</span>.<span class="ansi-green-fg">helpers</span>.<span class="ansi-green-fg">Display</span> = image/png #422d85e7-fa35-467d-be50-ebe246d13a69</pre>
</div>
</div>
</div>
<p>Let’s see a more advanced example. We can easily plot nice, interactive charts directly in our notebook using <a href="plot.ly">Plotly</a> and the <a href="https://github.com/alexarchambault/plotly-scala">plotly-scala</a> bindings.</p>
<div id="cell-22" class="cell" data-execution_count="11">
<div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb12-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> $ivy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>`org<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>plotly<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>scala<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>plotly<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>almond<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.4</span>`</span>
<span id="cb12-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> plotly<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> plotly<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>element<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> plotly<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>layout<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> plotly<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Almond<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_</span>
<span id="cb12-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{{</span>  </span>
<span id="cb12-4">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> trace1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Scatter</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb12-5">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb12-6">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb12-7">    fill <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Fill<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>ToZeroY</span>
<span id="cb12-8">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-9"></span>
<span id="cb12-10">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> trace2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Scatter</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb12-11">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb12-12">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb12-13">    fill <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Fill<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>ToNextY</span>
<span id="cb12-14">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-15"></span>
<span id="cb12-16">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>trace1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> trace2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-17"></span>
<span id="cb12-18">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-19"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}}</span></span></code></pre></div>
<div class="cell-output cell-output-display">

      <script type="text/javascript">
        require.config({
  paths: {
    d3: 'https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min',
    plotly: 'https://cdn.plot.ly/plotly-1.41.3.min',
    jquery: 'https://code.jquery.com/jquery-3.3.1.min'
  },

  shim: {
    plotly: {
      deps: ['d3', 'jquery'],
      exports: 'plotly'
    }
  }
});
        

        require(['plotly'], function(Plotly) {
          window.Plotly = Plotly;
        });
      </script>
    
</div>
<div class="cell-output cell-output-display">
<div class="chart" id="plot-25d7d03f-0ef2-42ed-92a7-564179c52cc0"></div>
<script>require(['plotly'], function(Plotly) {
  (function () {
  var data0 = {"x":[1.0,2.0,3.0,4.0],"y":[0.0,2.0,3.0,5.0],"fill":"tozeroy","type":"scatter"};
  var data1 = {"x":[1.0,2.0,3.0,4.0],"y":[3.0,5.0,1.0,7.0],"fill":"tonexty","type":"scatter"};

  var data = [data0, data1];
  var layout = {};

  Plotly.plot('plot-25d7d03f-0ef2-42ed-92a7-564179c52cc0', data, layout);
})();
});
      </script>
           
</div>
<div class="cell-output cell-output-display" data-execution_count="11">
<div class="ansi-escaped-output">
<pre><span class="ansi-green-fg">import </span><span class="ansi-cyan-fg">$ivy.$                                      
</span><span class="ansi-green-fg">import </span><span class="ansi-cyan-fg">plotly._, plotly.element._, plotly.layout._, plotly.Almond._
</span><span class="ansi-cyan-fg">res10_2</span>: <span class="ansi-green-fg">String</span> = <span class="ansi-green-fg">"plot-25d7d03f-0ef2-42ed-92a7-564179c52cc0"</span></pre>
</div>
</div>
</div>
<p>Here we use the ability to send JavaScript to generate inject the plotly widget into our frontend. Newer frontends like JupyterLab and nteract are more restrictive about JavaScript execution for security reasons. That’s why plotly-scala also sends a json representation of our plot which is then rendered by nteract or the JupyterLab Plotly extension.</p>
</section>
<section id="communicating-results" class="level3">
<h3 class="anchored" data-anchor-id="communicating-results">Communicating results</h3>
<p>The ability to generate and display rich (and possibly interactive) outputs is an invaluable tool for interactive data exploration and analysis, machine learning, and science experiments. That’s why interactive notebooks have recently been named the third most important tool for data scientists. Being able to show your code side-by-side with documentation, rich outputs and visualizations can be a very effective way to communicate results.</p>
</section>
<section id="teaching-and-learning" class="level3">
<h3 class="anchored" data-anchor-id="teaching-and-learning">Teaching and Learning</h3>
<p>Notebooks are also an interesting tool for teaching and learning. They can help you to create executable tutorials, docs and examples. For instance, I’ve recently converted the <a href="https://docs.scala-lang.org/tour/tour-of-scala.html">Scala Tour</a> into a set of Jupyter notebooks you can run on <a href="https://mybinder.org/v2/gh/almond-sh/examples/master?urlpath=lab/tree/scala-tour%2Fbasics.ipynb">Binder</a>.</p>
<blockquote class="twitter-tweet blockquote" data-lang="de" data-dnt="true">
<p lang="en" dir="ltr">
<img src="https://blog.brunk.io/posts/interactive-computing-with-jupyter-and-almond/scala_tour_tweet.png" width="500px"><a href="https://twitter.com/soebrunk/status/1075151747528708096?ref_src=twsrc^tfw"></a>
</p></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<section id="visualize-your-data-structures" class="level4">
<h4 class="anchored" data-anchor-id="visualize-your-data-structures">Visualize your data structures</h4>
<p>Or how about experimenting with a nice inline visualization of your data structures using the amazing <a href="https://stanch.github.io/reftree/">reftree</a> library?</p>
<div id="cell-24" class="cell" data-execution_count="12">
<div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb13-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> $ivy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>`io<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>github<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>stanch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>reftree<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0</span>`</span>
<span id="cb13-2"></span>
<span id="cb13-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{{</span></span>
<span id="cb13-4">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> reftree<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>render<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> reftree<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>diagram<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_</span>
<span id="cb13-5">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> reftree<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>contrib<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>SimplifiedInstances<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>string</span>
<span id="cb13-6">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> renderer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Renderer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>renderingOptions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">RenderingOptions</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>density <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">75</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb13-7">    </span>
<span id="cb13-8">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Person</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">String</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> age<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb13-9">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> people <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">List</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb13-10">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Person</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Alice"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">29</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb13-11">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Person</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Bob"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb13-12">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Person</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Charlie"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">34</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb13-13">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb13-14"></span>
<span id="cb13-15">  renderer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">render</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"example"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Diagram<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sourceCodeCaption</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>people<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb13-16"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}}</span></span>
<span id="cb13-17"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Image</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fromFile</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"example.png"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<div class="cell-output cell-output-stderr">
<pre><code>Downloading https://repo1.maven.org/maven2/xml-apis/xml-apis-ext/1.3.04/xml-apis-ext-1.3.04-sources.jar.sha1
Downloading https://repo1.maven.org/maven2/xml-apis/xml-apis-ext/1.3.04/xml-apis-ext-1.3.04-sources.jar</code></pre>
</div>
<div class="cell-output cell-output-display">
<div>
<figure class="figure">
<p><img src="https://blog.brunk.io/posts/interactive-computing-with-jupyter-and-almond/index_files/figure-html/cell-13-output-2.png" class="img-fluid figure-img"></p>
</figure>
</div>
</div>
<div class="cell-output cell-output-display" data-execution_count="12">
<div class="ansi-escaped-output">
<pre><span class="ansi-green-fg">import </span><span class="ansi-cyan-fg">$ivy.$                                
</span><span class="ansi-cyan-fg">res11_2</span>: <span class="ansi-green-fg">almond</span>.<span class="ansi-green-fg">api</span>.<span class="ansi-green-fg">helpers</span>.<span class="ansi-green-fg">Display</span> = image/png #c6b66980-c2ad-48e7-9a40-2ee06df0a5ce</pre>
</div>
</div>
</div>
</section>
</section>
<section id="conclusion" class="level3">
<h3 class="anchored" data-anchor-id="conclusion">Conclusion</h3>
<p>I hope that I could convince you that Jupyter notebooks are a powerful and incredibly flexible tool for interactive computing. As we’ve seen, they combine many strengths of the REPL and worksheets, while also adding unique new features. Their web-based interface, interleaving code with documentation, and the ability to send rich outputs from your code to the frontend give you a wealth of possibilies for things like prototyping, data visualization, communication of results, and teaching.</p>
<p>The <a href="https://almond-sh.github.io/almond/stable">almond kernel</a> makes that power available for Scala, including all the niceties of Ammonite. Even though it still needs some more integrations and documentation, it’s already quite usable and fun to work with.</p>
<p>To see more examples of what’s possible with Jupyter and almond, check out the <a href="https://github.com/almond-sh/examples">examples repo</a>. It consists of a growing collection of Jupyter notebooks, each containing executable Scala code. You can run all these notebooks in your browser without any local setup, <a href="https://mybinder.org/v2/gh/almond-sh/examples/master?urlpath=lab">using Binder</a>.</p>
<p>If you have any questions or feedback, don’t hesitate to leave a comment, or ping me on Twitter <a href="https://twitter.com/soebrunk"><span class="citation" data-cites="soebrunk">@soebrunk</span></a>.</p>


</section>

 ]]></description>
  <category>scala</category>
  <category>jupyter</category>
  <category>interactive computing</category>
  <guid>https://blog.brunk.io/posts/interactive-computing-with-jupyter-and-almond/</guid>
  <pubDate>Wed, 09 Jan 2019 23:00:00 GMT</pubDate>
  <media:content url="https://blog.brunk.io/posts/interactive-computing-with-jupyter-and-almond/Screenshot_JupyterLab_Almond.png" medium="image" type="image/png" height="129" width="144"/>
</item>
<item>
  <title>Dive into Deep Learning with Scala</title>
  <link>https://blog.brunk.io/posts/dive-into-deep-learning-with-scala-talk/</link>
  <description><![CDATA[ 





<p>Slides and recording from my talk at Scala Days Europe 2018 <a href="https://eu.scaladays.org/lect-6912-dive-into-deep-learning-with-scala.html">“Dive into Deep Learning with Scala”</a>.</p>
<script async="" class="speakerdeck-embed" data-id="63dc2f6c0879408996e10ef1e7b3707b" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>
<p><br> <strong>Update</strong>: The recording is now available. <iframe width="560" height="315" src="https://www.youtube.com/embed/06sVEKh6bVc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe></p>



 ]]></description>
  <category>deep-learning</category>
  <category>scala</category>
  <guid>https://blog.brunk.io/posts/dive-into-deep-learning-with-scala-talk/</guid>
  <pubDate>Tue, 15 May 2018 22:00:00 GMT</pubDate>
  <media:content url="https://img.youtube.com/vi/06sVEKh6bVc/0.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Deep Learning in Scala Part 3: Object Detection</title>
  <link>https://blog.brunk.io/posts/deep-learning-in-scala-part-3-object-detection/</link>
  <description><![CDATA[ 





<p>In this post, we’re going to create an off the shelve object detector using OpenCV and TensorFlow for Scala. The detector will be able to detect common objects like people in still images and videos. It will also be able to run on a live video stream captured from your webcam.</p>
<section id="object-detection" class="level3">
<h3 class="anchored" data-anchor-id="object-detection">Object detection</h3>
<p>In the <a href="../../posts/deep-learning-in-scala-part-2-hello-neural-net/index.html">previous post</a> we talked about image recognition (or image classification). Image recognition is about recognizing <strong>what</strong> the content of an image is. In <strong>object detection</strong>, we want to predict <strong>where</strong> one or multiple objects are located in an image. Usually when we say object detection we mean recognition and localization together. I.e. we want a neural net to tell us that the image contains a beagle, and to also tell us the location of the beagle within the image.</p>
<figure class="figure">
<img src="https://blog.brunk.io/posts/deep-learning-in-scala-part-3-object-detection/dogs.jpg" width="400px" alt="Dogs example" class="figure-img"> <img src="https://blog.brunk.io/posts/deep-learning-in-scala-part-3-object-detection/dogs_detections_output.jpg" width="400px" alt="Dogs object detection example" class="figure-img">
<figcaption>
In image recognition, the neural network predicts the content of the image as “beagle”. In object detection, it additionally predicts the position of the beagles.
</figcaption>
</figure>
<p>In most cases, a neural network is trained to predict the coordinates of the rectangle surrounding an object, called <strong>bounding box</strong>, and to classify the object within that bounding box. The classification part is almost always done using a convolutional neural network. For the bounding box predictions, several approaches exist with different speed and accuracy characteristics. Object detection is an area of active research, and the state of the art is advancing rapidly.</p>
<p>A task related to object detection is semantic segmentation, in which you basically try to classify each pixel of an image. Instance segmentation is the combination of semantic segmentation and object detection that distinguishes between different objects of the same class.</p>
<figure class="figure">
<img src="https://blog.brunk.io/posts/deep-learning-in-scala-part-3-object-detection/object_detection_image_segmentation.png" width="100%" class="figure-img">
<figcaption>
Object detection vs.&nbsp;semantic segmentation vs.&nbsp;instance segmentation. (<a href="http://deeplearning.csail.mit.edu/instance_ross.pdf">Image source: Ross Girshick</a>)
</figcaption>
</figure>
<p>In our example, we’ll stick with the simpler object detection using bounding boxes. Furthermore, we’re going to cheat a little bit to make our life even easier by skipping training entirely. Instead, we’ll use <a href="https://github.com/eaplatanios/tensorflow_scala">TensorFlow for Scala</a> to load a pretrained model from the <a href="https://github.com/tensorflow/models/blob/master/research/object_detection">TensorFlow object detection API</a> model zoo and run it on our input images.</p>
</section>
<section id="the-tensorflow-object-detection-api" class="level3">
<h3 class="anchored" data-anchor-id="the-tensorflow-object-detection-api">The TensorFlow Object Detection API</h3>
<p>According to its Readme, “the TensorFlow Object Detection API is an open source framework built on top of TensorFlow that makes it easy to construct, train and deploy object detection models.” The API is written in Python.</p>
<p>If you like, you can also use the TensorFlow object detection API to train a model on your own dataset instead of using a pretrained one. Doing so allows you to use your own classes, and a model that matches your data much better. The downside is that you have to provide your own training data, and convert it into the TFRecord format that TensorFlow can read. Once you’ve done that, there’s no code required to run training. Have a look at their <a href="https://github.com/tensorflow/models/blob/master/research/object_detection/README.md">documentation</a> for details.</p>
<p>The API currently supports two model families named <em>SSD (Single Shot Detector)</em> and <em>faster R-CNN (Regional Convolutional Neural Network)</em>. SSD is comparatively fast, enabling real time detection even on a CPU, while R-CNN is more accurate, albeit slower. For both model families multiple convolutional neural network variants like resnet or inception are available, providing different tradeoffs between speed and accuracy.</p>
<p>Most of the pretrained models are based on the <a href="http://cocodataset.org">COCO dataset</a> containing 300k images of 90 common objects. You can see which classes are available in the COCO dataset <a href="http://cocodataset.org/#explore">here</a>. A few pretrained R-CNN models are also available for the openimages and kitti datasets.</p>
</section>
<section id="building-an-object-detector" class="level3">
<h3 class="anchored" data-anchor-id="building-an-object-detector">Building an Object Detector</h3>
<p>Now that we have seen a brief overview of object detection, let’s get started with our example. We’ll use the computer vision library <a href="https://opencv.org/">OpenCV</a> to for image and video IO. While OpenCV is written in C++, there’s a nice Java wrapper called <a href="https://github.com/bytedeco/javacv/">JavaCV</a> available. <a href="https://github.com/bytedeco/sbt-javacv">SBT-JavaCV</a> is an SBT plugin that automatically chooses the right OpenCV dependency for your platform and architecture, so you don’t have to worry about installing or compiling OpenCV yourself. To learn more about JavaCV, check out the great <a href="https://github.com/bytedeco/javacv-examples">JavaCV examples ported from the OpenCV2 Cookbook</a> written in Scala.</p>
<p>The actual detection is done using <a href="https://github.com/eaplatanios/tensorflow_scala">TensorFlow for Scala</a>. Right now, it runs on Linux and Mac. For Linux it also has CUDA support for running on the GPU. If you want to try the example yourself, make sure you you use the right <a href="http://platanios.org/tensorflow_scala/installation.html#installation-0-dependencies-1">classifier</a> for the TensorFlow binaries in your build.sbt.</p>
<p>The <a href="https://github.com/sbrunk/scala-deeplearn-examples/blob/master/tensorflow/src/main/scala/io/brunk/examples/ObjectDetector.scala">full source code</a> (including imports) of this example is available on GitHub.</p>
<p>As a first step, we load the pretrained serialized model from disk and create a TensorFlow graph from it. We then create a session with that graph, which allows us to later run the model on our input.</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> modelDir <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lift</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">getOrElse</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ssd_inception_v2_coco_2017_11_17"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// load a pretrained detection model as TensorFlow graph</span></span>
<span id="cb1-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> graphDef <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GraphDef<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">parseFrom</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb1-4">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">BufferedInputStream</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">FileInputStream</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">File</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">File</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"models"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> modelDir<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"frozen_inference_graph.pb"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))))</span></span>
<span id="cb1-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> graph <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fromGraphDef</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>graphDef<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-6"></span>
<span id="cb1-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// create a session and add our pretrained graph to it</span></span>
<span id="cb1-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> session <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Session</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<p>We also have to load the mapping from the numeric class identifiers to human readable labels such as “cat” (remember neural networks operate on numeric tensors). For now, we just load labels from the COCO dataset. The labels are encoded as protocol buffers, and we use the great <a href="https://scalapb.github.io/index.html">ScalaPB</a> library to parse it.</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// load the protobuf label map containing the class number to string label mapping (from COCO)</span></span>
<span id="cb2-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> labelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">String</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> pbText <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Source</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fromResource</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mscoco_label_map.pbtxt"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>mkString</span>
<span id="cb2-4">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> stringIntLabelMap <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> StringIntLabelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fromAscii</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>pbText<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-5">  stringIntLabelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>item<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>collect <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">StringIntLabelMapItem</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>_<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Some</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>id<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Some</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>displayName<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span> id <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> displayName</span>
<span id="cb2-7">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}.</span>toMap</span>
<span id="cb2-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
<p>Before we can run our model we need another helper to convert our image from the <code>Mat</code> OpenCV operates on, to a TensorFlow <code>Tensor</code>.</p>
<div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// convert OpenCV tensor to TensorFlow tensor</span></span>
<span id="cb3-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">matToTensor</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Mat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">):</span> Tensor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> imageRGB <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Mat</span>
<span id="cb3-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cvtColor</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> imageRGB<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> COLOR_BGR2RGB<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// convert channels from OpenCV GBR to RGB</span></span>
<span id="cb3-5">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> imgBuffer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> imageRGB<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>createBuffer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">ByteBuffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb3-6">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> shape <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Shape</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>height<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">width</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>channels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-7">  Tensor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fromBuffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>UINT8<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> shape<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> imgBuffer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> imgBuffer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
<p>The <code>detect</code> method is where the actual detection takes place. Here we run our neural network in inference mode. It takes a TensorFlow <code>Tensor</code>, a <code>Graph</code>, and a <code>Session</code> as input. It first retrieves the placeholder tensors from the graph that will be used for input and output, and then sets the image tensor as input parameter. Finally, it runs the graph (the detection model) within the given session. The returned value is a bunch of tensors containing the bounding box coordinates as well as their confidence scores and classes.</p>
<div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// run the object detection model on an image</span></span>
<span id="cb4-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">detect</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Tensor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">):</span> DetectionOutput <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-3"></span>
<span id="cb4-4">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// retrieve the output placeholders</span></span>
<span id="cb4-5">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> imagePlaceholder <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">getOutputByName</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"image_tensor:0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-6">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> detectionBoxes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">getOutputByName</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"detection_boxes:0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-7">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> detectionScores <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">getOutputByName</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"detection_scores:0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-8">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> detectionClasses <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">getOutputByName</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"detection_classes:0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-9">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> numDetections <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">getOutputByName</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"num_detections:0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-10"></span>
<span id="cb4-11">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// set image as input parameter</span></span>
<span id="cb4-12">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> feeds <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>imagePlaceholder <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-13"></span>
<span id="cb4-14">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Run the detection model</span></span>
<span id="cb4-15">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>boxes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> scores<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> classes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> num<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span></span>
<span id="cb4-16">    session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">run</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>fetches <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>detectionBoxes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> detectionScores<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> detectionClasses<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> numDetections<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> feeds <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> feeds<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-17">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">DetectionOutput</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>boxes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> scores<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> classes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> num<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-18"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
<p>The <code>drawBoundingBoxes</code> method is responsible for drawing bounding boxes, scores and classes on top of the original image. We extract the values from our <code>DetectionOutput</code>, and then use on OpenCV’s drawing primitives. We only draw boxes whose confidence score exceeds a certain threshold (0.5 here).</p>
<div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// draw boxes with class and score around detected objects</span></span>
<span id="cb5-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">drawBoundingBoxes</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Mat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> labelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">String</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> detectionOutput<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> DetectionOutput<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">):</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Unit</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-3">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> until detectionOutput<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>boxes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>shape<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> score <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> detectionOutput<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scores</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>scalar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>asInstanceOf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb5-5">  </span>
<span id="cb5-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>score <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-7">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> box <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> detectionOutput<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">boxes</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>entriesIterator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>_<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>asInstanceOf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]).</span>toSeq</span>
<span id="cb5-8">      <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// we have to scale the box coordinates to the image size</span></span>
<span id="cb5-9">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> ymin <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">box</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">height</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()).</span>toInt</span>
<span id="cb5-10">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> xmin <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">box</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">width</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()).</span>toInt</span>
<span id="cb5-11">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> ymax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">box</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">height</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()).</span>toInt</span>
<span id="cb5-12">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> xmax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">box</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">width</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()).</span>toInt</span>
<span id="cb5-13">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> label <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> labelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">getOrElse</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>detectionOutput<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">classes</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>scalar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>asInstanceOf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">].</span>toInt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"unknown"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-14">  </span>
<span id="cb5-15">      <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// draw score value</span></span>
<span id="cb5-16">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">putText</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb5-17">        <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"$label%s</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> (</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">$score%1.2f</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">)</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// text</span></span>
<span id="cb5-18">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Point</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>xmin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ymin <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// text position</span></span>
<span id="cb5-19">        FONT_HERSHEY_PLAIN<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// font type</span></span>
<span id="cb5-20">        <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// font scale</span></span>
<span id="cb5-21">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Scalar</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">255</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// text color</span></span>
<span id="cb5-22">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// text thickness</span></span>
<span id="cb5-23">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// line type</span></span>
<span id="cb5-24">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">false</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// origin is at the top-left corner</span></span>
<span id="cb5-25">      <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// draw bounding box</span></span>
<span id="cb5-26">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rectangle</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb5-27">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Point</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>xmin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ymin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// upper left corner</span></span>
<span id="cb5-28">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Point</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>xmax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ymax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// lower right corner</span></span>
<span id="cb5-29">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Scalar</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">255</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// color</span></span>
<span id="cb5-30">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// thickness</span></span>
<span id="cb5-31">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// lineType</span></span>
<span id="cb5-32">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// shift</span></span>
<span id="cb5-33">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-34">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-35"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
<p>Running the detector on a single image is now as simple as creating a minimal UI for display (we make use of JavaCV’s <code>CanvasFrame</code> here ), then call <code>detect</code> and <code>drawBoundingBoxes</code> with the appropriate arguments.</p>
<div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// run detector on a single image</span></span>
<span id="cb6-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">detectImage</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Mat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> labelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">String</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]):</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Unit</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> canvasFrame <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">CanvasFrame</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Object Detection"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-4">  canvasFrame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">setDefaultCloseOperation</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">JFrame</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>EXIT_ON_CLOSE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// exit when the canvas frame is closed</span></span>
<span id="cb6-5">  canvasFrame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">setCanvasSize</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>height<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-6">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> detectionOutput <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">detect</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">matToTensor</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">drawBoundingBoxes</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> labelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> detectionOutput<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-8">  canvasFrame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">showImage</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> OpenCVFrameConverter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ToMat</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">convert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb6-9">  canvasFrame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">waitKey</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-10">  canvasFrame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dispose</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb6-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
<figure class="figure">
<img src="https://blog.brunk.io/posts/deep-learning-in-scala-part-3-object-detection/object_detection_scala_example.jpg" class="block figure-img" width="500">
<figcaption>
Object detector example output. It clearly detects my daughter as a person, but it still has some difficulties with her car. :-)
</figcaption>
</figure>
<p>If we want to run the detector on a video stream from a file or camera, the <code>OpenCVFrameGrabber</code> allows us to extract single video frames as images. We can feed these frames into the detector and draw bounding boxes just as we did in the single image case above.</p>
<div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// run detector on an image sequence</span></span>
<span id="cb7-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">detectSequence</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>grabber<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> FrameGrabber<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> labelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">String</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]):</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Unit</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> canvasFrame <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">CanvasFrame</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Object Detection"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> CanvasFrame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>getDefaultGamma <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> grabber<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>getGamma<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-4">  canvasFrame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">setDefaultCloseOperation</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">JFrame</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>EXIT_ON_CLOSE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// exit when the canvas frame is closed</span></span>
<span id="cb7-5">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> converter <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> OpenCVFrameConverter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ToMat</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb7-6">  grabber<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">start</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb7-7">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>frame <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">continually</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>grabber<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">grab</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()).</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">takeWhile</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>_ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span></span>
<span id="cb7-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>grabber<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>getLengthInFrames <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> grabber<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>getFrameNumber <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> grabber<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>getLengthInFrames<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> image <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> converter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">convert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>frame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// sometimes the first few frames are empty so we ignore them</span></span>
<span id="cb7-11">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> detectionOutput <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">detect</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">matToTensor</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// run our model</span></span>
<span id="cb7-12">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">drawBoundingBoxes</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> labelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> detectionOutput<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-13">      <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>canvasFrame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>isVisible<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// show our frame in the preview</span></span>
<span id="cb7-14">        canvasFrame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">showImage</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>frame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-15">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-16">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-17">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-18">  canvasFrame<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dispose</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb7-19">  grabber<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stop</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb7-20"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
<p>Finally, we build a simple command line application, which allows us to run the detector on either an image, a video file or on a live webcam stream.</p>
<div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb8-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">printUsageAndExit</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">():</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Unit</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-2">  <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Console</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">println</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb8-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb8-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">      |Usage: ObjectDetector image &lt;file&gt;|video &lt;file&gt;|camera &lt;deviceno&gt; [&lt;modelpath&gt;]</span></span>
<span id="cb8-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">      |  &lt;file&gt;      path to an image/video file</span></span>
<span id="cb8-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">      |  &lt;deviceno&gt;  camera device number (usually starts with 0)</span></span>
<span id="cb8-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">      |  &lt;modelpath&gt; optional path to the object detection model to be used. Default: ssd_inception_v2_coco_2017_11_17</span></span>
<span id="cb8-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">      |"""</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>stripMargin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>trim<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb8-9">  sys<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">exit</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb8-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb8-11"></span>
<span id="cb8-12">inputType <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">match</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-13">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"image"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span></span>
<span id="cb8-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> image <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">imread</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">args</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb8-15">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">detectImage</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>image<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> labelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb8-16">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"video"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span></span>
<span id="cb8-17">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> grabber <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">FFmpegFrameGrabber</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">args</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb8-18">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">detectSequence</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>grabber<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> labelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb8-19">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"camera"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span></span>
<span id="cb8-20">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> cameraDevice <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Integer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">parseInt</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">args</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb8-21">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> grabber <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">OpenCVFrameGrabber</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>cameraDevice<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb8-22">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">detectSequence</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>grabber<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> session<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> labelMap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb8-23">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> _ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">printUsageAndExit</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb8-24"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
<p>You can check out the project and run it yourself using sbt:</p>
<div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb9-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> git clone https://github.com/sbrunk/scala-deeplearn-examples</span></code></pre></div>
<p>For now, you have to download and extract the model you want to run yourself first from the <a href="https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md">object detection model zoo</a>, like so:</p>
<div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb10-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> cd scala-deeplearn-examples/tensorflow</span>
<span id="cb10-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> mkdir models <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> models</span>
<span id="cb10-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> wget http://download.tensorflow.org/models/object_detection/ssd_inception_v2_coco_2017_11_17.tar.gz</span>
<span id="cb10-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> tar xzf ssd_inception_v2_coco_2017_11_17.tar.gz</span>
<span id="cb10-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> cd ../..</span></code></pre></div>
<p>Then you should be able to run the detector:</p>
<div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb11-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> sbt <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tensorFlow/runMain io.brunk.examples.ObjectDetector image &lt;filename&gt;'</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Run on an image (i.e. try example_image.jpg)</span></span>
<span id="cb11-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> sbt <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tensorFlow/runMain io.brunk.examples.ObjectDetector camera 0'</span>         <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Run on your webcam</span></span>
<span id="cb11-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> sbt <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tensorFlow/runMain io.brunk.examples.ObjectDetector video &lt;filename&gt;'</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Run on a video</span></span></code></pre></div>
<p>Now you’ve seen how it looks like to create a simple object detector in ~150 lines of Scala code. The neural networks used here are almost state of the art, and I find the results already quite impressive. While we didn’t cover training here, it’s not too difficult using the TensorFlow Object Detection API, given training data in the right format. It would also be interesting to investigate how much work is required to run training using the TensorFlow Scala API.</p>
<p>I encourage you to check out the project, try different options, play with the source code, fork it, train on your own data, share your experiences, send a PR with enhancements. Most importantly, have fun :). If you have feedback or questions, please use the comment function below or ping me on Twitter <a href="https://twitter.com/soebrunk"><span class="citation" data-cites="soebrunk">@soebrunk</span></a>.</p>


</section>

 ]]></description>
  <category>deep-learning</category>
  <category>scala</category>
  <guid>https://blog.brunk.io/posts/deep-learning-in-scala-part-3-object-detection/</guid>
  <pubDate>Wed, 17 Jan 2018 23:00:00 GMT</pubDate>
</item>
<item>
  <title>Deep Learning in Scala Part 2: Hello, Neural Net!</title>
  <link>https://blog.brunk.io/posts/deep-learning-in-scala-part-2-hello-neural-net/</link>
  <description><![CDATA[ 





<p>In the <a href="../../posts/deep-learning-in-scala-part-1-basics-and-libraries/index.html">first part of this series</a>, we saw a high-level overview of deep learning, and why Scala is a good fit for building neural networks. We also discussed what a deep learning library should provide, and we looked at a few existing libraries. Now it’s time to build the canonical “Hello, World!” example for deep learning: Classifying handwritten digits.</p>
<section id="creating-a-neural-network" class="level3">
<h3 class="anchored" data-anchor-id="creating-a-neural-network">Creating a neural network</h3>
<p>Building a neural network usually consists of the following steps:</p>
<ol type="1">
<li>Determine your goal.</li>
<li>Prepare the training data (collect, preprocess, vectorize etc.).
<ol type="1">
<li>Divide the data into training set/<a href="https://en.wikipedia.org/wiki/Cross-validation_(statistics)">cross-validation set</a>/test set for evaluation.</li>
</ol></li>
<li>Create the neural network architecture.
<ol start="2" type="1">
<li>Define the types, number and size of layers.</li>
<li>Define other hyperparameters such as loss function, optimizer, or learning rate.</li>
</ol></li>
<li>Train your model on the training data.</li>
<li>Evaluate your model on the cross-validation set.</li>
<li>Depending on the results, repeat steps 3-5 with different hyperparameters, or collect more data until you’re satisfied with the results.</li>
<li>Do a final evaluation on the test set.</li>
</ol>
<p>In our case, the task is already set: We want to recognize handwritten digits. The second step, data preparation, usually takes most of the effort, but we don’t have to worry about it here because it has already been taken care of. We also simplify evaluation a bit here by using a single test dataset for evaluation and just focus on steps 3 to 5. Usually, you should use the cross-validation set while trying out how well different combinations of hyperparameters work, only doing the final evaluation on the test set.</p>
</section>
<section id="the-mnist-dataset" class="level3">
<h3 class="anchored" data-anchor-id="the-mnist-dataset">The MNIST Dataset</h3>
<p>The MNIST dataset is an image classification dataset containing handwritten digits. It is a classic dataset often used as the “hello world” dataset for machine learning algorithms.</p>
<p>Due to its popularity, most deep learning libraries already provide code for downloading and vectorizing the dataset, letting us focus on the actual learning task.</p>
<p>MNIST consists of a training set of 60000 black and white pictures sized 28 * 28 pixels and their corresponding digit as well as a test set containing another 10000 samples. It is large enough to be interesting, but still small enough that a you can train a model on a CPU.</p>
<figure class="figure">
<img src="https://blog.brunk.io/posts/deep-learning-in-scala-part-2-hello-neural-net/mnist_digits.png" class="block figure-img" alt="Example MNIST digit images">
<figcaption>
Example MNIST digit images
</figcaption>
</figure>
<p>We are going to train a simple neural network on that dataset in each of the libraries in order to get a feeling of what it looks like to work with them. We’ll use a simple neural network architecture called multilayer perceptron (MLP). The following picture shows how our network architecture looks like, conceptually.</p>
<figure class="figure">
<img src="https://blog.brunk.io/posts/deep-learning-in-scala-part-2-hello-neural-net/simple_neural_network_architecture.png" class="block figure-img" alt="Our neural network architecture">
<figcaption>
Our neural network architecture
</figcaption>
</figure>
<p>The neurons, denoted by circles, are stacked in layers where each vertical column of neurons represents a layer. The leftmost column is the input layer, the column in the middle is the only hidden layer in our case, and the one on the right represents the output layer.</p>
<p>The arrows show how the inputs of a neuron from one layer are connected to the outputs from the previous layer. As you can see in the image, each input is connected to all the outputs of the previous layer, which is why this type of layer is called a fully connected layer.</p>
<p>Each neuron has a number of weights or parameters, one for each input, whose values are determined during training. As we’ve seen in part one, these weights contain the memory of a neural network, and represent what the network has learned. In our case, how it maps the input image to the a digit.</p>
<p>The input layer just represents the input values and does not have any weights, nor does it do any computation. In our MNIST example the input is the raw pixels of the image, normalized to have a range between zero and one. So we have 28 * 28 input values, represented as a vector of 784 float values.</p>
<p>During a forward pass through the network, each input of a neuron is multiplied by its corresponding weight , and the results of that multiplication are summed up. In our hidden layer, the resulting value is then fed into an activation function called <code>relu</code> that just passes through all positive values but sets any negative number to zero.</p>
<p>In the output layer, we use a <code>softmax</code> function instead, which returns a probability score for each of the 10 classes representing digits. The digit with the highest probability is what the network predicts as image content.</p>
</section>
<section id="training-a-neural-network" class="level3">
<h3 class="anchored" data-anchor-id="training-a-neural-network">Training a neural network</h3>
<p>How do we find a set of weights that works well on new, previously unseen inputs? That’s what training is all about. During training, we take a batch of examples, and run it through our network, starting with random weights. We then compare the output with the correct results, called <strong>labels</strong> from our examples. More specifically, we compute the difference, or <strong>loss</strong>, between the two in order to measure how well the network performs. Because the model in our MNIST example predicts the probability of each digit being the content of a given image, a reasonable loss function is the <strong>cross entropy loss</strong>, which measures the difference between two probability distributions.</p>
<p>We want to <strong>minimize</strong> the loss in order to get a model that produces predictions close to our training examples. To do that, we calculate the gradient of that loss function with respect to our weights through an algorithm called backpropagation. You can imagine the gradient as being the slope of the loss function for each weight. Backpropagation is basically applying the chain rule (remember calculus?) in order to get the gradient for all weights. Given the gradient, an <strong>optimizer</strong> such** **as gradient descent changes each weight a little bit in the direction opposite to the gradient, decreasing the loss that way.</p>
<p>Don’t worry If it’s not completely clear to you how gradient descent and backpropagation work. The nice thing about using a neural network library is that it takes care of it for us, hiding the gory details behind a simple API call. If you want to gain a better understanding though, check out the <a href="https://youtu.be/IHZwWFHWa-w">second and third 3blue1brown videos</a> on neural networks.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/IHZwWFHWa-w" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen="">
</iframe>
<p>Evaluation is done on the training data as well as on the test dataset, which contains examples not seen by the network during training. This separation enables us to recognize <strong>overfitting</strong>, which basically means that the network is memorizing the training examples instead of learning to generalize.</p>
<p>We also have to define how long we want to train the network. A simple way is to just stop after a number of iterations. In our case we we use the number of epochs, that is, how often we run through the entire training set, as a stop criterion. Showing the loss during training can help us to see when it might make sense to stop because we won’t see much enhancement anymore.</p>
</section>
<section id="mnist-examples" class="level3">
<h3 class="anchored" data-anchor-id="mnist-examples">MNIST Examples</h3>
<p>Now that we’ve designed our neural network, lets finally see some actual code. For the full examples with imports, check out the <a href="https://github.com/sbrunk/scala-deeplearn-examples">corresponding project</a> on GitHub.</p>
<p>First, we define our numeric hyperparameters as constants. We’ll use these values in all implementations of our example.</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> seed         <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span>      <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// fixed random seed for reproducibility</span></span>
<span id="cb1-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> numInputs    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">28</span></span>
<span id="cb1-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> numHidden    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">512</span>     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// size (number of neurons) of our hidden layer</span></span>
<span id="cb1-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> numOutputs   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>      <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// digits from 0 to 9</span></span>
<span id="cb1-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> learningRate <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.01</span></span>
<span id="cb1-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> batchSize    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">128</span></span>
<span id="cb1-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> numEpochs    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span></span></code></pre></div>
<section id="dl4j" class="level4">
<h4 class="anchored" data-anchor-id="dl4j">DL4J</h4>
<p>In DL4J, training and test data is usually fed to the neural network via a <code>DataSetIterator</code>. DL4J already provides a <code>MnistDataSetIterator</code> that takes care of downloading and vectorizing the MNIST dataset.</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// download and load the MNIST images as tensors</span></span>
<span id="cb2-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> mnistTrain <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MnistDataSetIterator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>batchSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> seed<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> mnistTest <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MnistDataSetIterator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>batchSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">false</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> seed<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<p>We define the network architecture and other hyperparameters like the learning rate by creating a <code>NeuralNetConfiguration</code> using the classic Java builder pattern. From that configuration we create a <code>MultiLayerNetwork</code>, which can be used for training.</p>
<div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// define the neural network architecture</span></span>
<span id="cb3-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> conf <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> NeuralNetConfiguration<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Builder</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb3-3">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">seed</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>seed<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-4">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">optimizationAlgo</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>OptimizationAlgorithm<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>STOCHASTIC_GRADIENT_DESCENT<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-5">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">updater</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Updater<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>SGD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-6">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">weightInit</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>WeightInit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>XAVIER<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// random initialization of our weights</span></span>
<span id="cb3-7">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">learningRate</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>learningRate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-8">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>list <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// builder for creating stacked layers</span></span>
<span id="cb3-9">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">layer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> DenseLayer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Builder</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// define the hidden layer</span></span>
<span id="cb3-10">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nIn</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>numInputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-11">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nOut</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>numHidden<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-12">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">activation</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Activation<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>RELU<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-13">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">build</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb3-14">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">layer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> OutputLayer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Builder</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>LossFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>MCXENT<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// define loss and output layer</span></span>
<span id="cb3-15">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nIn</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>numHidden<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-16">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nOut</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>numOutputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-17">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">activation</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Activation<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>SOFTMAX<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">build</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb3-19">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">build</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb3-20"></span>
<span id="cb3-21"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> model <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MultiLayerNetwork</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>conf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-22">model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">init</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb3-23">model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">setListeners</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ScoreIterationListener</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// print the score every 100th iteration</span></span></code></pre></div>
<p>Training the model is just applying the <code>fit</code> method of the network to the training set. We go through our training set of 60000 pictures 10 times.</p>
<div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb4-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>_ <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> until numEpochs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-2">  model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fit</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mnistTrain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
<p>DL4J provides an Evaluation class that can calculate numerous metrics. Here we just print the accuracy of running the model on our training and test set.</p>
<div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// evaluate model performance</span></span>
<span id="cb5-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> DataSetIterator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">):</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Double</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> evaluator <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Evaluation</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>numOutputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-4">  dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">reset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb5-5">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;-</span> dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>asScala<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">output</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>getFeatureMatrix<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-7">    evaluator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">eval</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>getLabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> output<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-8">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-9">  evaluator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb5-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-11"></span>
<span id="cb5-12">log<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">info</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">s"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Train accuracy = </span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">${</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mnistTrain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">}"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-13">log<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">info</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">s"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Test accuracy = </span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">${</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mnistTest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">}"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<p>Running the example gives us the following output. The score value is the loss value we’re trying to minimize. As you can see, the loss decreases rapidly at first, then starts to flatten out soon. After 10 epochs of training we achieve an accuracy of 92.8% on the test set.</p>
<pre><code>10:41:42.267 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 0 is 2.294145107269287
10:42:31.753 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 100 is 1.4235080480575562
10:43:27.206 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 200 is 1.0206242799758911
10:44:20.751 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 300 is 0.7351394295692444
10:45:09.959 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 400 is 0.7129665017127991
10:46:02.553 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 500 is 0.6167545318603516

...

10:47:38.618 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 4200 is 0.34266236424446106
10:47:39.071 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 4300 is 0.20224857330322266
10:47:39.483 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 4400 is 0.3612464666366577
10:47:39.905 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 4500 is 0.24936261773109436
10:47:40.354 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 4600 is 0.2355252504348755
10:47:41.767 [main] INFO  io.brunk.examples.dl4j.MnistMLP$ - Train accuracy = 0.9259666666666667
10:47:41.905 [main] INFO  io.brunk.examples.dl4j.MnistMLP$ - Test accuracy = 0.9282</code></pre>
</section>
<section id="scalnet" class="level4">
<h4 class="anchored" data-anchor-id="scalnet">ScalNet</h4>
<p>We can download and vectorize the MNIST the same way as with DL4J above.</p>
<div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// download and load the MNIST images as tensors</span></span>
<span id="cb7-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> mnistTrain <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MnistDataSetIterator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>batchSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> seed<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> mnistTest <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MnistDataSetIterator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>batchSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">false</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> seed<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<p>Defining the network architecture looks quite similar to the <a href="https://keras.io/">Keras</a> API. We create a <code>Sequential</code> model, add our layers to it and then set the global hyperparameters in the call to <code>compile</code>.</p>
<div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb8-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// define the neural network architecture</span></span>
<span id="cb8-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Sequential <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Sequential</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb8-3">model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Dense</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>nOut <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> numHidden<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> nIn <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> numInputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> weightInit <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> WeightInit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>XAVIER<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>  activation <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"relu"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb8-4">model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">add</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Dense</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>nOut <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> numOutputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> weightInit <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> WeightInit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>XAVIER<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> activation <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"softmax"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb8-5">model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">compile</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>lossFunction <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> LossFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>MCXENT<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> optimizer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">SGD</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>learningRate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> momentum <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb8-6">  nesterov <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span></code></pre></div>
<p>Training is done through a single call to the <code>fit</code> method, using the number of epochs as argument.</p>
<div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb9-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// train the model</span></span>
<span id="cb9-2">model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fit</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mnistTrain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> nbEpoch <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> numEpochs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">List</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ScoreIterationListener</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)))</span></span></code></pre></div>
<p>Evaluation in ScalNet looks almost the same as it does in DL4J.</p>
<div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb10-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// evaluate model performance</span></span>
<span id="cb10-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> DataSetIterator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">):</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Double</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> evaluator <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Evaluation</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>numOutputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb10-4">  dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">reset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb10-5">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;-</span> dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>asScala<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb10-7">    evaluator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">eval</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>getLabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> output<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb10-8">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-9">  evaluator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb10-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-11"></span>
<span id="cb10-12">log<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">info</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">s"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Train accuracy = </span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">${</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mnistTrain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">}"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb10-13">log<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">info</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">s"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Test accuracy = </span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">${</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mnistTest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">}"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<p>Running the example gives us an output very similar to our previous example which is not surprising, given that ScalNet uses DL4J internally.</p>
<pre><code>23:13:20.200 [main] INFO  o.d.scalnet.models.Sequential - Layer 0: Dense
23:13:20.205 [main] INFO  o.d.scalnet.models.Sequential -  size: in=List(784) out=List(512)
23:13:20.232 [main] INFO  o.d.scalnet.models.Sequential - Layer 1: Dense
23:13:20.233 [main] INFO  o.d.scalnet.models.Sequential -  size: in=List(512) out=List(10)

...

23:13:24.830 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 0 is 2.294145107269287
23:13:27.563 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 100 is 1.4235080480575562
23:13:30.147 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 200 is 1.0206241607666016
23:13:32.889 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 300 is 0.7351393699645996

...

23:14:54.751 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 4300 is 0.20224834978580475
23:14:56.812 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 4400 is 0.3612460494041443
23:14:58.639 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 4500 is 0.24936220049858093
23:15:00.078 [main] INFO  o.d.o.l.ScoreIterationListener - Score at iteration 4600 is 0.23552563786506653
23:15:04.853 [main] INFO  io.brunk.examples.scalnet.MnistMLP$ - Train accuracy = 0.9259666666666667
23:15:05.280 [main] INFO  io.brunk.examples.scalnet.MnistMLP$ - Test accuracy = 0.9282</code></pre>
</section>
<section id="tensorflow-for-scala" class="level4">
<h4 class="anchored" data-anchor-id="tensorflow-for-scala">TensorFlow for Scala</h4>
<p>The provided <code>MNISTLoader</code> allows us to download and extract the MNIST dataset. After that, we create a DataSet for training and test data in order to feed the data into the training process.</p>
<div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb12-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// download and load the MNIST images as tensors</span></span>
<span id="cb12-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> dataSet <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> MNISTLoader<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">load</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Paths<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">get</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"datasets/MNIST"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb12-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> trainImages <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">TensorSlicesDataset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>trainImages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> trainLabels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">TensorSlicesDataset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>trainLabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> testImages <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">TensorSlicesDataset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>testImages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> testLabels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">TensorSlicesDataset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>testLabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> trainData <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span></span>
<span id="cb12-8">  trainImages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">zip</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>trainLabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-9">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">repeat</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb12-10">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">shuffle</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-11">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">batch</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>batchSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-12">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">prefetch</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> evalTrainData <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> trainImages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">zip</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>trainLabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">batch</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">prefetch</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-14"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> evalTestData <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> testImages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">zip</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>testLabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">batch</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">prefetch</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<p>First, we define our input shapes. We then build our neural network architecture by composing operations we want to apply to the input data using the <code>&gt;&gt;</code> operator. After defining loss function and optimizer, we create a <code>Model</code> that holds our configuration.</p>
<div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// define the neural network architecture</span></span>
<span id="cb13-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> input <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Input</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>UINT8<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Shape</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>trainImages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">shape</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>trainImages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">shape</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)))</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// type and shape of images</span></span>
<span id="cb13-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> trainInput <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Input</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>UINT8<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Shape</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// type and shape of labels</span></span>
<span id="cb13-4"></span>
<span id="cb13-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> layer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Flatten</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Input/Flatten"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// flatten the images into a single vector</span></span>
<span id="cb13-6">  tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Input/Cast"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> FLOAT32<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span></span>
<span id="cb13-7">  tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Linear</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Layer_1/Linear"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> numHidden<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> weightsInitializer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GlorotUniformInitializer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// hidden layer</span></span>
<span id="cb13-8">  tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ReLU</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Layer_1/ReLU"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// hidden layer activation</span></span>
<span id="cb13-9">  tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Linear</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"OutputLayer/Linear"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> numOutputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> weightsInitializer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GlorotUniformInitializer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// output layer</span></span>
<span id="cb13-10"></span>
<span id="cb13-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> trainingInputLayer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TrainInput/Cast"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> INT64<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// cast labels to long</span></span>
<span id="cb13-12"></span>
<span id="cb13-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> loss <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">SparseSoftmaxCrossEntropy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Loss/CrossEntropy"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span></span>
<span id="cb13-14">    tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Mean</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Loss/Mean"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ScalarSummary</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Loss/Summary"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Loss"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb13-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> optimizer <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>train<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GradientDescent</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>learningRate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb13-16"></span>
<span id="cb13-17"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> model <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Model</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>input<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> layer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> trainInput<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> trainingInputLayer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> loss<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> optimizer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<p>The <code>Estimator</code> is responsible for running the actual training process. We configure it with the model as well as some triggers for checkpoints, logging, and the stop criterion. Training is done with a call the the <code>train</code> method on our estimator.</p>
<div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb14-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> accMetric <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>metrics<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MapMetric</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb14-2">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Output<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Output<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">argmax</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>_2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>metrics<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb14-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> estimator <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">InMemoryEstimator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb14-4">  model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb14-5">  tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Configuration</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Some</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>summariesDir<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)),</span></span>
<span id="cb14-6">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// due to a bug, we can't use epochs directly as stop criterion</span></span>
<span id="cb14-7">  tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">StopCriteria</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>maxSteps <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Some</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">((</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60000</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> batchSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> numEpochs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)),</span></span>
<span id="cb14-8">  <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Set</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb14-9">    tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">LossLogger</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>trigger <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">StepHookTrigger</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)),</span></span>
<span id="cb14-10">    tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Evaluator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb14-11">      log <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span> evalTrainData<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> metrics <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>accMetric<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb14-12">      trigger <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">StepHookTrigger</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> name <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TrainEvaluation"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb14-13">    tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Evaluator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb14-14">      log <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span> evalTestData<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> metrics <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Seq</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>accMetric<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb14-15">      trigger <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">StepHookTrigger</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> name <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TestEvaluation"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb14-16">    tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">StepRateLogger</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>log <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">false</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> summaryDir <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> summariesDir<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> trigger <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">StepHookTrigger</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)),</span></span>
<span id="cb14-17">    tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">SummarySaver</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>summariesDir<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">StepHookTrigger</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)),</span></span>
<span id="cb14-18">    tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">CheckpointSaver</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>summariesDir<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> tf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>learn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">StepHookTrigger</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))))</span></span>
<span id="cb14-19"></span>
<span id="cb14-20"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// train the model</span></span>
<span id="cb14-21">estimator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">train</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span> trainData<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<p>We do the final evaluation ourselves, using a function that runs the model on a given set, compares it with the actual labels, and then divides the number of correct predictions by the total number of predictions.</p>
<div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb15-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>images<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Tensor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> labels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Tensor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">):</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Float</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-2">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> predictions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> estimator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">infer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span> images<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb15-3">  predictions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">argmax</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>UINT8<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">equal</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>labels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>FLOAT32<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span>scalar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>asInstanceOf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb15-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-5"></span>
<span id="cb15-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// evaluate model performance</span></span>
<span id="cb15-7">logger<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">info</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">s"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Train accuracy = </span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">${</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>trainImages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>trainLabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">}"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb15-8">logger<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">info</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">s"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Test accuracy = </span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">${</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>testImages<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> dataSet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>testLabels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">}"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<pre><code>2018-01-09 19:52:49.673 [main] INFO  Learn / Hooks / Loss Logger - (    N/A    ) Step:      0, Loss: 160.4288
2018-01-09 19:52:50.414 [main] INFO  Learn / Hooks / Evaluation - Step 0 TestEvaluation: Accuracy = 0.1842
2018-01-09 19:52:51.917 [main] INFO  Learn / Hooks / Evaluation - Step 0 TrainEvaluation: Accuracy = 0.1872
2018-01-09 19:52:52.420 [main] INFO  Learn / Hooks / Loss Logger - (    2.750 s) Step:    100, Loss: 1.3103
2018-01-09 19:52:52.866 [main] INFO  Learn / Hooks / Loss Logger - (    0.447 s) Step:    200, Loss: 0.9289
2018-01-09 19:52:53.288 [main] INFO  Learn / Hooks / Loss Logger - (    0.422 s) Step:    300, Loss: 1.5239
2018-01-09 19:52:53.694 [main] INFO  Learn / Hooks / Loss Logger - (    0.405 s) Step:    400, Loss: 1.2546

...

2018-01-09 19:53:13.956 [main] INFO  Learn / Hooks / Evaluation - Step 4000 TestEvaluation: Accuracy = 0.8979
2018-01-09 19:53:15.328 [main] INFO  Learn / Hooks / Evaluation - Step 4000 TrainEvaluation: Accuracy = 0.9042
2018-01-09 19:53:15.710 [main] INFO  Learn / Hooks / Loss Logger - (    2.054 s) Step:   4100, Loss: 0.3789
2018-01-09 19:53:16.102 [main] INFO  Learn / Hooks / Loss Logger - (    0.391 s) Step:   4200, Loss: 0.4389
2018-01-09 19:53:16.500 [main] INFO  Learn / Hooks / Loss Logger - (    0.399 s) Step:   4300, Loss: 0.3625
2018-01-09 19:53:16.908 [main] INFO  Learn / Hooks / Loss Logger - (    0.408 s) Step:   4400, Loss: 0.4442
2018-01-09 19:53:17.306 [main] INFO  Learn / Hooks / Loss Logger - (    0.398 s) Step:   4500, Loss: 0.8267
2018-01-09 19:53:17.659 [main] INFO  Learn / Hooks / Loss Logger - (    0.353 s) Step:   4600, Loss: 0.1517
2018-01-09 19:53:17.967 [main] INFO  Learn / Hooks / Termination - Stop requested: Exceeded maximum number of steps.
2018-01-09 19:53:19.399 [main] INFO  io.brunk.examples.MnistMLP$ - Train accuracy = 0.93158334
2018-01-09 19:53:19.723 [main] INFO  io.brunk.examples.MnistMLP$ - Test accuracy = 0.9233</code></pre>
</section>
<section id="mxnet" class="level4">
<h4 class="anchored" data-anchor-id="mxnet">MXNet</h4>
<p>MXNet does not provide binary artifacts for Scala at the moment so we have to compile it ourselves, based on the <a href="https://mxnet.incubator.apache.org/install/index.html">installation instructions</a> from the project website. We also have to download the <a href="http://data.mxnet.io/mxnet/data/mnist.zip">MNIST dataset</a>, and extract it into an mnist directory in our project.</p>
<p>MXNet provides an iterator that loads the MNIST dataset and returns batches as tensors. We have to initialize the iterator using a <code>Map[String, String]</code> of key-value pairs.</p>
<div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb17-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// load the MNIST images as tensors</span></span>
<span id="cb17-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> trainDataIter <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> IO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MNISTIter</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb17-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"image"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mnist/train-images-idx3-ubyte"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-4">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"label"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mnist/train-labels-idx1-ubyte"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-5">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"data_shape"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(1, 28, 28)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-6">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"label_name"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sm_label"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-7">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"batch_size"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> batchSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>toString<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-8">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"shuffle"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-9">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"flat"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-10">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"silent"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb17-11"></span>
<span id="cb17-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> testDataIter <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> IO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MNISTIter</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb17-13">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"image"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mnist/t10k-images-idx3-ubyte"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-14">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"label"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mnist/t10k-labels-idx1-ubyte"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-15">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"data_shape"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(1, 28, 28)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-16">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"label_name"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sm_label"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-17">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"batch_size"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> batchSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>toString<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-18">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"shuffle"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-19">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"flat"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb17-20">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"silent"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span></code></pre></div>
<p>The MXNet symbol API allows us to define our neural network architecture. The use of three parameter stems from the fact that it is a very direct port of the Python API. We set most parameters through a <code>Map</code> of key-value pairs.</p>
<pre><code>:::scala
// define the neural network architecture
val data = Symbol.Variable("data")
val fc1 = Symbol.FullyConnected(name = "fc1")()(Map("data" -&gt; data, "num_hidden" -&gt; numHidden))
val act1 = Symbol.Activation(name = "relu1")()(Map("data" -&gt; fc1, "act_type" -&gt; "relu"))
val fc2 = Symbol.FullyConnected(name = "fc3")()(Map("data" -&gt; act1, "num_hidden" -&gt; numOutputs))
val mlp = Symbol.SoftmaxOutput(name = "sm")()(Map("data" -&gt; fc2))</code></pre>
<p>Creating the model is done using a builder of the <code>FeedForward</code> class. Here we also set the global hyperparameters. If you have a Nvidia GPU, you can also change the context to gpu in order to speed up training considerably.</p>
<pre><code>:::scala
// create and train the model
val model = FeedForward.newBuilder(mlp)
  .setContext(Context.cpu()) // change to gpu if available
  .setTrainData(trainDataIter)
  .setEvalData(testDataIter)
  .setNumEpoch(numEpochs)
  .setOptimizer(new SGD(learningRate = learningRate))
  .setInitializer(new Xavier()) // random weight initialization
  .build()</code></pre>
<p>As done in the TensorFlow example, we calculate the accuracy ourselves on both training set and test set by running the model on our test set, and comparing it with the correct labels.</p>
<div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode scala code-with-copy"><code class="sourceCode scala"><span id="cb20-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// evaluate model performance</span></span>
<span id="cb20-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataset<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> DataIter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">):</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Float</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb20-3">  dataset<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">reset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb20-4">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> predictions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> model<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dataset<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>head</span>
<span id="cb20-5">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// get predicted labels</span></span>
<span id="cb20-6">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> predictedY <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> NDArray<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">argmax_channel</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>predictions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb20-7"></span>
<span id="cb20-8">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// get real labels</span></span>
<span id="cb20-9">  dataset<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">reset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb20-10">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> labels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dataset<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>_<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">label</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">copy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()).</span>toVector</span>
<span id="cb20-11">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> NDArray<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">concatenate</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>labels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb20-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">require</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>shape <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> predictedY<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>shape<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb20-13"></span>
<span id="cb20-14">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// calculate accuracy</span></span>
<span id="cb20-15">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">val</span> numCorrect <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>toArray zip predictedY<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>toArray<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>count <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb20-16">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>labelElem<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> predElem<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span> labelElem <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> predElem</span>
<span id="cb20-17">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb20-18">  numCorrect<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>toFloat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size</span>
<span id="cb20-19"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb20-20"></span>
<span id="cb20-21"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">println</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">s"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Train accuracy = </span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">${</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>trainDataIter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">}"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb20-22"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">println</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">s"</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Test accuracy = </span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">${</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">accuracy</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>testDataIter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">}"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<p>As in the other examples, we achieve an accuracy of 92% after 10 epochs.</p>
<pre><code>17:17:43.033 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[0] Train-accuracy=0.75642693
17:17:43.033 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[0] Time cost=1864
17:17:43.126 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[0] Train-accuracy=0.86478364
17:17:44.678 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[1] Train-accuracy=0.87207866
17:17:44.678 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[1] Time cost=1552
17:17:44.770 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[1] Train-accuracy=0.89252806
17:17:46.437 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[2] Train-accuracy=0.89007413
17:17:46.437 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[2] Time cost=1667
17:17:46.577 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[2] Train-accuracy=0.90134215

...

17:17:57.974 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[8] Train-accuracy=0.9203726
17:17:57.974 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[8] Time cost=1669
17:17:58.088 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[8] Train-accuracy=0.9240785
17:17:59.959 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[9] Train-accuracy=0.9228599
17:17:59.959 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[9] Time cost=1871
17:18:00.075 [run-main-0] INFO  ml.dmlc.mxnet.Model - Epoch[9] Train-accuracy=0.9263822
Train accuracy = 0.9240785
Test accuracy = 0.9263822</code></pre>
</section>
</section>
<section id="discussion" class="level3">
<h3 class="anchored" data-anchor-id="discussion">Discussion</h3>
<p>After having created and trained an example with each of the libraries, you might ask, which one should you should choose to start a deep learning project? While this decision depends a lot on your goal and context, let’s discuss a few pros and cons I’ve encountered.</p>
<p>DL4J is the oldest and to my impression it is also the most mature library. It covers most common network types, has comprehensive documentation, and also offers commercial support. If you want to use deep learning in production now, DL4J should be a good choice.</p>
<p>There’s still much room for improvements, though. For instance, ND4J is a bit limited when it comes to data types. It only supports float and double, and not both at the same time. You have to decide which one via a global switch. It also does not offer a native Scala API, leaving some of Scala’s advantages we discussed in the motivation to be desired.</p>
<p>This gap naturally leads to ScalNet, which looks promising, but needs more time to mature before it will be actually useful. For instance, it currently does not support any other optimizer besides gradient descent.</p>
<p>I feel a little bit ambivalent about MXNet. While not as mature as DL4J, it seems stable, and having the Scala API being part of the main project is definitely a plus. The API does feel a bit foreign, though, and does not make much use of Scala’s features. For instance, the Symbol API is more or less a direct translation of the Python API, is quite stringified and thus not very type safe. So there’s room for improvement here. Some of the MXNet APIs like the NDArray and IO API are not on par yet with their Python counterpart, i.e.&nbsp;there’s limited slicing on tensors, and no shuffling of inputs. The documentations contains some tutorials, and there are also a few example projects. ScalaDoc is basically empty though, which might stem from the fact that many classes are generated from the C++ sources.</p>
<p>TensorFlow for Scala is the most “scalaesque” of the libraries presented. It offers a mostly functional, immutable API, and it uses Scala’s advanced type system to provide type safety where possible. With some exceptions, i.e heavy usage of nulls, developing with it feels like writing idiomatic Scala most of the time. It also profits from TensorFlow upstream, which has a lot of momentum at the moment, and is used at Google in production from large scale backend to mobile. This means new research results are added fast, and lots of pretrained models are available, but it’s also well tested.</p>
<p>Development of TensorFlow for Scala has started only in 2017, and it’s made impressive progress since. There are still some rough edges though, and it needs much more testing, having many bugs still lurking around. Some introductory documentation exists, although incomplete. It has comprehensive ScalaDoc, something I wish more Scala libraries had.</p>
</section>
<section id="conclusion" class="level3">
<h3 class="anchored" data-anchor-id="conclusion">Conclusion</h3>
<p>Now we’ve seen how it looks like to train a very simple neural network in each of the libraries presented. Without any tuning, it is able to recognize handwritten digits with an accuracy of ~92%. With some enhancements, we could do even better, improving accuracy up to 99%. In research, MNIST is basically considered a solved problem, and the focus lies on more interesting challenges.</p>
<p>What we’ve done is course a very simple example, and we’ve barely scratched the surface of what’s possible with deep learning and with the libraries presented. To keep things simple, we haven’t touched many topics, for instance</p>
<ul>
<li>other types of neural networks, like convolutional neural networks (CNN), recurrent neural networks (RNN), or generative adversarial networks (GAN)</li>
<li>how to avoid overfitting</li>
<li>data science tools such as notebooks</li>
<li>visualization</li>
<li>distribution (multi gpu and multi host)</li>
</ul>
<p>As you can see, there’s much more to explore. I hope I can show you more interesting applications of deep learning in future blog posts. If you have any questions or feedback, don’t hesitate to leave a comment, or ping me on Twitter <a href="https://twitter.com/soebrunk"><span class="citation" data-cites="soebrunk">@soebrunk</span></a>.</p>


</section>

 ]]></description>
  <category>deep-learning</category>
  <category>scala</category>
  <guid>https://blog.brunk.io/posts/deep-learning-in-scala-part-2-hello-neural-net/</guid>
  <pubDate>Tue, 09 Jan 2018 14:30:00 GMT</pubDate>
  <media:content url="https://blog.brunk.io/posts/deep-learning-in-scala-part-2-hello-neural-net/simple_neural_network_architecture.png" medium="image" type="image/png" height="109" width="144"/>
</item>
<item>
  <title>Deep Learning in Scala Part 1: Basics and Libraries</title>
  <link>https://blog.brunk.io/posts/deep-learning-in-scala-part-1-basics-and-libraries/</link>
  <description><![CDATA[ 





<section id="introduction" class="level3">
<h3 class="anchored" data-anchor-id="introduction">Introduction</h3>
<p>Deep learning is a subset of machine learning, which has seen a tremendous growth in popularity recently. One of the reasons for that growth is that deep learning has brought huge advances to fields such as computer vision, speech recognition or machine translation. Those are fields that are mostly dealing with unstructured data that have traditionally been difficult for computers. Another reason for the success of deep learning, compared to traditional machine learning approaches, is its ability to automatically learn features from raw data, such as images, reducing the need for expensive manual <a href="https://en.wikipedia.org/wiki/Feature_engineering">feature engineering</a> and making it applicable to a broader range of domains.</p>
<p>Deep learning is actually just a newer term for modern artificial neural networks. It’s called “Deep”, because these networks tend to be stacked in a sequence of several successive layers of computation. In a nutshell, common types of deep neural networks can learn to approximate very complex functions by being <strong>trained</strong> on (usually a lot of) known examples. After being trained, a deep learning <strong>model</strong> can be applied to previously unseen data and, with high probability, make correct predictions about that data.</p>
<p>Neural networks are not a new idea, they have been around for decades. What’s changed is research progress in how to train deep networks more effectively, the internet, resulting in much more available training data, and gaming, resulting in high performance GPUs that can do parallel numeric operations efficiently.</p>
<p>Neural networks work by a running the input data through series of consecutive computational layers. Each layer takes the output of its previous layer and applies some transformation to it (usually a mathematical operation), in turn providing its own output as input for the next layer, up to the final output. At their core, neural networks are based on linear algebra operations on numeric <strong>tensors</strong> (tensors being a generalization of vectors and matrices to n dimensions). That’s why we have to be able to represent data as a tensor in order to use it as input of a neural network.</p>
<p>Each layer produces an intermediate <strong>representation</strong> or <strong>encoding</strong> of the input data, i.e.&nbsp;pixel values of an image, that brings it closer to the desired output, i.e.&nbsp;a class describing the content of that image. What’s interesting, is that these representations are learned through exposure to known examples, rather than being explicitly programmed.</p>
<p>Some of the layered operations in neural network are parameterized and the <strong>parameters</strong>, or <strong>weights</strong> of these operations, sometimes millions for complex networks, are what’s learned in the training process. These weights contain the memory of a neural network, they represent how the network has learned mapping input to output as a result of searching for statistical structure in the example data.</p>
<p>The basic shape of a neural network, inputs and outputs, the flow of data through the layers as well as the operations involved is usually defined manually. We call this the neural network architecture, and it can look quite differently, depending on the kind of data we want to process, complexity constraints and other factors. More generally, we call all parameters that aren’t learned but defined manually, including the neural network architecture, <strong>hyperparameters,</strong> in order to distinguish them from the weights determined during training. There’s ongoing research to find good hyperparameters automatically for a given task but for now it’s still mostly a manual process.</p>
<p>Depending on the complexity of the neural network, the amount of training data, and the available hardware, training can take a long time, sometimes weeks or even months. Fortunately, training can often be done as an offline process. Running a trained model on new data for predictions, also called <strong>inference,</strong> is naturally much faster as it only requires one pass through the network, instead of several training runs.</p>
<p>I won’t go into explaining how neural networks work in more detail here because there’s already a lot of great material available on the subject. For a great visual explanation, I highly recommend you to watch the <a href="https://www.youtube.com/watch?v=aircAruvnKk&amp;list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi">3Blue1Brown Video series</a>.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/aircAruvnKk" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen="">
</iframe>
<p>If you want to dive in deeper, I have added a few links to more learning resources at the end of this article. In the second part of this article series, I’m going to explain a few things in more detail to help you to follow through the examples.</p>
<p>We can also see neural networks as a new programming paradigm that allows us to learn certain functions. Inputs and outputs define the signature of our function. We define the neural network architecture to constrain the search space we want to use and we train the network on known examples to find a good implementation of the function. If we’re able to find a good solution, we can use the trained model as a black box just like any other function.</p>
<p>Deep learning is no silver bullet. It only works well with enough training data. Furthermore, while it works well for some tasks, it doesn’t for others. Despite some popular belief, deep learning does not enable general artificial intelligence. A more serious problem stems from the fact that training data created by humans such as language often contain racial and gender biases, which are picked up by a network, often reinforcing prejudices. Those are problems that have to be evaluated and addressed before choosing to use and how to use deep learning. Good programming language and API support can help to approach and master deep learning, which is what I will explore in the next section.</p>
</section>
<section id="why-scala" class="level3">
<h3 class="anchored" data-anchor-id="why-scala">Why Scala?</h3>
<p>The growing interest in deep learning has resulted in the development of many new neural network libraries in recent years. Python is undoubtedly leading as the language for implementing neural network algorithms, with many popular libraries and research implementations having their high-level parts written in Python. Lower level primitives such as the linear algebra operations underlying deep learning are usually written in C++ for performance and have almost always specialized GPU implementations as well. While Python is a great language, especially for scientific computing, data science and machine learning research, deep learning will probably <a href="https://medium.com/@karpathy/software-2-0-a64152b37c35">become much more ubiquitous in software development</a> and will be an essential part of many production systems in the future, systems written in a variety of languages often running on the JVM. Caused by that shift, we’ll also likely see more unified data science and software engineering teams similar to what’s happening in DevOps.</p>
<p>Moreover, as shown in this article, <a href="https://venturebeat.com/2017/11/28/infrastructure-3-0-building-blocks-for-the-ai-revolution/">learning and inference is only a small part of machine learning systems</a>. “… the majority of complexity manifests in data preparation, feature engineering, and operationalizing the distributed systems infrastructure necessary to perform these tasks at scale.” That last part is especially true for deep learning, as many neural networks tend to be computationally demanding and very data hungry, working best when fed with large numbers of training examples. That’s an area Scala is already good at, powering many of today’s large scale distributed and big data/fast data systems.</p>
<p>So why not go one step further and create, train and run neural networks using Scala as well? The language has as set of features that make it particularly well suited for building neural networks:</p>
<ul>
<li>Its functional nature and expressiveness is ideal for elegant composition of tensor operations and neural network architectures.</li>
<li>Scala’s syntax and its type inference enables expressing tensor operations in a concise and readable way, similar to what you can do in dynamically typed languages like Python or R.</li>
<li>At the same time, its powerful static type system can help catching certain kinds of errors early on at compile time, adding safety and often making development and especially maintenance more productive.</li>
</ul>
<p>Last but not least, and that’s of course just my personal opinion, Scala is oftentimes fun to program in.</p>
<p>What I want to do in the remainder of this article is to explore what deep learning libraries are available for Scala <strong>today</strong> and what they have to offer. Before we look at specific libraries, let’s first discuss what we expect from a deep learning library.</p>
</section>
<section id="what-to-expect-from-a-deep-learning-library" class="level3">
<h3 class="anchored" data-anchor-id="what-to-expect-from-a-deep-learning-library">What to expect from a deep learning library?</h3>
<p>As we’ve seen in the introduction, neural networks are based on linear algebra operations on numeric tensors. That’s why efficient numeric computing is essential for running and especially for training neural network models. Nowadays that means support for running on GPUs, which are by magnitudes faster than CPUs for this kind of computation. It also essentially means Nvidia GPUs for the time being because, with <a href="https://github.com/plaidml/plaidml">some</a> <a href="https://deeplearnjs.org/">exceptions</a>, most deep learning libraries rely on CUDA for GPU computations.</p>
<p>Therefore, a neural network library should provide an API for tensor operations that can be executed efficiently on specialized hardware like GPUs. Such an API should provide operations for creating and initializing tensors, reading/writing values from/to tensors, copying and transforming tensors. It should also provide core math operations such as tensor addition, matrix multiplication and so on. Combining those core building blocks in order to build higher-level functionality should be as easy as possible.</p>
<p>We could build a neural network from scratch using only these low level operations, and for research that level of control can sometimes be necessary. In most cases though, we would waste time and effort, trying to reinvent the wheel.</p>
<p>What we’re usually interested in is a higher level API that makes it easy to define a neural network architecture as well as train, evaluate and run a model. We would like that API to have “batteries included”, already providing building blocks for common tasks and ways to compose and extend them. For instance, most neural network APIs offer implementations of common layer types (i.e fully connected and convolutional layers) and activation functions as well as ways to parameterize and compose them in order to build a network architecture.</p>
<p>Training is usually the most complex part of a neural network. A library should therefore provide implementations of things like backpropagation (automatic computation of derivatives), optimization algorithms and loss functions. We also want it to take care of resource management and distribution, letting us focus on the training task itself.</p>
<p>An important part of the training process is the evaluation of model performance. Since training of more complex models is computationally expensive and can take days or even weeks, we want to get metrics as soon as possible, so evaluation should be integrated into the training loop. We also would like to define custom accuracy metrics and ideally get visualizations of those metrics out of the box.</p>
<p>Because a large part of a deep learning pipeline is made of data preparation, functionality for loading data, preprocessing and vectorization is just as important as the learning part itself. A library providing the right tools and integrations out of the box can make those tasks much easier.</p>
<p>Now that we have a rough idea what we expect from a neural network library, let’s define a list of criteria, that will help us to select matching libraries:</p>
<ul>
<li>Open source license.</li>
<li>Callable from Scala. While a Scala API would be nice, Java counts as well.</li>
<li>Supports <strong>creation</strong> and <strong>training</strong> of models, not only inference (loading trained models and doing predictions).</li>
<li>High-level API that offers building blocks for creating common neural network architectures with little overhead i.e.&nbsp;common layer types, optimizers and helpers for training and evaluation of models.</li>
<li>A certain level of maturity i.e.&nbsp;has documentation, examples and is actually working.</li>
<li>Is being actively developed (i.e.&nbsp;has seen some commits within the last months).</li>
<li>Supports running on CPUs as well as on compatible GPUs for better performance and allows training on multiple GPUs.</li>
<li>Runs as standalone Scala program (i.e.&nbsp;not only as part of Spark).</li>
<li>Bonus: Provides a “model zoo” of common neural networks (possibly already pre-trained on some dataset) and can import existing models created in other libraries for reuse.</li>
</ul>
</section>
<section id="library-selection" class="level3">
<h3 class="anchored" data-anchor-id="library-selection">Library selection</h3>
<p>After a non exhaustive search based on the criteria above, I’ve chosen to have a closer look at the following libraries.</p>
<ul>
<li><a href="https://deeplearning4j.org/">Eclipse Deeplearning4j</a></li>
<li><a href="https://github.com/deeplearning4j/ScalNet">ScalNet</a></li>
<li><a href="https://github.com/eaplatanios/tensorflow_scala">TensorFlow for Scala</a></li>
<li><a href="https://mxnet.incubator.apache.org/">Apache MXNet</a></li>
</ul>
<p>Note that the selection does not claim to be fully objective. Please feel free to contact me if you found another library that you think should be included as well.</p>
<section id="eclipse-deeplearning4j" class="level4">
<h4 class="anchored" data-anchor-id="eclipse-deeplearning4j">Eclipse Deeplearning4j</h4>
<p><img style="float: right;" src="https://blog.brunk.io/posts/deep-learning-in-scala-part-1-basics-and-libraries/dl4j_logo.png"> <a href="https://deeplearning4j.org/">Deeplearning4j</a> (DL4J) is a deep learning library for the JVM, primarily written in Java that became an Eclipse foundation project earlier this year. Compared to other more research oriented deep learning libraries, DL4J emphasises its focus on enterprise Java deployments and its integration with Big Data frameworks such as Hadoop and Spark.</p>
<p>Under the hood, it uses <a href="https://nd4j.org/">ND4J</a> (N-Dimensional Arrays for Java), a library for fast numeric computation and linear algebra operations on tensors written in Java and C++. ND4J works with float and double tensors and has GPU support based on CUDA. <a href="https://github.com/deeplearning4j/nd4s">ND4S</a> is a Scala wrapper on top of ND4J that uses Scala features such as operator overloading in order to offer a nicer syntax.</p>
<p>DL4J offers a high level Java API for creating, training and running neural networks that provides building blocks for most common neural network types. It’s easy to use from Scala, but lacks some of the features a native Scala API could offer.</p>
<p>DL4J also includes an ecosystem of supporting software such as <a href="https://deeplearning4j.org/datavec">DataVec</a> for data preprocessing and vectorization, or the training UI for monitoring of the training process. DL4J can, <a href="https://deeplearning4j.org/keras-supported-features">with some restrictions</a> import models created with <a href="https://keras.io/">Keras</a>, a popular high-level Python deep learning library. It can scale vertically by supporting parallel training on multiple GPUs as well as horizontally through its Spark integration. Commercial support is available through <a href="https://skymind.ai/">Skymind</a>, a company founded by the DL4J creators that employs many of the current DL4J developers. DL4J provides as <a href="https://github.com/deeplearning4j/deeplearning4j/tree/master/deeplearning4j-zoo/src/main/java/org/deeplearning4j/zoo/model">model zoo</a> containing mostly image classification models.</p>
</section>
<section id="scalnet" class="level4">
<h4 class="anchored" data-anchor-id="scalnet">ScalNet</h4>
<p><a href="https://github.com/deeplearning4j/ScalNet">ScalNet</a> is a Scala API on top of DL4J inspired by <a href="https://keras.io/">Keras</a>. ScalNet aims to make prototyping neural networks with Scala faster by offering high level building blocks for creating and training neural network through a concise Scala API. Because it uses DL4J under the hood, it shares many of its properties and you can use, for instance, ND4S and DataVec from ScalNet as well. It is currently in alpha, and many things are still missing, so it might not completely meet our maturity criterion. Contrary to the information in the readme, there is no need to build the DL4J chain and ScalNet from source, as prebuilt binaries exist for Scala 2.10/2.11 for the current version 0.9.1. There is also a branch with Scala 2.12 support.</p>
</section>
<section id="tensorflow-for-scala" class="level4">
<h4 class="anchored" data-anchor-id="tensorflow-for-scala">TensorFlow for Scala</h4>
<p><img style="float: right;" src="https://blog.brunk.io/posts/deep-learning-in-scala-part-1-basics-and-libraries/tf_logo.png"> <a href="https://www.tensorflow.org/">TensorFlow</a> is a popular numeric computing library from Google with strong support for deep learning. The core is written in C++ and supports execution on GPUs via CUDA. Programming in core TensorFlow is usually done by first creating a dataflow graph or computational graph, a symbolic representation of the computations and their dependencies. It is a mere description of the computation without executing anything. You then create a session that executes the graph on the existing computational resources. Advantages of this separation are much better options for optimization and parallelization on multiple GPUs and machines as well as better decoupling of business logic and resource management. At a high level, this is conceptually similar to how Akka Streams separates defining streams from running them (actors being the “computational resources” here).</p>
<p><img style="float: left;" src="https://blog.brunk.io/posts/deep-learning-in-scala-part-1-basics-and-libraries/tf_dataflow.gif"> Support for <a href="https://research.googleblog.com/2017/10/eager-execution-imperative-define-by.html">eager execution</a> was introduced recently as an experimental feature for running operations immediately in an imperative style instead of building a dataflow graph.</p>
<p>TensorFlow provides high level Python APIs for data preprocessing, creation and training of neural networks. Bindings for other languages like Java, Go and Rust are available but are primarily meant for inference (making predictions from trained models).</p>
<p><a href="https://github.com/eaplatanios/tensorflow_scala">TensorFlow for Scala</a> is a Scala API for TensorFlow created by Anthony Platanios. It is not an official TensorFlow module, but an independent project. It leverages the core TensorFlow C++ operations for high performance and GPU support. It provides a tensor API similar to <a href="http://www.numpy.org/">NumPy</a> for creating and manipulating tensors that also offers an imperative (eager execution) version of most TensorFlow core operations.</p>
<p>The core API is a Scala rewrite of a large part of the TensorFlow Python API that allows you to create and run a symbolic computation graph on tensors.</p>
<p>TensorFlow for Scala also adds its own high level learn API on top of the lower level APIs for building, running and training neural networks. It is similar to Keras (which is part of TensorFlow), but builds on Scala features to offer a rich and strongly typed functional API.</p>
<p>It is possible to load and reuse existing TensorFlow models as well as write them in the TensorFlow model serialization format, making it possible to leverage many available pretrained models. It is still a young project, but has made rapid progress last year.</p>
</section>
<section id="mxnet" class="level4">
<h4 class="anchored" data-anchor-id="mxnet">MXNet</h4>
<p><img style="float: right;" src="https://blog.brunk.io/posts/deep-learning-in-scala-part-1-basics-and-libraries/mxnet_logo.png"> MXNet is a deep learning library created in a joint effort from researchers of several universities. It recently moved under the Apache umbrella as an incubator project. MXNet is supported by companies such as Amazon, Intel and Baidu and is the <a href="http://www.allthingsdistributed.com/2016/11/mxnet-default-framework-deep-learning-aws.html">Deep Learning Framework of Choice at AWS</a> partly due to of its scalability. Similar to TensorFlow, its core is written in C++ with GPU support through CUDA.</p>
<p>MXNet offers APIs for a bunch of languages including Python, R, Julia, JavaScript, Scala and Go. In contrast to TensorFlow, the Scala API is an official part of the project. In MXNet, trained models can be serialized in a language agnostic way so it is possible to load and use a model from the Scala API that was created using Python.</p>
<p>Similar to TensorFlow, MXNet supports creating symbolic computation graphs, decoupling computation logic from execution. Furthermore, it provides support for eager execution as well for a more imperative approach. MXNet has recently introduced a high level machine learning API called <a href="http://gluon.mxnet.io/">gluon</a>. As of now, gluon is only available for Python, though.</p>
<p>In the <a href="deep-learning-in-scala-part-2-hello-neural-net.html">second part of this series</a>, we’ll get our hands dirty, starting with a very simple example to see you how it looks like to create, train and run a neural network with each of the libraries presented here.</p>
</section>
</section>
<section id="learning-resources" class="level3">
<h3 class="anchored" data-anchor-id="learning-resources"><a name="resources"></a>Learning Resources</h3>
<p>Here are a few pointers for more material that might be helpful for further reading/learning.</p>
<section id="books" class="level4">
<h4 class="anchored" data-anchor-id="books">Books</h4>
<ul>
<li>For learning the theoretical foundations, there’s <a href="http://www.deeplearningbook.org">Deep Learning</a> by Goodfellow et al.</li>
<li>For a more hands on approach, <a href="https://www.manning.com/books/deep-learning-with-python">Deep Learning with Python</a> from Keras Author Francois Chollet is a very good resource aimed at developers.</li>
<li><a href="http://neuralnetworksanddeeplearning.com/index.html">Neural Networks and Deep Learning</a> is a free online book about deep learning with good visual explanations.</li>
<li><a href="http://shop.oreilly.com/product/0636920035343.do">Deep Learning: A Practitioner’s Approach</a> explains deep learning concepts and uses DL4J to implement them.</li>
</ul>
</section>
<section id="online-courses" class="level4">
<h4 class="anchored" data-anchor-id="online-courses">Online Courses</h4>
<ul>
<li><a href="http://course.fast.ai/">Practical Deep Learning For Coders</a><strong>. </strong>Free hands-on course by Jeremy Howard.</li>
<li><a href="https://www.coursera.org/specializations/deep-learning">Deep Learning Specialization</a> by Andrew Ng at Coursera.</li>
<li><a href="https://www.udacity.com/course/deep-learning-nanodegree-foundation--nd101">Deep Learning Nanodegree</a> at Udacity.</li>
</ul>
</section>
<section id="articles" class="level4">
<h4 class="anchored" data-anchor-id="articles">Articles</h4>
<ul>
<li>A look at <a href="http://colah.github.io/posts/2015-09-NN-Types-FP/">neural networks from a functional programming perspective</a>.</li>
</ul>


</section>
</section>

 ]]></description>
  <category>deep-learning</category>
  <category>scala</category>
  <guid>https://blog.brunk.io/posts/deep-learning-in-scala-part-1-basics-and-libraries/</guid>
  <pubDate>Wed, 03 Jan 2018 23:00:00 GMT</pubDate>
</item>
</channel>
</rss>
