<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.6.2">Jekyll</generator><link href="http://fungai.org/feed.xml" rel="self" type="application/atom+xml" /><link href="http://fungai.org/" rel="alternate" type="text/html" /><updated>2018-01-02T06:04:51+00:00</updated><id>http://fungai.org/</id><title type="html">fungai.org - identify wild mushroom with deep learning</title><subtitle>fungai.org assists scientists and enthusiasts to easily identify wild mushroom species from images using deep learning technologies.
</subtitle><entry><title type="html">Tensorflow Reading List</title><link href="http://fungai.org/2018/01/02/tensorflow-reading-list/" rel="alternate" type="text/html" title="Tensorflow Reading List" /><published>2018-01-02T05:00:00+00:00</published><updated>2018-01-02T05:00:00+00:00</updated><id>http://fungai.org/2018/01/02/tensorflow-reading-list</id><content type="html" xml:base="http://fungai.org/2018/01/02/tensorflow-reading-list/">&lt;p&gt;Learning Python and Deep Learning is one thing. Mastering Tensorflow is another. Here is my own curated list of useful Tensorflow related resources. I’ll update this list on a regular basis.&lt;/p&gt;

&lt;h3 id=&quot;websites--courses&quot;&gt;Websites / Courses&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.tensorflow.org/&quot;&gt;Tensorflow.org&lt;/a&gt;: handy reference&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://web.stanford.edu/class/cs20si/syllabus.html&quot;&gt;CS 20SI: Tensorflow for Deep Learning Research&lt;/a&gt;: my personal favorite. First go-to point for beginner and experts alike.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://danijar.com/&quot;&gt;Danijar Hafner Blog&lt;/a&gt;: contains practical tips and advice on explaining Tensorflow concepts and structuring Tensorflow projects with great examples.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://twitter.com/jAtlas7&quot;&gt;Johnny Chan’s Twitter&lt;/a&gt;: I use my Twitter timeline to bookmark resources on Tensorflow, Deep Learning, and all things software development.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;useful-articles&quot;&gt;Useful Articles&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://danijar.com/what-is-a-tensorflow-session/&quot;&gt;What is a TensorFlow Graph and Session&lt;/a&gt;: with an excellent codices example.&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Johnny Chan</name></author><summary type="html">My personal reading list on mastering Tensorflow (updated regularly)</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://fungai.org/images/blog/tensorflow-logo.png" /></entry><entry><title type="html">Train a basic wild mushroom classifier</title><link href="http://fungai.org/2017/12/13/train-a-basic-wild-mushroom-classifier/" rel="alternate" type="text/html" title="Train a basic wild mushroom classifier" /><published>2017-12-13T14:30:00+00:00</published><updated>2017-12-13T14:30:00+00:00</updated><id>http://fungai.org/2017/12/13/train-a-basic-wild-mushroom-classifier</id><content type="html" xml:base="http://fungai.org/2017/12/13/train-a-basic-wild-mushroom-classifier/">&lt;p&gt;Earlier, we learnt about &lt;a href=&quot;http://fungai.org/2017/12/11/tensorflow-for-poets/&quot;&gt;transfer learning with Tensorflow for Poets retrain scripts&lt;/a&gt;, and &lt;a href=&quot;http://fungai.org/2017/12/11/tensorflow-for-poets/&quot;&gt;how to download images from ImageNet&lt;/a&gt;. In this article we will focus on combining these concepts and techniques and build a more specialized machine learning application.&lt;/p&gt;

&lt;h3 id=&quot;build-a-basic-wild-mushroom-classifier&quot;&gt;Build a Basic Wild Mushroom Classifier&lt;/h3&gt;

&lt;p&gt;In this tutorial, we are going to build a very basic image classification model together, to identify 5 types of wild mushrooms&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Fly Agaric (&lt;a href=&quot;http://www.image-net.org/synset?wnid=n13003061&quot;&gt;view on ImageNet: n13003061&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Scarlet Elf cup (&lt;a href=&quot;http://www.image-net.org/synset?wnid=n13030337&quot;&gt;view on ImageNet: n13030337&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Common Stinkhorn (&lt;a href=&quot;http://www.image-net.org/synset?wnid=n13040629&quot;&gt;view on ImageNet: n13040629&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Giant Puffball (&lt;a href=&quot;http://www.image-net.org/synset?wnid=n13044375&quot;&gt;view on ImageNet: n13044375&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Earthstar (&lt;a href=&quot;http://www.image-net.org/synset?wnid=n13044778&quot;&gt;view on ImageNet: n13044778&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But before getting our hands dirty let’s take a step back and form our high level strategy. We’ll use Google’s 7 Steps of Machine Learning to guide our implementation process.&lt;/p&gt;

&lt;h3 id=&quot;googles-7-steps-of-machine-learning&quot;&gt;Google’s 7 Steps of Machine Learning&lt;/h3&gt;

&lt;p&gt;Let’s review quickly the Google’s &lt;a href=&quot;https://www.youtube.com/watch?v=nKW8Ndu7Mjw&quot;&gt;7 Steps of Machine Learning&lt;/a&gt; (see 9:38 - 9:53):&lt;/p&gt;

&lt;iframe src=&quot;https://www.youtube.com/embed/nKW8Ndu7Mjw?rel=0&amp;amp;start=578&quot; frameborder=&quot;0&quot; gesture=&quot;media&quot; allow=&quot;encrypted-media&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Expand these 7 steps to suit our Wild Mushroom Classifier Project:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Gathering Data
    &lt;ul&gt;
      &lt;li&gt;Download reasonable amount of labelled images per wild mushroom type from ImageNet. We’ll need at least 250 labelled images per category: 200 for retraining (80% train, 10% validation, 10% test), and 50 for demo predictions later.&lt;/li&gt;
      &lt;li&gt;In other words, we will have at least 1250 labelled images for retraining (5 categories x 200 per category), and 250 labelled images for demo predictions (5 categories x 50 per category).&lt;/li&gt;
      &lt;li&gt;In total we will have 1500 images (1250 for retraining, and 250 for demo).&lt;/li&gt;
      &lt;li&gt;We’ll use &lt;a href=&quot;https://github.com/tzutalin/ImageNet_Utils&quot;&gt;ImageNet_Utils&lt;/a&gt; to help us download labelled images from ImageNet easily. Note that we’ll likely download more than we need to begin with. But that is ok, as we’ll only pick what we need in the data preparation phase in step 2 (250 labelled images per category).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Preparing that Data
    &lt;ul&gt;
      &lt;li&gt;Now that we’ve downloaded many images from ImageNet, we’ll manually pick 250 images per category and copy into a new directory structure (say, to a folder called &lt;code class=&quot;highlighter-rouge&quot;&gt;shrooms_250_clean&lt;/code&gt;). This will also help us avoid data imbalances, as we’ll have equal amount of images per category.&lt;/li&gt;
      &lt;li&gt;Do the image cleansing in our newly created &lt;code class=&quot;highlighter-rouge&quot;&gt;shrooms_250_clean&lt;/code&gt;. e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;.jpg&lt;/code&gt; format, non corrupted, must be in correct category, non flickr dummy image, reasonable file size, etc. Delete as appripriate.&lt;/li&gt;
      &lt;li&gt;As we do the image delete we may fall short on the 250 images per category target. Just copy more over any unused images (obtained from end of step 1.)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Choosing a Model
    &lt;ul&gt;
      &lt;li&gt;We will use &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#0&quot;&gt;Tensorflow for poets&lt;/a&gt; as our starting point baseline guide.&lt;/li&gt;
      &lt;li&gt;We Tensorflow for poets scripts are compatible with two models: Inception v3 and MobileNet.&lt;/li&gt;
      &lt;li&gt;Inception v3 is more accurate but heavier.&lt;/li&gt;
      &lt;li&gt;MobileNet is slightly less accurate but lighter and more suitable for low-power embedded devices.&lt;/li&gt;
      &lt;li&gt;Since this is our first attempt, let’s go for something light. We will use the MobileNet model. (plus, at some point in future we may consider running our trained model on an embedded device offline, with Raspberry Pi and Intel Movidius Neural Compute Stick).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Training
    &lt;ul&gt;
      &lt;li&gt;Run the &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#3&quot;&gt;Tensorflow for poets retrain script&lt;/a&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;retrain.py&lt;/code&gt; with the appropriate options.&lt;/li&gt;
      &lt;li&gt;Use tensorboard to monitor training progress and performance. We will focus mainly the accuracy and cross entropy charts for now.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Evaluation
    &lt;ul&gt;
      &lt;li&gt;Again, use tensorboard to monitor training progress and performance (mainly accuracy and cross entropy charts)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Hyperparameter Tuning
    &lt;ul&gt;
      &lt;li&gt;Can we improve our training accuracy (higher the better) and Cross Entropy Error (lower the better)?&lt;/li&gt;
      &lt;li&gt;Again, use Tensorboard.&lt;/li&gt;
      &lt;li&gt;Note: we will likely do this tuning under a separate article / tutorial.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Prediction
    &lt;ul&gt;
      &lt;li&gt;Remember our set-aside 50 demo images (per category) that were not used for training? Let’s use our now trained model to perform prediction (aka inference) with the help of &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#3&quot;&gt;Tensorflow for poets prediction script&lt;/a&gt;  &lt;code class=&quot;highlighter-rouge&quot;&gt;label_image.py&lt;/code&gt;, with appropriate options.&lt;/li&gt;
      &lt;li&gt;Of the 250 demo images (5 category x 50 images per category), how many did the model predict it correctly?&lt;/li&gt;
      &lt;li&gt;For the ones that the model predicted wrong, what do the images look like? This will give us an idea of whether the error is reasonable. For instance, if even a human would have a hard time classifying the image, maybe the model is not doing that bad?&lt;/li&gt;
      &lt;li&gt;(optional) create a program that automatically display images one by one (or in small batches), and perform prediction (and compute overall accuracy and error rate) in the same time? This may be good for showing off / demo purpose? (This will be covered under a separate article / tutorial instead)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;kiss---keep-it-simple-stupid&quot;&gt;KISS - Keep it Simple, Stupid&lt;/h3&gt;

&lt;p&gt;Our aim is to get things working as quickly as possible - understanding just enough about the high level process and implementing the workflow and get to the end. By walking through the process we will gain an appreciation on how we may potentially improve the process a bit. But that will be another job for another day. For now, let’s &lt;a href=&quot;https://en.wikipedia.org/wiki/KISS_principle&quot;&gt;keep it simple and stupid&lt;/a&gt;: we will complete an iteration loop as quickly as possible, from start to finish, and see some end results.&lt;/p&gt;

&lt;p&gt;OK, buckle up. Here we go.&lt;/p&gt;

&lt;h3 id=&quot;directory-structure&quot;&gt;Directory Structure&lt;/h3&gt;

&lt;p&gt;For ease of explaining, i’m going to assume any Github repositories are stored at &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos&lt;/code&gt;. i.e. our directory structure will eventually look like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;|- repos
  |- github-repo-1
  |- github-repo-2
  |- etc.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you do not have a &lt;code class=&quot;highlighter-rouge&quot;&gt;repos&lt;/code&gt; folder in your home directory, create it now:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ mkdir ~/repos
$ cd ~
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We will need two repositories in our &lt;code class=&quot;highlighter-rouge&quot;&gt;repos&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;|- repos
  |- my-ImageNet_Utils
  |- my-tensorflow-for-poets
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The two repositories above are actually from Github. You can download (and rename) these two repositories to your mac locally by doing this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cd ~/repos
$ git clone https://github.com/tzutalin/ImageNet_Utils my-ImageNet_Utils
$ git clone https://github.com/googlecodelabs/tensorflow-for-poets-2 my-tensorflow-for-poets
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice that I’ve renamed the original Github repositories &lt;code class=&quot;highlighter-rouge&quot;&gt;ImageNet_Utils&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;my-ImageNet_Utils&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;tensorflow-for-poets-2&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;my-tensorflow-for-poets&lt;/code&gt;. This is purely to avoid potential clashes or confusion if you happen already have &lt;code class=&quot;highlighter-rouge&quot;&gt;ImageNet_Utils&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;tensorflow-for-poets-2&lt;/code&gt; setup on your mac.&lt;/p&gt;

&lt;p&gt;In this article however, I’m going to stick with &lt;code class=&quot;highlighter-rouge&quot;&gt;my-ImageNet_Utils&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;my-tensorflow-for-poets&lt;/code&gt;, purely for instructional convenience. (In reality however you can name the repositories to whatever name you’d like.)&lt;/p&gt;

&lt;h3 id=&quot;step-1-gathering-data&quot;&gt;Step 1: Gathering Data&lt;/h3&gt;

&lt;p&gt;We download images from ImageNet with the help of this handy &lt;a href=&quot;https://github.com/tzutalin/ImageNet_Utils&quot;&gt;ImageNet_Utils tool&lt;/a&gt;, as introduced in &lt;a href=&quot;/2017/12/12/download-imagenet-images-by-wnid/&quot;&gt;a previous article&lt;/a&gt;. I’m going to recite the exact steps here:&lt;/p&gt;

&lt;p&gt;Navigate to &lt;code class=&quot;highlighter-rouge&quot;&gt;my-ImageNet_Utils&lt;/code&gt;repository directory (so we can see the Python files if we want to):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cd ~/repos/my-ImageNet_Utils
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ensure we have Python 2.7 environment setup (yes I know. We are in this age we should be using Python 3.6+ really. But from what I’ve tested so far, Python 2.7 works for this ImageNet_Utils tool. So just stick with it for now. We are only ever going to use it strictly for downloading ImageNet images). Let’s create a Python 2.7 environment with Anaconda (if you’ve already done this, skip to next step)&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ conda create --name py27p13 python=2.7.13
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Activate the Python environment (Python 2.7.13 is what I use):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ source activate py27p13
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We should see our conda environment name in our prompt like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py27p13) $
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now the fun part. We are going to download all ImageNet images for the 5 mushroom categories, as represented by the WordNet ID &lt;code class=&quot;highlighter-rouge&quot;&gt;wnid&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Open a terminal and start downloading all the images of Fly Agaric:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py27p13) $ cd ~/repos/my-ImageNet_Utils
(py27p13) $ ./downloadutils.py --downloadImages --wnid n13003061
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will download the images in a new sub-directory (within the &lt;code class=&quot;highlighter-rouge&quot;&gt;ImageNet_Utils&lt;/code&gt; repository) at:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;~/repos/ImageNet_Utils/13003061/n13003061_urlimages
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There will be some minor errors during the download process, due to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;URL no longer valid&lt;/li&gt;
  &lt;li&gt;URL points to a website instead of an image&lt;/li&gt;
  &lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can safetly ignore those errors. Of the many image URLs, we will at least get 250 (hopefully) good images, or more.&lt;/p&gt;

