Friday, November 8, 2019

I have a new blog!

New blog: https://shivangidas.github.io/blog

I made a progressive web app/blog with React.js. I am trying to post more often and applying the 'learn in public' rule :)

All new posts will be added there. It has a newsletter that you may want to subscribe to.
Here's the post on why I named it Overfitted and why I moved from blogger - https://shivangidas.github.io/blog/#/Overfitted



Monday, December 31, 2018

My 2018 in unordered lists

Places explored and loved:

  • Goa
  • Gokarna
  • Home
  • Delhi
  • Udaipur
  • Ooty
  • Surat, Bilimora
  • Mumbai
  • Halebeedu, Belur

All the books read:


Books loved and cherished:

  • When breath becomes air
  • Robot visions
  • The buried giant
  • The Hundred-Year-Old Man Who Climbed Out of the Window and Disappeared
  • Nation

Languages explored:

  • Node.js
  • Octave
  • Python
  • Tensorflow.js
  • Solidity
  • React.js

Things learnt/started:

  • Learnt and used Deep Learning
  • Made super cool Rest APIs
  • Unleashed the power of ORMs
  • Started exploring Ethereum
  • Published an online class
  • Wrote tech blogs (kind of) for the first time
  • Took boxing classes
  • Took Zumba classes
  • Practised Yoga  more often

Mistakes made:

  • Watched too many nonsensical reality shows
  • Didn't get into crypto soon enough
  • Postponed personal projects
  • Didn't learn about containers

Wednesday, November 14, 2018

Review: Death Note Box Set

Death Note Box Set Death Note Box Set by Tsugumi Ohba
My rating: 4 of 5 stars

The book is a masterpiece and I would love to give it five stars but I cannot overlook the fact that in the span of twelve books, no two named female characters have a conversation that's not about men, i.e., this series fails the bechdel test.

View all my reviews

Thursday, September 27, 2018

Review: The Guernsey Literary and Potato Peel Pie Society

The Guernsey Literary and Potato Peel Pie Society The Guernsey Literary and Potato Peel Pie Society by Mary Ann Shaffer
My rating: 5 of 5 stars

I thoroughly enjoyed reading this book. Yes, the characters are too black and white, yes the plot isn't much of a plot, and yes, the World War II cannot be felt, however, this a perfect book when you're home alone and sick in bed :)
And why can we not like perfect characters?! I absolutely love letters and this book gave me so many of them.

View all my reviews

Wednesday, September 26, 2018

Review: Robot Visions

Robot Visions Robot Visions by Isaac Asimov
My rating: 5 of 5 stars



View all my reviews

Review: Brave New World

Brave New World Brave New World by Aldous Huxley
My rating: 4 of 5 stars

In this Brave New World, society wants one to be happy. Happy by any means, by conditioning one to be satisfied by menial jobs, easy sex, meaningless lives... In case one doesn't agree, he/she is removed from society or ridiculed till they commit suicide... not quite different from the world today.

Makes me wonder what people sent away do? I would like to think it's something like 'Atlas Shrugged'.

View all my reviews

Monday, July 23, 2018

Using MobileNet with TensorFlow.js

What?

We are going to build an image classifier with MobileNet in TensorFlow js from scratch (installing python included)

Why?

I wanted to learn how to use a pre-trained model in javascript.

How?

Find complete code here and demo

Installing Python and TensorFlow

Follow this https://www.tensorflow.org/install/install_windows for windows installation.
  1. Download python 3.5 or 3.6. Version 3.7 will NOT work out as of July 2018. It doesn't download tensorflow js (henceforth referred to as tfjs)
  2. Run pip3 install --upgrade tensorflow (for CPU only)
    Or 
    pip3 install --upgrade tensorflow-gpu (for GPU)

Convert MobileNet model to tfjs model

  1. Get the MobileNet model from here
  2. This model is in tensorflow and needs to be converted to a tfjs model. Refer https://github.com/tensorflow/tfjs-converter

    tensorflowjs_converter \
        --input_format=tf_frozen_model \
        --output_node_names='MobilenetV1/Predictions/Reshape_1' \
        --saved_model_tags=serve \
        F:/image/image-
        classifier/mobilenet_v1_1.0_224/mobilenet_v1_1.0_224_frozen.pb \
        F:/image/image-classifier/modelv1
    

Load the frozen model

I use GitHub as a fast and dirty way to host static files. Upload your model to a GitHub repository and use the raw path in your code.

const MODEL_URL =
  "https://raw.githubusercontent.com/shivangidas/image-
  classifier/master/modelv1/tensorflowjs_model.pb";
const WEIGHTS_URL =
  "https://raw.githubusercontent.com/shivangidas/image-
  classifier/master/modelv1/weights_manifest.json";
let model;
(async () => {
  model = await tf.loadFrozenModel(MODEL_URL, WEIGHTS_URL);
})();

Get ImageNet classes

ImageNet Dataset has 1000 classes. You can read more here.

let IMAGENET_CLASSES = [];
$.getJSON(
    "https://raw.githubusercontent.com/shivangidas/image-
     classifier/master/mobilenet/imagenet_classes.json",
    function(data) {
      $.each(data, function(key, val) {
        IMAGENET_CLASSES.push(val);
      });
    }
  );

Make Predictions

  1. We get the image from the image tag. Refer full code for image selection part.
    let imageData = document.getElementById("imageSrc");
  2. Make tensor from the image using tfjs inbuilt function fromPixels()
    Resize the tensor to 224x224 and make the datatype float.
    The MobileNet version we are using (MobileNet_v1_1.0_224) takes an input of size [batchSize,224,224, 3]
  3. let pixels = tf.fromPixels(imageData)
                   .resizeNearestNeighbor([224, 224])
                   .toFloat();
  4. Normalize tensors to values between -1 and 1. Add a dimension as we have just one image to predict, no batch.
    let offset = tf.scalar(128);
    pixels = pixels.sub(offset).div(offset).expandDims();
  5. Call predict on the tensor
    const output = await model.predict(pixels);
  6. We get probabilities of 1000 classes.
    Sort and map to the classes we imported at the beginning.
    Here we are showing the top ten classes.

    const predictions = Array.from(output.dataSync())
                           .map(function(p, i) {
                              return {
                                probabilty: p,
                                classname: IMAGENET_CLASSES[i]
                              };
                           })
                           .sort((a, b) => b.probabilty - a.probabilty)
                           .slice(0, 10);
    
    console.log(predictions);
Putting it together:

let offset = tf.scalar(128);
let imageData = document.getElementById("imageSrc");
let pixels = tf.fromPixels(imageData)
               .resizeNearestNeighbor([224, 224])
               .toFloat();

pixels = pixels.sub(offset).div(offset).expandDims();
      
const output = await model.predict(pixels);
const predictions = Array.from(output.dataSync())
                         .map(function(p, i) {
                          return {
                            probabilty: p,
                            classname: IMAGENET_CLASSES[i]
                          };
                       })
                       .sort((a, b) => b.probabilty - a.probabilty)
                       .slice(0, 10);

console.log(predictions);

That's it!

Well not really. We are making 7 extra tensors that we need to dispose to prevent a memory leak. That means the tensors created will persist in GPU and take up space. I went to great lengths to dispose of them individually but if you come up with a better solution (maybe using tidy), do let me know.

References

All the links above