Merge branch 'mat_dev2'
This commit is contained in:
Коммит
63789f4893
18
README.md
18
README.md
|
@ -9,3 +9,21 @@ This decouples the app developers and data scientists, to make sure that the pro
|
|||
Variation to this tutorial could be consuming the ML application as an endpoint instead of packaging it in the app.
|
||||
|
||||
The goal is to show how easy it is do devops for an AI application.
|
||||
|
||||
|
||||
Steps to set up build and test
|
||||
* Create VM on Azure
|
||||
* Install Docker
|
||||
* Setup Docker to be executed without sudo
|
||||
If you want to avoid typing sudo whenever you run the docker command, add your username to the docker group:
|
||||
|
||||
• sudo usermod -aG docker ${USER}
|
||||
To apply the new group membership, you can log out of the server and back in, or you can type the following:
|
||||
|
||||
• su - ${USER}
|
||||
You will be prompted to enter your user's password to continue. Afterwards, you can confirm that your user is now added to the docker group by typing:
|
||||
|
||||
• id -nG
|
||||
* Login to ACR so credentials are stored
|
||||
* Install anaconda
|
||||
https://medium.com/@GalarnykMichael/install-python-on-ubuntu-anaconda-65623042cb5a
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
import base64
|
||||
import json
|
||||
import logging
|
||||
import urllib
|
||||
from io import BytesIO
|
||||
import sys
|
||||
|
||||
import requests
|
||||
import toolz
|
||||
from PIL import Image, ImageOps
|
||||
|
||||
ch = logging.StreamHandler(sys.stdout)
|
||||
ch.setLevel(logging.INFO)
|
||||
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
ch.setFormatter(formatter)
|
||||
|
||||
|
||||
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
|
||||
logger = logging.getLogger(__name__)
|
||||
# logger.addHandler(ch)
|
||||
|
||||
TEST_IMAGES ={ # Examples used for testing
|
||||
'https://www.britishairways.com/assets/images/information/about-ba/fleet-facts/airbus-380-800/photo-gallery/240x295-BA-A380-exterior-2-high-res.jpg':
|
||||
'n02690373 airliner',
|
||||
}
|
||||
|
||||
def read_image_from(url):
|
||||
return toolz.pipe(url,
|
||||
urllib.request.urlopen,
|
||||
lambda x: x.read(),
|
||||
BytesIO)
|
||||
|
||||
|
||||
def to_rgb(img_bytes):
|
||||
return Image.open(img_bytes).convert('RGB')
|
||||
|
||||
|
||||
@toolz.curry
|
||||
def resize(img_file, new_size=(100, 100)):
|
||||
return ImageOps.fit(img_file, new_size, Image.ANTIALIAS)
|
||||
|
||||
|
||||
def to_base64(img):
|
||||
imgio = BytesIO()
|
||||
img.save(imgio, 'PNG')
|
||||
imgio.seek(0)
|
||||
dataimg = base64.b64encode(imgio.read())
|
||||
return dataimg.decode('utf-8')
|
||||
|
||||
|
||||
def to_img(img_url):
|
||||
return toolz.pipe(img_url,
|
||||
read_image_from,
|
||||
to_rgb,
|
||||
resize(new_size=(224,224)))
|
||||
|
||||
|
||||
def img_url_to_json(url):
|
||||
img_data = toolz.pipe(url,
|
||||
to_img,
|
||||
to_base64)
|
||||
return json.dumps({'input':'[\"{0}\"]'.format(img_data)})
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
logger.info('Starting classifier test')
|
||||
headers = {'content-type': 'application/json'}
|
||||
for url, label in TEST_IMAGES.items():
|
||||
jsonimg = img_url_to_json(url)
|
||||
r = requests.post('http://0.0.0.0:88/score', data=jsonimg, headers=headers)
|
||||
json_response = r.json()
|
||||
logger.info(json_response)
|
||||
prediction=json_response['result'][0][0][0][0]
|
||||
if prediction != label:
|
||||
raise ValueError('The predicted label {} is not the same as {}'.format(prediction,label))
|
||||
logger.info('CORRECT! {}'.format(prediction))
|
|
@ -0,0 +1,35 @@
|
|||
#!/bin/bash
|
||||
# This script tests the docker image passed to it
|
||||
|
||||
IMAGE=$1
|
||||
echo "Starting Docker image " $IMAGE
|
||||
|
||||
docker pull $IMAGE
|
||||
docker run -d -p 88:88 $IMAGE
|
||||
|
||||
sleep 10
|
||||
|
||||
# Simple API test
|
||||
echo "Testing API"
|
||||
reply=$(curl -s http://0.0.0.0:88/version)
|
||||
if [[ $reply == 2.0rc1 ]]; then
|
||||
echo -e "Successfully validated version API call"
|
||||
else
|
||||
echo "Basic API call failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Testing classification
|
||||
echo "Testing Classification"
|
||||
source ~/anaconda/bin/activate root
|
||||
result=$(python test/classify.py)
|
||||
source ~/anaconda/bin/deactivate
|
||||
|
||||
echo $result
|
||||
|
||||
echo "Stopping container and removing"
|
||||
docker stop $(docker ps -a -q)
|
||||
docker rm $(docker ps -a -q)
|
||||
|
||||
echo "Finished"
|
||||
exit 0
|
Загрузка…
Ссылка в новой задаче