Some students may be confused when learning machine learning, do not know how to get started, read a lot of classic books introduced a variety of algorithms, but still do not know how to use it to solve the problem, even if know, and found the need to prepare the environment, training and deployment of the machine, ah, good trouble. Today, I’m going to introduce you to an easy to use method, give you ready-made samples and code, follow the steps, you can experience the whole process of using machine learning on your Mac. For example, if we train the model with a cat and a dog, all the model will learn is a cat and a dog, and if we train the model with a button and a search box, all the model will learn is a button and a search box.

If you want to see how machine learning can be used to solve real problems, check out this article: How to Use Deep Learning to Identify UI components. It introduces problem definition, algorithm selection, sample preparation, model training, model evaluation, model service deployment, and model application.

Environment to prepare

Installation Anaconda

Download address: www.anaconda.com/products/in…





$ source ~/.bashrc
Copy the code

You can run the following command to view environment variables

$ cat ~/.bashrc
Copy the code

You can see that anaconda’s environment variables have been automatically added to the.bashrc file





$ conda list
Copy the code

As you can see, there are a number of packages already installed in Anaconda. If there are any packages that use these packages, there is no need to install them, and the Python environment is installed.






Pay attention to






Installation-dependent dependencies

Keras, TensorFlow, and Opencv-Python are not available in Anaconda and need to be installed separately.

$ pip install keras
$ pip install tensorflow
$ pip install opencv-python
Copy the code

Sample preparation

There are only four categories: Button, Keyboard, Searchbar and Switch, with about 200 samples for each category.








Model training


Develop training logic

Create a new project called train-project. The file structure is as follows:

. ├ ─ ─ CNN_net. Py ├ ─ ─ the dataset ├ ─ ─ nn_train. Py └ ─ ─ utils_paths. PyCopy the code

The code of the entry file is as follows. The logic here is to input the prepared sample to the image classification algorithm SimpleVGGNet and set some training parameters, such as learning rate, Epoch and Batch Size. Then execute this training logic and finally obtain a model file.

# nn_train.py
from CNN_net import SimpleVGGNet
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

from keras.optimizers import SGD
from keras.preprocessing.image import ImageDataGenerator
import utils_paths
import matplotlib.pyplot as plt
from cv2 import cv2
import numpy as np
import argparse
import random
import pickle

import os

Read data and tags
print("------ Start reading data ------")
data = []
labels = []

# Get the image data path for subsequent reading
imagePaths = sorted(list(utils_paths.list_images('./dataset')))
random.seed(42)
random.shuffle(imagePaths)

image_size = 256
Read the data through
for imagePath in imagePaths:
    # Read image data
    image = cv2.imread(imagePath)
    image = cv2.resize(image, (image_size, image_size))
    data.append(image)
    # fetch tag
    label = imagePath.split(os.path.sep)[2 -]
    labels.append(label)

data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)

# Data set segmentation
(trainX, testX, trainY, testY) = train_test_split(data,labels, test_size=0.25, random_state=42)

# Convert the label to one-hot Encoding format
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
testY = lb.transform(testY)

# Data enhancement processing
aug = ImageDataGenerator(
    rotation_range=30, 
    width_shift_range=0.1,
    height_shift_range=0.1, 
    shear_range=0.2, 
    zoom_range=0.2,
    horizontal_flip=True, 
    fill_mode="nearest")

# Build convolutional neural network
model = SimpleVGGNet.build(width=256, height=256, depth=3,classes=len(lb.classes_))

Set the initialization hyperparameter

Vector #
INIT_LR = 0.01
# Epoch  
# Set 5 here in order to finish the training as soon as possible, you can set it higher, such as 30
EPOCHS = 5   
# Batch Size
BS = 32

# Loss function, compile model
print("------ Start training network ------")
opt = SGD(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="categorical_crossentropy", optimizer=opt,metrics=["accuracy"])

# Train the network model
H = model.fit_generator(
    aug.flow(trainX, trainY, batch_size=BS),
    validation_data=(testX, testY), 
    steps_per_epoch=len(trainX) // BS,
    epochs=EPOCHS
)


# test
print("------ Test network ------")
predictions = model.predict(testX, batch_size=32)
print(classification_report(testY.argmax(axis=1), predictions.argmax(axis=1), target_names=lb.classes_))

