* Creates a convolutional neural network (Convnet) for the MNIST data. * * @returns {tf.Model} An instance of tf.Model.
()
| 33 | * @returns {tf.Model} An instance of tf.Model. |
| 34 | */ |
| 35 | function createConvModel() { |
| 36 | // Create a sequential neural network model. tf.sequential provides an API |
| 37 | // for creating "stacked" models where the output from one layer is used as |
| 38 | // the input to the next layer. |
| 39 | const model = tf.sequential(); |
| 40 | |
| 41 | // The first layer of the convolutional neural network plays a dual role: |
| 42 | // it is both the input layer of the neural network and a layer that performs |
| 43 | // the first convolution operation on the input. It receives the 28x28 pixels |
| 44 | // black and white images. This input layer uses 16 filters with a kernel size |
| 45 | // of 5 pixels each. It uses a simple RELU activation function which pretty |
| 46 | // much just looks like this: __/ |
| 47 | model.add(tf.layers.conv2d({ |
| 48 | inputShape: [IMAGE_H, IMAGE_W, 1], |
| 49 | kernelSize: 3, |
| 50 | filters: 16, |
| 51 | activation: 'relu' |
| 52 | })); |
| 53 | |
| 54 | // After the first layer we include a MaxPooling layer. This acts as a sort of |
| 55 | // downsampling using max values in a region instead of averaging. |
| 56 | // https://www.quora.com/What-is-max-pooling-in-convolutional-neural-networks |
| 57 | model.add(tf.layers.maxPooling2d({poolSize: 2, strides: 2})); |
| 58 | |
| 59 | // Our third layer is another convolution, this time with 32 filters. |
| 60 | model.add(tf.layers.conv2d({kernelSize: 3, filters: 32, activation: 'relu'})); |
| 61 | |
| 62 | // Max pooling again. |
| 63 | model.add(tf.layers.maxPooling2d({poolSize: 2, strides: 2})); |
| 64 | |
| 65 | // Add another conv2d layer. |
| 66 | model.add(tf.layers.conv2d({kernelSize: 3, filters: 32, activation: 'relu'})); |
| 67 | |
| 68 | // Now we flatten the output from the 2D filters into a 1D vector to prepare |
| 69 | // it for input into our last layer. This is common practice when feeding |
| 70 | // higher dimensional data to a final classification output layer. |
| 71 | model.add(tf.layers.flatten({})); |
| 72 | |
| 73 | model.add(tf.layers.dense({units: 64, activation: 'relu'})); |
| 74 | |
| 75 | // Our last layer is a dense layer which has 10 output units, one for each |
| 76 | // output class (i.e. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9). Here the classes actually |
| 77 | // represent numbers, but it's the same idea if you had classes that |
| 78 | // represented other entities like dogs and cats (two output classes: 0, 1). |
| 79 | // We use the softmax function as the activation for the output layer as it |
| 80 | // creates a probability distribution over our 10 classes so their output |
| 81 | // values sum to 1. |
| 82 | model.add(tf.layers.dense({units: 10, activation: 'softmax'})); |
| 83 | |
| 84 | return model; |
| 85 | } |
| 86 | |
| 87 | /** |
| 88 | * Creates a model consisting of only flatten, dense and dropout layers. |