&lt;p&gt;Do the same for the other &lt;code class=&quot;highlighter-rouge&quot;&gt;wnid&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py27p13) $ cd ~/repos/my-ImageNet_Utils
(py27p13) $ ./downloadutils.py --downloadImages --wnid n13030337
(py27p13) $ ./downloadutils.py --downloadImages --wnid n13040629
(py27p13) $ ./downloadutils.py --downloadImages --wnid n13044375
(py27p13) $ ./downloadutils.py --downloadImages --wnid n13003061
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once all is done we shall see our 5 new directories at &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-ImageNet_Utils&lt;/code&gt; :&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-download-1.png&quot; alt=&quot;imagenet-download-1.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let’s take a look at the downloaded images:&lt;/p&gt;

&lt;p&gt;Fly Agaric images at &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/ImageNet_Utils/n13030337/n13003061_urlimages&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-download-2.png&quot; alt=&quot;imagenet-download-2.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Scarlet Elf cup images at &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/ImageNet_Utils/n13030337/n13030337_urlimages&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-download-3.png&quot; alt=&quot;imagenet-download-3.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Common Stinkhorn images at &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/ImageNet_Utils/n13040629/n13040629_urlimages&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-download-4.png&quot; alt=&quot;imagenet-download-4.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Giant Puffball images at &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/ImageNet_Utils/n13044375/n13044375_urlimages&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-download-5.png&quot; alt=&quot;imagenet-download-5.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Earthstar images at &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/ImageNet_Utils/n13003061/n13003061_urlimages&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-download-6.png&quot; alt=&quot;imagenet-download-6.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Notice that we will inevitably have more images in certain categories than the other from our initial raw datasets.&lt;/p&gt;

&lt;h3 id=&quot;step-2-preparing-that-data&quot;&gt;Step 2: Preparing that Data&lt;/h3&gt;

&lt;h4 id=&quot;decision-pick-our-subset-and-clean-or-the-other-way-round&quot;&gt;Decision: Pick our subset and clean (or the other way round?)&lt;/h4&gt;

&lt;p&gt;Now that we have the raw ImageNet images downloaded to &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/ImageNet_Utils/&lt;/code&gt;, we have a decision to make: we can either (1) clean all the raw images, then pick our random 250 images per category, or (2) the other way round - pick aound 250 images per category, then clean this smaller subset. Let’s compare these two options.&lt;/p&gt;

&lt;p&gt;Option (1): clean everything up front once and then pick our 250 images per category. Advantage of this is that know our entire dataset will be clean at the end of the data cleansing. This allows flexibility in long run - for instance, we will be able to select our fixed subset of any size, be it 250 images per category, 300 per category, or even 500 per category, we will be able to do that easily. The only drawback of this option is the massive effort in cleaning more data than we actually need upfront, for our initial prototype. If you have already done the tensorflow for poets tutorial previously, you’ll know that around 200 retrain images will be good enough to get started. If we look at fly agaric alone, we already have 850 ish images in this category - to clean all 850 fly agaric images when all we need is just 250 from that category, could slow down our first attempt to this exercise. Imagine we have 5 categories to clean! At the time of writing this, step 1 would have downloaded 842 Fly agaric images, 310 scarlet elf cup, 613 common stinkhorn, 643 giant puffball, and 572 earthstar. That’s a total of 2980 images to clean (when all we need is 1250 images: 250 per category x 5 categories). This option will likely double the number of images to clean than actually required.&lt;/p&gt;

&lt;p&gt;Option (2): pick our 250 images per category, and then clean these subsets. Advantage of this is &lt;strong&gt;focus&lt;/strong&gt;. We know 250 clean images per category is good enough. We pick only 250 raw images and focus on getting them cleansed. This will ensure we are not distracted too much upfront, at such an early stage. The downside of this option is that (as you’ve probably have guessed), is that we may occasionally fall short on images and have to import more. So say we have started with 250 fly agaric images, and we’ve found 30 dirty ones and ended up deleting them and reduce our bucket size to 220 fly agaric images. We then copy and paste the additional 30 unused fly agaric images to this bucket (to make it up to 250). We do the cleaning on this 30 images, find 5 dirty ones, delete them, and ended up with 245 clean images in this bucket. We repeat the process until we obtain the entire set of 250 clean fly agaric images. The downside as you see is the additional manual work involved. But with a systematic approach, it is possible to reduce the likelihood of dirty images in our 250 buckets. This option is not perfect, but for a first attempt in building this wild mushroom classificaton app, it is good enough for getting things done and gaining relevant experience, and so we will choose this option in this tutorial.&lt;/p&gt;

&lt;p&gt;In this tutorial we will use option (2) - pick around 250 images per category, then clean this smaller subset.&lt;/p&gt;

&lt;h4 id=&quot;create-a-new-folder-dedicated-to-our-250-cleansed-images-per-category&quot;&gt;Create a new folder dedicated to our 250 cleansed images per category&lt;/h4&gt;

&lt;p&gt;let’s create a new folder to store our ~250 clean images per categories:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py27p13) $ cd ~/repos/my-ImageNet_Utils
(py27p13) $ mkdir shrooms-clean-250-each
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Within this &lt;code class=&quot;highlighter-rouge&quot;&gt;shrooms-clean-250-each&lt;/code&gt;, let’s create 5 subdirectories with appropriate names:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py27p13) $ cd ~/repos/my-ImageNet_Utils
(py27p13) $ mkdir n13003061-fly-agaric
(py27p13) $ mkdir n13030337-scarlet-elf-cup
(py27p13) $ mkdir n13040629-common-stinkhorn
(py27p13) $ mkdir n13044375-giant-puffball
(py27p13) $ mkdir n13044778-Earthstar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Our directory &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-ImageNet_Utils/shrooms-clean-250-each&lt;/code&gt; should look like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/shrooms-clean-250-each.png&quot; alt=&quot;shrooms-clean-250-each&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;copy-250-images-per-category-for-cleansing&quot;&gt;Copy 250 images per category for cleansing&lt;/h4&gt;

&lt;p&gt;This step is a bit manual, but easy to do for first timer. Open up two Finder windows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Finder 1 points to the clean images directory: &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-ImageNet_Utils&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Finder 2 points to the retraining images directory: &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-ImageNet_Utils/shrooms-clean-250-each&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Finder 1, sort the images by descending by file size. Copy the first 250 clean images per category over to Finder 2, like this:&lt;/p&gt;

&lt;div class=&quot;table-wrapper&quot;&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Category&lt;/th&gt;
        &lt;th&gt;Copy from Finder 1&lt;/th&gt;
        &lt;th&gt;Paste to Finder 2&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Fly Agaric&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13030337/n13003061_urlimages/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061-fly-agaric/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Scarlet Elf cup&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13030337/n13030337_urlimages/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13030337-scarlet-elf-cup/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Common Stinkhorn&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13040629/n13040629_urlimages/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13040629-common-stinkhorn/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Giant Puffball&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13044375/n13044375_urlimages/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13044375-giant-puffball/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Earthstar&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061/n13003061_urlimages/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061-earthstar/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

&lt;/div&gt;

&lt;p&gt;What is the reason for doing a sort descending by file size? It’s just a trick: images with larger file size is likely to be more valid than smaller ones. In particular, images with 2KB or below are very likely invalid images. Focusing larger size images will likely reduce the population of “dirty” images. But it’s entirely up to you how you’d like to do it.&lt;/p&gt;

&lt;h4 id=&quot;do-some-cleaning&quot;&gt;Do some cleaning&lt;/h4&gt;

&lt;p&gt;Now, review the images in &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-ImageNet_Utils/shrooms-clean-250-each/&lt;/code&gt;. Delete any invalid images as appropriate.&lt;/p&gt;

&lt;p&gt;For example, while I was checking through my Earthstar images, these are what I consider valid and invalid images:&lt;/p&gt;

&lt;h5 id=&quot;example-valid-earth-star-keep-these-&quot;&gt;Example: Valid Earth Star (keep these) &lt;i class=&quot;fa fa-check&quot; aria-hidden=&quot;true&quot;&gt;&lt;/i&gt;&lt;/h5&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;valid-earthstar-1.png.png&quot; src=&quot;/images/blog/valid-earthstar-1.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;valid-earthstar-2.png.png&quot; src=&quot;/images/blog/valid-earthstar-2.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;valid-earthstar-3.png.png&quot; src=&quot;/images/blog/valid-earthstar-3.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;valid-earthstar-4.png.png&quot; src=&quot;/images/blog/valid-earthstar-4.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h5 id=&quot;example-invnalid-earth-star-delete-these-&quot;&gt;Example: Invnalid Earth Star (delete these) &lt;i class=&quot;fa fa-times&quot; aria-hidden=&quot;true&quot;&gt;&lt;/i&gt;&lt;/h5&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;invalid-earthstar-1.png.png&quot; src=&quot;/images/blog/invalid-earthstar-1.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;invalid-earthstar-2.png.png&quot; src=&quot;/images/blog/invalid-earthstar-2.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;invalid-earthstar-3.png.png&quot; src=&quot;/images/blog/invalid-earthstar-3.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;imagenet-partial-downloaded-image.png&quot; src=&quot;/images/blog/imagenet-partial-downloaded-image.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;  
&lt;/div&gt;

&lt;p&gt;(Note: reason for deleting some mushroom images is that they are in the wrong category! Earth star should have star shape. This requires a bit domain knowledge / google-ing)&lt;/p&gt;

&lt;p&gt;Notice that as we delete images, our “250 per bucket” will start to fall short. In this case, just add more unused images and repeat the cleaning step (probably a few times). In the end of we should have 250 clean images per category, stored at &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-ImageNet_Utils/shrooms-clean-250-each/&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id=&quot;prepare-the-clean-data-for-tensorflow-for-poets&quot;&gt;Prepare the clean data for tensorflow for poets&lt;/h4&gt;

&lt;p&gt;First of all, recall our directory structure:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;|- repos
  |- my-ImageNet_Utils
  |- my-tensorflow-for-poets
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So far we have been working with the &lt;code class=&quot;highlighter-rouge&quot;&gt;my-ImageNet_Utils&lt;/code&gt; repository: we’ve downaloded raw ImageNet images there and prepared 250 clean images per wild mushroom category - all stored under &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-ImageNet_Utils/shrooms-clean-250-each/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We now need to copy the images accordingly to the &lt;code class=&quot;highlighter-rouge&quot;&gt;my-tensorflow-for-poets&lt;/code&gt;, so we can run some scripts to perform transfer learning and predictions. If you have come across the tensorflow for poets exercise previously, you would have learnt that all the (untracked) working files are stored under &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-tensorflow-for-poets/tf_files&lt;/code&gt;. This will include images for retraining, the retrained models / graphs, labels, etc. We can basically store anything relating to retraining in this location for convenience.&lt;/p&gt;

&lt;h4 id=&quot;prepare-200-images-per-category-for-transfer-learning&quot;&gt;Prepare 200 Images per category for transfer learning&lt;/h4&gt;

&lt;p&gt;Create the &lt;code class=&quot;highlighter-rouge&quot;&gt;shrooms-train-200-each&lt;/code&gt; folder at &lt;code class=&quot;highlighter-rouge&quot;&gt;~repos/my-tensorflow-for-poets&lt;/code&gt;, and create a similar directory structure to the &lt;code class=&quot;highlighter-rouge&quot;&gt;shrooms-clean-250-each&lt;/code&gt; that we created and populated earlier:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py27p13) $ cd ~/repos/my-tensorflow-for-poets/tf_files
(py27p13) $ mkdir shrooms-train-200-each
(py27p13) $ cd shrooms-train-200-each
(py27p13) $ mkdir n13003061-fly-agaric
(py27p13) $ mkdir n13030337-scarlet-elf-cup
(py27p13) $ mkdir n13040629-common-stinkhorn
(py27p13) $ mkdir n13044375-giant-puffball
(py27p13) $ mkdir n13044778-Earthstar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, open up two Finder windows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Finder 1 points to the clean images directory: &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-ImageNet_Utils/shrooms-clean-250-each&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Finder 2 points to the retraining images directory: &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-tensorflow-for-poets/tf_files/shrooms-train-200-each&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Finder 1, sort the images by name. Copy the &lt;strong&gt;first 200&lt;/strong&gt; clean images per category over to Finder 2, like this:&lt;/p&gt;

&lt;div class=&quot;table-wrapper&quot;&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Category&lt;/th&gt;
        &lt;th&gt;copy from Finder 1&lt;/th&gt;
        &lt;th&gt;paste to Finder 2&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Fly Agaric&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061-fly-agaric/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061-fly-agaric/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Scarlet Elf cup&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13030337-scarlet-elf-cup/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13030337-scarlet-elf-cup/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Common Stinkhorn&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13040629-common-stinkhorn/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13040629-common-stinkhorn/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Giant Puffball&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13044375-giant-puffball/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13044375-giant-puffball/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Earthstar&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061-earthstar/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061-earthstar/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

&lt;/div&gt;

&lt;h4 id=&quot;prepare-50-images-per-category-for-prediction&quot;&gt;Prepare 50 Images per category for prediction&lt;/h4&gt;

&lt;p&gt;This will be very similar to our previous step, but we copy over the remaining 50 unused images over for demo / prediction activities later.&lt;/p&gt;

