Created
May 26, 2018 17:17
-
-
Save anaisbetts/d7e349153c6d37e1f5db08e1a74ff5fe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @license | |
* Copyright 2018 Google LLC. All Rights Reserved. | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
* ============================================================================= | |
*/ | |
import * as tf from '@tensorflow/tfjs'; | |
import {MnistData} from './data'; | |
const model = tf.sequential(); | |
model.add(tf.layers.conv2d({ | |
inputShape: [28, 28, 1], | |
kernelSize: 5, | |
filters: 8, | |
strides: 1, | |
activation: 'relu', | |
kernelInitializer: 'varianceScaling' | |
})); | |
model.add(tf.layers.maxPooling2d({poolSize: [2, 2], strides: [2, 2]})); | |
model.add(tf.layers.conv2d({ | |
kernelSize: 5, | |
filters: 16, | |
strides: 1, | |
activation: 'relu', | |
kernelInitializer: 'varianceScaling' | |
})); | |
model.add(tf.layers.maxPooling2d({poolSize: [2, 2], strides: [2, 2]})); | |
model.add(tf.layers.flatten()); | |
model.add(tf.layers.dense( | |
{units: 10, kernelInitializer: 'varianceScaling', activation: 'softmax'})); | |
const LEARNING_RATE = 0.15; | |
const optimizer = tf.train.sgd(LEARNING_RATE); | |
model.compile({ | |
optimizer: optimizer, | |
loss: 'categoricalCrossentropy', | |
metrics: ['accuracy'], | |
}); | |
const BATCH_SIZE = 64; | |
const TRAIN_BATCHES = 150; | |
// Every few batches, test accuracy over many examples. Ideally, we'd compute | |
// accuracy over the whole test set, but for performance we'll use a subset. | |
const TEST_BATCH_SIZE = 1000; | |
const TEST_ITERATION_FREQUENCY = 5; | |
async function train() { | |
//ui.isTraining(); | |
const lossValues = []; | |
const accuracyValues = []; | |
for (let i = 0; i < TRAIN_BATCHES; i++) { | |
const batch = data.nextTrainBatch(BATCH_SIZE); | |
let testBatch; | |
let validationData; | |
// Every few batches test the accuracy of the mode. | |
if (i % TEST_ITERATION_FREQUENCY === 0) { | |
testBatch = data.nextTestBatch(TEST_BATCH_SIZE); | |
validationData = [ | |
testBatch.xs.reshape([TEST_BATCH_SIZE, 28, 28, 1]), testBatch.labels | |
]; | |
} | |
// The entire dataset doesn't fit into memory so we call fit repeatedly | |
// with batches. | |
const history = await model.fit( | |
batch.xs.reshape([BATCH_SIZE, 28, 28, 1]), batch.labels, | |
{batchSize: BATCH_SIZE, validationData, epochs: 1}); | |
const loss = history.history.loss[0]; | |
const accuracy = history.history.acc[0]; | |
// Plot loss / accuracy. | |
lossValues.push({'batch': i, 'loss': loss, 'set': 'train'}); | |
//ui.plotLosses(lossValues); | |
if (testBatch != null) { | |
accuracyValues.push({'batch': i, 'accuracy': accuracy, 'set': 'train'}); | |
//ui.plotAccuracies(accuracyValues); | |
} | |
batch.xs.dispose(); | |
batch.labels.dispose(); | |
if (testBatch != null) { | |
testBatch.xs.dispose(); | |
testBatch.labels.dispose(); | |
} | |
await tf.nextFrame(); | |
} | |
} | |
function showTestResults(batch, predictions, labels) { | |
const testExamples = batch.xs.shape[0]; | |
let totalCorrect = 0; | |
for (let i = 0; i < testExamples; i++) { | |
const prediction = predictions[i]; | |
const label = labels[i]; | |
const correct = prediction === label; | |
if (correct) totalCorrect++; | |
console.log(`pred: ${prediction} - ${correct}`); | |
} | |
console.log(`${totalCorrect}/${testExamples} => ${(totalCorrect/testExamples) * 100.0}% correct`); | |
} | |
async function showPredictions() { | |
const testExamples = 100; | |
const batch = data.nextTestBatch(testExamples); | |
tf.tidy(() => { | |
const output = model.predict(batch.xs.reshape([-1, 28, 28, 1])); | |
const axis = 1; | |
const labels = Array.from(batch.labels.argMax(axis).dataSync()); | |
const predictions = Array.from(output.argMax(axis).dataSync()); | |
showTestResults(batch, predictions, labels); | |
}); | |
} | |
let data; | |
async function load() { | |
data = new MnistData(); | |
await data.load(); | |
} | |
export async function mnist() { | |
await load(); | |
await train(); | |
showPredictions(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright 2016 The TensorFlow Authors. All Rights Reserved. | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
"""Convolutional Neural Network Estimator for MNIST, built with tf.layers.""" | |
from __future__ import absolute_import | |
from __future__ import division | |
from __future__ import print_function | |
import numpy as np | |
import tensorflow as tf | |
tf.logging.set_verbosity(tf.logging.INFO) | |
def cnn_model_fn(features, labels, mode): | |
"""Model function for CNN.""" | |
# Input Layer | |
# Reshape X to 4-D tensor: [batch_size, width, height, channels] | |
# MNIST images are 28x28 pixels, and have one color channel | |
input_layer = tf.reshape(features["x"], [-1, 28, 28, 1]) | |
# Convolutional Layer #1 | |
# Computes 32 features using a 5x5 filter with ReLU activation. | |
# Padding is added to preserve width and height. | |
# Input Tensor Shape: [batch_size, 28, 28, 1] | |
# Output Tensor Shape: [batch_size, 28, 28, 32] | |
conv1 = tf.layers.conv2d( | |
inputs=input_layer, | |
filters=32, | |
kernel_size=[5, 5], | |
padding="same", | |
activation=tf.nn.relu) | |
# Pooling Layer #1 | |
# First max pooling layer with a 2x2 filter and stride of 2 | |
# Input Tensor Shape: [batch_size, 28, 28, 32] | |
# Output Tensor Shape: [batch_size, 14, 14, 32] | |
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2) | |
# Convolutional Layer #2 | |
# Computes 64 features using a 5x5 filter. | |
# Padding is added to preserve width and height. | |
# Input Tensor Shape: [batch_size, 14, 14, 32] | |
# Output Tensor Shape: [batch_size, 14, 14, 64] | |
conv2 = tf.layers.conv2d( | |
inputs=pool1, | |
filters=64, | |
kernel_size=[5, 5], | |
padding="same", | |
activation=tf.nn.relu) | |
# Pooling Layer #2 | |
# Second max pooling layer with a 2x2 filter and stride of 2 | |
# Input Tensor Shape: [batch_size, 14, 14, 64] | |
# Output Tensor Shape: [batch_size, 7, 7, 64] | |
pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2) | |
# Flatten tensor into a batch of vectors | |
# Input Tensor Shape: [batch_size, 7, 7, 64] | |
# Output Tensor Shape: [batch_size, 7 * 7 * 64] | |
pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64]) | |
# Dense Layer | |
# Densely connected layer with 1024 neurons | |
# Input Tensor Shape: [batch_size, 7 * 7 * 64] | |
# Output Tensor Shape: [batch_size, 1024] | |
dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu) | |
# Add dropout operation; 0.6 probability that element will be kept | |
dropout = tf.layers.dropout( | |
inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN) | |
# Logits layer | |
# Input Tensor Shape: [batch_size, 1024] | |
# Output Tensor Shape: [batch_size, 10] | |
logits = tf.layers.dense(inputs=dropout, units=10) | |
predictions = { | |
# Generate predictions (for PREDICT and EVAL mode) | |
"classes": tf.argmax(input=logits, axis=1), | |
# Add `softmax_tensor` to the graph. It is used for PREDICT and by the | |
# `logging_hook`. | |
"probabilities": tf.nn.softmax(logits, name="softmax_tensor") | |
} | |
if mode == tf.estimator.ModeKeys.PREDICT: | |
return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions) | |
# Calculate Loss (for both TRAIN and EVAL modes) | |
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits) | |
# Configure the Training Op (for TRAIN mode) | |
if mode == tf.estimator.ModeKeys.TRAIN: | |
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001) | |
train_op = optimizer.minimize( | |
loss=loss, | |
global_step=tf.train.get_global_step()) | |
return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op) | |
# Add evaluation metrics (for EVAL mode) | |
eval_metric_ops = { | |
"accuracy": tf.metrics.accuracy( | |
labels=labels, predictions=predictions["classes"])} | |
return tf.estimator.EstimatorSpec( | |
mode=mode, loss=loss, eval_metric_ops=eval_metric_ops) | |
def main(unused_argv): | |
# Load training and eval data | |
mnist = tf.contrib.learn.datasets.load_dataset("mnist") | |
train_data = mnist.train.images # Returns np.array | |
train_labels = np.asarray(mnist.train.labels, dtype=np.int32) | |
eval_data = mnist.test.images # Returns np.array | |
eval_labels = np.asarray(mnist.test.labels, dtype=np.int32) | |
# Create the Estimator | |
mnist_classifier = tf.estimator.Estimator( | |
model_fn=cnn_model_fn, model_dir="/tmp/mnist_convnet_model") | |
# Set up logging for predictions | |
# Log the values in the "Softmax" tensor with label "probabilities" | |
tensors_to_log = {"probabilities": "softmax_tensor"} | |
logging_hook = tf.train.LoggingTensorHook( | |
tensors=tensors_to_log, every_n_iter=50) | |
# Train the model | |
train_input_fn = tf.estimator.inputs.numpy_input_fn( | |
x={"x": train_data}, | |
y=train_labels, | |
batch_size=100, | |
num_epochs=None, | |
shuffle=True) | |
mnist_classifier.train( | |
input_fn=train_input_fn, | |
steps=20000, | |
hooks=[logging_hook]) | |
# Evaluate the model and print results | |
eval_input_fn = tf.estimator.inputs.numpy_input_fn( | |
x={"x": eval_data}, | |
y=eval_labels, | |
num_epochs=1, | |
shuffle=False) | |
eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn) | |
print(eval_results) | |
if __name__ == "__main__": | |
tf.app.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment