รับการคาดการณ์จากโมเดลอิมเมจ TensorFlow ก่อนการฝึกบน Vertex AI

1. ภาพรวม

ในชั้นเรียนนี้ คุณจะใช้ Vertex AI เพื่อรับการคาดการณ์จากโมเดลการจัดประเภทรูปภาพที่ฝึกล่วงหน้า

สิ่งที่ได้เรียนรู้

โดยคุณจะได้เรียนรู้วิธีต่อไปนี้

  • นําเข้าโมเดล TensorFlow ไปยัง Vertex AI Model Registry
  • ดูการคาดการณ์ออนไลน์
  • อัปเดตฟังก์ชันการแสดงผล TensorFlow

ต้นทุนทั้งหมดในการใช้งานห้องทดลองนี้ใน Google Cloud อยู่ที่ประมาณ $1

2. ข้อมูลเบื้องต้นเกี่ยวกับ Vertex AI

ห้องทดลองนี้ใช้ข้อเสนอผลิตภัณฑ์ AI ใหม่ล่าสุดที่มีให้บริการใน Google Cloud Vertex AI ผสานรวมข้อเสนอ ML ทั่วทั้ง Google Cloud เข้าด้วยกันเพื่อมอบประสบการณ์การพัฒนาที่ราบรื่น ก่อนหน้านี้ โมเดลที่ฝึกด้วย AutoML และโมเดลที่กำหนดเองจะเข้าถึงได้ผ่านบริการแยกต่างหาก ข้อเสนอใหม่นี้รวมทั้ง 2 รายการไว้ใน API เดียว พร้อมกับผลิตภัณฑ์ใหม่อื่นๆ นอกจากนี้ คุณยังย้ายข้อมูลโปรเจ็กต์ที่มีอยู่ไปยัง Vertex AI ได้ด้วย

Vertex AI มีผลิตภัณฑ์หลายอย่างเพื่อรองรับเวิร์กโฟลว์ ML ตั้งแต่ต้นจนจบ ห้องทดลองนี้จะมุ่งเน้นที่ผลิตภัณฑ์ที่ไฮไลต์ไว้ด้านล่าง ได้แก่ การคาดคะเนและ Workbench

ภาพรวมผลิตภัณฑ์ Vertex

3. ภาพรวมกรณีการใช้งาน

ในบทแนะนำนี้ คุณจะได้เรียนรู้วิธีนําโมเดลที่ฝึกล่วงหน้าจาก TensorFlow Hub ไปใช้งานใน Vertex AI TensorFlow Hub เป็นพื้นที่เก็บข้อมูลโมเดลที่ได้รับการฝึกฝนสำหรับขอบเขตปัญหาที่หลากหลาย เช่น การฝัง การสร้างข้อความ การเปลี่ยนคำพูดเป็นข้อความ การแบ่งกลุ่มรูปภาพ และอื่นๆ

ตัวอย่างที่ใช้ในห้องทดลองนี้คือโมเดลการจัดประเภทรูปภาพ MobileNet V1 ที่ผ่านการฝึกล่วงหน้าในชุดข้อมูล ImageNet การใช้โมเดลสำเร็จรูปจาก TensorFlow Hub หรือที่เก็บข้อมูล Deep Learning อื่นๆ ที่คล้ายกันจะช่วยให้คุณติดตั้งใช้งานโมเดล ML คุณภาพสูงสําหรับงานการคาดการณ์จํานวนหนึ่งได้โดยไม่ต้องกังวลเรื่องการฝึกโมเดล

4. ตั้งค่าสภาพแวดล้อม

คุณต้องมีโปรเจ็กต์ Google Cloud Platform ที่เปิดใช้การเรียกเก็บเงินเพื่อเรียกใช้โค้ดแล็บนี้ หากต้องการสร้างโปรเจ็กต์ ให้ทำตามวิธีการที่นี่

ขั้นตอนที่ 1: เปิดใช้ Compute Engine API

ไปที่ Compute Engine แล้วเลือกเปิดใช้ หากยังไม่ได้เปิดใช้

ขั้นตอนที่ 2: เปิดใช้ Vertex AI API

ไปที่ส่วน Vertex AI ของ Cloud Console แล้วคลิกเปิดใช้ Vertex AI API

แดชบอร์ด Vertex AI

ขั้นตอนที่ 3: สร้างอินสแตนซ์ Vertex AI Workbench

จากส่วน Vertex AI ของ Cloud Console ให้คลิก Workbench