&lt;p&gt;Create the &lt;code class=&quot;highlighter-rouge&quot;&gt;shrooms-demo-50-each&lt;/code&gt; folder at &lt;code class=&quot;highlighter-rouge&quot;&gt;~repos/my-tensorflow-for-poets&lt;/code&gt;, and create a similar directory structure to the &lt;code class=&quot;highlighter-rouge&quot;&gt;shrooms-clean-250-each&lt;/code&gt; that we created and populated earlier:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py27p13) $ cd ~/repos/my-tensorflow-for-poets/tf_files
(py27p13) $ mkdir shrooms-demo-50-each
(py27p13) $ cd shrooms-demo-50-each
(py27p13) $ mkdir n13003061-fly-agaric
(py27p13) $ mkdir n13030337-scarlet-elf-cup
(py27p13) $ mkdir n13040629-common-stinkhorn
(py27p13) $ mkdir n13044375-giant-puffball
(py27p13) $ mkdir n13044778-Earthstar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, open up two Finder windows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Finder 1 points to the clean images directory: &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-ImageNet_Utils/shrooms-clean-250-each&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Finder 2 points to the retraining images directory: &lt;code class=&quot;highlighter-rouge&quot;&gt;~/repos/my-tensorflow-for-poets/tf_files/shrooms-demo-50-each&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Finder 1, sort the images by name. Copy the &lt;strong&gt;last 50&lt;/strong&gt; clean images per category over to this folder, like this:&lt;/p&gt;

&lt;div class=&quot;table-wrapper&quot;&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Category&lt;/th&gt;
        &lt;th&gt;copy from Finder 1&lt;/th&gt;
        &lt;th&gt;paste to Finder 2&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Fly Agaric&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061-fly-agaric/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061-fly-agaric/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Scarlet Elf cup&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13030337-scarlet-elf-cup/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13030337-scarlet-elf-cup/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Common Stinkhorn&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13040629-common-stinkhorn/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13040629-common-stinkhorn/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Giant Puffball&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13044375-giant-puffball/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13044375-giant-puffball/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Earthstar&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061-earthstar/&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061-earthstar/&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

&lt;/div&gt;

&lt;p&gt;We won’t need the terminal window anymore. Just close it.&lt;/p&gt;

&lt;h3 id=&quot;step-3-choosing-a-model&quot;&gt;Step 3: Choosing a Model&lt;/h3&gt;

&lt;p&gt;The tensorflow for poets retraining script can retrain either Inception V3 model or MobileNet.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Inception V3 model: optimized for accuracy, at the cost of size (1st choice accuracy of 78% on ImageNet, and 85 MB in size)&lt;/li&gt;
  &lt;li&gt;MobileNets: optimized to be small and efficient, at the cost of some accuracy (1st choice accuracy of 70.5% on ImageNet, and 19 MB in size)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s keep it simple. Use MobileNet - as suggested in Tensorflow for Poets. Once we’ve got this working nicely, we may try Inception v3 / other models in future.&lt;/p&gt;

&lt;h3 id=&quot;step-4-training&quot;&gt;Step 4: Training&lt;/h3&gt;

&lt;p&gt;This is probably one of the most important steps. We will follow the &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#3&quot;&gt;tensorflow for poets retraining guide&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;setup-python-3x-tensorflow-environment&quot;&gt;Setup Python 3.x Tensorflow environment&lt;/h4&gt;

&lt;p&gt;On Python version: Python 3.x is likely to be more supported in the long run (comparing to 2.x). So let’s use it.&lt;/p&gt;

&lt;p&gt;On Tensorflow version: At the time of writing this, tensorflow is on version 1.4.1, which includes &lt;code class=&quot;highlighter-rouge&quot;&gt;tensorflow-tensorboard &lt;/code&gt; (version v0.4.0rc3). This will likely change as time goes by.&lt;/p&gt;

&lt;p&gt;We will be reusing the instructions from our previous article &lt;a href=&quot;/2017/12/11/tensorflow-for-poets/&quot;&gt;Tensorflow for Poets&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Create a conda environment with Anaconda (this may take a while). If you’ve already done this previously, feel free to skip this step. Open a brand new terminal window:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cd ~
$ conda create --name py36-tf14 python=3.6 --channel conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Activate conda environment:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ source activate
$ source activate py36-tf14
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Our command prompt should now look like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Install tensorflow with &lt;code class=&quot;highlighter-rouge&quot;&gt;pip&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ pip install &quot;tensorflow==1.4.1&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Side note: why not use &lt;code class=&quot;highlighter-rouge&quot;&gt;conda install tensorflow&lt;/code&gt; instead? My answer: at the time of writing this article, the Tensorflow on conda-forge channel was only up to 1.4.0. Tensorboard turned out to be a bit buggy with this version (from what I’ve seen). Install Tensorflow with &lt;code class=&quot;highlighter-rouge&quot;&gt;pip&lt;/code&gt; with version &lt;code class=&quot;highlighter-rouge&quot;&gt;1.4.1&lt;/code&gt; seems to have fixed it. (this version may be even higher as time goes by).&lt;/p&gt;

&lt;p&gt;Our conda environment should now look like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ conda list
# packages in environment at /Users/johnny/anaconda/envs/py36-tf14:
#
bleach                    1.5.0                     &amp;lt;pip&amp;gt;
ca-certificates           2017.11.5                     0    conda-forge
certifi                   2017.11.5                py36_0    conda-forge
enum34                    1.1.6                     &amp;lt;pip&amp;gt;
html5lib                  0.9999999                 &amp;lt;pip&amp;gt;
Markdown                  2.6.10                    &amp;lt;pip&amp;gt;
ncurses                   5.9                          10    conda-forge
numpy                     1.13.3                    &amp;lt;pip&amp;gt;
openssl                   1.0.2n                        0    conda-forge
pip                       9.0.1                    py36_0    conda-forge
protobuf                  3.5.0.post1               &amp;lt;pip&amp;gt;
python                    3.6.3                         4    conda-forge
readline                  7.0                           0    conda-forge
setuptools                38.2.4                   py36_0    conda-forge
six                       1.11.0                    &amp;lt;pip&amp;gt;
sqlite                    3.20.1                        0    conda-forge
tensorflow                1.4.1                     &amp;lt;pip&amp;gt;
tensorflow-tensorboard    0.4.0rc3                  &amp;lt;pip&amp;gt;
tk                        8.6.7                         0    conda-forge
Werkzeug                  0.13                      &amp;lt;pip&amp;gt;
wheel                     0.30.0                     py_1    conda-forge
xz                        5.2.3                         0    conda-forge
zlib                      1.2.11                        0    conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: at the time of writing this, &lt;code class=&quot;highlighter-rouge&quot;&gt;tensorflow v1.4.1&lt;/code&gt; seems to work well with &lt;code class=&quot;highlighter-rouge&quot;&gt;tensorflow-tensorboard v0.4.0rc3&lt;/code&gt; (aka tensorboard).&lt;/p&gt;

&lt;h4 id=&quot;start-tensorboard-in-the-background&quot;&gt;Start TensorBoard in the background&lt;/h4&gt;

&lt;p&gt;I just wanted to emphasize, Tensorboard is &lt;strong&gt;awesome&lt;/strong&gt;. I’ve learnt a great deal on model training with Tensorboard and would highly recommend using it for two main visualization charts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;accuracy (higher the better)&lt;/li&gt;
  &lt;li&gt;cross entropy (lower the better)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s start tensorboard in the background&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ cd ~/repos/my-tensorflow-for-poets
(py36-tf14) $ tensorboard --logdir tf_files/training_summaries --host=localhost &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If it works, navigate to &lt;a href=&quot;http://localhost:6006&quot;&gt;http://localhost:6006&lt;/a&gt; and see the TensorBoard frontend:&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-12&quot;&gt;&lt;img alt=&quot;tensorboard-1.png&quot; src=&quot;/images/blog/tensorboard-1.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Note: if we wish to re-run the above tensorboard command, make sure we kill the previously created tensorboard session (to avoid port collision). In fact, let’s try it. Issue the following to kill Tensorboard:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ pkill -f &quot;tensorboard&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that tensorboard is killed, &lt;a href=&quot;http://localhost:6006&quot;&gt;http://localhost:6006&lt;/a&gt; should now show nothing.&lt;/p&gt;

&lt;p&gt;To start Tensorboard again, just issue this again:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ tensorboard --logdir tf_files/training_summaries --host=localhost &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Navigate back to &lt;a href=&quot;http://localhost:6006&quot;&gt;http://localhost:6006&lt;/a&gt;, Tensorboard is back!&lt;/p&gt;

&lt;p&gt;OK you’ve got the idea. (side note: from experience, we will likely start and kill Tensorboard from time to time, as needed.)&lt;/p&gt;

&lt;h4 id=&quot;configure-our-mobilenet&quot;&gt;Configure our MobileNet&lt;/h4&gt;

&lt;p&gt;There are two main MobileNet configuration hyperparameters: Input image resolution (&lt;code class=&quot;highlighter-rouge&quot;&gt;TFP_IMAGE_SIZE&lt;/code&gt;) and relative size (&lt;code class=&quot;highlighter-rouge&quot;&gt;TFP_RELATIVE_SIZE&lt;/code&gt;). According to &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#3&quot;&gt;the Tensorflow for Poets retraining guide&lt;/a&gt;, pick the following configuration options:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Input image resolution (&lt;code class=&quot;highlighter-rouge&quot;&gt;TFP_IMAGE_SIZE&lt;/code&gt;): &lt;code class=&quot;highlighter-rouge&quot;&gt;128&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;160&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;192&lt;/code&gt;, or &lt;code class=&quot;highlighter-rouge&quot;&gt;224&lt;/code&gt; px. Unsurprisingly, feeding in a higher resolution image takes more processing time, but results in better classification accuracy. We recommend 224 as an initial setting.&lt;/li&gt;
  &lt;li&gt;The relative size (&lt;code class=&quot;highlighter-rouge&quot;&gt;TFP_RELATIVE_SIZE&lt;/code&gt;) of the model as a fraction of the largest MobileNet: &lt;code class=&quot;highlighter-rouge&quot;&gt;1.0&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;0.75&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;0.50&lt;/code&gt;, or &lt;code class=&quot;highlighter-rouge&quot;&gt;0.25&lt;/code&gt;. We recommend &lt;code class=&quot;highlighter-rouge&quot;&gt;0.5&lt;/code&gt; as an initial setting. The smaller models run significantly faster, at a cost of accuracy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s set these as shell environmental variables for the current terminal you are in. Just simply copy the following block, paste it in terminal, and run it:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export TFP_IMAGE_SIZE=&quot;224&quot;
export TFP_RELATIVE_SIZE=&quot;0.50&quot;
export TFP_ARCHITECTURE=&quot;mobilenet_${TFP_RELATIVE_SIZE}_${TFP_IMAGE_SIZE}&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s confirm that we’ve set these variables correctly (copy the following block, paste it in terminal, and run it):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;echo ${TFP_IMAGE_SIZE}
echo ${TFP_RELATIVE_SIZE}
echo ${TFP_ARCHITECTURE}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You shall see:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;244
0.50
mobilenet_0.5_224
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: if we wish to try out other MobileNet configuration options, just edit the environmental variable export scripts above and re-run.&lt;/p&gt;

&lt;h5 id=&quot;wait-what-if-i-want-to-use-inception-v3&quot;&gt;Wait, what if I want to use Inception V3?&lt;/h5&gt;

&lt;p&gt;In case you would like to use the Inception V3 architecture (instead of MobileNet), just simply do the following instead:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export TFP_ARCHITECTURE=&quot;inception_v3&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The retrain script we run later on only cares about the environmental variable &lt;code class=&quot;highlighter-rouge&quot;&gt;TFP_ARCHITECTURE&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id=&quot;configure-image-retrain-path&quot;&gt;Configure Image Retrain Path&lt;/h4&gt;

&lt;p&gt;We need to tell the retrain script where to find our training images (i.e. our 200 per category). By default the retrain script will use a split of 80% (160) train / 10% (20) validation / 10% (20) test, but we can alter that in our retrain script later.&lt;/p&gt;

&lt;p&gt;But first, we need to export one more environmental variable. i.e. the root directory name of the training images - which if you recall from step 2 on data preparation, it is &lt;code class=&quot;highlighter-rouge&quot;&gt;shrooms-train-200-each&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Copy the following line, paste it in terminal, and run it:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export TFP_IMAGES_DIR=&quot;shrooms-train-200-each&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;how-to-use-the-retrain-script&quot;&gt;How to use the retrain script&lt;/h4&gt;

&lt;p&gt;Ensure we are in the correct location:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ cd ~/repos/my-tensorflow-for-poets
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To see what options are there:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ python -m scripts.retrain -h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;do-the-training&quot;&gt;Do the training&lt;/h4&gt;