# Draw the resulting curve
N = np.arange(0, EPOCHS)
plt.style.use("ggplot")
plt.figure()
plt.plot(N, H.history["loss"], label="train_loss")
plt.plot(N, H.history["val_loss"], label="val_loss")
plt.plot(N, H.history["accuracy"], label="train_acc")
plt.plot(N, H.history["val_accuracy"], label="val_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend()
plt.savefig('./output/cnn_plot.png')

# Save the model
print("------ Save the model ------")
model.save('./cnn.model.h5')
f = open('./cnn_lb.pickle'."wb")
f.write(pickle.dumps(lb))
f.close()
Copy the code

For practical application scenarios, the data set is large, and the EPOCH will be set relatively large and trained on high-performance machines. Now we need to complete the training task on the local Mac, we only give a few samples to train the model, and the epoch is also very small (5). Of course, the recognition accuracy of the model will be poor, but the purpose of this article is to complete a machine learning task on the local Mac.

Start training

Execute the following command to begin training:

$ python nn_train.py
Copy the code

The training process log is as follows:









Model to evaluate

Now that we have the model file cnn.model.h5, we can write a prediction script that will be executed locally to predict the classification of an image.

$ python predict.py
Copy the code
# predict.py
import allspark
import io
import numpy as np
import json
from PIL import Image
import requests
import threading
import cv2
import os
import tensorflow as tf
from tensorflow.keras.models import load_model
import time

model = load_model('./train/cnn.model.h5')
The input to # pred should be an array of images that have been converted to a NUMpy array
# pred = model.predict(['./validation/button/button-demoplus-20200216-16615.png'])

This order must be the same as label.json. The output of the model is an array with the maximum index as the predicted value
Label = [
    "button"."keyboard"."searchbar"."switch"
    ]
testPath = "./test/button.png"

images = []
image = cv2.imread(testPath)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

image = cv2.resize(image,(256.256))
images.append(image)
images = np.asarray(images)

pred = model.predict(images)

print(pred)

max_ = np.argmax(pred)
print('Predicted result is:',Label[max_])

Copy the code

If you want to know the accuracy of this model, you can also input a batch of data with known classification into the model. After model prediction, the classification predicted by the model is compared with the real classification to calculate the accuracy and recall rate.

Model service deployment

Develop model services

But in practice, we predict the category of an image by asking an API for the returned result given an image. We need to write a model service, deploy it remotely, and get a deployed model service API. Now we can write a model service and deploy it locally.

# Model service app.py
import allspark
import io
import numpy as np
import json
from PIL import Image
import requests
import threading
import cv2
import tensorflow as tf
from tensorflow.keras.models import load_model


with open('label.json') as f:
    mp = json.load(f)
labels = {value:key for key,value in mp.items()}

def create_opencv_image_from_stringio(img_stream, cv2_img_flag=- 1):
  img_stream.seek(0)
  img_array = np.asarray(bytearray(img_stream.read()), dtype=np.uint8)
  image_temp = cv2.imdecode(img_array, cv2_img_flag)
  if image_temp.shape[2] = =4:
    image_channel3 = cv2.cvtColor(image_temp, cv2.COLOR_BGRA2BGR)
    image_mask = image_temp[:,:,3] #.reshape(image_temp.shape[0],image_temp.shape[1], 1)
    image_mask = np.stack((image_mask, image_mask, image_mask), axis = 2)
    index_mask = np.where(image_mask == 0)
    image_channel3[index_mask[0], index_mask[1], index_mask[2]] = 255
    return image_channel3
  else:
    return image_temp

def get_string_io(origin_path):
  r = requests.get(origin_path, timeout=2)
  stringIo_content = io.BytesIO(r.content)
  return stringIo_content

def handleReturn(pred, percent, msg_length):
  result = {
    "content":[]
  }
  argm = np.argsort(-pred, axis = 1)
  for i in range(msg_length):
      label = labels[argm[i, 0]]
      index = argm[i, 0]
      if(pred[i, index] > percent):
        confident = True
      else:
        confident = False
      result['content'].append({'isConfident': confident, 'label': label})
  return result


def process(msg, model):
  msg_dict = json.loads(msg)
  percent = msg_dict['threshold']
  msg_dict = msg_dict['images']
  msg_length = len(msg_dict)
  desire_size = 256
  
  images = []
  for i in range(msg_length):
    image_temp = create_opencv_image_from_stringio(get_string_io(msg_dict[i]))
    image_temp = cv2.cvtColor(image_temp, cv2.COLOR_BGR2RGB)
    image = cv2.resize(image_temp, (256.256))  
    images.append(image)
  images = np.asarray(images)
  pred = model.predict(images)
  return bytes(json.dumps(handleReturn(pred, percent, msg_length)) ,'utf-8')  


def worker(srv, thread_id, model):
  while True:
    msg = srv.read()
    try:
      rsp = process(msg, model)
      srv.write(rsp)
    except Exception as e:
      srv.error(500,bytes('invalid data format'.'utf-8'))

if __name__ == '__main__':
    desire_size = 256
    model = load_model('./cnn.model.h5')
    
    context = allspark.Context(4)
    queued = context.queued_service()

    workers = []
    for i in range(10):
        t = threading.Thread(target=worker, args=(queued, i, model))
        t.setDaemon(True)
        t.start()
        workers.append(t)
    for t in workers:
        t.join()



Copy the code

Deploy model services

Once the model service is written and deployed locally, an environment needs to be installed. Start by creating a model service project: deploy-project, copy cnn.model.h5 to this project, and install the environment under this project.

.
├── app.py
├── cnn.model.h5
└── label.json
Copy the code

Installation environment

3. Python -3.2 Building a Development environment -3.2.3 Using a pre-built development image (recommended)

Install the Docker

You can view the Mac Docker installation documentation directly

#Installation with Homebrew requires current Homebrew: https://brew.sh
$ brew cask install docker
Copy the code

Once installed, a Docker icon will appear on the desktop.

Create anaconda’s virtual environment
#To create a Python environment using conda, specify a fixed name for the directory: ENV
$Conda create -p ENV python=3.7

#Install the EAS Python SDK
$ ENV/bin/pip install http://eas-data.oss-cn-shanghai.aliyuncs.com/sdk/allspark-0.9-py2.py3-none-any.whl

#Install other dependency packages
$ ENV/bin/pip install tensorflow keras opencv-python

#Activating a Virtual Environment
$ conda activate ./ENV

#Exiting the virtual environment (when not in use)
$ conda deactivate
Copy the code

Run the Docker environment

Change /Users/chang/Desktop/ mL-test /deploy-project to your own project path

sudo docker run -ti -v  /Users/chang/Desktop/ml-test/deploy-project:/home -p 8080:8080  
registry.cn-shanghai.aliyuncs.com/eas/eas-python-base-image:py3.6-allspark-0.8
Copy the code

Local deployment

Now that you can deploy locally, execute the following command:

cd /home
./ENV/bin/python app.py
Copy the code

The following log shows that the deployment was successful.











curl -X POST 'localhost:8080/predict' \ -H 'Content-Type: application/json' \ -d '{ "images": (" https://img.alicdn.com/tfs/TB1W8K2MeH2gK0jSZJnXXaT1FXa-638-430.png "), "threshold", 0.5} 'Copy the code

The predicted results are as follows:

{"content": [{"isConfident": true, "label": "keyboard"}]}
Copy the code

The complete code

Clone code repository: github.com/imgcook/ml-… After the environment is installed, run the following commands directly.

#1. Training model
$ cd train-project
$ python nn_train.py

#Generate the model file: cnn.model.h5

#2. Copy the model file to deploy-Project to deploy the model service
#Start by installing the model service runtime environment
$ conda activate ./ENV
$sudo docker run -ti -v /Users/chang/Desktop/ml-test/deploy-project:/home -p 8080:8080 registry.cn-shanghai.aliyuncs.com/eas/eas-python-base-image:py3.6-allspark-0.8
$ cd /home
$ ./ENV/bin/python app.py

#Get the model service API: localhost:8080/predict

#3. Access model servicescurl -X POST 'localhost:8080/predict' \ -H 'Content-Type: application/json' \ -d '{ "images": (" https://img.alicdn.com/tfs/TB1W8K2MeH2gK0jSZJnXXaT1FXa-638-430.png "), "threshold", 0.5} 'Copy the code

The last

Ok, so to summarize the process of using deep learning here. We chose SimpleVGGNet as the image classification algorithm (equivalent to a function), passed the prepared data to this function, ran this function (learn the characteristics and labels of the data set) to get an output, the model file model.h5.