เมนู Vertex AI

เปิดใช้ Notebooks API หากยังไม่ได้เปิด

Notebook_api

เมื่อเปิดใช้แล้ว ให้คลิกโน้ตบุ๊กที่มีการจัดการ

Notebooks_UI

จากนั้นเลือกสมุดบันทึกใหม่

new_notebook

ตั้งชื่อสมุดบันทึก แล้วเลือกบัญชีบริการในส่วนสิทธิ์

create_notebook

เลือกการตั้งค่าขั้นสูง

ในส่วนความปลอดภัย ให้เลือก "เปิดใช้เทอร์มินัล" หากยังไม่ได้เปิดใช้

enable_terminal

คุณปล่อยการตั้งค่าขั้นสูงอื่นๆ ทั้งหมดไว้ตามเดิมได้

จากนั้นคลิกสร้าง การจัดสรรอินสแตนซ์จะใช้เวลา 2-3 นาที

เมื่อสร้างอินสแตนซ์แล้ว ให้เลือกเปิด JupyterLab

open_jupyterlab

5. ลงทะเบียนโมเดล

ขั้นตอนที่ 1: อัปโหลดโมเดลไปยัง Cloud Storage

คลิกลิงก์นี้เพื่อไปที่หน้า TensorFlow Hub สำหรับโมเดล MobileNet V1 ที่ฝึกในชุดข้อมูล ImagNet

เลือกดาวน์โหลดเพื่อดาวน์โหลดอาร์ติแฟกต์รูปแบบที่บันทึกไว้

download_model

จากส่วน Cloud Storage ของ Google Cloud Console ให้เลือกสร้าง

create_bucket

ตั้งชื่อที่เก็บข้อมูลและเลือก us-central1 เป็นภูมิภาค จากนั้นคลิกสร้าง

specify_bucket

อัปโหลดโมเดล TensorFlow Hub ที่ดาวน์โหลดไปยังที่เก็บข้อมูล อย่าลืมแตกไฟล์ก่อน

gcs_model

ข้อมูลพร็อพเพอร์ตี้ควรมีลักษณะดังนี้

imagenet_mobilenet_v1_050_128_classification_5/
  saved_model.pb
  variables/
    variables.data-00000-of-00001
    variables.index

ขั้นตอนที่ 2: นําเข้าโมเดลไปยังรีจิสทรี

ไปที่ส่วนรีจิสทรีโมเดล Vertex AI ของ Cloud Console

model_registry

เลือกนําเข้า

เลือกนําเข้าเป็นรูปแบบใหม่ แล้วตั้งชื่อรูปแบบ

name_and_region

ในส่วนการตั้งค่าโมเดล ให้ระบุคอนเทนเนอร์ TensorFlow ที่สร้างไว้ล่วงหน้าล่าสุด จากนั้นเลือกเส้นทางใน Cloud Storage ที่คุณจัดเก็บอาร์ติแฟกต์ของโมเดลไว้

select_container

คุณอาจข้ามส่วนการอธิบายได้

จากนั้นเลือกนําเข้า

เมื่อนำเข้าแล้ว คุณจะเห็นโมเดลในรีจิสทรีโมเดล

imported_model

6. ทำให้โมเดลใช้งานได้

จากรีจิสทรีโมเดล ให้เลือกจุด 3 จุดทางด้านขวาของโมเดลแล้วคลิกทำให้ใช้งานได้ที่ปลายทาง

deploy_model

ในส่วนกำหนดปลายทาง ให้เลือกสร้างปลายทางใหม่ แล้วตั้งชื่อปลายทาง

ในส่วนการตั้งค่าโมเดล ให้ตั้งค่าจํานวนโหนดการประมวลผลสูงสุดเป็น 1 และประเภทเครื่องเป็น n1-standard-2 และตั้งค่าอื่นๆ ทั้งหมดตามเดิม จากนั้นคลิกทำให้ใช้งานได้

endpoint_settings

เมื่อติดตั้งใช้งานแล้ว สถานะการติดตั้งใช้งานจะเปลี่ยนเป็นติดตั้งใช้งานใน Vertex AI

deploy_status

7. รับการคาดการณ์

เปิดโน้ตบุ๊ก Workbench ที่คุณสร้างในขั้นตอนการตั้งค่า สร้างโน้ตบุ๊ก TensorFlow 2 ใหม่จากตัวเปิด

tf_nb