&lt;p&gt;Copy the following block, paste it in terminal, and run it (this will start the re-training). Notice we are using the environmental variables (&lt;code class=&quot;highlighter-rouge&quot;&gt;TFP_IMAGES_DIR&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;TFP_ARCHITECTURE&lt;/code&gt;) that we exported earlier. That’s the reason for setting up those environmental variables eariler.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python -m scripts.retrain \
  --image_dir=tf_files/${TFP_IMAGES_DIR} \
  --bottleneck_dir=tf_files/bottlenecks \
  --model_dir=tf_files/models/ \
  --summaries_dir=tf_files/training_summaries/basic/&quot;${TFP_ARCHITECTURE}&quot; \
  --output_graph=tf_files/retrained_graph.pb \
  --output_labels=tf_files/retrained_labels.txt \
  --how_many_training_steps=500 \
  --architecture=&quot;${TFP_ARCHITECTURE}&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A bit of explanation (with the help of the official Tensorflow for Poets tutorial)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;image_dir&lt;/code&gt;: this is where we’ve stored our training images. The directory must exist already. Otherwise the script will fail.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bottleneck_dir&lt;/code&gt;: A bottleneck is an informal term we often use for the layer just before the final output layer that actually does the classification. Every image is reused multiple times during training. Calculating the layers behind the bottleneck for each image takes a significant amount of time. Since these lower layers of the network are not being modified their outputs can be cached and reused. The directory will be automatically created.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;model_dir&lt;/code&gt;: The location where the “frozen” MobileNet models are downloaded. The directory will be automatically created.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;summaries_dir&lt;/code&gt;: the directory where tensorboard summaries will be saved to. Note our use of &lt;code class=&quot;highlighter-rouge&quot;&gt;${TFP_ARCHITECTURE}&lt;/code&gt; - if we are to try out a different MobileNet configuration option, the script will create a tensorboard summary without overwriting our old ones. The benefit of this option is to enable us to name-space our summary - so we can do some comparisons in our tuning step before commiting to the model(s) we want to use in production environment later on. We will see our training and validation summary in Tensorboard under the namespace called &lt;code class=&quot;highlighter-rouge&quot;&gt;basic/${TFP_ARCHITECTURE}&lt;/code&gt;. (as you will see shortly). One thing to mention now - later on if you want to perform hyperparameter tuning, you may wish to namespace the summary as &lt;code class=&quot;highlighter-rouge&quot;&gt;something-else/&quot;${TFP_ARCHITECTURE}&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;output_graph&lt;/code&gt;: this is our new (re)trained graph file. The prediction phase later on will need this. If we are to deploy our prediction model on an embedded device, this will likely just save a copy of this file to the device.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;output_labels&lt;/code&gt;: this file shows our ground truth labels - extracted from our &lt;code class=&quot;highlighter-rouge&quot;&gt;image_dir&lt;/code&gt; directory structure. The prediction phase later on will need this. If we are to deploy our prediction model on an embedded device, this will likely just save a copy of this file to the device.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;how_many_training_steps&lt;/code&gt;: the script will run for 4000 steps (aka epochs) by default. This may take 30 minutes. By reducing this to 500 steps, the script may complete within around 5 minutes on a modern CPU laptop, while giving us reasonable good accuracy (of around 85-95%.). Handy for what we are trying to achieve, which is to get from start to the end as quickly as possible, while producing an output that is reasonable good enough.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that most of these options have a default value and we don’t strictly need to specify all of them. I would highly recommend to take a good read of the retrain script, try and understand how it works and what it does, etc.&lt;/p&gt;

&lt;p&gt;One more thing to note, by default the script uses this split: 80% train / 10% validation / 10% test. Given we have 200 images per category, we will be using 160 for training, 20 for validation, and 20 for testing. We can however adjust this split accordingly by specifying options when running the script.&lt;/p&gt;

&lt;p&gt;Wait for the script to run. Should all go well we should get a final validation accuracy of somewhere between 85-95%.&lt;/p&gt;

&lt;h3 id=&quot;step-5-evaluation&quot;&gt;Step 5: Evaluation&lt;/h3&gt;

&lt;p&gt;Tensorboard is the place to go - to evaluate how good our retrained model is. The intuitions are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;training accuracy graph should be &lt;strong&gt;concave down and increasing&lt;/strong&gt; towards 100% as we perform more epochs (steps). See diagram below (bottom right).&lt;/li&gt;
  &lt;li&gt;training cross entropy should be &lt;strong&gt;concave up and decreasing&lt;/strong&gt; towards 0 as we perform more epochs (steps). See diagram below. (top left)&lt;/li&gt;
  &lt;li&gt;validation trend should closely resemble training trend. If the two lines deviate too much, it implies the model is not generic enough.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/shape-of-graph.gif&quot; alt=&quot;shape-of-graph.gif&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The above image was kindly borrowed from &lt;a href=&quot;http://tutorial.math.lamar.edu/Classes/CalcI/ShapeofGraphPtII.aspx&quot;&gt;Paul’s Online Math Notes&lt;/a&gt; - on the shape of a graph&lt;/p&gt;

&lt;h4 id=&quot;visualize-training-summary-on-tensorboard&quot;&gt;Visualize training summary on Tensorboard&lt;/h4&gt;

&lt;p&gt;If tensorboard is already running, navigate to &lt;a href=&quot;http://localhost:6006&quot;&gt;http://localhost:6006&lt;/a&gt; to visualize.&lt;/p&gt;

&lt;p&gt;Otherwise, copy the following block to a terminal, run it (to get tensorboard running)&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd ~/repos/my-tensorflow-for-poets
pkill -f &quot;tensorboard&quot;
tensorboard --logdir tf_files/training_summaries --host=localhost &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If it works, we shall see the accuracy chart (higher the better), cross entropy chart (lower the better), and other analysis.&lt;/p&gt;

&lt;p&gt;As this is our first attempt to this problem (without too much hyperparameter tuning), it should be expected that the validation result to be not as good as the training result. Despite that, we still get over 90% accuracy in our validation set (which is actually, pretty good considering we haven’t performed much tuning at this stage, and our restricted number of retraining image samples).&lt;/p&gt;

&lt;p&gt;Here are some snapshots from Tensorboard:&lt;/p&gt;

&lt;h5 id=&quot;accuracy-cross-entropy-and-more&quot;&gt;Accuracy, Cross Entropy, and more&lt;/h5&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/tensorboard-6a.png&quot; alt=&quot;tensorboard-6a.png&quot; /&gt;&lt;/p&gt;

&lt;h5 id=&quot;graph&quot;&gt;Graph&lt;/h5&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/tensorboard-6b.png&quot; alt=&quot;tensorboard-6b.png&quot; /&gt;&lt;/p&gt;

&lt;h5 id=&quot;distribution&quot;&gt;Distribution&lt;/h5&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/tensorboard-6c.png&quot; alt=&quot;tensorboard-6c.png&quot; /&gt;&lt;/p&gt;

&lt;h5 id=&quot;histogram&quot;&gt;Histogram&lt;/h5&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/tensorboard-6d.png&quot; alt=&quot;tensorboard-6d.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We shall do more deep dive into tensorboard at a later time. For now, let’s just say our main interests are the accuracy and cross entropy charts. (in fact, I would say accuracy is probably the most important one. We need high accuracy for both training and validation)&lt;/p&gt;

&lt;h3 id=&quot;step-6-hyperparameter-tuning&quot;&gt;Step 6: Hyperparameter Tuning&lt;/h3&gt;

&lt;p&gt;I would suggest for the purpose of this article we skip hyperparameter tuning for now. It deserves an article on its on - so let’s do this in a separate article.&lt;/p&gt;

&lt;p&gt;To see what options are there:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ cd ~/repos/my-tensorflow-for-poets
(py36-tf14) $ python -m scripts.retrain -h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To see the default values take a look at the retrain script (&lt;code class=&quot;highlighter-rouge&quot;&gt;~repos/my-tensorflow-for-poets/scripts/retrain.py&lt;/code&gt;) options and default values. This will give us some inspiration on some of the hyperparameters we may use for tuning. I’ve taken a look at the script myself and put my findings into the following table for ease of references (you may need to scroll right to see more).&lt;/p&gt;

