1 of 73

Your phone is learning!

Introduction to Tensorflow on Android

Bartosz Kraszewski

about.me/bartoszk

2 of 73

About me

  • Bartosz Kraszewski
  • Android Team Leader @softwarehut.com
  • AI Enthusiast

3 of 73

What is Machine Learning?

4 of 73

“Machine learning is the science of getting computers to act without being explicitly programmed.” – Stanford

5 of 73

“Machine learning is based on algorithms that can learn from data without relying on rules-based programming.”- McKinsey & Co.

6 of 73

Example

Image classification

(Food Recognition)

It's a cat!

7 of 73

Another example

Face emotion recognition

8 of 73

Something from my phone

9 of 73

Let’s imagine complex system using ML

Collect Data

Label Data

Train Model

Export to cloud

Export to mobile

10 of 73

Google Sketch

11 of 73

Captcha

12 of 73

Use trained model in production

Input test data

Trained Model

Output decision

13 of 73

What’s mobile developer part in this process?

Just give me data

Just use my model

No questions!

14 of 73

Start career in Data Science

  • Get PHD in Math
  • Become Data Scientist

15 of 73

Start career in Data Science

  • Get PHD in Math
  • Become Data Scientist

16 of 73

We are still part of a process!

17 of 73

Online Courses!

18 of 73

How mobile world meet Machine Learning?

19 of 73

Introduction to Tensorflow

20 of 73

Tensorflow

  • Framework for Machine Learning and Deep Learning
  • Numerical operation library
  • Visualize process by Data Flow Graphs

21 of 73

  • Available for Android, IOS, Raspberry PI

22 of 73

  • Name comes from Tensor - geometrical representation of scalar, vector and matrix

23 of 73

Google Samples for Tensorflow

  • TF Classify
  • TF Detect
  • TF Stylize

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android

24 of 73

25 of 73

TF Classify

26 of 73

TF Detect

27 of 73

TF Stylize

28 of 73

Want more?

  • Let’s create our own smart app!

29 of 73

30 of 73

Mnist Data Set

60k training images, 10k test images

31 of 73

Number representation

28x28 2d float array flattened to 784 elements array with grayscale values:

0.0 - white pixel, 1.0- black pixel

also has antialiasing supported

32 of 73

Model Representation

0

1

2

783

0

1

2

3

4

5

6

7

8

9

Class index, probability (0, 1)

Pixel address, color value (0, 1.0)

33 of 73

Model Representation

0

1

2

783

0 - 0.0

1 - 0.0

2 - 0.0

3 - 0.0

4 - 0.997

5 - 0.01

6 - 0.001

7 - 0.0

8 - 0.0

9 - 0.0

Class index, probability (0, 1)

Pixel address, color value (0.0, 1.0)

Magic

Dragons

Even more magic

34 of 73

Model source

  • Convolutional Neural Network with 97.3% accuracy
  • https://www.tensorflow.org/tutorials/layers

35 of 73

36 of 73

Step one - Android Studio

  • New project
  • Add NDK Support
  • Add tensorflow library

implementation 'org.tensorflow:tensorflow-android:+'

  • For simple project - no need to create cmake files, setup bazel etc

37 of 73

Step two - Implement UI

38 of 73

Create custom draw component