เรียกใช้เซลล์ต่อไปนี้เพื่อนำเข้าไลบรารีที่จำเป็น

from google.cloud import aiplatform

import tensorflow as tf
import numpy as np
from PIL import Image

โมเดล MobileNet ที่คุณดาวน์โหลดจาก TensorFlow Hub ได้รับการฝึกบนชุดข้อมูล ImageNet เอาต์พุตของโมเดล MobileNet คือตัวเลขที่สอดคล้องกับป้ายกำกับคลาสในชุดข้อมูล ImageNet หากต้องการแปลหมายเลขดังกล่าวเป็นป้ายกำกับสตริง คุณจะต้องดาวน์โหลดป้ายกำกับรูปภาพ

# Download image labels

labels_path = tf.keras.utils.get_file('ImageNetLabels.txt','https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())

คุณต้องกําหนดทรัพยากรปลายทางเพื่อเข้าถึงปลายทาง อย่าลืมแทนที่ {PROJECT_NUMBER} และ {ENDPOINT_ID}

PROJECT_NUMBER = "{PROJECT_NUMBER}"
ENDPOINT_ID = "{ENDPOINT_ID}"

endpoint = aiplatform.Endpoint(
    endpoint_name=f"projects/{PROJECT_NUMBER}/locations/us-central1/endpoints/{ENDPOINT_ID}")

คุณดูหมายเลขโปรเจ็กต์ได้ในหน้าแรกของคอนโซล

หมายเลขโปรเจ็กต์

และรหัสปลายทางในส่วนปลายทางของ Vertex AI

endpoint_id

ถัดไป คุณจะต้องทดสอบปลายทาง

ก่อนอื่นให้ดาวน์โหลดอิมเมจต่อไปนี้และอัปโหลดไปยังอินสแตนซ์

test_image

เปิดรูปภาพด้วย PIL จากนั้นปรับขนาดและปรับสเกลเป็น 255 โปรดทราบว่าขนาดรูปภาพที่โมเดลต้องการจะดูได้บนหน้าฮับ TensorFlow ของโมเดล

IMAGE_PATH = "test-image.jpg"
IMAGE_SIZE = (128, 128)

im = Image.open(IMAGE_PATH)
im = im.resize(IMAGE_SIZE
im = np.array(im)/255.0

ถัดไป ให้แปลงข้อมูล NumPy เป็นลิสต์เพื่อให้ส่งในเนื้อหาของคำขอ HTTP ได้

x_test = im.astype(np.float32).tolist()

สุดท้าย ให้เรียกใช้การคาดการณ์กับปลายทาง แล้วค้นหาป้ายกำกับสตริงที่เกี่ยวข้อง

# make prediction request
result = endpoint.predict(instances=[x_test]).predictions

# post process result
predicted_class = tf.math.argmax(result[0], axis=-1)
string_label = imagenet_labels[predicted_class]

print(f"label ID: {predicted_class}")
print(f"string label: {string_label}")

8. [ไม่บังคับ] ใช้การแสดง TF เพื่อเพิ่มประสิทธิภาพการคาดการณ์

สําหรับตัวอย่างที่เหมือนจริงมากขึ้น คุณอาจต้องการส่งรูปภาพไปยังปลายทางโดยตรงแทนการโหลดรูปภาพใน NumPy ก่อน วิธีนี้มีประสิทธิภาพมากกว่า แต่คุณจะต้องแก้ไขฟังก์ชันการแสดงผลของโมเดล TensorFlow การแก้ไขนี้จําเป็นต่อการแปลงข้อมูลอินพุตเป็นรูปแบบที่โมเดลคาดหวัง

ขั้นตอนที่ 1: แก้ไขฟังก์ชันการแสดงโฆษณา

เปิดโน้ตบุ๊ก TensorFlow ใหม่และนําเข้าไลบรารีที่จําเป็น

from google.cloud import aiplatform

import tensorflow as tf

แทนที่จะดาวน์โหลดอาร์ติแฟกต์โมเดลที่บันทึกไว้ คราวนี้คุณจะโหลดโมเดลลงใน TensorFlow โดยใช้ hub.KerasLayer ซึ่งจะรวม TensorFlow savedModel เป็นเลเยอร์ Keras หากต้องการสร้างโมเดล ให้ใช้ Keras Sequential API กับโมเดล TF Hub ที่ดาวน์โหลดมาเพื่อเป็นเลเยอร์ และระบุรูปร่างอินพุตให้กับโมเดล

tfhub_model = tf.keras.Sequential(
    [hub.KerasLayer("https://tfhub.dev/google/imagenet/mobilenet_v1_050_128/classification/5")]
)
tfhub_model.build([None, 128, 128, 3])

กำหนด URI ให้กับที่เก็บข้อมูลที่คุณสร้างไว้ก่อนหน้านี้

BUCKET_URI = "gs://{YOUR_BUCKET}"
MODEL_DIR = BUCKET_URI + "/bytes_model"

เมื่อคุณส่งคําขอไปยังเซิร์ฟเวอร์การคาดการณ์ออนไลน์ เซิร์ฟเวอร์ HTTP จะได้รับคําขอ เซิร์ฟเวอร์ HTTP จะดึงคำขอการคาดการณ์จากเนื้อหาคำขอ HTTP ระบบจะส่งต่อคําขอการคาดการณ์ที่ดึงมายังฟังก์ชันการแสดงผล สําหรับคอนเทนเนอร์การคาดการณ์ที่สร้างไว้ล่วงหน้าของ Vertex AI ระบบจะส่งเนื้อหาคําขอไปยังฟังก์ชันการแสดงผลเป็น tf.string

หากต้องการส่งรูปภาพไปยังบริการการคาดการณ์ คุณจะต้องเข้ารหัสไบต์รูปภาพที่บีบอัดเป็นฐาน 64 ซึ่งจะทำให้เนื้อหาปลอดภัยจากการแก้ไขขณะส่งข้อมูลไบนารีผ่านเครือข่าย

เนื่องจากโมเดลที่ติดตั้งใช้งานต้องการข้อมูลอินพุตเป็นไบต์ดิบ (ไม่มีการบีบอัด) คุณจึงต้องตรวจสอบว่าข้อมูลที่เข้ารหัส Base64 ได้รับการแปลงกลับเป็นไบต์ดิบ (เช่น JPEG) แล้ว จากนั้นประมวลผลล่วงหน้าให้ตรงกับข้อกําหนดของอินพุตโมเดลก่อนที่จะส่งเป็นอินพุตไปยังโมเดลที่ติดตั้งใช้งาน

วิธีแก้ปัญหานี้คือให้กําหนดฟังก์ชันการแสดง (serving_fn) และแนบไปกับโมเดลเป็นขั้นตอนก่อนการประมวลผล คุณเพิ่มตัวตกแต่ง @tf.function เพื่อให้ฟังก์ชันการแสดงผลผสานรวมกับโมเดลพื้นฐาน (แทนที่จะเป็นช่วงต้นบน CPU)

CONCRETE_INPUT = "numpy_inputs"


def _preprocess(bytes_input):
    decoded = tf.io.decode_jpeg(bytes_input, channels=3)
    decoded = tf.image.convert_image_dtype(decoded, tf.float32)
    resized = tf.image.resize(decoded, size=(128, 128))
    return resized


@tf.function(input_signature=[tf.TensorSpec([None], tf.string)])
def preprocess_fn(bytes_inputs):
    decoded_images = tf.map_fn(
        _preprocess, bytes_inputs, dtype=tf.float32, back_prop=False
    )
    return {
        CONCRETE_INPUT: decoded_images
    }  # User needs to make sure the key matches model's input


@tf.function(input_signature=[tf.TensorSpec([None], tf.string)])
def serving_fn(bytes_inputs):
    images = preprocess_fn(bytes_inputs)
    prob = m_call(**images)
    return prob


m_call = tf.function(tfhub_model.call).get_concrete_function(
    [tf.TensorSpec(shape=[None, 128, 128, 3], dtype=tf.float32, name=CONCRETE_INPUT)]
)

tf.saved_model.save(tfhub_model, MODEL_DIR, signatures={"serving_default": serving_fn})

เมื่อคุณส่งข้อมูลสำหรับการคาดการณ์เป็นแพ็กเก็ตคำขอ HTTP ข้อมูลรูปภาพจะเข้ารหัส Base64 แต่โมเดล TensorFlow จะรับอินพุต numpy ฟังก์ชันการแสดงผลจะแปลงจากฐาน 64 ให้เป็นอาร์เรย์ Numpy

เมื่อส่งคําขอการคาดการณ์ คุณต้องกําหนดเส้นทางคําขอไปยังฟังก์ชันการแสดงผลแทนโมเดล คุณจึงจําเป็นต้องทราบชื่อเลเยอร์อินพุตของฟังก์ชันการแสดงผล เรารับชื่อนี้ได้จากลายเซ็นฟังก์ชันการแสดงผล

loaded = tf.saved_model.load(MODEL_DIR)

serving_input = list(
    loaded.signatures["serving_default"].structured_input_signature[1].keys()
)[0]
print("Serving function input name:", serving_input)

ขั้นตอนที่ 2: นําเข้าไปยังรีจิสทรีและทําให้ใช้งานได้

ในส่วนก่อนหน้านี้ คุณได้ดูวิธีนำเข้าโมเดลไปยัง Vertex AI Model Registry ผ่าน UI ในส่วนนี้ คุณจะเห็นวิธีอื่นในการใช้ SDK แทน โปรดทราบว่าคุณยังคงใช้ UI ที่นี่แทนได้หากต้องการ

model = aiplatform.Model.upload(
    display_name="optimized-model",
    artifact_uri=MODEL_DIR,
    serving_container_image_uri="us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-8:latest",
)

print(model)

นอกจากนี้ คุณยังทําให้โมเดลใช้งานได้โดยใช้ SDK แทน UI ได้ด้วย

endpoint = model.deploy(
     deployed_model_display_name='my-bytes-endpoint',
     traffic_split={"0": 100},
     machine_type="n1-standard-4",
     accelerator_count=0,
     min_replica_count=1,
     max_replica_count=1,
   )

ขั้นตอนที่ 3: ทดสอบโมเดล

ตอนนี้คุณทดสอบปลายทางได้แล้ว เนื่องจากเราได้แก้ไขฟังก์ชันการแสดงผลแล้ว ในตอนนี้คุณสามารถส่งรูปภาพได้โดยตรง (เข้ารหัส Base64) ในคำขอแทนที่จะโหลดรูปภาพลงใน NumPy ก่อน วิธีนี้ยังช่วยให้คุณสามารถส่งรูปภาพขนาดใหญ่โดยไม่ถึงขีดจำกัดขนาดสำหรับ Vertex AI Predictions ได้อีกด้วย

ดาวน์โหลดป้ายกำกับรูปภาพอีกครั้ง

import numpy as np
labels_path = tf.keras.utils.get_file('ImageNetLabels.txt','https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt')
imagenet_labels = np.array(open(labels_path).read().splitlines())

เข้ารหัสรูปภาพ Base64

import base64

with open("test-image.jpg", "rb") as f:
    data = f.read()
b64str = base64.b64encode(data).decode("utf-8")

ทำการเรียกใช้การคาดการณ์โดยระบุชื่อเลเยอร์อินพุตของฟังก์ชันการแสดงผลที่เรากำหนดไว้ในตัวแปร serving_input ก่อนหน้านี้

instances = [{serving_input: {"b64": b64str}}]

# Make request
result = endpoint.predict(instances=instances).predictions

# Convert image class to string label
predicted_class = tf.math.argmax(result[0], axis=-1)
string_label = imagenet_labels[predicted_class]

print(f"label ID: {predicted_class}")
print(f"string label: {string_label}")

🎉 ยินดีด้วย 🎉

คุณได้เรียนรู้วิธีใช้ Vertex AI เพื่อทำสิ่งต่อไปนี้

  • โฮสต์และทำให้โมเดลที่ฝึกไว้ล่วงหน้าใช้งานได้

ดูข้อมูลเพิ่มเติมเกี่ยวกับส่วนต่างๆ ของ Vertex ได้ในเอกสารประกอบ

9. ล้างข้อมูล

เนื่องจากสมุดบันทึกที่มีการจัดการของ Vertex AI Workbench มีฟีเจอร์ปิดเครื่องเมื่อไม่มีการใช้งาน เราจึงไม่ต้องกังวลเกี่ยวกับการปิดอินสแตนซ์ หากต้องการปิดอินสแตนซ์ด้วยตนเอง ให้คลิกปุ่มหยุดในส่วน Vertex AI Workbench ของคอนโซล หากต้องการลบสมุดบันทึกทั้งหมด ให้คลิกปุ่ม "ลบ"

หยุดอินสแตนซ์

หากต้องการลบที่เก็บข้อมูล ให้ใช้เมนูการนำทางใน Cloud Console เพื่อไปยังพื้นที่เก็บข้อมูล เลือกที่เก็บข้อมูล แล้วคลิก "ลบ"

ลบพื้นที่เก็บข้อมูล