&lt;div class=&quot;table-wrapper&quot;&gt;

  &lt;table&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;option&lt;/td&gt;
        &lt;td&gt;type&lt;/td&gt;
        &lt;td&gt;default value&lt;/td&gt;
        &lt;td&gt;description&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
    &lt;tfoot&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;image_dir&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;str&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;&quot;&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Path to folders of labeled images.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;output_graph&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;str&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;/tmp/output_graph.pb&quot; &lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Where to save the trained graph.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;intermediate_output_graphs_dir&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;str&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;/tmp/intermediate_graph/&quot;&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Where to save the intermediate graphs.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;intermediate_store_frequency&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;How many steps to store intermediate graph. If “0” then will not store.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;output_labels&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;str&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;/tmp/output_labels.txt&quot;&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Where to save the trained graph’s labels.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;summaries_dir&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;str&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;/tmp/retrain_logs&quot;&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Where to save summary logs for TensorBoard.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;how_many_training_steps&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;4000&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;How many training steps to run before ending.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;learning_rate&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;float&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;0.01&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;How large a learning rate to use when training.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;testing_percentage&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;10&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;What percentage of images to use as a test set.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;validation_percentage&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;10&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;What percentage of images to use as a validation set.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;eval_step_interval&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;10&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;How often to evaluate the training results.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;train_batch_size&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;100&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;How many images to train on at a time.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;test_batch_size&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-1&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;How many images to test on. This test set is only used once, to evaluate the final accuracy of the model after training completes. A value of -1 causes the entire test set to be used, which leads to more stable results across runs.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;validation_batch_size&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;100&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;How many images to use in an evaluation batch. This validation set is used much more often than the test set, and is an early indicator of how accurate the model is during training. A value of -1 causes the entire validation set to be used, which leads to more stable results across training iterations, but may be slower on large training sets.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;print_misclassified_test_images&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bool&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;False&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Whether to print out a list of all misclassified test images.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;model_dir&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;str&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;/tmp/imagenet&quot;&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Path to classify_image_graph_def.pb, imagenet_synset_to_human_label_map.txt, and &lt;code class=&quot;highlighter-rouge&quot;&gt;imagenet_2012_challenge_label_map_proto.pb&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bottleneck_dir&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;str&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;/tmp/bottleneck&quot;&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Path to cache bottleneck layer values as files.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;final_tensor_name&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;str&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;final_result&quot;&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;The name of the output classification layer in the retrained graph.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;flip_left_right&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bool&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;False&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;random_crop&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;A percentage determining how much of a margin to randomly crop off the training images.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;random_scale&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;A percentage determining how much to randomly scale up the size of the training images by&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;random_brightness&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;A percentage determining how much to randomly multiply the training image input pixels up or down by.&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;architecture&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;str&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;inception_v3&quot;&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Which model architecture to use. ‘inception_v3’ is the most accurate, but also the slowest. For faster or smaller models, chose a MobileNet with the form ‘mobilenet_&lt;parameter size=&quot;&quot;&gt;_&lt;input_size&gt;[_quantized]'. For example, 'mobilenet_1.0_224' will pick a model that is 17 MB in size and takes 224 pixel input images, while 'mobilenet_0.25_128_quantized' will choose a much less accurate, but smaller and faster network that's 920 KB on disk and takes 128x128 images. See [this link](https://research.googleblog.com/2017/06/mobilenets-open-source-models-for.html) for more information on Mobilenet.&lt;/input_size&gt;&lt;/parameter&gt;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tfoot&gt;
  &lt;/table&gt;

&lt;/div&gt;

&lt;h3 id=&quot;step-7-prediction&quot;&gt;Step 7: Prediction&lt;/h3&gt;

&lt;p&gt;Firs of all, make sure we are at the appropriate location:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ cd ~/repos/my-tensorflow-for-poets
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To perform a prediction we use the &lt;code class=&quot;highlighter-rouge&quot;&gt;label_image&lt;/code&gt; script (copy following block, paste in a terminal, and run it)&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python -m scripts.label_image \
    --graph=tf_files/retrained_graph.pb  \
    --image=tf_files/shrooms-demo-50-each/n13003061-fly-agaric/110269850_ea5678a3ef.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: the demo images in &lt;code class=&quot;highlighter-rouge&quot;&gt;tf_files/shrooms-demo-50-each/&lt;/code&gt; were not used in our training step earlier - so it should be fun to visualize.&lt;/p&gt;

&lt;p&gt;We should get an output like this in the terminal:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Evaluation time (1-image): 0.237s

n13003061 fly agaric 0.999988
n13040629 common stinkhorn 1.22072e-05
n13044778 earthstar 8.6851e-08
n13044375 giant puffball 3.17381e-08
n13030337 scarlet elf cup 1.16116e-08
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Yay! The image is a Fly Agaric, and the model predicted high confidence that it is a Fly Agaric (and low for other categories).&lt;/p&gt;

&lt;p&gt;Feel free also to take a look at what other options are out there:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ python -m scripts.label_image -h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;try-out-a-handful-of-prediction-manually&quot;&gt;try out a handful of prediction manually&lt;/h4&gt;

&lt;p&gt;Just to quickly see for ourself that our retrained model is what we would expect to see, let’s try perform predictions on a few more handful demo images! For the purpose of this article, I’m going to manually run the predict script one by one, for (say) 3 demo images per categories (for the 5 categories) - so we get an idea of our application outputs.&lt;/p&gt;

&lt;p&gt;Instead of printing the boring texts, I will manually do some “artistic” editing with PowerPoint - just to get the idea across a bit more effectively (this is to avoid performing excessive programming at such an early phase)&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-1a.png&quot; src=&quot;/images/blog/pred-1a.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-1b.png&quot; src=&quot;/images/blog/pred-1b.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-1c.png&quot; src=&quot;/images/blog/pred-1c.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-2a.png&quot; src=&quot;/images/blog/pred-2a.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-2b.png&quot; src=&quot;/images/blog/pred-2b.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-2c.png&quot; src=&quot;/images/blog/pred-2c.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-3a.png&quot; src=&quot;/images/blog/pred-3a.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-3b.png&quot; src=&quot;/images/blog/pred-3b.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-3c.png&quot; src=&quot;/images/blog/pred-3c.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-4a.png&quot; src=&quot;/images/blog/pred-4a.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-4b.png&quot; src=&quot;/images/blog/pred-4b.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-4c.png&quot; src=&quot;/images/blog/pred-4c.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-5a.png&quot; src=&quot;/images/blog/pred-5a.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-5b.png&quot; src=&quot;/images/blog/pred-5b.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;pred-5c.png&quot; src=&quot;/images/blog/pred-5c.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;One thing I’ve learnt about deep learning is that the prediction performance depends heavily on the training data. The model is more likely to be able to classify correctly / with high confidence when the test image contains features that are similar to the corresponding training images. The prediction confidence is likely low when the test image deviates a lot from the training image.&lt;/p&gt;

&lt;p&gt;One more thing, as we train on more categories (say 1000 instead of just 5), the prediction confidence will be less concentrated. i.e. if you feed in an image that is not a mushroom, but a car, hopefully it will provide very low probabilities across a range of mushroom labels, instead of just wrongly predict it is a “fly agaric” with high confidence. Just a theory.&lt;/p&gt;

&lt;h4 id=&quot;create-an-automated-prediction-process&quot;&gt;create an automated prediction process&lt;/h4&gt;

&lt;p&gt;It would be beneficial to have some kind of slide show type app that flash through the demo images one by one, or in batches, to show the prediction vs ground truth, along with the overall accuracy / errors. Sort of like &lt;a href=&quot;https://fungai-react-ui.herokuapp.com/fungpredict&quot;&gt;this ReactJS frontend demo&lt;/a&gt; but hopefully better! (This will be another project for another time.)&lt;/p&gt;

&lt;h4 id=&quot;potential-improvement-opportunities&quot;&gt;Potential Improvement Opportunities&lt;/h4&gt;

&lt;p&gt;Some ideas to jot down:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;study the tensorflow for poets retrain and prediction scripts. Could we use other better options?&lt;/li&gt;
  &lt;li&gt;an utility to enable user to upload photos and obtain prediction on the fly&lt;/li&gt;
  &lt;li&gt;hook up the retrained model to perform prediction offline? (e.g. rasberry pi, camera, Movidius Neural Compute stick?)&lt;/li&gt;
  &lt;li&gt;more automated / systematic way to regularly obtain more training images, perform retraining, update models?&lt;/li&gt;
  &lt;li&gt;A/B testing of different models?&lt;/li&gt;
  &lt;li&gt;video streaming and perform prediction on the fly?&lt;/li&gt;
  &lt;li&gt;perform training on more mushroom categories?&lt;/li&gt;
  &lt;li&gt;use crops to generate more data?&lt;/li&gt;
  &lt;li&gt;hyperparameter tuning?&lt;/li&gt;
  &lt;li&gt;YOLO?&lt;/li&gt;
  &lt;li&gt;Do some &lt;a href=&quot;http://yosinski.com/deepvis&quot;&gt;deepvis&lt;/a&gt; type visualization of the neural network?&lt;/li&gt;
  &lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;In this article we’ve had a go creating a basic wild mushroom classification app that performs image classification on 5 types of mushroom with the help of Google’s 7 steps to machine learning, and the Tensorflow for Poets Google lab. We’ve successfully performed a start-to-finish iteration on building our first app and gained some hands-on experiences. We’ve discussed some potential improvements and next steps that we may try out later on.&lt;/p&gt;

&lt;p&gt;Just to recall, here are the 7 steps to machine learning:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Gathering Data&lt;/li&gt;
  &lt;li&gt;Preparing that Data&lt;/li&gt;
  &lt;li&gt;Choosing a Model&lt;/li&gt;
  &lt;li&gt;Training&lt;/li&gt;
  &lt;li&gt;Evaluation&lt;/li&gt;
  &lt;li&gt;Hyperparameter Tuning&lt;/li&gt;
  &lt;li&gt;Prediction&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We will revisit Hyperparameter Tuning in a separate article. We will also try and improve our app further with automation and standardization etc.&lt;/p&gt;

&lt;p&gt;Congratulation. You’ve now gained some hands-on experience implementing transfer learning. I hope this will get you started on doing something even more exciting.&lt;/p&gt;</content><author><name>Johnny Chan</name></author><summary type="html">Train a basic image classification model to identify 5 types of wild mushrooms, with Transfer Learning, Tensorflow, Tensorboard, MobileNet, and ImageNet images. Inspired by the Tensorflow for Poets Google Lab.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://fungai.org/images/blog/mushroom-classifier-poc.png" /></entry><entry><title type="html">Download ImageNet Images by WordNet ID</title><link href="http://fungai.org/2017/12/12/download-imagenet-images-by-wnid/" rel="alternate" type="text/html" title="Download ImageNet Images by WordNet ID" /><published>2017-12-12T14:30:00+00:00</published><updated>2017-12-12T14:30:00+00:00</updated><id>http://fungai.org/2017/12/12/download-imagenet-images-by-wnid</id><content type="html" xml:base="http://fungai.org/2017/12/12/download-imagenet-images-by-wnid/">&lt;p&gt;From &lt;a href=&quot;/2017/12/11/tensorflow-for-poets/&quot;&gt;this earlier post&lt;/a&gt; we learnt to easily train a specialized image classification model with Transfer Learning without writing a single line of code. With the help of the retrain script provided by the Google Codelab &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#0&quot;&gt;Tensorflow for Poets&lt;/a&gt;, all we need is a directory structure containing directories of training images like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;|- my-training-images/
  |- daisy/
    |- some-image-1.jpg
    |- some-image-2.jpg
    |- some-image-3.jpg
  |- dandelion/
    |- some-image-4.jpg
    |- some-image-5.jpg
    |- some-image-6.jpg
  |- roses/
    |- some-image-7.jpg
    |- some-image-8.jpg
    |- some-image-9.jpg
  |- sunflowers/
    |- some-image-10.jpg
    |- some-image-11.jpg
    |- some-image-12.jpg
  |- tulip/
    |- some-image-13.jpg
    |- some-image-14.jpg
    |- some-image-15.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In summary:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;each sub-directory takes the name of the training image label (e.g. daisy)&lt;/li&gt;
  &lt;li&gt;within the sub-directory, we store the training images belong to that class. It doesn’t matter how we name these images as long as the images are stored within that folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;imagenet-intro&quot;&gt;ImageNet Intro&lt;/h3&gt;

&lt;p&gt;Say we’d like to obtain some training images of different types of mushrooms, one way to get these images is via &lt;a href=&quot;http://www.image-net.org/&quot;&gt;ImageNet&lt;/a&gt;. Here is the official description of the site:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;ImageNet is an image database organized according to the WordNet hierarchy (currently only the nouns), in which each node of the hierarchy is depicted by hundreds and thousands of images. Currently we have an average of over five hundred images per node. We hope ImageNet will become a useful resource for researchers, educators, students and all of you who share our passion for pictures.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each image category is represented in the form of WordNet ID, also known as &lt;code class=&quot;highlighter-rouge&quot;&gt;wnid&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;lookup-category-and-wnid&quot;&gt;Lookup Category and WNID&lt;/h3&gt;

&lt;p&gt;For starter, go to the &lt;a href=&quot;http://www.image-net.org/&quot;&gt;ImageNet website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Search for an image category that we want. Say, &lt;code class=&quot;highlighter-rouge&quot;&gt;fly agaric&lt;/code&gt; (a type of mushroom).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-1.png&quot; alt=&quot;imagenet-1.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-2.png&quot; alt=&quot;imagenet-2.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-3.png&quot; alt=&quot;imagenet-3.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Some observations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;we should see is a grid of Fly agaric images.&lt;/li&gt;
  &lt;li&gt;we should see the WNID of this category, from the URL: &lt;a href=&quot;http://www.image-net.org/synset?wnid=n13003061&quot;&gt;http://www.image-net.org/synset?wnid=n13003061&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, if we scoll down along the hierarchy bar on the left, we should eventually see our &lt;code class=&quot;highlighter-rouge&quot;&gt;fly agaric&lt;/code&gt; (note the nested structure).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-4.png&quot; alt=&quot;imagenet-4.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-5.png&quot; alt=&quot;imagenet-5.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-6.png&quot; alt=&quot;imagenet-6.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-7.png&quot; alt=&quot;imagenet-7.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-8.png&quot; alt=&quot;imagenet-8.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-9.png&quot; alt=&quot;imagenet-9.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Note above that our &lt;code class=&quot;highlighter-rouge&quot;&gt;fly agaric&lt;/code&gt; is highlighted in blue in the scroll bar.&lt;/p&gt;

&lt;p&gt;Let’s return to the main screen:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-3.png&quot; alt=&quot;imagenet-3.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Click on the Treemap Visualization tab:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-12.png&quot; alt=&quot;imagenet-12.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The above snapshot tells us that &lt;code class=&quot;highlighter-rouge&quot;&gt;fly agaric&lt;/code&gt; is a leaf node. i.e. there are no sub categories underneath this node. If we click on the icon on the top right, it will copy one WNID (n13003061) to the clipboard. (if however the category is not a leaf node clicking the icon will copy all the immediate child WNIDs underneath it as well. But that is another story to tell.)&lt;/p&gt;

&lt;p&gt;Now, if we click the Downloads tab, we may find the list of image URLs associated with this WNID:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-10.png&quot; alt=&quot;imagenet-10.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Click the URLs button will review the list of URLs. Note the API in address bar: &lt;a href=&quot;http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=n13003061&quot;&gt;http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=n13003061&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-11.png&quot; alt=&quot;imagenet-11.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This API is handy. Basically, by providing the API a &lt;code class=&quot;highlighter-rouge&quot;&gt;wnid&lt;/code&gt;, it returns the list of image URLs associated with that &lt;code class=&quot;highlighter-rouge&quot;&gt;wnid&lt;/code&gt;. If we copy a handful of URLs and paste it in a browser, we can see for ourselves the images are indeed &lt;code class=&quot;highlighter-rouge&quot;&gt;fly agaric&lt;/code&gt;. Warning: ImageNet is not perfect. There could be errors (hopefully small portion only). It’s constantly improving with its internal validation system.&lt;/p&gt;

&lt;h3 id=&quot;download-imagenet-images-by-wnid&quot;&gt;Download Imagenet Images by WNID&lt;/h3&gt;

&lt;p&gt;Now we know how to resolve &lt;code class=&quot;highlighter-rouge&quot;&gt;wnid&lt;/code&gt; from a name (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;fly agaric&lt;/code&gt;) via the ImageNet website, we can download the images for a desired &lt;code class=&quot;highlighter-rouge&quot;&gt;wnid&lt;/code&gt; with the help of this very handy tool called &lt;a href=&quot;https://github.com/tzutalin/ImageNet_Utils&quot;&gt;ImageNet_Utils&lt;/a&gt;, an open sourced tool published on Github developed by &lt;a href=&quot;https://github.com/tzutalin&quot;&gt;tzutalin&lt;/a&gt;. Follow the instructions to download images.&lt;/p&gt;

&lt;p&gt;Here are the steps that I follow to download images for &lt;code class=&quot;highlighter-rouge&quot;&gt;fly agaric&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;wnid = n13003061&lt;/code&gt;):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;git clone the repository:
 &lt;code class=&quot;highlighter-rouge&quot;&gt;$ git clone https://github.com/tzutalin/ImageNet_Utils&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;navigate into the repository:
 &lt;code class=&quot;highlighter-rouge&quot;&gt;$ cd ImageNet_Utils&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;the script seems to work well with Python 2.7 (and not so for Python 3.x). So let’s create an Anaconda python environment (feel free to use Python 3.x if you like. I used Python 3.6 originally and bumped into errors. So guessing the scripts aren’t Python 3.x compatible yet - maybe):
 &lt;code class=&quot;highlighter-rouge&quot;&gt;$ conda create py27p13 python=2.7.13&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;activate the conda environment (so we have Python 2.7 enabled in an isolated environment):
 &lt;code class=&quot;highlighter-rouge&quot;&gt;(py27p13) $ source activate py27p13&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;do a one-liner command:
 &lt;code class=&quot;highlighter-rouge&quot;&gt;(py27p13) $ ./downloadutils.py --downloadImages --wnid n13003061&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;this will start the download. Note that there may be errors / anomalies - which I will describe later.&lt;/li&gt;
  &lt;li&gt;the images will be saved to the repository: &lt;code class=&quot;highlighter-rouge&quot;&gt;./n13003061/n13003061_urlimages/&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;(at a later stage) move the entire image folder to somewhere else. Restructure it to make it suitable for our transfer learning exercise.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, move to somewhere else and restructure the directory like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;|- my-training-images/
  |- n13003061_fly_agaric
    |- image-1.jpg
    |- image-2.jpg
    |- etc...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;limitation-of-imagenet-image-download&quot;&gt;Limitation of ImageNet Image Download&lt;/h3&gt;

&lt;p&gt;So far I’ve come across some small anomalies / limitations of downloading images from ImageNet via URLs. This is not a significant general problems, thought it would be worth mentioning here.&lt;/p&gt;

&lt;h4 id=&quot;broken-url&quot;&gt;Broken URL&lt;/h4&gt;

&lt;p&gt;Say the URL is no longer valid, we may get errors like this during download (just some examples I’ve seen).&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;HTTP Error 403: Forbidden
HTTP Error 404: Not Found
Fail to download
&amp;lt;urlopen error [Errno 51] Network is unreachable&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The download script will simply print the error and move on to the next URL, and so on.&lt;/p&gt;

&lt;h4 id=&quot;flickr-dummy-image&quot;&gt;Flickr dummy image&lt;/h4&gt;

&lt;p&gt;When an image no longer exists on &lt;a href=&quot;https://www.flickr.com/&quot;&gt;Flickr&lt;/a&gt; (where some images are stored), you will see a dummy image that looks like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/flickr-dummy-image.jpg&quot; alt=&quot;flickr-dummy-image.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You will see quite a number of this. The strategy is to either remove them manually (by eye), or find a programmatic way to remove these later on.&lt;/p&gt;

&lt;p&gt;Update 2017-12-13: I just noticed image like this has a file size of about 2 KB. Most good images have a size of a least 40 KB. A quick win could be to do a sort by file size in the Mac finder window, and filter away the very small images, such as this.&lt;/p&gt;

&lt;h4 id=&quot;corrupted-image&quot;&gt;Corrupted Image&lt;/h4&gt;

&lt;p&gt;The download process is not perfect. Sometimes an image could be partially downloaded. For instance, when I click on one of this partially downloaded images, it just loads forever (or shows sign of errors). Such as this one:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blog/imagenet-partial-downloaded-image.png&quot; alt=&quot;imagenet-partial-downloaded-image.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;These images then to have really small file size, of less than 2 KB (as far as I could see).&lt;/p&gt;

&lt;p&gt;A quick win is probably to just filter out files like this. Only when have the time we then attempt download again in future.&lt;/p&gt;

&lt;h4 id=&quot;non-image-type&quot;&gt;Non Image Type&lt;/h4&gt;

&lt;p&gt;You’d also notice some files downloaded are not actually images (&lt;code class=&quot;highlighter-rouge&quot;&gt;.jpg&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;.png&lt;/code&gt;, etc), but text files (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;.php&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;.html&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;.txt&lt;/code&gt;, etc).&lt;/p&gt;

