Jekyll2021-06-08T15:18:23+00:00http://pinchuk.be/pinchuk.bePython 2D Array of Zeros Paradox2018-08-19T00:00:00+00:002018-08-19T00:00:00+00:00http://pinchuk.be/2018/08/19/python-2d-array-of-zeros-paradox<p><img src="/assets/meditation.jpg" alt="" /></p>
<p>I have tried to create an array of zeros in Python <strong>without</strong> using NumPy.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">python3</span>
<span class="o">>>></span> <span class="n">a</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">0</span><span class="p">]</span><span class="o">*</span><span class="mi">3</span><span class="p">]</span><span class="o">*</span><span class="mi">3</span>
<span class="o">>>></span> <span class="n">a</span>
<span class="p">[[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]]</span>
<span class="o">>>></span> <span class="n">b</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]]</span>
<span class="o">>>></span> <span class="n">b</span>
<span class="p">[[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]]</span>
<span class="o">>>></span> <span class="n">a</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
<span class="o">>>></span> <span class="n">a</span>
<span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]]</span>
<span class="o">>>></span> <span class="n">b</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
<span class="o">>>></span> <span class="n">b</span>
<span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]]</span>
</code></pre></div></div>
<p>So yes, there is here a mystery - at least if you don’t understand what is going on. The paradox is solved by understanding that <code class="highlighter-rouge">[[0]*3]</code> is shallow copied by the outer <code class="highlighter-rouge">*3</code>. At least this is my suspicious, although I could not find yet the documentation that states that asterisk over a list executes shallo-copy of the list. If you do not know about shallow copy in Python, Google it :-)</p>
<p>Anyway, the only way I found, so far, to write this correctly is using list comprehension: <code class="highlighter-rouge">[[0]*3 for i in range(3)]</code>.</p>Editing Locally, Running Remotely2018-06-17T12:45:00+00:002018-06-17T12:45:00+00:00http://pinchuk.be/2018/06/17/editing-locally-running-remotely<p><img src="/assets/flowers.jpg" alt="" /></p>
<p>The title says it all. I wanted to run my Python (TensorFlow) programs on my server, while editing on my laptop. Simple. The solution is not perfect, but it is useful, so I document it here. On the local machine (the laptop, where you edit your Python program) create the following script called <code class="highlighter-rouge">python3.6_remote</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
ssh pinchuk@192.168.0.173 ts_wrapper <span class="nt">-u</span> - < <span class="nv">$1</span>
</code></pre></div></div>
<p>On the remote machine (the server, where you want the program to actually run) you create the following script called <code class="highlighter-rouge">ts_wrapper</code>:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="nb">cd</span> /path/in/remote/
<span class="nb">source</span> /path/in/remote/virtualenv/bin/activate
python3 <span class="nv">$1</span>
</code></pre></div></div>
<p>This second script has to be placed in, for example, /usr/local/bin, so it can be found. And as can be seen, it assumes that your Python stuff (e.g. TensorFlow) is installed in <a href="https://virtualenv.pypa.io/en/stable/" target="_blank">virtualenv</a> there.</p>
<p>And that’s it. Now if you run for example <code class="highlighter-rouge">python3.6_remote ./hello.py</code> it will run the local program <code class="highlighter-rouge">hello.py</code> on the remote machine and you will get back its output.</p>
<p>The caviats are:</p>
<ol>
<li>If your local script reads a file, it will now try to read it while running in the remote machine and in <code class="highlighter-rouge">/path/in/remote</code>. So you have to copy the data files to the remote machine. The easiest is to create on the remote machine identical folders structure.</li>
<li>When you use a library locally, you will have to install it also remotely to the virtualenv.</li>
</ol>
<p>Thanks to <a href="https://unix.stackexchange.com/users/4194/arcege">Arcege</a> from <a href="https://unix.stackexchange.com/questions/299657/run-local-python-script-on-remote-machine/306538" target="_blank">https://unix.stackexchange.com/questions/299657/run-local-python-script-on-remote-machine/306538</a> for the idea.</p>“I will build a wall and have my parents pay for it”2018-05-22T00:00:00+00:002018-05-22T00:00:00+00:00http://pinchuk.be/2018/05/22/i-will-build-a-wall-and-will-have-my-parents-pay-for-it<p><img src="/assets/jonathan_climbs.jpg" alt="climbs" /></p>
<p>OK. Jonathan, here when he was 13, does not really risk his life climbing on rocks. But sometimes you can cut the picture in a very impressive manner. Still, Jonathan and me climb quite a lot. Mainly bouldering indoor. And when you are serious, you have to practice. So we needed to have a wall.</p>
<p>Our first plan was to build a small climbing wall in Jonathan’s room. Luckily, this plan was vetoed by my wife with the message “you will destroy our house!!!”.</p>
<p>So we compromised on the garage. Just that the garage had a very old asbestos roofing. Not a very healthy place to practise. So we decided to invest and renew the roof. Good luck with that… No one wants to deal with such a small project - only a few square meters of asbestos, and, in general, tiny roof.</p>
<p>So we decided that Jonathan and me will do the work. We will gain by that a huge amount of money that would, otherwise, be paid to a contractor. And we will get part of that fortune to build our dream wall.</p>
<p>This was our garage back then, covered with climbing plant. This was in the end of the winter, with the traditional snowman residues in the middle of the grass.</p>
<p><img src="/assets/climbing_wall/IMG_20170114_095731252.jpg" alt="" /></p>
<p>After some reading about the danger in dealing with asbestos, I got for us some protection from Amazon. And then we started, first by removing the climbing plants:</p>
<p><img src="/assets/climbing_wall/IMG_20170514_143208452.jpg" alt="" /></p>
<p>As you can see, regarding the protection no compromises were made.</p>
<p><img src="/assets/climbing_wall/IMG_20170521_193427063.jpg" alt="" /></p>
<p>We got rid of the old roof (tiles and the asbestos plates).</p>
<p><img src="/assets/climbing_wall/IMG_20170525_163847787_HDR.jpg" alt="" /></p>
<p>And as this garage is about 80 years old, we got also new beams for the new roof. Originally I was very worried about the work with the beams. This sounded to me like something only professional builders do. And I am a very modest do-it-yourself guy. So the pictures below shows how simple it actually is.</p>
<p><img src="/assets/climbing_wall/IMG_20170526_155741999_HDR.jpg" alt="" height="236px" />
<img src="/assets/climbing_wall/IMG_20170526_165652.jpg" alt="" height="236px" /></p>
<p><img src="/assets/climbing_wall/IMG_20170526_165814.jpg" alt="" height="275px" />
<img src="/assets/climbing_wall/IMG_20170526_165826.jpg" alt="" height="275px" /></p>
<p><img src="/assets/climbing_wall/IMG_20170526_165952692_HDR.jpg" alt="" /></p>
<p>And I am lucky that Jonathan took care of my head so it will not be totally bruised by bumping again and again to the very same beam.</p>
<p><img src="/assets/climbing_wall/IMG_20170526_203607.jpg" alt="" /></p>
<p>And in general these were amazingly beautiful days - we enjoyed every moment of the work.</p>
<p><img src="/assets/climbing_wall/IMG_20170527_101742.jpg" alt="" height="236px" />
<img src="/assets/climbing_wall/IMG_20170527_101829540_HDR.jpg" alt="" height="236px" /></p>
<p><img src="/assets/climbing_wall/IMG_20170527_101907349.jpg" alt="" height="206px" />
<img src="/assets/climbing_wall/IMG_20170527_102010614.jpg" alt="" height="206px" /></p>
<p><img src="/assets/climbing_wall/IMG_20170527_102045286.jpg" alt="" height="236px" />
<img src="/assets/climbing_wall/IMG_20170527_143644.jpg" alt="" height="236px" /></p>
<p>And then we placed the new roof.</p>
<p><img src="/assets/climbing_wall/IMG_20170527_171331.jpg" alt="" /></p>
<p>Now we had to start working on the wall. But we had a plan. Seriously. Following our adventures with the 3D Printer we built, Jonathan is a master in <a href="https://www.sketchup.com" target="_blank">SketchUp</a>. And together with me (the once-upon-a-time-mechanical-engineer), he came with a very nice plan:</p>
<p><img src="/assets/climbing_wall/plan/image3.jpg" alt="" /></p>
<p>From the other side you can see the construction that holds the plates.
<img src="/assets/climbing_wall/plan/image5.jpg" alt="" /></p>
<p>And just that you understand the sizes:
<img src="/assets/climbing_wall/plan/image8.jpg" alt="" /></p>
<p>The beams construction plan is very useful as even before we started the roof tearing down project, we could already order the exact beams we needed.</p>
<p><img src="/assets/climbing_wall/plan/image4.jpg" alt="" /></p>
<p>Now we started working on the wall. Big fun.
<img src="/assets/climbing_wall/IMG_20170628_213040.jpg" alt="" /></p>
<p><img src="/assets/climbing_wall/IMG_20170629_213006.jpg" alt="" /></p>
<p><img src="/assets/climbing_wall/IMG_20170630_131808409.jpg" alt="" /></p>
<p>And in the middle of the work, in one weekend we managed to solve a big problem: climbing holds cost a fortune.</p>
<p>The guys from our real climbing wall (<a href="https://klimzaalblok.be" target="_blank">Klimzaal Blok</a>) suggested that we check with <a href="https://www.axisroundedges.com" target="_blank">Axis Round Edges</a>. I looked at the price list, very concerned, and then called Frank Bogerman. Frank was very welcoming and suggested we come on a Saturday. So we travelled to Roterdam.</p>
<p>When we arrived, we found out that Frank has already prepared around 10 boxes of holds that were production-left-overs, and holds from demonstrations. Frank said something like “for people who build private walls in their garage we keep these holds and give them in a special price”. And the price was per Kg.</p>
<p>Hmm… while Jonathan was selecting the holds from the different boxes, I went to weigh some of them. Then I thought, “cool!”.</p>
<p><img src="/assets/climbing_wall/IMG_20170701_141037361.jpg" alt="" height="206px" />
<img src="/assets/climbing_wall/IMG_20170701_141054035.jpg" alt="" height="206px" /></p>
<p>From a plan of buying maybe 50 holds, we ended up with much more than 200 holds. And not small holds. Bolts were given together with the holds (again priced by weight). And two boxes of screws for free (!?!), and a bag of sand for free. And plenty of tips regarding how to do things.</p>
<p>We are really thankful to <a href="https://www.axisroundedges.com" target="_blank">Axis Round Edges</a>.</p>
<p>Now we were extra motivated to continue building.</p>
<p><img src="/assets/climbing_wall/IMG_20170703_181425.jpg" alt="" height="352px" />
<img src="/assets/climbing_wall/IMG_20170707_223208.jpg" alt="" height="352px" /></p>
<p><img src="/assets/climbing_wall/IMG_20170708_195130.jpg" alt="" height="387px" />
<img src="/assets/climbing_wall/IMG_20170709_223745077.jpg" alt="" height="387px" /></p>
<p>Because we had a very accurate plan, we could cut the beams to measure and just place them in their designated locations as if they were Lego bricks.</p>
<p><img src="/assets/climbing_wall/IMG_20170712_174103.jpg" alt="" height="275px" />
<img src="/assets/climbing_wall/IMG_20170713_215053.jpg" alt="" height="275px" /></p>
<p>First climbing on holds (we used these holds as handles for these heavy plywood plates).</p>
<p><img src="/assets/climbing_wall/IMG_20170715_224740.jpg" alt="" height="352px" />
<img src="/assets/climbing_wall/IMG_20170715_224918.jpg" alt="" height="352px" /></p>
<p>We would not leave the wall without painting it:</p>
<p><img src="/assets/climbing_wall/IMG_20170719_221916.jpg" alt="" height="352px" />
<img src="/assets/climbing_wall/IMG_jonathan_paints.jpg" alt="" height="352px" /></p>
<p>Exactly as planned:
<img src="/assets/climbing_wall/IMG_20170917_082017.jpg" alt="" /></p>
<p>Now we can climb :-)</p>
<p><img src="/assets/climbing_wall/20171128_205715.jpg" alt="" height="275px" />
<img src="/assets/climbing_wall/20171128_205754.jpg" alt="" height="275px" /></p>
<p><img src="/assets/climbing_wall/20171128_205843.jpg" alt="" height="275px" />
<img src="/assets/climbing_wall/20171128_205859.jpg" alt="" height="275px" /></p>
<p>The only thing left to do is to get proper matrasses. We first got four cheap matrasses but with those we could not really take risks on the wall. We started asking around and got an old double matrass, and then we got rid of an old sofa which was really nice as it contained a lot of hard foam. And we got also an old wall to wall carpet.</p>
<p><img src="/assets/climbing_wall/20180522_214820.jpg" alt="" /></p>
<p>Now we had to cover it with the green (as in the plan) PVC cover, so it is nice and shiny. But first we have to plan and then to fight with the heavy PVC cover:</p>
<p><img src="/assets/climbing_wall/20180525_211554.jpg" alt="" height="275px" />
<img src="/assets/climbing_wall/20180525_204139.jpg" alt="" height="275px" /></p>
<p>And after some fighting we got an impression of how it is going to look like.</p>
<p><img src="/assets/climbing_wall/20180525_214128.jpg" alt="" rotate="90" /></p>
<p>Now we had to place some light beams on the cover so it is connected nicely to the floor. Like that:</p>
<p><img src="/assets/climbing_wall/crash_pad_done.jpg" alt="" /></p>
<p>And that’s it. We are done building. Really. Well, just a small plan for a volume on the blue wall (it turns out that a straight wall is not as interesting as we expected), and maybe a small extended wall on the left, but - really - nothing big :-)</p>TensorFlow Digit Recognizer2018-05-21T14:12:04+00:002018-05-21T14:12:04+00:00http://pinchuk.be/jekyll/update/2018/05/21/TensorFlow-digits-recognizer<p><img src="/assets/stones.jpg" alt="" /></p>
<p>When learning about TensorFlow, I find myself googling for hours, while trying to get things done. I put this exercise here so others may find an example that works, and that includes some things I had difficulties to get done and could not find an example.</p>
<p>So, this example is a simple implementation of handwritten digits recognition using TensorFlow. But unlike other example I found, it uses a data file is from the excellent <a href="https://www.coursera.org/learn/machine-learning" target="_blank">Coursera Machine Learning course</a>. This file is a subset of the MNIST handwritten digit dataset (<a href="http://yann.lecun.com/exdb/mnist" target="_blank">http://yann.lecun.com/exdb/mnist</a>) saved as a Matlab data file. All examples of handwritten digits recognition loaded the data like this:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mnist</span> <span class="o">=</span> <span class="n">tf</span><span class="o">.</span><span class="n">contrib</span><span class="o">.</span><span class="n">learn</span><span class="o">.</span><span class="n">datasets</span><span class="o">.</span><span class="n">load_dataset</span><span class="p">(</span><span class="s">"mnist"</span><span class="p">)</span>
</code></pre></div></div>
<p>And when you get the data differently you may get into one annoying pitfall of getting a cryptic <em>InvalidArgumentError</em>: “<code>assertion failed: [Label IDs must < n_classes] [Condition x < y did not hold element-wise:]...</code>”. This happens because TensorFlow expects the integers from 0 up to the number of classes as class labels (so range(0, num_classes)).</p>
<p>And finally, if you want to use a built-in Estimator, but still you want to use TensorBoard, surprisinly it is very difficult to find how to do that. So this is also included in this exercise. The trick is the <code>run_config</code> usage in the definition of the classifier. And in order to see the graph and summaries, you have to run</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tensorboard --logdir=./log
</code></pre></div></div>
<p>from the same directory you run the script.</p>
<p>Here is the script:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env python3</span>
<span class="c">#</span>
<span class="c"># Simple implementation of handwritten digits recognition using TensorFlow.</span>
<span class="c"># The example allows observing the summaries using TensorBoard.</span>
<span class="c">#</span>
<span class="kn">import</span> <span class="nn">tensorflow</span> <span class="k">as</span> <span class="n">tf</span>
<span class="kn">from</span> <span class="nn">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">train_test_split</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="nn">scipy</span>
<span class="kn">from</span> <span class="nn">scipy</span> <span class="kn">import</span> <span class="n">io</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">()</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
<span class="n">np</span><span class="o">.</span><span class="n">set_printoptions</span><span class="p">(</span><span class="n">threshold</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">nan</span><span class="p">)</span>
<span class="n">RANDOM_SEED</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">BATCH_SIZE</span> <span class="o">=</span> <span class="mi">100</span>
<span class="n">TRAIN_STEPS</span> <span class="o">=</span> <span class="mi">5000</span>
<span class="n">LOG</span> <span class="o">=</span> <span class="s">'./log'</span>
<span class="k">def</span> <span class="nf">load_data</span><span class="p">():</span>
<span class="c"># The data file is from the excellent Coursera Machine Learning</span>
<span class="c"># (https://www.coursera.org/learn/machine-learning) course. It is subset of the</span>
<span class="c"># MNIST handwritten digit dataset (http://yann.lecun.com/exdb/mnist) saved as a</span>
<span class="c"># Matlab data file.</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">scipy</span><span class="o">.</span><span class="n">io</span><span class="o">.</span><span class="n">loadmat</span><span class="p">(</span><span class="s">"ex3data1.mat"</span><span class="p">)</span>
<span class="n">X</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s">'X'</span><span class="p">]</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s">'y'</span><span class="p">]</span><span class="o">.</span><span class="n">T</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">int32</span><span class="p">)</span>
<span class="c"># convert all 10s to zeros. Apparently TensorFlow expects the integers from 0</span>
<span class="c"># up to the number of classes as class labels (range(0, num_classes)). If we do</span>
<span class="c"># not do this conversion we get the cryptic InvalidArgumentError: "assertion failed:</span>
<span class="c"># [Label IDs must < n_classes] [Condition x < y did not hold element-wise:]</span>
<span class="n">y</span><span class="p">[</span><span class="n">y</span> <span class="o">==</span> <span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">return</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="n">X</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">load_data</span><span class="p">()</span>
<span class="n">X_train</span><span class="p">,</span> <span class="n">X_test</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">y_test</span> <span class="o">=</span> <span class="n">train_test_split</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">test_size</span><span class="o">=</span><span class="mf">0.20</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="n">RANDOM_SEED</span><span class="p">)</span>
<span class="n">image_feature_columns</span> <span class="o">=</span> <span class="p">[</span><span class="n">tf</span><span class="o">.</span><span class="n">feature_column</span><span class="o">.</span><span class="n">numeric_column</span><span class="p">(</span><span class="s">"x"</span><span class="p">,</span> <span class="n">shape</span><span class="o">=</span><span class="p">[</span><span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">])]</span>
<span class="n">optimizer</span> <span class="o">=</span> <span class="n">tf</span><span class="o">.</span><span class="n">train</span><span class="o">.</span><span class="n">AdamOptimizer</span><span class="p">(</span><span class="mf">1e-4</span><span class="p">)</span>
<span class="n">run_config</span> <span class="o">=</span> <span class="n">tf</span><span class="o">.</span><span class="n">contrib</span><span class="o">.</span><span class="n">learn</span><span class="o">.</span><span class="n">RunConfig</span><span class="p">()</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">model_dir</span><span class="o">=</span><span class="n">LOG</span><span class="p">)</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">save_summary_steps</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
<span class="n">classifier</span> <span class="o">=</span> <span class="n">tf</span><span class="o">.</span><span class="n">estimator</span><span class="o">.</span><span class="n">DNNClassifier</span><span class="p">(</span>
<span class="n">feature_columns</span><span class="o">=</span><span class="n">image_feature_columns</span><span class="p">,</span>
<span class="n">hidden_units</span><span class="o">=</span><span class="p">[</span><span class="mi">400</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">26</span><span class="p">,</span> <span class="mi">100</span><span class="p">],</span>
<span class="n">optimizer</span><span class="o">=</span><span class="n">optimizer</span><span class="p">,</span>
<span class="n">n_classes</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span>
<span class="n">dropout</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span>
<span class="n">config</span><span class="o">=</span><span class="n">run_config</span>
<span class="p">)</span>
<span class="n">train_input_fn</span> <span class="o">=</span> <span class="n">tf</span><span class="o">.</span><span class="n">estimator</span><span class="o">.</span><span class="n">inputs</span><span class="o">.</span><span class="n">numpy_input_fn</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="p">{</span><span class="s">"x"</span><span class="p">:</span> <span class="n">X_train</span><span class="p">},</span>
<span class="n">y</span><span class="o">=</span><span class="n">y_train</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">int32</span><span class="p">),</span>
<span class="n">num_epochs</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span>
<span class="n">batch_size</span><span class="o">=</span><span class="n">BATCH_SIZE</span><span class="p">,</span>
<span class="n">shuffle</span><span class="o">=</span><span class="bp">True</span>
<span class="p">)</span>
<span class="n">classifier</span><span class="o">.</span><span class="n">train</span><span class="p">(</span><span class="n">input_fn</span><span class="o">=</span><span class="n">train_input_fn</span><span class="p">,</span>
<span class="n">steps</span><span class="o">=</span><span class="n">TRAIN_STEPS</span><span class="p">)</span>
<span class="n">eval_input_fn</span> <span class="o">=</span> <span class="n">tf</span><span class="o">.</span><span class="n">estimator</span><span class="o">.</span><span class="n">inputs</span><span class="o">.</span><span class="n">numpy_input_fn</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="p">{</span><span class="s">"x"</span><span class="p">:</span> <span class="n">X_test</span><span class="p">},</span>
<span class="n">y</span><span class="o">=</span><span class="n">y_test</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">int32</span><span class="p">),</span>
<span class="n">num_epochs</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
<span class="n">shuffle</span><span class="o">=</span><span class="bp">False</span>
<span class="p">)</span>
<span class="n">eval_result</span> <span class="o">=</span> <span class="n">classifier</span><span class="o">.</span><span class="n">evaluate</span><span class="p">(</span><span class="n">input_fn</span><span class="o">=</span><span class="n">eval_input_fn</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">'</span><span class="se">\n</span><span class="s">Test set accuracy: {accuracy:0.3f}</span><span class="se">\n</span><span class="s">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="n">eval_result</span><span class="p">))</span>
<span class="n">main</span><span class="p">()</span>
</code></pre></div></div>Simple NumPy Neural Network for Digits Recognition2018-04-30T00:00:00+00:002018-04-30T00:00:00+00:00http://pinchuk.be/2018/04/30/simple-numpy-neural-network-for-digits-recognition<p><img src="/assets/jumping.jpg" alt="" /></p>
<p>There is an excellent blog explaing Neural Network. It is <a href="https://iamtrask.github.io/2015/07/12/basic-python-network/" target="_blank">A Neural Network in 11 lines of Python (Part 1)</a>. I recommend to read also the second part.</p>
<p>Anyway, after reading it and memorizing the 11 lines as recommended (very useful recommendation!), I wanted to implement something that is a bit more impressive than the simple example given in that post.</p>
<p>So I decided to try recognizing digits. I used as input <a href="/assets/files/ex3data1.mat" target="_blank">the data file</a> from the recommended <a href="https://www.coursera.org/learn/machine-learning" target="_blank">Coursera Machine Learning course</a>. This file is a subset of the MNIST handwritten digit dataset (<a href="http://yann.lecun.com/exdb/mnist" target="_blank">http://yann.lecun.com/exdb/mnist</a>) saved as a Matlab data file.</p>
<p>In the 11-lines-post, the bias units are not added. In the script below I have added those or else the algorithm does not really learn.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env python3</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="kn">import</span> <span class="nn">scipy</span>
<span class="kn">from</span> <span class="nn">scipy</span> <span class="kn">import</span> <span class="n">io</span>
<span class="kn">from</span> <span class="nn">scipy</span> <span class="kn">import</span> <span class="n">sparse</span>
<span class="k">def</span> <span class="nf">sigmoid</span><span class="p">(</span><span class="n">z</span><span class="p">):</span>
<span class="k">return</span> <span class="mi">1</span> <span class="o">/</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="n">z</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">sigmoid_output_to_derivative</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
<span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">multiply</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">a</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">int_vec_to_bin_mat</span><span class="p">(</span><span class="n">indices</span><span class="p">):</span>
<span class="n">indptr</span> <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">indices</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">ones</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">indices</span><span class="p">))</span>
<span class="n">matrix</span> <span class="o">=</span> <span class="n">scipy</span><span class="o">.</span><span class="n">sparse</span><span class="o">.</span><span class="n">csr_matrix</span><span class="p">((</span><span class="n">data</span><span class="p">,</span> <span class="n">indices</span><span class="p">,</span> <span class="n">indptr</span><span class="p">))</span><span class="o">.</span><span class="n">todense</span><span class="p">()</span>
<span class="n">matrix</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">[:,</span> <span class="mi">10</span><span class="p">]</span>
<span class="n">matrix</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">:</span><span class="mi">10</span><span class="p">]</span>
<span class="k">return</span> <span class="n">matrix</span>
<span class="k">def</span> <span class="nf">predict</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">w0</span><span class="p">,</span> <span class="n">w1</span><span class="p">):</span>
<span class="n">l1</span> <span class="o">=</span> <span class="n">sigmoid</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">w0</span><span class="p">))</span>
<span class="n">l1_plus</span> <span class="o">=</span> <span class="n">add_column_of_ones</span><span class="p">(</span><span class="n">l1</span><span class="p">)</span>
<span class="n">l2</span> <span class="o">=</span> <span class="n">sigmoid</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">l1_plus</span><span class="p">,</span> <span class="n">w1</span><span class="p">))</span>
<span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="nb">round</span><span class="p">(</span><span class="n">l2</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">vector_to_number</span><span class="p">(</span><span class="n">p</span><span class="p">):</span>
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="nb">sum</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">elif</span> <span class="n">p</span><span class="o">.</span><span class="nb">sum</span><span class="p">()</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">diag</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">11</span><span class="p">)))</span>
<span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span><span class="o">.</span><span class="nb">sum</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">def</span> <span class="nf">add_column_of_ones</span><span class="p">(</span><span class="n">mat</span><span class="p">):</span>
<span class="n">vector_of_ones</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">ones</span><span class="p">((</span><span class="n">mat</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="mi">1</span><span class="p">))</span>
<span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">c_</span><span class="p">[</span><span class="n">mat</span><span class="p">,</span> <span class="n">vector_of_ones</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">slice_data</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">train_percentage</span><span class="p">):</span>
<span class="n">m</span> <span class="o">=</span> <span class="n">X</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">m_train</span> <span class="o">=</span> <span class="nb">round</span><span class="p">(</span><span class="n">m</span> <span class="o">*</span> <span class="n">train_percentage</span><span class="p">)</span>
<span class="n">X_train</span> <span class="o">=</span> <span class="n">X</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="n">m_train</span><span class="p">,</span> <span class="p">:]</span>
<span class="n">y_train</span> <span class="o">=</span> <span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="n">m_train</span><span class="p">,</span> <span class="p">:]</span>
<span class="n">X_test</span> <span class="o">=</span> <span class="n">X</span><span class="p">[</span><span class="n">m_train</span><span class="p">:,</span> <span class="p">:]</span>
<span class="n">y_test</span> <span class="o">=</span> <span class="n">y</span><span class="p">[</span><span class="n">m_train</span><span class="p">:,</span> <span class="p">:]</span>
<span class="k">return</span> <span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">X_test</span><span class="p">,</span> <span class="n">y_test</span>
<span class="k">def</span> <span class="nf">show_number</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="s">"----------------------------------------"</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">20</span><span class="p">):</span>
<span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">20</span><span class="p">):</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">x</span><span class="p">[</span><span class="n">j</span> <span class="o">*</span> <span class="mi">20</span> <span class="o">+</span> <span class="n">i</span><span class="p">]</span>
<span class="k">if</span> <span class="mf">0.2</span> <span class="o"><</span> <span class="n">v</span> <span class="o"><</span> <span class="mf">0.5</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="s">'.'</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s">''</span><span class="p">)</span>
<span class="k">elif</span> <span class="mf">0.5</span> <span class="o"><</span> <span class="n">v</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="s">'+'</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s">''</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="s">' '</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s">''</span><span class="p">)</span>
<span class="k">print</span><span class="p">()</span>
<span class="k">print</span><span class="p">()</span>
<span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">scipy</span><span class="o">.</span><span class="n">io</span><span class="o">.</span><span class="n">loadmat</span><span class="p">(</span><span class="s">"ex3data1.mat"</span><span class="p">)</span>
<span class="n">X</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s">'X'</span><span class="p">]</span> <span class="c"># (5000, 400)</span>
<span class="n">X</span> <span class="o">=</span> <span class="n">add_column_of_ones</span><span class="p">(</span><span class="n">X</span><span class="p">)</span> <span class="c"># (5000, 401)</span>
<span class="n">original_y</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s">'y'</span><span class="p">]</span> <span class="c"># (5000, 1)</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">int_vec_to_bin_mat</span><span class="p">(</span><span class="n">original_y</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">T</span><span class="p">)</span> <span class="c"># (5000, 10)</span>
<span class="n">randomize</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">X</span><span class="p">))</span>
<span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">shuffle</span><span class="p">(</span><span class="n">randomize</span><span class="p">)</span>
<span class="n">X</span> <span class="o">=</span> <span class="n">X</span><span class="p">[</span><span class="n">randomize</span><span class="p">]</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">y</span><span class="p">[</span><span class="n">randomize</span><span class="p">]</span>
<span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">X_test</span><span class="p">,</span> <span class="n">y_test</span><span class="p">)</span> <span class="o">=</span> <span class="n">slice_data</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="mf">0.8</span><span class="p">)</span>
<span class="n">m_train</span> <span class="o">=</span> <span class="n">X_train</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">m_test</span> <span class="o">=</span> <span class="n">X_test</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">epsilon</span> <span class="o">=</span> <span class="mf">0.4</span>
<span class="n">alpha</span> <span class="o">=</span> <span class="mf">0.0015</span>
<span class="n">w0</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">epsilon</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">((</span><span class="mi">401</span><span class="p">,</span> <span class="mi">45</span><span class="p">))</span> <span class="o">-</span> <span class="n">epsilon</span>
<span class="n">w1</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">epsilon</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">((</span><span class="mi">46</span><span class="p">,</span> <span class="mi">10</span><span class="p">))</span> <span class="o">-</span> <span class="n">epsilon</span>
<span class="n">training_error</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3000</span><span class="p">):</span>
<span class="n">l0</span> <span class="o">=</span> <span class="n">X_train</span> <span class="c"># (5000, 401)</span>
<span class="n">l1</span> <span class="o">=</span> <span class="n">sigmoid</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">l0</span><span class="p">,</span> <span class="n">w0</span><span class="p">))</span> <span class="c"># (5000, 45)</span>
<span class="n">l1_plus</span> <span class="o">=</span> <span class="n">add_column_of_ones</span><span class="p">(</span><span class="n">l1</span><span class="p">)</span> <span class="c"># (5000, 46)</span>
<span class="n">l2</span> <span class="o">=</span> <span class="n">sigmoid</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">l1_plus</span><span class="p">,</span> <span class="n">w1</span><span class="p">))</span> <span class="c"># (5000, 10)</span>
<span class="n">l2_error</span> <span class="o">=</span> <span class="n">y_train</span> <span class="o">-</span> <span class="n">l2</span> <span class="c"># (5000, 10)</span>
<span class="n">l2_delta</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">multiply</span><span class="p">(</span><span class="n">l2_error</span><span class="p">,</span> <span class="n">sigmoid_output_to_derivative</span><span class="p">(</span><span class="n">l2</span><span class="p">))</span> <span class="c"># (5000, 10)</span>
<span class="n">l1_error</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">l2_delta</span><span class="p">,</span> <span class="n">w1</span><span class="o">.</span><span class="n">T</span><span class="p">)</span> <span class="c"># (5000, 46)</span>
<span class="n">l1_error</span> <span class="o">=</span> <span class="n">l1_error</span><span class="p">[:,</span> <span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="c"># (5000, 45)</span>
<span class="n">l1_delta</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">multiply</span><span class="p">(</span><span class="n">l1_error</span><span class="p">,</span> <span class="n">sigmoid_output_to_derivative</span><span class="p">(</span><span class="n">l1</span><span class="p">))</span> <span class="c"># (5000, 45)</span>
<span class="n">w0</span> <span class="o">=</span> <span class="n">w0</span> <span class="o">+</span> <span class="n">alpha</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">l0</span><span class="o">.</span><span class="n">T</span><span class="p">,</span> <span class="n">l1_delta</span><span class="p">)</span>
<span class="n">w1</span> <span class="o">=</span> <span class="n">w1</span> <span class="o">+</span> <span class="n">alpha</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">l1_plus</span><span class="o">.</span><span class="n">T</span><span class="p">,</span> <span class="n">l2_delta</span><span class="p">)</span>
<span class="n">training_error</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="nb">abs</span><span class="p">(</span><span class="n">l2_error</span><span class="p">))</span>
<span class="k">if</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">100</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">print</span><span class="p">(</span><span class="s">"Error of epoch {}: {}"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">training_error</span><span class="p">))</span>
<span class="n">correct_predictions</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">incorrect_predictions</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">m_test</span><span class="p">):</span>
<span class="n">predicted_number</span> <span class="o">=</span> <span class="n">vector_to_number</span><span class="p">(</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="p">:],</span> <span class="n">w0</span><span class="p">,</span> <span class="n">w1</span><span class="p">))</span>
<span class="n">real_number</span> <span class="o">=</span> <span class="n">vector_to_number</span><span class="p">(</span><span class="n">y_test</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="p">:])</span>
<span class="n">show_number</span><span class="p">(</span><span class="n">X_test</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="p">:])</span>
<span class="k">if</span> <span class="n">predicted_number</span> <span class="o">==</span> <span class="n">real_number</span><span class="p">:</span>
<span class="n">correct_predictions</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">print</span><span class="p">(</span><span class="s">"Predicted correctly {}"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">predicted_number</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">incorrect_predictions</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">print</span><span class="p">(</span><span class="s">"Predicted incorrectly {} as {}"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">real_number</span><span class="p">,</span> <span class="n">predicted_number</span><span class="p">))</span>
<span class="n">accuracy</span> <span class="o">=</span> <span class="n">correct_predictions</span> <span class="o">/</span> <span class="p">(</span><span class="n">correct_predictions</span> <span class="o">+</span> <span class="n">incorrect_predictions</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="s">"Accuracy over {} samples is {}</span><span class="si">%</span><span class="s">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">m_test</span><span class="p">,</span> <span class="n">accuracy</span> <span class="o">*</span> <span class="mi">100</span><span class="p">))</span>
<span class="k">print</span><span class="p">(</span><span class="s">"Training error: {}"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">training_error</span><span class="p">))</span>
</code></pre></div></div>Beautiful Raspberry Pi2016-05-13T00:00:00+00:002016-05-13T00:00:00+00:00http://pinchuk.be/2016/05/13/Beautiful-Raspberry-Pi<p><img src="/assets/Beautiful Raspberry Pi.jpg" alt="Beautiful Raspberry Pi" /></p>
<p>So I wanted to have a website. Maybe I will write in another blog entry how I got disappointed from some web hosting companies, and decided to have my own server.</p>
<p>But this is not at all simple - server hardware cost money, take much electricity etc. And because my better half starts a company soon, and is familiar with MODX - I had also an extra requirement.</p>
<p>It turns out that I had already some hardware ready to use. A Raspberry Pi 2 Model B. Why not actually?</p>
<p>Well - will such a tiny and weak computer run MODX? I had to try out. <img src="/assets/raspberryPi2B.png" alt="RaspberryPi2B" align="right" height="200px" /></p>
<p>After some hours of learning and trying different operating systems of Rasberry Pi I got to the default and most obvious installation - raspbian - and specifically RASPBIAN JESSIE LITE. Who knows why I did not try this first…</p>
<p>After installing it on the small 8G SDCard I had, I sat on the floor in front of our TV, with a keyboard I stole from the family PC and an old mouse. And because setting up the wifi did not work for me immediatly - I improvised a network cable that got to that spot in the house. 2 minutes later I had sshd running:</p>
<p>sudo apt-get install openssh-client openssh-server</p>
<p>Now I could just leave my raspberry pi in its nice box (which I printed - but this is for a separated blog entry), go to my desk, and ssh to my new server and play with it. Fun!</p>
<p>Few minutes later - after installing apache2, mysql, and php I was ready to download and install MODX.</p>
<p>It all worked like charm and the answer to the question above is big yes! This tiny and weak computer - Raspberry Pi 2 Model B - is strong enough to run MODX. I actually cannot really feel that it is slow.</p>
<p>It is so nice to go to sleep after things worked out well - even at 2AM.</p>