Flowers Image Classification with TensorFlow on Cloud ML Engine

This notebook demonstrates how to do image classification from scratch on a flowers dataset using the Estimator API.


In [ ]:
import os
PROJECT = "cloud-training-demos" # REPLACE WITH YOUR PROJECT ID
BUCKET = "cloud-training-demos-ml" # REPLACE WITH YOUR BUCKET NAME
REGION = "us-central1" # REPLACE WITH YOUR BUCKET REGION e.g. us-central1
MODEL_TYPE = "cnn"

# do not change these
os.environ["PROJECT"] = PROJECT
os.environ["BUCKET"] = BUCKET
os.environ["REGION"] = REGION
os.environ["MODEL_TYPE"] = MODEL_TYPE
os.environ["TFVERSION"] = "1.13"  # Tensorflow version

In [ ]:
%%bash
gcloud config set project $PROJECT
gcloud config set compute/region $REGION

Input functions to read JPEG images

The key difference between this notebook and the MNIST one is in the input function. In the input function here, we are doing the following:

  • Reading JPEG images, rather than 2D integer arrays.
  • Reading in batches of batch_size images rather than slicing our in-memory structure to be batch_size images.
  • Resizing the images to the expected HEIGHT, WIDTH. Because this is a real-world dataset, the images are of different sizes. We need to preprocess the data to, at the very least, resize them to constant size.

Run as a Python module

Since we want to run our code on Cloud ML Engine, we've packaged it as a python module.

The model.py and task.py containing the model code is in flowersmodel

Complete the TODOs in model.py before proceeding!

Once you've completed the TODOs, run it locally for a few steps to test the code.


In [ ]:
%%bash
rm -rf flowersmodel.tar.gz flowers_trained
gcloud ai-platform local train \
    --module-name=flowersmodel.task \
    --package-path=${PWD}/flowersmodel \
    -- \
    --output_dir=${PWD}/flowers_trained \
    --train_steps=5 \
    --learning_rate=0.01 \
    --batch_size=2 \
    --model=$MODEL_TYPE \
    --augment \
    --train_data_path=gs://cloud-ml-data/img/flower_photos/train_set.csv \
    --eval_data_path=gs://cloud-ml-data/img/flower_photos/eval_set.csv

Now, let's do it on ML Engine. Note the --model parameter


In [ ]:
%%bash
OUTDIR=gs://${BUCKET}/flowers/trained_${MODEL_TYPE}
JOBNAME=flowers_${MODEL_TYPE}_$(date -u +%y%m%d_%H%M%S)
echo $OUTDIR $REGION $JOBNAME
gsutil -m rm -rf $OUTDIR
gcloud ai-platform jobs submit training $JOBNAME \
    --region=$REGION \
    --module-name=flowersmodel.task \
    --package-path=${PWD}/flowersmodel \
    --job-dir=$OUTDIR \
    --staging-bucket=gs://$BUCKET \
    --scale-tier=BASIC_GPU \
    --runtime-version=$TFVERSION \
    -- \
    --output_dir=$OUTDIR \
    --train_steps=1000 \
    --learning_rate=0.01 \
    --batch_size=40 \
    --model=$MODEL_TYPE \
    --augment \
    --batch_norm \
    --train_data_path=gs://cloud-ml-data/img/flower_photos/train_set.csv \
    --eval_data_path=gs://cloud-ml-data/img/flower_photos/eval_set.csv

Monitor training with TensorBoard

To activate TensorBoard within the JupyterLab UI navigate to "File" - "New Launcher". Then double-click the 'Tensorboard' icon on the bottom row.

TensorBoard 1 will appear in the new tab. Navigate through the three tabs to see the active TensorBoard. The 'Graphs' and 'Projector' tabs offer very interesting information including the ability to replay the tests.

You may close the TensorBoard tab when you are finished exploring.

Deploying and predicting with model

Deploy the model:


In [ ]:
%%bash
MODEL_NAME="flowers"
MODEL_VERSION=${MODEL_TYPE}
MODEL_LOCATION=$(gsutil ls gs://${BUCKET}/flowers/trained_${MODEL_TYPE}/export/exporter | tail -1)
echo "Deleting and deploying $MODEL_NAME $MODEL_VERSION from $MODEL_LOCATION ... this will take a few minutes"
#gcloud ai-platform versions delete --quiet ${MODEL_VERSION} --model ${MODEL_NAME}
#gcloud ai-platform models delete ${MODEL_NAME}
gcloud ai-platform models create ${MODEL_NAME} --regions $REGION
gcloud ai-platform versions create ${MODEL_VERSION} --model ${MODEL_NAME} --origin ${MODEL_LOCATION} --runtime-version=$TFVERSION

To predict with the model, let's take one of the example images that is available on Google Cloud Storage

The online prediction service expects images to be base64 encoded as described here.


In [ ]:
%%bash
IMAGE_URL=gs://cloud-ml-data/img/flower_photos/sunflowers/1022552002_2b93faf9e7_n.jpg

# Copy the image to local disk.
gsutil cp $IMAGE_URL flower.jpg

# Base64 encode and create request message in json format.
python -c 'import base64, sys, json; img = base64.b64encode(open("flower.jpg", "rb").read()).decode(); print(json.dumps({"image_bytes":{"b64": img}}))' &> request.json

Send it to the prediction service


In [ ]:
%%bash
gcloud ai-platform predict \
    --model=flowers \
    --version=${MODEL_TYPE} \
    --json-instances=./request.json
# Copyright 2017 Google Inc. 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.