&lt;p&gt;This is probably due to some URLs are no longer valid and the server decided to respond with a text file instead of an image.&lt;/p&gt;

&lt;p&gt;This can be filtered away easily by file type. (do a sort in Mac finder, or programmatically using filename extension).&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;In this article we have:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;define our objective: to have a directory structure for storing training images, for performing transfer learning - as required by &lt;a href=&quot;/2017/12/11/tensorflow-for-poets/&quot;&gt;this earlier post&lt;/a&gt;, or Google Codelab &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#0&quot;&gt;Tensorflow for Poets&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;introduce &lt;a href=&quot;http://www.image-net.org/&quot;&gt;ImageNet&lt;/a&gt;: how to resolve WordNet ID (&lt;code class=&quot;highlighter-rouge&quot;&gt;wnid&lt;/code&gt;) given an image category name, and use the API to get the image URLs associated with the selected &lt;code class=&quot;highlighter-rouge&quot;&gt;wnid&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;introduce &lt;a href=&quot;https://github.com/tzutalin/ImageNet_Utils&quot;&gt;ImageNet_Utils&lt;/a&gt;, a handy tool to ease the ImageNet image download process. This downloads the images via URLs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next steps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;repeat the process above, and download training images per mushroom category (e.g. fly agaric, common stinkhorn, scarlet elf cup, etc.)&lt;/li&gt;
  &lt;li&gt;split the downloaded images into 3 sets: training, validation, and test. From the readme of &lt;a href=&quot;https://github.com/tzutalin/ImageNet_Utils&quot;&gt;ImageNet_Utils&lt;/a&gt;, the tool appears to have the feature to accomplish this too.&lt;/li&gt;
&lt;/ul&gt;</content><author><name>Johnny Chan</name></author><summary type="html">Download ImageNet images for Transfer Learning, with ImageNet-Utils</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://fungai.org/images/blog/imagenet-logo.png" /></entry><entry><title type="html">Tensorflow for Poets</title><link href="http://fungai.org/2017/12/11/tensorflow-for-poets/" rel="alternate" type="text/html" title="Tensorflow for Poets" /><published>2017-12-11T14:30:00+00:00</published><updated>2017-12-11T14:30:00+00:00</updated><id>http://fungai.org/2017/12/11/tensorflow-for-poets</id><content type="html" xml:base="http://fungai.org/2017/12/11/tensorflow-for-poets/">&lt;p&gt;In this article we build a Flower Image Recognition Model with Transfer Learning Techniques, Python 3.6.3, Tensorflow 1.4.1 and tensorflow-tensorboard v0.4.0rc3. This article is inspired by the &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#0&quot;&gt;Tensorflow for Poets&lt;/a&gt; transfer learning exercise.&lt;/p&gt;

&lt;p&gt;At the time of writing this, tensorflow is on version 1.4.1, which includes &lt;code class=&quot;highlighter-rouge&quot;&gt;tensorflow-tensorboard &lt;/code&gt; (version v0.4.0rc3). My development environment is a Macbook Pro (El Capitan) and Anaconda (for creating isolated Python environments).&lt;/p&gt;

&lt;h3 id=&quot;download-github-repository&quot;&gt;Download Github repository&lt;/h3&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git clone https://github.com/googlecodelabs/tensorflow-for-poets-2

$ cd tensorflow-for-poets-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;setup-python-environment&quot;&gt;Setup Python Environment&lt;/h3&gt;

&lt;p&gt;Create a conda environment with Anaconda (this may take a while):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ conda create --name py36-tf14 python=3.6 --channel conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Activate conda environment:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ source activate

$ source activate py36-tf14
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Install tensorflow with &lt;code class=&quot;highlighter-rouge&quot;&gt;pip&lt;/code&gt; (this will also automatically install &lt;code class=&quot;highlighter-rouge&quot;&gt;tensorflow-tensorboard&lt;/code&gt;):&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ pip install tensorflow
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Our conda environment should now look like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ conda list
# packages in environment at /Users/johnny/anaconda/envs/py36-tf14:
#
bleach                    1.5.0                     &amp;lt;pip&amp;gt;
ca-certificates           2017.11.5                     0    conda-forge
certifi                   2017.11.5                py36_0    conda-forge
enum34                    1.1.6                     &amp;lt;pip&amp;gt;
html5lib                  0.9999999                 &amp;lt;pip&amp;gt;
Markdown                  2.6.10                    &amp;lt;pip&amp;gt;
ncurses                   5.9                          10    conda-forge
numpy                     1.13.3                    &amp;lt;pip&amp;gt;
openssl                   1.0.2n                        0    conda-forge
pip                       9.0.1                    py36_0    conda-forge
protobuf                  3.5.0.post1               &amp;lt;pip&amp;gt;
python                    3.6.3                         4    conda-forge
readline                  7.0                           0    conda-forge
setuptools                38.2.4                   py36_0    conda-forge
six                       1.11.0                    &amp;lt;pip&amp;gt;
sqlite                    3.20.1                        0    conda-forge
tensorflow                1.4.1                     &amp;lt;pip&amp;gt;
tensorflow-tensorboard    0.4.0rc3                  &amp;lt;pip&amp;gt;
tk                        8.6.7                         0    conda-forge
Werkzeug                  0.13                      &amp;lt;pip&amp;gt;
wheel                     0.30.0                     py_1    conda-forge
xz                        5.2.3                         0    conda-forge
zlib                      1.2.11                        0    conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: at the time of writing this, &lt;code class=&quot;highlighter-rouge&quot;&gt;tensorflow v1.4.1&lt;/code&gt; seems to work well with &lt;code class=&quot;highlighter-rouge&quot;&gt;tensorflow-tensorboard v0.4.0rc3&lt;/code&gt; (aka tensorboard).&lt;/p&gt;

&lt;p&gt;Try and run tensorboard (if it works just keep it running).&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ tensorboard --logdir tf_files/training_summaries --host=localhost &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If it works, navigate to &lt;a href=&quot;http://localhost:6006&quot;&gt;http://localhost:6006 &lt;/a&gt; and see the TensorBoard frontend:&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-12&quot;&gt;&lt;img alt=&quot;tensorboard-1.png&quot; src=&quot;/images/blog/tensorboard-1.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Note: if we wish to re-run the above tensorboard command, make sure we kill the previously created tensorboard session, like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ pkill -f &quot;tensorboard&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note also: if you still have problem with tensorboard, checkout &lt;a href=&quot;https://github.com/tensorflow/tensorboard/issues/207&quot;&gt;this GitHub thread&lt;/a&gt; (scroll down see wchargin’s comment on 17th Aug 2017). Maybe we just need to upgrade both &lt;code class=&quot;highlighter-rouge&quot;&gt;tensorflow&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;tensorflow-tensorboard&lt;/code&gt; with pip.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ pip install --upgrade tensorflow tensorflow-tensorboard
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One more note, as time goes by, the version number of tensorflow is likely to increase. This article will install the latest version. Just to be safe, you might wish to explicitly &lt;a href=&quot;https://stackoverflow.com/questions/5226311/installing-specific-package-versions-with-pip&quot;&gt;specify the corresponding version number&lt;/a&gt; for tensorflow (likewise Python, etc.). e.g.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ pip install &quot;tensorflow==1.4.1&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;download-flower-pictures&quot;&gt;Download flower pictures&lt;/h3&gt;

&lt;p&gt;Make sure we are still at the root directory of the Github repository. i.e. the directory structure should look something like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ ls -l
total 40
-rw-r--r--   1 johnny  staff    969 Dec 11 14:08 CONTRIBUTING.md
-rw-r--r--   1 johnny  staff  11357 Dec 11 14:08 LICENSE
-rw-r--r--   1 johnny  staff   1373 Dec 11 14:08 README.md
drwxr-xr-x   4 johnny  staff    136 Dec 11 14:08 android
drwxr-xr-x  10 johnny  staff    340 Dec 11 14:08 scripts
drwxr-xr-x   5 johnny  staff    170 Dec 11 14:34 tf_files
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;By default there is an empty directory called &lt;code class=&quot;highlighter-rouge&quot;&gt;tf_filies&lt;/code&gt;. This is where the training images will be downloaded to.&lt;/p&gt;

&lt;p&gt;To download images do this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ curl http://download.tensorflow.org/example_images/flower_photos.tgz | tar xz -C tf_files
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This essentially:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;download the compressed file &lt;code class=&quot;highlighter-rouge&quot;&gt;flower_photos.tgz&lt;/code&gt; from the tensorflow website&lt;/li&gt;
  &lt;li&gt;extract the the file to &lt;code class=&quot;highlighter-rouge&quot;&gt;/tf_files&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;in the end we shall see a new directory &lt;code class=&quot;highlighter-rouge&quot;&gt;/tf_files/flower_photos&lt;/code&gt; which contains the training images of the flowers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s take a look at extracted directory:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ cd tf_files/flower_photos/
(py36-tf14) $ ls -l
total 824
-rw-r-----    1 johnny  staff  418049 Feb  9  2016 LICENSE.txt
drwx------  635 johnny  staff   21590 Feb 10  2016 daisy
drwx------  900 johnny  staff   30600 Feb 10  2016 dandelion
drwx------  643 johnny  staff   21862 Feb 10  2016 roses
drwx------  701 johnny  staff   23834 Feb 10  2016 sunflowers
drwx------  801 johnny  staff   27234 Feb 10  2016 tulips
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Observations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It contains 5 directories.&lt;/li&gt;
  &lt;li&gt;Each directory is named by the flower category (e.g. daisy, dandelion, roses, sunflowers, tublips).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a sample of what the images look like in each category:&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;h4&gt;daisy:&lt;/h4&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;daisy-1-294451721_5106537b34.jpg&quot; src=&quot;/images/blog/daisy-1-294451721_5106537b34.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;daisy-2-301964511_fab84ea1c1.jpg&quot; src=&quot;/images/blog/daisy-2-301964511_fab84ea1c1.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;daisy-3-daisy-3-299129811_d6ebda9970&quot; src=&quot;/images/blog/daisy-3-299129811_d6ebda9970.jpg&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;h4&gt;dandelion:&lt;/h4&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;dandelion-1-11405573_24a8a838cc_n.jpg&quot; src=&quot;/images/blog/dandelion-1-11405573_24a8a838cc_n.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;dandelion-2-163702807_e508544acd_n.jpg&quot; src=&quot;/images/blog/dandelion-2-163702807_e508544acd_n.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;dandelion-3-463736819_f779800165.jpg&quot; src=&quot;/images/blog/dandelion-3-463736819_f779800165.jpg&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;h4&gt;roses:&lt;/h4&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;rose-1-118974357_0faa23cce9_n.jpg&quot; src=&quot;/images/blog/rose-1-118974357_0faa23cce9_n.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;rose-2-12240303_80d87f77a3_n.jpg&quot; src=&quot;/images/blog/rose-2-12240303_80d87f77a3_n.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;rose-3-145862135_ab710de93c_n.jpg&quot; src=&quot;/images/blog/rose-3-145862135_ab710de93c_n.jpg&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;h4&gt;sunflowers:&lt;/h4&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;sunflowers-1-23204123212_ef32fbafbe.jpg&quot; src=&quot;/images/blog/sunflowers-1-23204123212_ef32fbafbe.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;sunflowers-2-22183521655_56221bf2a4_n.jpg&quot; src=&quot;/images/blog/sunflowers-2-22183521655_56221bf2a4_n.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;sunflowers-3-21518663809_3d69f5b995_n.jpg&quot; src=&quot;/images/blog/sunflowers-3-21518663809_3d69f5b995_n.jpg&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;h4&gt;tulips:&lt;/h4&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;tulips-1-130685347_afbffe3afa_n.jpg&quot; src=&quot;/images/blog/tulips-1-130685347_afbffe3afa_n.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;tulips-2-11746548_26b3256922_n.jpg&quot; src=&quot;/images/blog/tulips-2-11746548_26b3256922_n.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;tulips-3-112428665_d8f3632f36_n.jpg&quot; src=&quot;/images/blog/tulips-3-112428665_d8f3632f36_n.jpg&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&quot;configure-mobilenet&quot;&gt;Configure MobileNet&lt;/h3&gt;

&lt;p&gt;Follow the instruction &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#3&quot;&gt;Configure MobileNet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We have a choice of Inception V3 model (78% accuracy and 85MB) or MobileNet (70.5% accuracy and 19MB). We go for the lighter weight MobileNet.&lt;/p&gt;