public class DrawingView extends View {

private Bitmap bitmap;

private Canvas canvas;

private Path path;

private Paint bitmapPaint;

private Paint paint;

public DrawingView(Context c, AttributeSet set) {

super(c, set);

path = new Path();

bitmapPaint = new Paint(Paint.DITHER_FLAG);

}

39 of 73

https://github.com/bkraszewski/MachineLearningDemo

40 of 73

Step three - load model

executor.execute(() -> {

try {

classifier = Classifier.create(getApplicationContext().getAssets(),

MODEL_FILE,

LABEL_FILE,

INPUT_SIZE,

INPUT_NAME,

OUTPUT_NAME);

} catch (final Exception e) {

throw new RuntimeException("Error initializing TensorFlow!", e);

}

});

41 of 73

Initialization params

INPUT_SIZE = 28;

INPUT_NAME = "input";

OUTPUT_NAME = "output";

MODEL_FILE = "file:///android_asset/expert-graph.pb";

LABEL_FILE = "file:///android_asset/labels.txt";

42 of 73

Step fourth - initialize classifier

Classifier classifier = new Classifier();

classifier.tfHelper = new TensorFlowInferenceInterface(assetManager, modelPath);

43 of 73

Let’s prepare data...

44 of 73

How Android Stores bitmap?

ARGB - 32 bit integer

Alpha: 0 - 255

Red: 0 - 255

Green: 0 - 255

Blue: 0 - 255

In Hex: #FFFF0000

45 of 73

What data classifier requires?

46 of 73

Step fifth - convert bitmap to Tensor

Bitmap original = drawingView.getBitmap();

Bitmap scaled = Bitmap.createScaledBitmap(original, 28, 28, false);

int width = 28;

int[] pixels = new int[width * width];

scaled.getPixels(pixels, 0, width, 0, 0, width, width);

47 of 73

private float[] createInputPixels(int[] pixels) {

float[] normalized = ColorConverter.convertToTfFormat(pixels);

return normalized;

}

48 of 73

Read color values

for (int i = 0; i < argbPixels.length; i++) {

int aargbPixel = argbPixels[i];

int alpha = (aargbPixel >> 24) & 0xff;

int r = (aargbPixel >> 16) & 0xff;

int g = (aargbPixel >> 8) & 0xff;

int b = aargbPixel & 0xff;

}

49 of 73

Ignore transparent pixels

if (alpha == 0) {

ret[i] = 0.0f;

continue;

}

50 of 73

Convert to grayscale

int avg = (r + g + b) / 3;

51 of 73

Convert to float and add alpha

float grayscaled = avg / 255.0f;

withAlpha = grayscaled * (alpha / 255.0f);

52 of 73

Invert value

ret[i] = 1.0f - grayscaled;

53 of 73

Let’s unit test converter!

54 of 73

int[] blackPixels = new int[4];

for (int a = 0; a < blackPixels.length; a++) {

blackPixels[a] = Color.BLACK;

}

float[] tfInput = ColorConverter.convertToTfFormat(blackPixels);

assertEquals(blackPixels.length, tfInput.length);

for (int a = 0; a < tfInput.length; a++) {

assertEquals(1.0f, tfInput[a], ACCEPTED_DELTA);

}

55 of 73

int[] blackPixels = new int[4];

for (int a = 0; a < blackPixels.length; a++) {

blackPixels[a] = Color.BLACK;

}

float[] tfInput = ColorConverter.convertToTfFormat(blackPixels);

assertEquals(blackPixels.length, tfInput.length);

for (int a = 0; a < tfInput.length; a++) {

assertEquals(1.0f, tfInput[a], ACCEPTED_DELTA);

}

56 of 73

Step sixth - communicate with model

final float[] pixels …

tfHelper.feed(inputName, pixels,

inputSize * inputSize);

tfHelper.run(outputNames);

tfHelper.fetch(outputName, output);

57 of 73

Step sixth - communicate with model

final float[] pixels …

tfHelper.feed(inputName, pixels,

inputSize * inputSize);

tfHelper.run(outputNames);

tfHelper.fetch(outputName, output);

58 of 73

Step sixth - communicate with model

final float[] pixels …

tfHelper.feed(inputName, pixels,

inputSize * inputSize);

tfHelper.run(outputNames);

tfHelper.fetch(outputName, output);

59 of 73

Tensorflow data type: Tensor

N dimensional array of data type

Each Tensor has:

  • Data type: float32, int32, string
  • Rank:
    • 0d - scalar - simple value: 1 or 5 or 999
    • 1d - vector - simple array: [1, 2]
    • 2d - matrix - simple 2d array [[0,1], [1,2]]
  • Shape
    • Number of elements in each dimensions

60 of 73

61 of 73

Let’s use theory

public Classification recognize(final float[] pixels) {

tfHelper.feed(inputName, pixels, inputSize * inputSize);

Rank 1 Tensor

Shape of tensor is 28 * 28 = 784

62 of 73

Step sixth - display classification results

Classification classification = classifier.recognize(retPixels);

String result = String.format("It’s a %s with conf: %f", classification.getLabel(), classification.getConf());

Toast.makeText(this, result, Toast.LENGTH_SHORT).show();

63 of 73

64 of 73

It's working!

65 of 73

Let me do some Machine Learning...

66 of 73

Install Tensorflow

  • Follow instructions:
  • https://www.tensorflow.org/install/
  • Python is required
  • Nvidia CUDA GPU processing is optional

67 of 73

Hello world

import tensorflow as tf

hello = tf.constant('Hello,TensorFlow!')

sess = tf.Session()

print(sess.run(hello))

68 of 73

Experiment with existing implementations:

69 of 73

Export model to .pb format

70 of 73

Android Demo App:

https://github.com/bkraszewski/MachineLearningDemo

71 of 73

Interesting materials

72 of 73

Explore, experiment, ask why?

73 of 73

Thanks!