In this article, I will quickly show you how to use KerAS to train a simple CNN (convolutional neural network) to recognize MNIST (a handwritten numeric data set) and apply the trained network to a Web browser.

The DEMO address: starkwang. Making. IO/keras – js – DE…


Zero. Preparation

First, you need to install Keras on your computer. Please refer to the official Keras documentation for details


A quick start

First of all, IT is highly recommended to read MNIST For ML Beginners in the official documentation of Tensorflow, which is the Chinese translation of geek Academy

MNIST is a popular entry-level machine learning/computer vision dataset that contains various handwritten digital images from 0 to 9:

Each image is 28 * 28 in size and is represented by a 28 * 28 two-dimensional array. In other words, each image is made up of 784 pixels, each pixel having a value between 0 and 255.

For example, here is a “3” :

000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 038 043 105 255 253 253 253 253 253 174 006 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 105 255 253 253 253 253 174 006 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 043 139 224 226 252 253 252 252 252 252 252 252 158 014 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 178 252 252 252 252 252 253 252 252 252 252 252 252 252 059 000 000 000 000 000 000 000 000 000 000 000 000 000 000 109 252 252 230 132 133 132 132 189 252 252 252 252 059 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 004 029 029 024 000 000 000 000 000 014 226 252 252 172 007 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 085 243 252 252 144 000 000 000 000 000 000 000 000 000 000 000 000 000 000 088 189 252 252 252 014 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 091 212 247 252 252 252 204 009 000 000 000 000 000 000 000 000 000 000 000 000 000 000 032 125 193 193 193 253 252 252 238 102 028 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 045 222 252 252 252 252 253 252 252 252 177 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 045 223 253 253 253 253 255 253 253 253 253 074 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 031 123 052 044 044 044 044 143 252 252 074 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 015 252 252 074 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 086 252 252 074 000 000 000 000 000 000 000 000 000 000 000 000 000 000 005 075 009 000 000 000 000 000 000 098 242 252 252 074 000 000 000 000 000 000 000 000 000 000 000 000 000 061 183 252 029 000 000 000 000 000 018 092 239 252 252 243 065 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 208 252 252 147 134 134 134 134 203 253 252 188 083 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 208 252 252 252 252 252 252 252 252 252 252 252 252 252 252 252 253 230 153 008 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 049 157 252 252 252 252 252 217 207 146 045 000 000 000 000 000 000 000 000 000 000 007 103 235 252 172 103 024 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000Copy the code

Using KerAS, it is easy to import MNIST datasets:

from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
Copy the code

In general, the network model we want to obtain has a fixed input and output:

  • The input is a 28 by 28 two-dimensional integer array
  • The output is an array of length 10, representing the possibilities from 0 to 9 (for example, if there is an image with 80% probability 1 and 20% probability 7, the array is[0, 0.8, 0, 0, 0, 0, 0, 0, 0.2, 0, 0])

Second, use kerAS training network

The model we want to train consists of the following layers of networks:

  1. The convolution layer of 32 3×3 convolution kernels
  2. The convolution layer of 64 3×3 convolution kernels
  3. Pooling layer whose sampling factor is (2, 2)
  4. Dropout layer
  5. Flatten layer
  6. ReLu full connection layer
  7. Dropout layer
  8. Softmax full connection layer

It is very convenient to use KERas to train a CNN network to recognize MNIST. Here is an official example (source here) :

from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K

batch_size = 128
num_classes = 10
epochs = 12

# input image dimensions
img_rows, img_cols = 28.28

# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0].1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0].1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0].'train samples')
print(x_test.shape[0].'test samples')

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()
model.add(Conv2D(32, kernel_size=(3.3),
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, (3.3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2.2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

# Save model
model.save('myMnistCNN.h5')
Copy the code

If you already have Keras installed, just run it:

python mnist_cnn.py
Copy the code

3. Transform the output model

After obtaining the trained.h5 file, the model cannot be used directly because we need to transcode it. Keras-js provides a Python script to do this automatically:

python ./python/encoder.py -q myMnistCNN.h5
Copy the code

This script converts the.h5 file into a keras-js readable format that contains all the models and parameters of the trained neural network.

Import the model using Keras-js

First we need to introduce keras-js, which can be introduced directly with the script tag:

<script src="https://unpkg.com/keras-js"></script>
Copy the code

It can also be introduced by using webpack build after NPM installation, referencehere

To create a Model, keras-JS will automatically load the corresponding bin file:

const model = new KerasJS.Model({
    filepath: '/path/to/mnist_cnn.bin'.gpu: true.transferLayerOutputs: true
})
Copy the code

After initialization, it can be used for MNIST recognition. The input is an array with a length of 784 (including gray values of 28*28 pixels), and the output is an array with a length of 10 (probability of 0-9) :

(Use the “3” data example given above.)

model
  .ready()
  .then((a)= > {
    // Data is an array of 784 lengths, with each entry between 0 and 255
    // Here we need to convert the array to Float32
    const inputData = new Float32Array(data)
    / / recognition
    return model.predict(inputData)
  })
  .then(outputData= > {
    // The probability that the output is 0-9, for example:
    // {output: [0, 0, 0, 0.8, 0, 0, 0.2, 0, 0, 0]}
  })
  .catch(err= > {
    // ...
  })
Copy the code

5. Canvas implements a writing board

The last step is to implement a script board, which I won’t show you the actual code. The main thing is to use mousedown, Mousemove, and Mouseup events to draw graphics.

After drawing, call ctx.getImageData to get the pixel data in canvas. Each pixel corresponds to four values, which are the RGBA value of each point in turn. After processing, a gray array with a length of 784 can be obtained. Then use the model. Predict mentioned above.