&lt;p&gt;Here we get to choose two hyperparameters (stored as environmental variables). Note that I prefix the variables with &lt;code class=&quot;highlighter-rouge&quot;&gt;TFP_&lt;/code&gt; to indicate these are “&lt;strong&gt;T&lt;/strong&gt;ensor&lt;strong&gt;F&lt;/strong&gt;low for &lt;strong&gt;P&lt;/strong&gt;oet related”&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;TFP_IMAGE_SIZE&lt;/code&gt; (input image resolution): &lt;code class=&quot;highlighter-rouge&quot;&gt;128&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;160&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;192&lt;/code&gt;, or &lt;code class=&quot;highlighter-rouge&quot;&gt;224&lt;/code&gt; px. The recommended is 224px to start with. Higher resolution image takes more processing time, but results in better classification accuracy.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;TFP_RELATIVE_SIZE&lt;/code&gt; (The relative size of the model as a fraction of the largest MobileNet: &lt;code class=&quot;highlighter-rouge&quot;&gt;1.0&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;0.75&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;0.50&lt;/code&gt;, or &lt;code class=&quot;highlighter-rouge&quot;&gt;0.25&lt;/code&gt;. The recommended is &lt;code class=&quot;highlighter-rouge&quot;&gt;0.50&lt;/code&gt; to start with. The smaller models run significantly faster, at a cost of accuracy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s set these as shell environmental variables:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ export TFP_IMAGE_SIZE=&quot;224&quot;
(py36-tf14) $ export TFP_RELATIVE_SIZE=&quot;0.50&quot;
(py36-tf14) $ export TFP_ARCHITECTURE=&quot;mobilenet_${TFP_RELATIVE_SIZE}_${TFP_IMAGE_SIZE}&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s confirm that we’ve set these variables correctly:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ echo ${TFP_IMAGE_SIZE}
224

(py36-tf14) $ echo ${TFP_RELATIVE_SIZE}
0.50

(py36-tf14) $ echo ${TFP_ARCHITECTURE}
mobilenet_0.5_224
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;investigate-retraining-script&quot;&gt;Investigate retraining script&lt;/h3&gt;

&lt;p&gt;We are still at the root of the github repository.&lt;/p&gt;

&lt;p&gt;Let’s take a look at the transfer learning (i.e. re-training) script. See &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#3&quot;&gt;the original page&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;Note the script appears to support Python 3.5. It “should” be ok for Python 3.6 (which we are on currently). You may get some warning on this when you run python scripts (not critical).&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;python&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scripts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;retrain&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;usage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;retrain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image_dir&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMAGE_DIR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_graph&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OUTPUT_GRAPH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intermediate_output_graphs_dir&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INTERMEDIATE_OUTPUT_GRAPHS_DIR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intermediate_store_frequency&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INTERMEDIATE_STORE_FREQUENCY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_labels&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OUTPUT_LABELS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summaries_dir&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SUMMARIES_DIR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;how_many_training_steps&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HOW_MANY_TRAINING_STEPS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LEARNING_RATE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testing_percentage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TESTING_PERCENTAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validation_percentage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VALIDATION_PERCENTAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eval_step_interval&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EVAL_STEP_INTERVAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_batch_size&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TRAIN_BATCH_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_batch_size&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TEST_BATCH_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validation_batch_size&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VALIDATION_BATCH_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_misclassified_test_images&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_dir&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MODEL_DIR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bottleneck_dir&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BOTTLENECK_DIR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;final_tensor_name&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FINAL_TENSOR_NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flip_left_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_crop&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RANDOM_CROP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_scale&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RANDOM_SCALE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_brightness&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RANDOM_BRIGHTNESS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;p&quot;&gt;[--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;architecture&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ARCHITECTURE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;optional&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;exit&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image_dir&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMAGE_DIR&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;folders&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;labeled&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;images&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_graph&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OUTPUT_GRAPH&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;Where&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;save&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trained&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intermediate_output_graphs_dir&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INTERMEDIATE_OUTPUT_GRAPHS_DIR&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;Where&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;save&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intermediate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;graphs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intermediate_store_frequency&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INTERMEDIATE_STORE_FREQUENCY&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;How&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;many&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;steps&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intermediate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;0&quot;&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;will&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_labels&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OUTPUT_LABELS&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;Where&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;save&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trained&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'s labels.
  --summaries_dir SUMMARIES_DIR
                        Where to save summary logs for TensorBoard.
  --how_many_training_steps HOW_MANY_TRAINING_STEPS
                        How many training steps to run before ending.
  --learning_rate LEARNING_RATE
                        How large a learning rate to use when training.
  --testing_percentage TESTING_PERCENTAGE
                        What percentage of images to use as a test set.
  --validation_percentage VALIDATION_PERCENTAGE
                        What percentage of images to use as a validation set.
  --eval_step_interval EVAL_STEP_INTERVAL
                        How often to evaluate the training results.
  --train_batch_size TRAIN_BATCH_SIZE
                        How many images to train on at a time.
  --test_batch_size TEST_BATCH_SIZE
                        How many images to test on. This test set is only used
                        once, to evaluate the final accuracy of the model
                        after training completes. A value of -1 causes the
                        entire test set to be used, which leads to more stable
                        results across runs.
  --validation_batch_size VALIDATION_BATCH_SIZE
                        How many images to use in an evaluation batch. This
                        validation set is used much more often than the test
                        set, and is an early indicator of how accurate the
                        model is during training. A value of -1 causes the
                        entire validation set to be used, which leads to more
                        stable results across training iterations, but may be
                        slower on large training sets.
  --print_misclassified_test_images
                        Whether to print out a list of all misclassified test
                        images.
  --model_dir MODEL_DIR
                        Path to classify_image_graph_def.pb,
                        imagenet_synset_to_human_label_map.txt, and
                        imagenet_2012_challenge_label_map_proto.pbtxt.
  --bottleneck_dir BOTTLENECK_DIR
                        Path to cache bottleneck layer values as files.
  --final_tensor_name FINAL_TENSOR_NAME
                        The name of the output classification layer in the
                        retrained graph.
  --flip_left_right     Whether to randomly flip half of the training images
                        horizontally.
  --random_crop RANDOM_CROP
                        A percentage determining how much of a margin to
                        randomly crop off the training images.
  --random_scale RANDOM_SCALE
                        A percentage determining how much to randomly scale up
                        the size of the training images by.
  --random_brightness RANDOM_BRIGHTNESS
                        A percentage determining how much to randomly multiply
                        the training image input pixels up or down by.
  --architecture ARCHITECTURE
                        Which model architecture to use. '&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inception_v3&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' is the
                        most accurate, but also the slowest. For faster or
                        smaller models, chose a MobileNet with the form
                        '&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mobilenet_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_quantized&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'.
                        For example, '&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mobilenet_1&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_224&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' will pick a model
                        that is 17 MB in size and takes 224 pixel input
                        images, while '&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mobilenet_0&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;.25&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_128_quantized&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' will
                        choose a much less accurate, but smaller and faster
                        network that'&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;920&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KB&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;disk&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;takes&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x128&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;images&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;See&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;https&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;://&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;research&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;googleblog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2017&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mobilenets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;models&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;more&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;information&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;Mobilenet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you have read the script, you’d notice that it only accepts images in the JPEG format. i.e. any of these extensions are valid: &lt;code class=&quot;highlighter-rouge&quot;&gt;['jpg', 'jpeg', 'JPG', 'JPEG']&lt;/code&gt;. So beware.&lt;/p&gt;

&lt;h3 id=&quot;perform-the-re-training&quot;&gt;Perform the re-training&lt;/h3&gt;

&lt;p&gt;Before doing this, export one more environmental variable. i.e. the root directory of the training images.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export TFP_IMAGES_DIR=&quot;flower_photos&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Do this in one big command. Tweak the optional parameters as needed.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ python -m scripts.retrain \
  --bottleneck_dir=tf_files/bottlenecks \
  --how_many_training_steps=500 \
  --model_dir=tf_files/models/ \
  --summaries_dir=tf_files/training_summaries/&quot;${TFP_ARCHITECTURE}&quot; \
  --output_graph=tf_files/retrained_graph.pb \
  --output_labels=tf_files/retrained_labels.txt \
  --architecture=&quot;${TFP_ARCHITECTURE}&quot; \
  --image_dir=tf_files/${TFP_IMAGES_DIR}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will take about 5 minutes to run.&lt;/p&gt;

&lt;p&gt;Here is a snippet of the last few lines of the console log:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;INFO:tensorflow:2017-12-11 21:52:23.925171: Step 480: Train accuracy = 96.0%
INFO:tensorflow:2017-12-11 21:52:23.925308: Step 480: Cross entropy = 0.117489
INFO:tensorflow:2017-12-11 21:52:23.966271: Step 480: Validation accuracy = 87.0% (N=100)
INFO:tensorflow:2017-12-11 21:52:24.376953: Step 490: Train accuracy = 94.0%
INFO:tensorflow:2017-12-11 21:52:24.377087: Step 490: Cross entropy = 0.150749
INFO:tensorflow:2017-12-11 21:52:24.420469: Step 490: Validation accuracy = 88.0% (N=100)
INFO:tensorflow:2017-12-11 21:52:24.789445: Step 499: Train accuracy = 89.0%
INFO:tensorflow:2017-12-11 21:52:24.789592: Step 499: Cross entropy = 0.297373
INFO:tensorflow:2017-12-11 21:52:24.827349: Step 499: Validation accuracy = 90.0% (N=100)
INFO:tensorflow:Final test accuracy = 90.1% (N=362)
INFO:tensorflow:Froze 2 variables.
Converted 2 variables to const ops.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Test accuracy of 90%. This is probably top 5 accuracy. See this article &lt;a href=&quot;https://research.googleblog.com/2017/06/mobilenets-open-source-models-for.html&quot;&gt;MobileNets: Open-Source Models for Efficient On-Device Vision&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note also we now also have some new outputs at &lt;code class=&quot;highlighter-rouge&quot;&gt;tf_files&lt;/code&gt; directory:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ cd tf_files/
(py36-tf14) $ ls -l
total 10728
drwxr-xr-x  7 johnny  staff      238 Dec 11 21:51 bottlenecks
drwxr-x---  9 johnny  staff      306 Dec 11 14:34 flower_photos
drwxr-xr-x  4 johnny  staff      136 Dec 11 21:49 models
-rw-r--r--  1 johnny  staff  5488099 Dec 11 21:52 retrained_graph.pb
-rw-r--r--  1 johnny  staff       40 Dec 11 21:52 retrained_labels.txt
drwxr-xr-x  3 johnny  staff      102 Dec 11 21:49 training_summaries
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Take a look at Tensorboard at &lt;a href=&quot;http://localhost:6006/&quot;&gt;http://localhost:6006/&lt;/a&gt; which now displays the re-training summary.&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;tensorboard-2.png&quot; src=&quot;/images/blog/tensorboard-2.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;tensorboard-3.png&quot; src=&quot;/images/blog/tensorboard-3.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;tensorboard-4.png&quot; src=&quot;/images/blog/tensorboard-4.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;tensorboard-5.png&quot; src=&quot;/images/blog/tensorboard-5.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Now is probably a good time to take a break. Then come back, and try and understanding what is going on, before moving on to the next step. I would suggest to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;read through &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#3&quot;&gt;the rest of the original instruction on retraining the network&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;read the paper &lt;a href=&quot;http://www.cs.unc.edu/~wliu/papers/GoogLeNet.pdf&quot;&gt;Going Deeper with Convolutions&lt;/a&gt;. Remarks: it turns out image cropping increases performance marginally? Try work out number of parameters and computations required and ensure result matches the one in paper (for understanding).&lt;/li&gt;
  &lt;li&gt;navigate around Tensorboard. What the summary is trying to tell us?&lt;/li&gt;
  &lt;li&gt;study the training script &lt;code class=&quot;highlighter-rouge&quot;&gt;/scripts/retrain.py&lt;/code&gt;. What does it do exactly?&lt;/li&gt;
  &lt;li&gt;take a look at the newly created files at &lt;code class=&quot;highlighter-rouge&quot;&gt;/tf_files/&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/bottlenecks&lt;/code&gt; contain the images in the form of bottlenect values. i.e. each file has 1001 values.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the cached input values of the final layer is stored at &lt;code class=&quot;highlighter-rouge&quot;&gt;/tf_files/bottlenecks&lt;/code&gt; (these are generated once for reuse in the retraining phase&lt;/li&gt;
  &lt;li&gt;the retrained model (aka retrained graph) is now stored at &lt;code class=&quot;highlighter-rouge&quot;&gt;/tf_files/retrained_graph.pb&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;the retrained lables are stored in a file at &lt;code class=&quot;highlighter-rouge&quot;&gt;tf_files/retrained_labels.txt&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;perform-classification-inference&quot;&gt;Perform classification inference&lt;/h3&gt;

&lt;p&gt;The script that does this is &lt;code class=&quot;highlighter-rouge&quot;&gt;/scripts/label_image&lt;/code&gt;. The default options should be good enough but let’s take a look at these options anyway:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ python -m  scripts.label_image -h

usage: label_image.py [-h] [--image IMAGE] [--graph GRAPH] [--labels LABELS]
                      [--input_height INPUT_HEIGHT]
                      [--input_width INPUT_WIDTH] [--input_mean INPUT_MEAN]
                      [--input_std INPUT_STD] [--input_layer INPUT_LAYER]
                      [--output_layer OUTPUT_LAYER]

optional arguments:
  -h, --help            show this help message and exit
  --image IMAGE         image to be processed
  --graph GRAPH         graph/model to be executed
  --labels LABELS       name of file containing labels
  --input_height INPUT_HEIGHT
                        input height
  --input_width INPUT_WIDTH
                        input width
  --input_mean INPUT_MEAN
                        input mean
  --input_std INPUT_STD
                        input std
  --input_layer INPUT_LAYER
                        name of input layer
  --output_layer OUTPUT_LAYER
                        name of output layer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To perform inference for a test image do something like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python -m scripts.label_image \
    --graph=tf_files/retrained_graph.pb  \
    --image=tf_files/flower_photos/daisy/21652746_cc379e0eea_m.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ python -m scripts.label_image \
  --graph=tf_files/retrained_graph.pb  \
  --image=tf_files/flower_photos/daisy/21652746_cc379e0eea_m.jpg

Evaluation time (1-image): 0.267s

daisy 0.998764
dandelion 0.00100535
sunflowers 0.000216147
roses 1.42537e-05
tulips 6.22144e-07
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note it returns the top 5 (softmax) probabilities. Model is ~99% confident the image eis a daisy.&lt;/p&gt;

&lt;p&gt;Do the same for rose:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(py36-tf14) $ python -m scripts.label_image \
  --graph=tf_files/retrained_graph.pb  \
  --image=tf_files/flower_photos/roses/2414954629_3708a1a04d.jpg

Evaluation time (1-image): 0.244s

roses 0.954326
tulips 0.0456478
dandelion 1.27241e-05
daisy 1.15512e-05
sunflowers 1.34952e-06
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;what-next&quot;&gt;What next&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;try other hyperparameters&lt;/li&gt;
  &lt;li&gt;train on our own categories (e.g. fungi categories)&lt;/li&gt;
  &lt;li&gt;build a frontend for inferences. e.g.
    &lt;ul&gt;
      &lt;li&gt;web app&lt;/li&gt;
      &lt;li&gt;mobile app&lt;/li&gt;
      &lt;li&gt;video streaming / realtime classification app&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><author><name>Johnny Chan</name></author><summary type="html">Build a Flower Image Recognition Model with Transfer Learning Techniques, Python 3.6.3, Tensorflow 1.4.1 and tensorflow-tensorboard v0.4.0rc3.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://fungai.org/images/blog/daisy-1.jpg" /></entry><entry><title type="html">IDZ Interview</title><link href="http://fungai.org/2017/12/06/IDZ-interview-johnny-chan/" rel="alternate" type="text/html" title="IDZ Interview" /><published>2017-12-06T12:30:00+00:00</published><updated>2017-12-06T12:30:00+00:00</updated><id>http://fungai.org/2017/12/06/IDZ-interview-johnny-chan</id><content type="html" xml:base="http://fungai.org/2017/12/06/IDZ-interview-johnny-chan/">&lt;p&gt;Update 12th Dec 2017: this post is now &lt;a href=&quot;https://software.intel.com/en-us/blogs/2017/12/11/intel-software-innovator-johnny-chan-programmer-educator-and-open-source-enthusiast&quot;&gt;published at Intel Developer Zone&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;tell-us-about-your-background&quot;&gt;Tell us about your background.&lt;/h4&gt;

&lt;p&gt;Professionally I’ve been a technologist for a large global investment bank, an analytics consultant for a major UK commercial and private bank, a full-stack developer for a wellness startup, and briefly an engineering intern for an airline. In my spare time I am the creator and author of &lt;a href=&quot;http://mathalope.co.uk/&quot;&gt;Mathalope.co.uk&lt;/a&gt; (a tech blog visited by 120,000+ students and professionals from 180+ countries so far), volunteer developer of the &lt;a href=&quot;http://fordw.org/&quot;&gt;Friends of Russia Dock Woodland Website&lt;/a&gt;, open source software contributor, hackathon competitor, and part of the Intel Software Innovator Program. I am currently working on becoming a better machine learning engineer and educator.&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-3&quot;&gt;&lt;img alt=&quot;citi-1.jpg&quot; src=&quot;/images/blog/citi-1.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;cw-1.jpg&quot; src=&quot;/images/blog/cw-1.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-3&quot;&gt;&lt;img alt=&quot;rbs-1.jpg&quot; src=&quot;/images/blog/rbs-1.jpg&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h4 id=&quot;what-got-you-started-in-technology&quot;&gt;What got you started in technology?&lt;/h4&gt;

&lt;p&gt;When I was studying masters in aeronautical engineering at Imperial College London, I learnt to write small Fortran/Matlab programs where you could throw at it say satellite data, and it spit out geographical location on Earth. I then started my professional technology career in 2008 for a global investment bank, where I collaborated with colleagues from all 4 regions globally (EMEA, ASPAC, NAM and LATAM), developed and rolled-out a fully automated capacity planning and analytics tool, along with governance and processes - protecting the 100,000+ production systems (including Windows, UNIX, AIX, VM, and Mainframe platforms) from risk of overloading. I built the system with proprietary technologies such as SAS, Oracle, Autosys batch scheuling, Windows/UNIX scripts, and internal configuration databases. In 2014 I decided to learn about open source technologies in my spare time and as a result created &lt;a href=&quot;http://mathalope.co.uk/&quot;&gt;Mathalope.co.uk&lt;/a&gt;. Since then I’ve learnt to program in more than 10 languages, and my current favorites are Python and JavaScripts due to their expressiveness, syntax, and relevance to building modern applications. You can check out my &lt;a href=&quot;https://github.com/Atlas7/&quot;&gt;Github contributions here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since a year ago I also taught myself machine learning and parallel distributed computing with the help of &lt;a href=&quot;https://www.deeplearning.ai/&quot;&gt;deeplearning.ai&lt;/a&gt;, &lt;a href=&quot;https://www.coursera.org/learn/machine-learning&quot;&gt;Stanford Machine learning courses&lt;/a&gt;, Karpathy’s &lt;a href=&quot;http://cs231n.stanford.edu/&quot;&gt;Stanford cs231n Convolutional Nerual Networks for Visual Recognition&lt;/a&gt;, &lt;a href=&quot;https://colfaxresearch.com/how-series&quot;&gt;Colfax High Performance Computing Deep-dive series&lt;/a&gt;, and &lt;a href=&quot;https://github.com/ChristosChristofidis/awesome-deep-learning&quot;&gt;many other deep learning books and courses online&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;cert-stanford-ml-1.png&quot; src=&quot;/images/blog/cert-stanford-ml-1.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;cert-deeplearning-ai-1.png&quot; src=&quot;/images/blog/cert-deeplearning-ai-1.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-4&quot;&gt;&lt;img alt=&quot;cert-colfax-xeon-phi&quot; src=&quot;/images/blog/cert-colfax-xeon-phi.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h4 id=&quot;what-projects-are-you-working-on-now&quot;&gt;What projects are you working on now?&lt;/h4&gt;

&lt;p&gt;I am currently building &lt;a href=&quot;http://fungai.org/&quot;&gt;fungAI.org&lt;/a&gt; - a machine learning application with the aim of identifying wild mushroom species from images using deep learning techniques. The project was primarily inspired and motivated by a casual friend’s Facebook post from a walking trip:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“hey do you know what mushroom this is?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Coincidentally &lt;a href=&quot;https://twitter.com/lemon_disco&quot;&gt;my partner who is a conservationist&lt;/a&gt; happens also to be a mushroom enthusiast and so naturally we’ve formed a &lt;a href=&quot;http://fungai.org/team/&quot;&gt;couple’s team&lt;/a&gt;. We think the project will be fun and educational.&lt;/p&gt;

&lt;p&gt;You can &lt;a href=&quot;http://fungai.org/concept/&quot;&gt;read more about the project concept&lt;/a&gt;, try out an &lt;a href=&quot;https://fungai-react-ui.herokuapp.com/fungpredict&quot;&gt;initial ReactJS frontend toy demo&lt;/a&gt;, and check out this &lt;a href=&quot;https://devmesh.intel.com/projects/fungi-barbarian&quot;&gt;Intel DevMesh Fungi Barbarian Project page&lt;/a&gt;. All project source codes are open sourced on GitHub - you may find &lt;a href=&quot;http://fungai.org/demos/&quot;&gt;more Demos and Github repository links here&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;fungi-barbarian-concept-v2.png&quot; src=&quot;/images/blog/fungi-barbarian-concept-v2.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;fungai-poc-3.png&quot; src=&quot;/images/blog/fungai-poc-3.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;fungai-poc-1.png&quot; src=&quot;/images/blog/fungai-poc-1.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;fungai-poc-2.png&quot; src=&quot;/images/blog/fungai-poc-2.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h4 id=&quot;tell-us-about-a-technology-challenge-youve-had-to-overcome-in-a-project&quot;&gt;Tell us about a technology challenge you’ve had to overcome in a project.&lt;/h4&gt;

&lt;p&gt;During the summer of 2015 I spent the entire weekend just trying to get &lt;a href=&quot;https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_tutorials.html&quot;&gt;OpenCV-Python&lt;/a&gt;, Windows, and the &lt;a href=&quot;https://docs.anaconda.com/anaconda/&quot;&gt;Anaconda package manager&lt;/a&gt; to work together for a &lt;a href=&quot;https://www.youtube.com/watch?v=A0OFX6W1AcA&quot;&gt;personal computer vision project&lt;/a&gt;. I remember searching really hard on the internet for solutions, trying out many of them, and failed uncountable times. After many rounds of trial-and-errors and investigations I eventually solved the problem by combining multiple “partially working” solutions. In the end I decided to &lt;a href=&quot;http://mathalope.co.uk/2015/05/07/opencv-python-how-to-install-opencv-python-package-to-anaconda-windows/&quot;&gt;write an article summarising my solution via a blog post&lt;/a&gt; which has since been viewed more than 120,000 times. To increase the range of impact I also &lt;a href=&quot;https://stackoverflow.com/questions/23119413/how-do-i-install-python-opencv-through-conda#answer-30281466&quot;&gt;posted it as a solution to a Stackoverflow Forum&lt;/a&gt; - the forum has so far been viewed over 200,000 times and my solution has received 50+ “good citizen brownie points” upvotes. It turns out many developers around the world had also bumped into similar issues at the time and got the problem solved with the help of the articles.&lt;/p&gt;

&lt;p&gt;This experience has taught me an important lesson on making an impact: it doesn’t have to be building the next Google or Facebook - all it requires could be as simple as writing up a summary of how you’ve solved a problem and sharing it online. We only get to live once.&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-12&quot;&gt;&lt;img alt=&quot;opencv-conda-blog-comment-4.png&quot; src=&quot;/images/blog/opencv-conda-blog-comment-4.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h4 id=&quot;what-trends-do-you-see-happening-in-technology-in-the-near-future&quot;&gt;What trends do you see happening in technology in the near future?&lt;/h4&gt;

&lt;p&gt;A recent talk presented by &lt;a href=&quot;https://www.youtube.com/user/oreillymedia&quot;&gt;O’Reilly&lt;/a&gt; and &lt;a href=&quot;https://www.intelnervana.com/&quot;&gt;Intel Nervana&lt;/a&gt; in September 2017: &lt;a href=&quot;https://www.youtube.com/watch?v=NQK4ZY_gwKI&quot;&gt;AI is the New Electricity by Andrew Ng&lt;/a&gt; discussed the trends and value creation of machine learning. This is my one-liner summary taken from Andrew:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Today, vast majority of values across industry is created by Supervised Learning, and closely followed by Transfer Learning&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Personally, I am super excited about transfer learning and believe this technique will be used a lot in solving many specialized problems. Say we wish to &lt;a href=&quot;https://www.tensorflow.org/tutorials/image_retraining&quot;&gt;train a model to recognize different types of flowers&lt;/a&gt; for instance. Instead of having to spend months training a model from scratch with millions of flower images, we can take a very massive short-cut: take a pre-trained model like &lt;a href=&quot;https://www.kaggle.com/google-brain/inception-v3&quot;&gt;Inception v3&lt;/a&gt; that is already very good at regconising objects from &lt;a href=&quot;http://www.image-net.org/&quot;&gt;ImageNet data&lt;/a&gt;, use it as a starting point and train that more specialized flower recognition model from there. The end result? You only require about 200 images per flower category, and the training of a new model would take only about 30 minutes on a modern laptop on CPU.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This suddenly makes deep learning very inclusive to everybody&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An ultra powerful and expensive graphics processing unit (GPU) is no longer a “must have requirement” to solve deep learning problems. Transfer learning and open source software together have made deep learning more inclusive and accessible to all. The power of &lt;strong&gt;inclusiveness&lt;/strong&gt; will enable stronger communities, knowledge sharing, and further technological advancement of deep learning in the near future.&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;desk-1.jpg&quot; src=&quot;/images/blog/desk-1.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;mnist-1.jpg&quot; src=&quot;/images/blog/mnist-1.jpg&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h4 id=&quot;how-does-intel-help-you-succeed&quot;&gt;How does Intel help you succeed?&lt;/h4&gt;

&lt;p&gt;Intel supports innovative projects, such as &lt;a href=&quot;http://fungai.org&quot;&gt;fungAI.org&lt;/a&gt; that I’m currently working on, by providing access to state-of-the-art deep learning technologies: &lt;a href=&quot;https://www.intel.com/content/www/us/en/products/processors/xeon-phi/xeon-phi-processors.html&quot;&gt;Intel Xeon-Phi&lt;/a&gt; enabled cluster nodes for model training, &lt;a href=&quot;https://developer.movidius.com/&quot;&gt;Intel Movidius Neural Compute Stick&lt;/a&gt; for embedded machine learning applications, and more. At a personal level, Intel has provided me access to a community of technology experts and &lt;a href=&quot;https://software.intel.com/en-us/intel-software-innovators/meet-innovators&quot;&gt;innovators&lt;/a&gt; from artificial intelligence (AI), Internet of Things (IoT), virtual reality (VR), and Game Development  - where I get to learn and be inspired from. Recently I was sponsored by Intel to take part in events including the &lt;a href=&quot;https://software.intel.com/en-us/blogs/2016/12/02/intel-software-innovator-summit-2016&quot;&gt;Seattle Intel Software Innovator Summit 2016&lt;/a&gt; and Nuremberg Embedded World Expo 2017, where I had the opportunity to travel, learn, and contribute to the tech community. I really appreciate the amount of efforts the Intel Software Innovator Program team has put together in enabling long-term success of the innovation community. It has been a privilege and I thank you all for the opportunities.&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-12&quot;&gt;&lt;img alt=&quot;innovator-summit-2016-seattle-1.png&quot; src=&quot;/images/blog/innovator-summit-2016-seattle-1.png&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;innovator-summit-2016-seattle-2.png&quot; src=&quot;/images/blog/innovator-summit-2016-seattle-2.png&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;innovator-1.jpg&quot; src=&quot;/images/blog/innovator-1.jpg&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h4 id=&quot;outside-of-technology-what-type-of-hobbies-do-you-enjoy&quot;&gt;Outside of technology, what type of hobbies do you enjoy?&lt;/h4&gt;

&lt;p&gt;Since 2009 I’ve been playing social mixed-gender non-contact &lt;a href=&quot;http://www.in2touch.com/&quot;&gt;touch rugby&lt;/a&gt; and &lt;a href=&quot;http://www.trytagrugby.com/&quot;&gt;tag rugby&lt;/a&gt; leagues here in London. It’s a fun way to socialize and meet new friends in an active way. I would highly recommend this social sport to anybody.&lt;/p&gt;

&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-12&quot;&gt;&lt;img alt=&quot;touch-rugby-2.jpg&quot; src=&quot;/images/blog/touch-rugby-2.jpg&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;touch-rugby-4.jpg&quot; src=&quot;/images/blog/touch-rugby-4.jpg&quot; /&gt;&lt;/div&gt;
    &lt;div class=&quot;col-sm-6&quot;&gt;&lt;img alt=&quot;touch-rugby-3.jpg&quot; src=&quot;/images/blog/touch-rugby-3.jpg&quot; /&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;</content><author><name>Johnny Chan</name></author><summary type="html">Intel Developer Zone Interview</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://fungai.org/images/blog/avatar-jc.jpg" /></entry></feed>