diff --git a/deployment/tfhub/object-detection-base64.ipynb b/deployment/tfhub/object-detection-base64.ipynb
new file mode 100644
index 0000000..12b29a5
--- /dev/null
+++ b/deployment/tfhub/object-detection-base64.ipynb
@@ -0,0 +1,603 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "rKn_w61SNijN"
+ },
+ "source": [
+ "# Object Detection - SSD Mobilenet V2 from TensorFlow Hub (Base64 Images)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DF3TUJI2VfYt"
+ },
+ "source": [
+ "This model identifies objects present in images, returning its scores, labels and bounding boxes.\n",
+ "\n",
+ "We are using a dataset from [UCF](https://www.crcv.ucf.edu/data/GMCP_Geolocalization/#Dataset) and the model [SSD Mobilenet V2](https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1) from [TensorFlow Hub](https://www.tensorflow.org/hub)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vTeFMlSIVic0"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wvqC2djzNijQ"
+ },
+ "source": [
+ "## 1. Dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "0flMWU41BY2W"
+ },
+ "source": [
+ "This notebook has been tested with **Python 3.8.15** and the following package versions:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "2T-GZ3zUNijQ"
+ },
+ "outputs": [],
+ "source": [
+ "%%capture\n",
+ "!pip install beautifulsoup4==4.6.3\n",
+ "!pip install dill==0.3.6\n",
+ "!pip install numpy==1.23.5\n",
+ "!pip install Pillow==7.1.2\n",
+ "!pip install requests==2.28.1\n",
+ "!pip install tensorflow==2.11.0\n",
+ "!pip install tensorflow-hub==0.12.0\n",
+ "!pip install verta==0.21.1\n",
+ "!pip install wget==3.2"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CtIgsA4aB2ga"
+ },
+ "source": [
+ "## 2. Imports"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "7SuugL_lOuaN"
+ },
+ "outputs": [],
+ "source": [
+ "import base64\n",
+ "import concurrent.futures\n",
+ "import io\n",
+ "import numpy as np\n",
+ "import os\n",
+ "import pandas as pd\n",
+ "import requests\n",
+ "import tempfile\n",
+ "import tensorflow as tf\n",
+ "import tensorflow_hub as hub\n",
+ "import time\n",
+ "import wget\n",
+ "\n",
+ "from bs4 import BeautifulSoup\n",
+ "from PIL import Image, ImageOps\n",
+ "from verta import Client\n",
+ "from verta.endpoint.autoscaling import Autoscaling\n",
+ "from verta.endpoint.autoscaling.metrics import CpuUtilizationTarget, MemoryUtilizationTarget, RequestsPerWorkerTarget\n",
+ "from verta.endpoint.resources import Resources\n",
+ "from verta.endpoint.update import DirectUpdateStrategy\n",
+ "from verta.environment import Python\n",
+ "from verta.registry import VertaModelBase, verify_io\n",
+ "from verta.utils import ModelAPI"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "LB20pSYuXcCD"
+ },
+ "source": [
+ "## 3. Verta Set Up"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "hGwbnFGlXgJh"
+ },
+ "outputs": [],
+ "source": [
+ "os.environ['VERTA_HOST'] = ''\n",
+ "os.environ['VERTA_EMAIL'] = ''\n",
+ "os.environ['VERTA_DEV_KEY'] = ''"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "wVcbn1_3Xhtm",
+ "outputId": "5846dfc7-3243-4784-d2bc-672d25dc6af7"
+ },
+ "outputs": [],
+ "source": [
+ "client = Client(os.environ['VERTA_HOST'])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5bBHXvKnX_Je"
+ },
+ "source": [
+ "## 4. Model Class"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "o3YNlqVMEi6c"
+ },
+ "outputs": [],
+ "source": [
+ "class DetectObject(VertaModelBase):\n",
+ " def __init__(self, artifacts=None):\n",
+ " module_handle = 'https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1'\n",
+ " self.detector = hub.load(module_handle).signatures['default']\n",
+ " \n",
+ " def handle_img(self, img, width=640, height=480):\n",
+ " _, path = tempfile.mkstemp(suffix='.jpg')\n",
+ " img_encoded = img.encode('utf-8')\n",
+ " img_bytes = io.BytesIO(base64.b64decode(img_encoded))\n",
+ " img_arr = np.array(Image.open(img_bytes), dtype=np.uint8)\n",
+ " img = Image.fromarray(img_arr)\n",
+ " img = ImageOps.grayscale(img)\n",
+ " img.thumbnail((width, height), Image.LANCZOS)\n",
+ " img.save(path)\n",
+ "\n",
+ " return path\n",
+ "\n",
+ " def load_img(self, path):\n",
+ " img = tf.io.read_file(path)\n",
+ " img = tf.image.decode_jpeg(img, channels=3)\n",
+ " \n",
+ " return img\n",
+ "\n",
+ " def filter_results(self, file_name, response, entity='Car', min_score=.2):\n",
+ " unused_keys = ['detection_class_labels', 'detection_class_names']\n",
+ " response = {key: value.numpy().tolist() for key, value in response.items()}\n",
+ " response = {key: val for key, val in response.items() if key not in unused_keys}\n",
+ " response['detection_class_entities'] = [v.decode() for v in response['detection_class_entities']]\n",
+ "\n",
+ " entities = response['detection_class_entities']\n",
+ " scores = response['detection_scores']\n",
+ " bboxes = response['detection_boxes']\n",
+ " result = {}\n",
+ "\n",
+ " for i in range(len(entities)):\n",
+ " if entities[i] == entity and scores[i] >= min_score:\n",
+ " ymin, xmin, ymax, xmax = bboxes[i]\n",
+ " result = {\n",
+ " 'file_name': file_name,\n",
+ " 'has_car': True,\n",
+ " 'score': scores[i],\n",
+ " 'bboxes': {'ymin': ymin, 'xmin': xmin, 'ymax': ymax, 'xmax': xmax}\n",
+ " }\n",
+ " break\n",
+ "\n",
+ " if len(result) == 0:\n",
+ " result = {\n",
+ " 'file_name': file_name,\n",
+ " 'has_car': False,\n",
+ " 'score': 0,\n",
+ " 'bboxes': {'ymin': 0, 'xmin': 0, 'ymax': 0, 'xmax': 0}\n",
+ " }\n",
+ " \n",
+ " return result\n",
+ "\n",
+ " def run_detector(self, file_name, image_path):\n",
+ " img = self.load_img(image_path)\n",
+ " img = tf.image.convert_image_dtype(img, tf.float32)[tf.newaxis, ...]\n",
+ " \n",
+ " response = self.detector(img)\n",
+ " result = self.filter_results(file_name, response)\n",
+ " \n",
+ " return result\n",
+ "\n",
+ " def detect_objects(self, file_name, img):\n",
+ " start_time = time.time()\n",
+ " image_path = self.handle_img(img)\n",
+ " result = self.run_detector(file_name, image_path)\n",
+ " end_time = time.time()\n",
+ "\n",
+ " return result\n",
+ "\n",
+ " @verify_io\n",
+ " def predict(self, data):\n",
+ " file_name, img = data\n",
+ " result = self.detect_objects(file_name, img)\n",
+ "\n",
+ " return result"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5SvthV9gd4lk"
+ },
+ "source": [
+ "## 5. Model Register"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "UR7XtPNOHTgO",
+ "outputId": "13f00122-72ab-4ba5-b4c1-e518bfbe04b3"
+ },
+ "outputs": [],
+ "source": [
+ "registered_model = client.get_or_create_registered_model(name='Object Detection - TF Hub')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "vFlrCL2EWnJR",
+ "outputId": "ccb50cb2-2080-4ba3-b41e-d3d0be4db0a8"
+ },
+ "outputs": [],
+ "source": [
+ "model = registered_model.create_standard_model(\n",
+ " name = 'base64',\n",
+ " model_cls = DetectObject,\n",
+ " model_api = ModelAPI(\n",
+ " [{'file_name': '', 'img': ''}],\n",
+ " [{\n",
+ " 'file_name': '',\n",
+ " 'has_car': False,\n",
+ " 'score': 0,\n",
+ " 'bboxes': {\n",
+ " 'ymin': 0,\n",
+ " 'xmin': 0,\n",
+ " 'ymax': 0,\n",
+ " 'xmax': 0\n",
+ " }\n",
+ " }]\n",
+ " ),\n",
+ " environment = Python(requirements = ['tensorflow', 'tensorflow_hub', 'dill', 'Pillow', 'wget'])\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "60NCs0j8KHvg"
+ },
+ "source": [
+ "## 6. Auto Scaling and Resources"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "LBLEtVauKBNP"
+ },
+ "outputs": [],
+ "source": [
+ "autoscaling = Autoscaling(min_replicas=1, max_replicas=20, min_scale=0.1, max_scale=10)\n",
+ "autoscaling.add_metric(CpuUtilizationTarget(0.6))\n",
+ "autoscaling.add_metric(MemoryUtilizationTarget(0.7))\n",
+ "autoscaling.add_metric(RequestsPerWorkerTarget(1))\n",
+ "resources = Resources(cpu=1., memory='4Gi') "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Y0gm6fOse6BP"
+ },
+ "source": [
+ "## 7. Model Endpoint"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "wZi8X-LoCORa"
+ },
+ "outputs": [],
+ "source": [
+ "endpoint = client.get_or_create_endpoint('object-detection-base64')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "F4-9M2_xKF7R",
+ "outputId": "cc97b5dc-b66f-45d5-862c-fb66670f2742"
+ },
+ "outputs": [],
+ "source": [
+ "%%time\n",
+ "endpoint.update(\n",
+ " model, \n",
+ " strategy = DirectUpdateStrategy(),\n",
+ " autoscaling = autoscaling,\n",
+ " resources = resources,\n",
+ " wait = True\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "0Zgc18ocXbCE"
+ },
+ "outputs": [],
+ "source": [
+ "deployed_model = endpoint.get_deployed_model()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NbxYiJJsX5oL"
+ },
+ "source": [
+ "## 8. Predictions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "p7x7dfWoCNxK"
+ },
+ "outputs": [],
+ "source": [
+ "url = 'http://www.cs.ucf.edu/~aroshan/index_files/Dataset_PitOrlManh/images/'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "4nS6rzzyK58c"
+ },
+ "outputs": [],
+ "source": [
+ "req = requests.get(url)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "gH_5iPC84jmu"
+ },
+ "outputs": [],
+ "source": [
+ "soup = BeautifulSoup(req.text, 'lxml')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "Hl_MzSFXX2oo"
+ },
+ "outputs": [],
+ "source": [
+ "urls = []\n",
+ "\n",
+ "for link in soup.find_all('a'):\n",
+ " href = link.get('href')\n",
+ " \n",
+ " if href.endswith('.jpg'):\n",
+ " image_url = f\"{url}/{href}\"\n",
+ " urls.append(image_url)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "Ifi5nJeBX_1G"
+ },
+ "outputs": [],
+ "source": [
+ "urls = urls[:10]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "6puNawPEYBJl"
+ },
+ "outputs": [],
+ "source": [
+ "def process_image(url):\n",
+ " file_name = os.path.basename(url)\n",
+ " wget.download(url, file_name)\n",
+ "\n",
+ " with open(file_name, 'rb') as img:\n",
+ " img_encoded = base64.b64encode(img.read())\n",
+ " img = img_encoded.decode('utf-8')\n",
+ " \n",
+ " return deployed_model.predict([file_name, img])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "5msNtuwt8AXa",
+ "outputId": "5df1b40c-45bd-4eb3-ba54-72bd16b75e65"
+ },
+ "outputs": [],
+ "source": [
+ "results = []\n",
+ "start_time = time.time()\n",
+ "\n",
+ "with concurrent.futures.ThreadPoolExecutor() as executor:\n",
+ " for result in executor.map(process_image, urls):\n",
+ " results.append(result)\n",
+ "\n",
+ "end_time = time.time()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "jGY1FLwWYBXq"
+ },
+ "outputs": [],
+ "source": [
+ "total_time = end_time - start_time\n",
+ "total_time = time.strftime('%Hh %Mm %Ss', time.gmtime(total_time))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "-k2mErxvYBdZ",
+ "outputId": "0ec4f897-0495-45b3-c8af-25d808dad3a7"
+ },
+ "outputs": [],
+ "source": [
+ "print(f\"Processing Time: {total_time} for {len(urls)} images.\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "sy8guzzgA5df"
+ },
+ "outputs": [],
+ "source": [
+ "results_rows = []\n",
+ "\n",
+ "for img_result in results:\n",
+ " img_result = img_result.copy()\n",
+ " img_result.update(img_result.pop('bboxes'))\n",
+ " results_rows.append(pd.Series(img_result))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "XOKZr5qBJqup"
+ },
+ "outputs": [],
+ "source": [
+ "df = pd.concat(results_rows, axis=1).T"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 363
+ },
+ "id": "pi546PBJJqj9",
+ "outputId": "6f599bef-50e3-4a03-d4ed-340a8f6e2606"
+ },
+ "outputs": [],
+ "source": [
+ "df"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "VeV_oVzddA0m"
+ },
+ "outputs": [],
+ "source": [
+ "endpoint.delete()"
+ ]
+ }
+ ],
+ "metadata": {
+ "colab": {
+ "provenance": []
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0]"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
diff --git a/deployment/tfhub/object-detection-url.ipynb b/deployment/tfhub/object-detection-url.ipynb
new file mode 100644
index 0000000..79b1ab9
--- /dev/null
+++ b/deployment/tfhub/object-detection-url.ipynb
@@ -0,0 +1,628 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "rKn_w61SNijN"
+ },
+ "source": [
+ "# Object Detection - SSD Mobilenet V2 from TensorFlow Hub (Image URLS)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "DF3TUJI2VfYt"
+ },
+ "source": [
+ "This model identifies objects present in images, returning its scores, labels and bounding boxes.\n",
+ "\n",
+ "We are using a dataset from [UCF](https://www.crcv.ucf.edu/data/GMCP_Geolocalization/#Dataset) and the model [SSD Mobilenet V2](https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1) from [TensorFlow Hub](https://www.tensorflow.org/hub)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vTeFMlSIVic0"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wvqC2djzNijQ"
+ },
+ "source": [
+ "## 1. Dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "0flMWU41BY2W"
+ },
+ "source": [
+ "This notebook has been tested with **Python 3.8.15** and the following package versions:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "2T-GZ3zUNijQ"
+ },
+ "outputs": [],
+ "source": [
+ "%%capture\n",
+ "!pip install beautifulsoup4==4.6.3\n",
+ "!pip install dill==0.3.6\n",
+ "!pip install Pillow==7.1.2\n",
+ "!pip install requests==2.28.1\n",
+ "!pip install tensorflow==2.11.0\n",
+ "!pip install tensorflow-hub==0.12.0\n",
+ "!pip install verta==0.21.1\n",
+ "!pip install wget==3.2"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "CtIgsA4aB2ga"
+ },
+ "source": [
+ "## 2. Imports"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "7SuugL_lOuaN"
+ },
+ "outputs": [],
+ "source": [
+ "import concurrent.futures\n",
+ "import os\n",
+ "import pandas as pd\n",
+ "import requests\n",
+ "import tempfile\n",
+ "import tensorflow as tf\n",
+ "import tensorflow_hub as hub\n",
+ "import time\n",
+ "import wget\n",
+ "\n",
+ "from bs4 import BeautifulSoup\n",
+ "from PIL import Image, ImageOps\n",
+ "from verta import Client\n",
+ "from verta.endpoint.autoscaling import Autoscaling\n",
+ "from verta.endpoint.autoscaling.metrics import CpuUtilizationTarget, MemoryUtilizationTarget, RequestsPerWorkerTarget\n",
+ "from verta.endpoint.resources import Resources\n",
+ "from verta.endpoint.update import DirectUpdateStrategy\n",
+ "from verta.environment import Python\n",
+ "from verta.registry import VertaModelBase, verify_io\n",
+ "from verta.utils import ModelAPI"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "LB20pSYuXcCD"
+ },
+ "source": [
+ "## 3. Verta Set Up"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "hGwbnFGlXgJh"
+ },
+ "outputs": [],
+ "source": [
+ "os.environ['VERTA_HOST'] = ''\n",
+ "os.environ['VERTA_EMAIL'] = ''\n",
+ "os.environ['VERTA_DEV_KEY'] = ''"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "wVcbn1_3Xhtm",
+ "outputId": "f14f925f-7a48-4832-f95e-fc4de209514f"
+ },
+ "outputs": [],
+ "source": [
+ "client = Client(os.environ['VERTA_HOST'])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5bBHXvKnX_Je"
+ },
+ "source": [
+ "## 4. Model Class"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "o3YNlqVMEi6c"
+ },
+ "outputs": [],
+ "source": [
+ "class DetectObject(VertaModelBase):\n",
+ " def __init__(self, artifacts=None):\n",
+ " module_handle = 'https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1'\n",
+ " self.detector = hub.load(module_handle).signatures['default']\n",
+ " \n",
+ " def handle_img(self, file_name, url, width=640, height=480):\n",
+ " wget.download(url, file_name)\n",
+ " img = Image.open(file_name)\n",
+ " img = ImageOps.grayscale(img)\n",
+ " img.thumbnail((width, height), Image.LANCZOS)\n",
+ " img.save(file_name)\n",
+ "\n",
+ " def load_img(self, path):\n",
+ " img = tf.io.read_file(path)\n",
+ " img = tf.image.decode_jpeg(img, channels=3)\n",
+ " \n",
+ " return img\n",
+ "\n",
+ " def filter_results(self, file_name, response, entity='Car', min_score=.2):\n",
+ " unused_keys = ['detection_class_labels', 'detection_class_names']\n",
+ " response = {key: value.numpy().tolist() for key, value in response.items()}\n",
+ " response = {key: val for key, val in response.items() if key not in unused_keys}\n",
+ " response['detection_class_entities'] = [v.decode() for v in response['detection_class_entities']]\n",
+ "\n",
+ " entities = response['detection_class_entities']\n",
+ " scores = response['detection_scores']\n",
+ " bboxes = response['detection_boxes']\n",
+ " result = {}\n",
+ "\n",
+ " for i in range(len(entities)):\n",
+ " if entities[i] == entity and scores[i] >= min_score:\n",
+ " ymin, xmin, ymax, xmax = bboxes[i]\n",
+ " result = {\n",
+ " 'file_name': file_name,\n",
+ " 'has_car': True,\n",
+ " 'score': scores[i],\n",
+ " 'bboxes': {'ymin': ymin, 'xmin': xmin, 'ymax': ymax, 'xmax': xmax}\n",
+ " }\n",
+ " break\n",
+ "\n",
+ " if len(result) == 0:\n",
+ " result = {\n",
+ " 'file_name': file_name,\n",
+ " 'has_car': False,\n",
+ " 'score': 0,\n",
+ " 'bboxes': {'ymin': 0, 'xmin': 0, 'ymax': 0, 'xmax': 0}\n",
+ " }\n",
+ " \n",
+ " return result\n",
+ "\n",
+ " def run_detector(self, file_name):\n",
+ " img = self.load_img(file_name)\n",
+ " img = tf.image.convert_image_dtype(img, tf.float32)[tf.newaxis, ...]\n",
+ " \n",
+ " response = self.detector(img)\n",
+ " result = self.filter_results(file_name, response)\n",
+ " \n",
+ " return result\n",
+ "\n",
+ " def detect_objects(self, file_name, url):\n",
+ " start_time = time.time()\n",
+ " self.handle_img(file_name, url)\n",
+ " result = self.run_detector(file_name)\n",
+ " end_time = time.time()\n",
+ " \n",
+ " return result\n",
+ "\n",
+ " @verify_io\n",
+ " def predict(self, data):\n",
+ " result = []\n",
+ "\n",
+ " for item in data:\n",
+ " file_name, url = item['file_name'], item['url']\n",
+ " result.append(self.detect_objects(file_name, url))\n",
+ "\n",
+ " return result\n",
+ "\n",
+ " def example(self):\n",
+ " return [{\n",
+ " 'file_name': '000001_1.jpg',\n",
+ " 'url': 'http://www.cs.ucf.edu/~aroshan/index_files/Dataset_PitOrlManh/images/000001_1.jpg',\n",
+ " }]\n",
+ "\n",
+ " def describe(self):\n",
+ " return {\n",
+ " 'method': 'predict',\n",
+ " 'args': f\"{self.example()}\",\n",
+ " 'returns': \"\"\"\n",
+ " [\n",
+ " [{\n",
+ " 'file_name': '',\n",
+ " 'has_car': False,\n",
+ " 'score': 0,\n",
+ " 'bboxes': {\n",
+ " 'ymin': 0, \n",
+ " 'xmin': 0, \n",
+ " 'ymax': 0,\n",
+ " 'xmax': 0 \n",
+ " }\n",
+ " }]\n",
+ " ]\n",
+ " \"\"\",\n",
+ " 'description': 'Identify whether a given object is present in the image URL.',\n",
+ " 'input_description': 'Image URL.',\n",
+ " 'output_description': \"\"\"\n",
+ " A JSON object containing the image file name, a boolean value indicating \n",
+ " if the object was found in the image, its score and bounding box\n",
+ " \"\"\"\n",
+ " }"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "5SvthV9gd4lk"
+ },
+ "source": [
+ "## 5. Model Register"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "UR7XtPNOHTgO",
+ "outputId": "99b78ecb-a7e8-452a-91dc-8c9ef7ab0faf"
+ },
+ "outputs": [],
+ "source": [
+ "registered_model = client.get_or_create_registered_model(name='Object Detection - TF Hub')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "vFlrCL2EWnJR",
+ "outputId": "976ab8fc-9343-4ff9-b127-7c3153943a7c"
+ },
+ "outputs": [],
+ "source": [
+ "model = registered_model.create_standard_model(\n",
+ " name = 'url',\n",
+ " model_cls = DetectObject,\n",
+ " model_api = ModelAPI(\n",
+ " [{'file_name': '', 'url': ''}],\n",
+ " [{\n",
+ " 'file_name': '',\n",
+ " 'has_car': False,\n",
+ " 'score': 0,\n",
+ " 'bboxes': {\n",
+ " 'ymin': 0,\n",
+ " 'xmin': 0,\n",
+ " 'ymax': 0,\n",
+ " 'xmax': 0\n",
+ " }\n",
+ " }]\n",
+ " ),\n",
+ " environment = Python(requirements = ['tensorflow', 'tensorflow_hub', 'dill', 'Pillow', 'wget'])\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "60NCs0j8KHvg"
+ },
+ "source": [
+ "## 6. Auto Scaling and Resources"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "LBLEtVauKBNP"
+ },
+ "outputs": [],
+ "source": [
+ "autoscaling = Autoscaling(min_replicas=1, max_replicas=20, min_scale=0.1, max_scale=10)\n",
+ "autoscaling.add_metric(CpuUtilizationTarget(0.6))\n",
+ "autoscaling.add_metric(MemoryUtilizationTarget(0.7))\n",
+ "autoscaling.add_metric(RequestsPerWorkerTarget(1))\n",
+ "resources = Resources(cpu=1., memory='4Gi')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Y0gm6fOse6BP"
+ },
+ "source": [
+ "## 7. Model Endpoint"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "wZi8X-LoCORa"
+ },
+ "outputs": [],
+ "source": [
+ "endpoint = client.get_or_create_endpoint('object-detection-url')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "F4-9M2_xKF7R",
+ "outputId": "acf0965c-da8b-442b-f170-a9af8c2255bf"
+ },
+ "outputs": [],
+ "source": [
+ "%%time\n",
+ "endpoint.update(\n",
+ " model, \n",
+ " strategy = DirectUpdateStrategy(),\n",
+ " autoscaling = autoscaling,\n",
+ " resources = resources,\n",
+ " wait = True\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "0Zgc18ocXbCE"
+ },
+ "outputs": [],
+ "source": [
+ "deployed_model = endpoint.get_deployed_model()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NbxYiJJsX5oL"
+ },
+ "source": [
+ "## 8. Predictions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "p7x7dfWoCNxK"
+ },
+ "outputs": [],
+ "source": [
+ "url = 'http://www.cs.ucf.edu/~aroshan/index_files/Dataset_PitOrlManh/images/'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "4nS6rzzyK58c"
+ },
+ "outputs": [],
+ "source": [
+ "req = requests.get(url)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "gH_5iPC84jmu"
+ },
+ "outputs": [],
+ "source": [
+ "soup = BeautifulSoup(req.text, 'lxml')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "Hl_MzSFXX2oo"
+ },
+ "outputs": [],
+ "source": [
+ "urls = []\n",
+ "\n",
+ "for link in soup.find_all('a'):\n",
+ " href = link.get('href')\n",
+ " \n",
+ " if href.endswith('.jpg'):\n",
+ " image_url = f\"{url}/{href}\"\n",
+ " urls.append(image_url)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "Ifi5nJeBX_1G"
+ },
+ "outputs": [],
+ "source": [
+ "urls = urls[:10]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "urls = [{'file_name': os.path.basename(url), 'url': url} for url in urls]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "6puNawPEYBJl"
+ },
+ "outputs": [],
+ "source": [
+ "def process_image(url):\n",
+ " return deployed_model.predict([url])[0]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "twDxykU5YBSp"
+ },
+ "outputs": [],
+ "source": [
+ "results = []\n",
+ "start_time = time.time()\n",
+ "\n",
+ "with concurrent.futures.ThreadPoolExecutor() as executor:\n",
+ " for result in executor.map(process_image, urls):\n",
+ " results.append(result)\n",
+ " \n",
+ "end_time = time.time()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "jGY1FLwWYBXq"
+ },
+ "outputs": [],
+ "source": [
+ "total_time = end_time - start_time\n",
+ "total_time = time.strftime('%Hh %Mm %Ss', time.gmtime(total_time))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "-k2mErxvYBdZ",
+ "outputId": "0991b3d4-f6e0-42ea-cf3e-b1769dbed44c"
+ },
+ "outputs": [],
+ "source": [
+ "print(f\"Processing Time: {total_time} for {len(urls)} images.\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "fqs3kM3D8v7t"
+ },
+ "outputs": [],
+ "source": [
+ "results_rows = []\n",
+ "\n",
+ "for img_result in results:\n",
+ " img_result = img_result.copy()\n",
+ " img_result.update(img_result.pop('bboxes'))\n",
+ " results_rows.append(pd.Series(img_result))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "W-B6TQLCBJkJ"
+ },
+ "outputs": [],
+ "source": [
+ "df = pd.concat(results_rows, axis=1).T"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 363
+ },
+ "id": "aDZ4yL5ABJ_y",
+ "outputId": "2ef798ff-d4a2-411d-c274-e7f0cd8ae1ed"
+ },
+ "outputs": [],
+ "source": [
+ "df"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "VeV_oVzddA0m"
+ },
+ "outputs": [],
+ "source": [
+ "endpoint.delete()"
+ ]
+ }
+ ],
+ "metadata": {
+ "colab": {
+ "provenance": []
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0]"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
diff --git a/deployment/tfhub/object-detection/base64/.gitignore b/deployment/tfhub/object-detection/base64/.gitignore
deleted file mode 100644
index a2a8dea..0000000
--- a/deployment/tfhub/object-detection/base64/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-.env/
diff --git a/deployment/tfhub/object-detection/base64/object-detection-base64-deploy.ipynb b/deployment/tfhub/object-detection/base64/object-detection-base64-deploy.ipynb
deleted file mode 100644
index e4d5e0f..0000000
--- a/deployment/tfhub/object-detection/base64/object-detection-base64-deploy.ipynb
+++ /dev/null
@@ -1,391 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Object Identification (TensorFlow Hub) - Base64 Images"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This notebook identifies whether a given object is present in a set of images. If the object is found, it returns a dataframe with the file name, score and bounding boxes.\n",
- "We are using a dataset from [UCF](https://www.crcv.ucf.edu/data/GMCP_Geolocalization/#Dataset) that contains 62,058 high quality Google Street View images, and [TensorFlow Hub](https://www.tensorflow.org/hub), a library and platform for transfer learning."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "
"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This notebook has been tested with Python 3.10.6 and the following package versions:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "!pip install dill==0.3.6\n",
- "!pip install Pillow==9.3.0\n",
- "!pip install tensorflow==2.11.0\n",
- "!pip install tensorflow-hub==0.12.0\n",
- "!pip install verta==0.21.1\n",
- "!pip install wget==3.2"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Imports"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import base64\n",
- "import io\n",
- "import json\n",
- "import numpy as np\n",
- "import os\n",
- "import tempfile\n",
- "import tensorflow as tf\n",
- "import tensorflow_hub as hub\n",
- "import time\n",
- "import wget\n",
- "\n",
- "from PIL import Image, ImageOps\n",
- "from verta import Client\n",
- "from verta.endpoint.autoscaling import Autoscaling\n",
- "from verta.endpoint.autoscaling.metrics import CpuUtilizationTarget, MemoryUtilizationTarget, RequestsPerWorkerTarget\n",
- "from verta.endpoint.resources import Resources\n",
- "from verta.endpoint.update import DirectUpdateStrategy\n",
- "from verta.environment import Python\n",
- "from verta.registry import VertaModelBase, verify_io\n",
- "from verta.utils import ModelAPI"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Model Class"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "class DetectObject(VertaModelBase):\n",
- " def __init__(self, artifacts=None):\n",
- " module_handle = 'https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1'\n",
- " self.detector = hub.load(module_handle).signatures['default']\n",
- " \n",
- " def handle_img(self, img, width=640, height=480):\n",
- " _, path = tempfile.mkstemp(suffix='.jpg')\n",
- " img_str = json.loads(img)\n",
- " img_bytes = img_str.encode('utf-8')\n",
- " img_bytes = io.BytesIO(base64.b64decode(img_bytes))\n",
- " img_arr = np.array(Image.open(img_bytes), dtype=np.uint8)\n",
- " img = Image.fromarray(img_arr)\n",
- " img = ImageOps.grayscale(img)\n",
- " img.thumbnail((width, height), Image.Resampling.LANCZOS)\n",
- " img.save(path, format = 'JPEG', quality = 90)\n",
- " \n",
- " print(f\"Image downloaded to {path}.\")\n",
- " return path\n",
- "\n",
- " def load_img(self, path):\n",
- " img = tf.io.read_file(path)\n",
- " img = tf.image.decode_jpeg(img, channels=3)\n",
- " \n",
- " return img\n",
- "\n",
- " def filter_results(self, file, response, entity='Car', min_score=.2):\n",
- " unused_keys = ['detection_class_labels', 'detection_class_names']\n",
- " response = {key: value.numpy().tolist() for key, value in response.items()}\n",
- " response = {key: val for key, val in response.items() if key not in unused_keys}\n",
- " response['detection_class_entities'] = [v.decode() for v in response['detection_class_entities']]\n",
- "\n",
- " entities = response['detection_class_entities']\n",
- " scores = response['detection_scores']\n",
- " bboxes = response['detection_boxes']\n",
- " result = {}\n",
- "\n",
- " for i in range(len(entities)):\n",
- " if entities[i] == entity and scores[i] >= min_score:\n",
- " ymin, xmin, ymax, xmax = bboxes[i]\n",
- " result = {\n",
- " 'file': file,\n",
- " 'has_car': True,\n",
- " 'score': scores[i],\n",
- " 'bboxes': {'ymin': ymin, 'xmin': xmin, 'ymax': ymax, 'xmax': xmax}\n",
- " }\n",
- " break\n",
- "\n",
- " if len(result) == 0:\n",
- " result = {\n",
- " 'file': file,\n",
- " 'has_car': False,\n",
- " 'score': 0,\n",
- " 'bboxes': {'ymin': 0, 'xmin': 0, 'ymax': 0, 'xmax': 0}\n",
- " }\n",
- " \n",
- " print(f\"Found {result['has_car']} object(s).\")\n",
- " return result\n",
- "\n",
- " def run_detector(self, file, image_path):\n",
- " img = self.load_img(image_path)\n",
- " img = tf.image.convert_image_dtype(img, tf.float32)[tf.newaxis, ...]\n",
- " \n",
- " response = self.detector(img)\n",
- " result = self.filter_results(file, response)\n",
- " \n",
- " return result\n",
- "\n",
- " def detect_objects(self, file, img_arr):\n",
- " start_time = time.time()\n",
- " image_path = self.handle_img(img_arr)\n",
- " result = self.run_detector(file, image_path)\n",
- " end_time = time.time()\n",
- "\n",
- " print(f\"Inference time: {end_time - start_time}.\")\n",
- " return result\n",
- "\n",
- " @verify_io\n",
- " def predict(self, data):\n",
- " file, img_arr = data\n",
- " result = self.detect_objects(file, img_arr)\n",
- "\n",
- " return result\n",
- "\n",
- " def describe(self):\n",
- " \"\"\"Return a description of the service.\"\"\" \n",
- " return {\n",
- " \"method\": \"predict\",\n",
- " \"args\": f\"{self.example()}\",\n",
- " \"returns\": \"file, has_car, score, ymin, xmin, ymax, xmax\",\n",
- " \"description\": \"\"\"\n",
- " Identify whether a given object is present in the image, with its score and bounding boxes.\n",
- " \"\"\",\n",
- " \"input_description\": \"\"\"\n",
- " A list with base64 images.\n",
- " \"\"\",\n",
- " \"output_description\": \"\"\"\n",
- " A CSV file with information about all the processed images.\n",
- " The columns presents the file names, if the object was found (boolean), its score and bounding boxes.\n",
- " \"\"\"\n",
- " }\n",
- " \n",
- " def example(self):\n",
- " \"\"\"Return example input json-serializable data.\"\"\"\n",
- " url = 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_0.jpg'\n",
- " file = url.split('/')[-1]\n",
- " wget.download(url, file)\n",
- "\n",
- " with open(file, 'rb') as img:\n",
- " img_bytes = base64.b64encode(img.read())\n",
- " img_str = img_bytes.decode('utf-8')\n",
- " img_str = json.dumps(img_str)\n",
- " \n",
- " return [\"000001_0.jpg\", img_str]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Verta Set Up"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "VERTA_HOST = 'app.verta.ai'\n",
- "PROJECT_NAME = 'Object Detection V1'\n",
- "MODEL_NAME = 'base64'\n",
- "ENDPOINT_NAME = 'object-detection-base64'\n",
- "\n",
- "os.environ['VERTA_EMAIL'] = ''\n",
- "os.environ['VERTA_DEV_KEY'] = ''"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Model Registration "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "client = Client(VERTA_HOST)\n",
- "project = client.set_project(PROJECT_NAME)\n",
- "registered_model = client.get_or_create_registered_model(\n",
- " name = PROJECT_NAME, \n",
- " labels = ['object-detection']\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "input = {\n",
- " \"file_name\": \"\",\n",
- " \"image_str\": \"\"\n",
- "}\n",
- "output = {\n",
- " \"file_name\": \"\",\n",
- " \"has_car\": False,\n",
- " \"score\": 0,\n",
- " \"ymin\": 0,\n",
- " \"xmin\": 0,\n",
- " \"ymax\": 0,\n",
- " \"xmax\": 0\n",
- "}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "model = registered_model.create_standard_model(\n",
- " model_cls = DetectObject,\n",
- " environment = Python(requirements = ['tensorflow', 'tensorflow_hub', 'dill', 'Pillow', 'wget']),\n",
- " model_api = ModelAPI([input], [output]),\n",
- " name = MODEL_NAME\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## VM Auto Scaling and Resources Configuration"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "autoscaling = Autoscaling(min_replicas = 1, max_replicas = 20, min_scale = 0.1, max_scale = 10)\n",
- "autoscaling.add_metric(CpuUtilizationTarget(0.6))\n",
- "autoscaling.add_metric(MemoryUtilizationTarget(0.7))\n",
- "autoscaling.add_metric(RequestsPerWorkerTarget(1))\n",
- "resources = Resources(cpu = 2., memory = '12Gi')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Endpoint Creation"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "endpoint = client.get_or_create_endpoint(ENDPOINT_NAME)\n",
- "status = endpoint.update(\n",
- " model, \n",
- " strategy = DirectUpdateStrategy(),\n",
- " autoscaling = autoscaling,\n",
- " resources = resources,\n",
- " wait = True\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Prediction Test"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "assert status['status'] == \"active\"\n",
- "url = 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_0.jpg'\n",
- "file = url.split('/')[-1]\n",
- "wget.download(url, file)\n",
- "\n",
- "with open(file, 'rb') as img:\n",
- " img_bytes = base64.b64encode(img.read())\n",
- " img_str = img_bytes.decode('utf-8')\n",
- " img_str = json.dumps(img_str)\n",
- "\n",
- "endpoint.get_deployed_model().predict([file, img_str])\n",
- "print(status)"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.6"
- },
- "vscode": {
- "interpreter": {
- "hash": "2bb62b3221a3e8eb4d56ef3abf33b59c1166039d4d316f70559cb86bddd6b450"
- }
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/deployment/tfhub/object-detection/base64/object-detection-base64-predict.ipynb b/deployment/tfhub/object-detection/base64/object-detection-base64-predict.ipynb
deleted file mode 100644
index 1acd850..0000000
--- a/deployment/tfhub/object-detection/base64/object-detection-base64-predict.ipynb
+++ /dev/null
@@ -1,241 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Object Identification (TensorFlow Hub) - Base64 Images"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This notebook identifies whether a given object is present in a set of images. If the object is found, it returns a dataframe with the file name, score and bounding boxes.\n",
- "We are using a dataset from [UCF](https://www.crcv.ucf.edu/data/GMCP_Geolocalization/#Dataset) that contains 62,058 high quality Google Street View images, and [TensorFlow Hub](https://www.tensorflow.org/hub), a library and platform for transfer learning."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "
"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This notebook has been tested with Python 3.10.6 and the following package versions:\n",
- "\n",
- "- pandas==1.5.2\n",
- "- verta==0.21.1"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "!pip install pandas==1.5.2\n",
- "!pip install verta==0.21.1\n",
- "!pip install wget==3.2"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Imports"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import base64\n",
- "import multiprocessing as mp\n",
- "import numpy as np\n",
- "import os\n",
- "import pandas as pd\n",
- "import time\n",
- "import json\n",
- "import wget\n",
- "\n",
- "from verta import Client"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Helper Functions"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def load_imgs(n_imgs):\n",
- " urls = [\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_0.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_1.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_2.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_3.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_4.jpg'\n",
- " ]\n",
- " urls = urls[:n_imgs]\n",
- " data = []\n",
- "\n",
- " for url in urls:\n",
- " file = url.split('/')[-1]\n",
- " wget.download(url, file)\n",
- " \n",
- " with open(file, 'rb') as img:\n",
- " img_bytes = base64.b64encode(img.read())\n",
- " img_str = img_bytes.decode('utf-8')\n",
- " img_str = json.dumps(img_str)\n",
- " \n",
- " data.append([file, img_str])\n",
- "\n",
- " return data"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def show_metrics(n_imgs, n_threads, start_time, end_time):\n",
- " total_time = end_time - start_time\n",
- " total_time = time.strftime('%Mm %Ss', time.gmtime(total_time))\n",
- " \n",
- " print(f'Images processed: {n_imgs}.')\n",
- " print(f'Threads: {n_threads}.')\n",
- " print(f'Total time: {total_time}.')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def show_results(results):\n",
- " cols = list(results[0].keys())[:-1]\n",
- " cols.extend(list(results[0]['bboxes'].keys()))\n",
- " data = []\n",
- "\n",
- " for item in results:\n",
- " values = list(item.values())[0:3]\n",
- " values.extend(list(item['bboxes'].values()))\n",
- " data.append(values)\n",
- "\n",
- " df = pd.DataFrame(data, columns=cols)\n",
- " print(df)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Main Function\n",
- "After setting up Verta, it processes the images in parallel, presents metrics and saves the result to a CSV file."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def main():\n",
- " VERTA_HOST = 'app.verta.ai'\n",
- " ENDPOINT_NAME = 'object-detection-base64'\n",
- "\n",
- " os.environ['VERTA_EMAIL'] = ''\n",
- " os.environ['VERTA_DEV_KEY'] = ''\n",
- "\n",
- " client = Client(VERTA_HOST, debug=True)\n",
- " endpoint = client.get_or_create_endpoint(ENDPOINT_NAME)\n",
- " model = endpoint.get_deployed_model()\n",
- "\n",
- " n_threads = int(mp.cpu_count())\n",
- " n_imgs = 1\n",
- " imgs = load_imgs(n_imgs)\n",
- " \n",
- " start_time = time.time()\n",
- " pool = mp.Pool(n_threads)\n",
- " map_results = pool.map_async(model.predict, imgs, chunksize=1)\n",
- "\n",
- " while not map_results.ready():\n",
- " print(f\"Images remaining: {map_results._number_left}\")\n",
- " time.sleep(5)\n",
- "\n",
- " results = map_results.get()\n",
- " pool.close()\n",
- " pool.join()\n",
- " end_time = time.time()\n",
- "\n",
- " show_metrics(n_imgs, n_threads, start_time, end_time)\n",
- " show_results(results)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Execution"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "if __name__ == '__main__':\n",
- " main()"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.6"
- },
- "vscode": {
- "interpreter": {
- "hash": "2bb62b3221a3e8eb4d56ef3abf33b59c1166039d4d316f70559cb86bddd6b450"
- }
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/deployment/tfhub/object-detection/url/.gitignore b/deployment/tfhub/object-detection/url/.gitignore
deleted file mode 100644
index a2a8dea..0000000
--- a/deployment/tfhub/object-detection/url/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-.env/
diff --git a/deployment/tfhub/object-detection/url/object-detection-url-deploy.ipynb b/deployment/tfhub/object-detection/url/object-detection-url-deploy.ipynb
deleted file mode 100644
index 3df4927..0000000
--- a/deployment/tfhub/object-detection/url/object-detection-url-deploy.ipynb
+++ /dev/null
@@ -1,367 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Object Identification (TensorFlow Hub) - Images URLs"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This notebook identifies whether a given object is present in a set of images. If the object is found, it returns a dataframe with the file name, score and bounding boxes.\n",
- "We are using a dataset from [UCF](https://www.crcv.ucf.edu/data/GMCP_Geolocalization/#Dataset) that contains 62,058 high quality Google Street View images, and [TensorFlow Hub](https://www.tensorflow.org/hub), a library and platform for transfer learning."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "
"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This notebook has been tested with Python 3.10.6 and the following package versions:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "!pip install dill==0.3.6\n",
- "!pip install Pillow==9.3.0\n",
- "!pip install tensorflow==2.11.0\n",
- "!pip install tensorflow-hub==0.12.0\n",
- "!pip install verta==0.21.1"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Imports"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import tempfile\n",
- "import tensorflow as tf\n",
- "import tensorflow_hub as hub\n",
- "import time\n",
- "import urllib.request\n",
- "\n",
- "from PIL import Image, ImageOps\n",
- "from verta import Client\n",
- "from verta.endpoint.autoscaling import Autoscaling\n",
- "from verta.endpoint.autoscaling.metrics import CpuUtilizationTarget, MemoryUtilizationTarget, RequestsPerWorkerTarget\n",
- "from verta.endpoint.resources import Resources\n",
- "from verta.endpoint.update import DirectUpdateStrategy\n",
- "from verta.environment import Python\n",
- "from verta.registry import VertaModelBase, verify_io\n",
- "from verta.utils import ModelAPI"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Model Class"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "class DetectObject(VertaModelBase):\n",
- " def __init__(self, artifacts=None):\n",
- " module_handle = 'https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1'\n",
- " self.detector = hub.load(module_handle).signatures['default']\n",
- " \n",
- " def handle_img(self, data, width=640, height=480):\n",
- " _, path = tempfile.mkstemp(suffix='.jpg')\n",
- " file_path = f\"{tempfile.gettempdir()}/tmp-{data[0].split('/')[-1]}\"\n",
- " urllib.request.urlretrieve(data[1], file_path)\n",
- " img = Image.open(file_path)\n",
- " img = ImageOps.grayscale(img)\n",
- " img.thumbnail((width, height), Image.Resampling.LANCZOS)\n",
- " img.save(path, format='JPEG', quality=90)\n",
- " \n",
- " print(f\"Image downloaded to {path}.\")\n",
- " return path\n",
- "\n",
- " def load_img(self, path):\n",
- " img = tf.io.read_file(path)\n",
- " img = tf.image.decode_jpeg(img, channels=3)\n",
- " \n",
- " return img\n",
- "\n",
- " def filter_results(self, file, response, entity='Car', min_score=.2):\n",
- " unused_keys = ['detection_class_labels', 'detection_class_names']\n",
- " response = {key: value.numpy().tolist() for key, value in response.items()}\n",
- " response = {key: val for key, val in response.items() if key not in unused_keys}\n",
- " response['detection_class_entities'] = [v.decode() for v in response['detection_class_entities']]\n",
- "\n",
- " entities = response['detection_class_entities']\n",
- " scores = response['detection_scores']\n",
- " bboxes = response['detection_boxes']\n",
- " result = {}\n",
- "\n",
- " for i in range(len(entities)):\n",
- " if entities[i] == entity and scores[i] >= min_score:\n",
- " ymin, xmin, ymax, xmax = bboxes[i]\n",
- " result = {\n",
- " 'file': file,\n",
- " 'has_car': True,\n",
- " 'score': scores[i],\n",
- " 'bboxes': {'ymin': ymin, 'xmin': xmin, 'ymax': ymax, 'xmax': xmax}\n",
- " }\n",
- " break\n",
- "\n",
- " if len(result) == 0:\n",
- " result = {\n",
- " 'file': file,\n",
- " 'has_car': False,\n",
- " 'score': 0,\n",
- " 'bboxes': {'ymin': 0, 'xmin': 0, 'ymax': 0, 'xmax': 0}\n",
- " }\n",
- " \n",
- " print(f\"Found {result['has_car']} object(s).\")\n",
- " return result\n",
- "\n",
- " def run_detector(self, file, image_path):\n",
- " img = self.load_img(image_path)\n",
- " img = tf.image.convert_image_dtype(img, tf.float32)[tf.newaxis, ...]\n",
- " \n",
- " response = self.detector(img)\n",
- " result = self.filter_results(file, response)\n",
- " \n",
- " return result\n",
- "\n",
- " def detect_objects(self, data):\n",
- " start_time = time.time()\n",
- " image_path = self.handle_img(data)\n",
- " result = self.run_detector(data[0], image_path)\n",
- " end_time = time.time()\n",
- "\n",
- " print(f\"Inference time: {end_time - start_time}.\")\n",
- " return result\n",
- "\n",
- " @verify_io\n",
- " def predict(self, data):\n",
- " result = self.detect_objects(data)\n",
- "\n",
- " return result\n",
- "\n",
- " def describe(self):\n",
- " \"\"\"Return a description of the service.\"\"\"\n",
- " return {\n",
- " \"method\": \"predict\",\n",
- " \"args\": f\"{self.example()}\",\n",
- " \"returns\": \"file, has_car, score, ymin, xmin, ymax, xmax\",\n",
- " \"description\": \"\"\"\n",
- " Identify whether a given object is present in the URL image, with its score and bounding boxes.\n",
- " \"\"\",\n",
- " \"input_description\": \"\"\"\n",
- " A list with image URLs.\n",
- " \"\"\",\n",
- " \"output_description\": \"\"\"\n",
- " A CSV file with information about all the processed images.\n",
- " The columns presents the file names, if the object was found (boolean), its score and bounding boxes.\n",
- " \"\"\"\n",
- " }\n",
- " \n",
- " def example(self):\n",
- " \"\"\"Return example input json-serializable data.\"\"\"\n",
- " return [\"000001_0.jpg\", \"http://s3.amazonaws.com/verta-starter/street-view-images/000001_0.jpg\"]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Verta Set Up"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "VERTA_HOST = 'app.verta.ai'\n",
- "PROJECT_NAME = 'Object Detection V1'\n",
- "MODEL_NAME = 'url'\n",
- "ENDPOINT_NAME = 'object-detection-url'\n",
- "\n",
- "os.environ['VERTA_EMAIL'] = ''\n",
- "os.environ['VERTA_DEV_KEY'] = ''"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Model Registration"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "client = Client(VERTA_HOST)\n",
- "project = client.set_project(PROJECT_NAME)\n",
- "registered_model = client.get_or_create_registered_model(\n",
- " name = PROJECT_NAME, \n",
- " labels = ['object-detection']\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "input = {\n",
- " \"file_name\": \"\",\n",
- " \"image_str\": \"\"\n",
- "}\n",
- "output = {\n",
- " \"file_name\": \"\",\n",
- " \"has_car\": False,\n",
- " \"score\": 0,\n",
- " \"ymin\": 0,\n",
- " \"xmin\": 0,\n",
- " \"ymax\": 0,\n",
- " \"xmax\": 0\n",
- "}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "model = registered_model.create_standard_model(\n",
- " model_cls = DetectObject,\n",
- " environment = Python(requirements = ['tensorflow', 'tensorflow_hub', 'dill', 'Pillow']),\n",
- " model_api = ModelAPI([input], [output]),\n",
- " name = MODEL_NAME\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## VM Auto Scaling and Resources Configuration"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "autoscaling = Autoscaling(min_replicas = 1, max_replicas = 20, min_scale = 0.1, max_scale = 10)\n",
- "autoscaling.add_metric(CpuUtilizationTarget(0.6))\n",
- "autoscaling.add_metric(MemoryUtilizationTarget(0.7))\n",
- "autoscaling.add_metric(RequestsPerWorkerTarget(1))\n",
- "resources = Resources(cpu = 2., memory = '12Gi')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Endpoint Creation"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "endpoint = client.get_or_create_endpoint(ENDPOINT_NAME)\n",
- "status = endpoint.update(\n",
- " model, \n",
- " strategy = DirectUpdateStrategy(),\n",
- " autoscaling = autoscaling,\n",
- " resources = resources,\n",
- " wait = True\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Prediction Test"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "assert status['status'] == \"active\"\n",
- "url = 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_0.jpg'\n",
- "file = url.split('/')[-1]\n",
- "endpoint.get_deployed_model().predict([file, url])\n",
- "print(status)"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.6"
- },
- "vscode": {
- "interpreter": {
- "hash": "a88be0c350f3368d00cb8cbcc8a29525670c96bbb38149ff34103f663f5a90a2"
- }
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/deployment/tfhub/object-detection/url/object-detection-url-predict.ipynb b/deployment/tfhub/object-detection/url/object-detection-url-predict.ipynb
deleted file mode 100644
index edac5e3..0000000
--- a/deployment/tfhub/object-detection/url/object-detection-url-predict.ipynb
+++ /dev/null
@@ -1,228 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Object Identification (TensorFlow Hub) - Images URLs"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This notebook identifies whether a given object is present in a set of images. If the object is found, it returns a dataframe with the file name, score and bounding boxes.\n",
- "We are using a dataset from [UCF](https://www.crcv.ucf.edu/data/GMCP_Geolocalization/#Dataset) that contains 62,058 high quality Google Street View images, and [TensorFlow Hub](https://www.tensorflow.org/hub), a library and platform for transfer learning."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "
"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This notebook has been tested with Python 3.10.6 and the following package versions:\n",
- "\n",
- "- pandas==1.5.2\n",
- "- verta==0.21.1"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "!pip install pandas==1.5.2\n",
- "!pip install verta==0.21.1"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Imports"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import multiprocessing as mp\n",
- "import os\n",
- "import pandas as pd\n",
- "import time\n",
- "\n",
- "from verta import Client"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Helper Functions"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def load_urls():\n",
- " urls = [\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_0.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_1.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_2.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_3.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_4.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000001_5.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000002_0.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000002_1.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000002_2.jpg',\n",
- " 'http://s3.amazonaws.com/verta-starter/street-view-images/000002_3.jpg'\n",
- " ]\n",
- " \n",
- " return [[url.strip().split('/')[-1], url.strip()] for url in urls]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def show_metrics(n_urls, n_threads, start_time, end_time):\n",
- " total_time = end_time - start_time\n",
- " total_time = time.strftime('%Mm %Ss', time.gmtime(total_time))\n",
- " \n",
- " print(f'URLs processed: {n_urls}.')\n",
- " print(f'Threads: {n_threads}.')\n",
- " print(f'Total time: {total_time}.')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def show_results(results):\n",
- " cols = list(results[0].keys())[:-1]\n",
- " cols.extend(list(results[0]['bboxes'].keys()))\n",
- " data = []\n",
- "\n",
- " for item in results:\n",
- " values = list(item.values())[0:3]\n",
- " values.extend(list(item['bboxes'].values()))\n",
- " data.append(values)\n",
- "\n",
- " df = pd.DataFrame(data, columns = cols)\n",
- " print(df)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Main Function\n",
- "After setting up Verta, it processes the images in parallel, presents metrics and saves the result to a CSV file."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "def main():\n",
- " VERTA_HOST = 'app.verta.ai'\n",
- " ENDPOINT_NAME = 'object-detection-url'\n",
- "\n",
- " os.environ['VERTA_EMAIL'] = ''\n",
- " os.environ['VERTA_DEV_KEY'] = ''\n",
- "\n",
- " client = Client(VERTA_HOST, debug=True)\n",
- " endpoint = client.get_or_create_endpoint(ENDPOINT_NAME)\n",
- " model = endpoint.get_deployed_model()\n",
- "\n",
- " n_threads = int(mp.cpu_count())\n",
- " n_urls = 5\n",
- " urls = load_urls()[:n_urls]\n",
- "\n",
- " start_time = time.time()\n",
- " pool = mp.Pool(n_threads)\n",
- " map_results = pool.map_async(model.predict, urls, chunksize=1)\n",
- "\n",
- " while not map_results.ready():\n",
- " print(f\"URLs remaining: {map_results._number_left}\")\n",
- " time.sleep(1.5)\n",
- "\n",
- " results = map_results.get()\n",
- " pool.close()\n",
- " pool.join()\n",
- " end_time = time.time()\n",
- "\n",
- " show_metrics(n_urls, n_threads, start_time, end_time)\n",
- " show_results(results)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Execution"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "if __name__ == '__main__':\n",
- " main()"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.6"
- },
- "vscode": {
- "interpreter": {
- "hash": "a88be0c350f3368d00cb8cbcc8a29525670c96bbb38149ff34103f663f5a90a2"
- }
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}