۱. مقدمه
در این آزمایشگاه کد، ما در مورد کاربرد ذخیرهسازی و تحلیل تصاویر حرکات یوگا در BigQuery و پیادهسازی یک مدل طبقهبندی با BigQuery ML برای برچسبگذاری حرکات تنها با استفاده از ساختارهای SQL و بدون هیچ نوع کد دیگری بحث خواهیم کرد.
بیگکوئری و BQML
بیگکوئری یک انبار داده چند ابری بدون سرور است که میتواند از بایت تا پتابایت با سربار عملیاتی صفر مقیاسپذیر باشد. این امر آن را به انتخابی عالی برای ذخیره دادههای آموزشی یادگیری ماشین تبدیل میکند. علاوه بر این، قابلیتهای یادگیری ماشینی ( BQML ) و تحلیلی داخلی بیگکوئری به شما امکان میدهد پیشبینیهای بدون کد را فقط با استفاده از کوئریهای SQL ایجاد کنید. و میتوانید با کوئریهای فدرال به دادهها از منابع خارجی دسترسی پیدا کنید و نیاز به خطوط لوله ETL پیچیده را از بین ببرید. میتوانید اطلاعات بیشتر در مورد هر آنچه بیگکوئری ارائه میدهد را در صفحه بیگکوئری بخوانید.
تاکنون، ما BigQuery را به عنوان یک انبار داده ابری کاملاً مدیریتشده میشناسیم که به کاربران در تجزیه و تحلیل دادههای ساختاریافته و نیمهساختاریافته کمک میکند. اما،
- بیگکوئری (BigQuery) گسترش یافته است تا تمام تجزیه و تحلیلها و یادگیری ماشین را روی دادههای بدون ساختار نیز انجام دهد.
- ما میتوانیم از کوئریهای SQL برای انجام تحلیلهای عمیق، تجزیه و تحلیل و یادگیری ماشین روی تصاویر، ویدیوها، صدا و غیره در مقیاس بزرگ و بدون نیاز به نوشتن کد اضافی استفاده کنیم.
- ما این توانایی را داریم که دادههای ساختاریافته و بدون ساختار را طوری ترکیب کنیم که انگار همه آنها در یک جدول با هم وجود دارند.
ما این موارد را در مورد کاربرد طبقهبندی حرکات یوگا که در بخش بعدی پوشش داده شده است، مورد بحث قرار خواهیم داد.
طبقهبندی دادههای تصویر با BigQuery ML
توانایی پردازش و تجزیه و تحلیل تصاویر با استفاده از پرسوجوهای ساختاریافته، گویی دادههای ساختاریافته هستند، اولین مورد از این نوع است. اکنون حتی میتوانیم با استفاده از مدلهای طبقهبندی یادگیری ماشین با استفاده از BigQuery ML، نتایج را پیشبینی کنیم. من مراحل مربوطه را برای درک آسان به 5 مرحله تقسیم کردهام:

مراحل فوق اگر فقط به عنوان برچسب به آنها نگاه کنیم، میتوانند پیچیده باشند. جزئیات هر یک از اجزای درگیر مانند BigQuery Dataset، اتصال BigLake، Cloud Storage Buckets (Containers)، Object Table (External data source)، BQML و غیره، همگی در بخش پیادهسازی تعریف شدهاند. بنابراین اگر هنوز با این اصطلاحات آشنا نیستید، ناامید نشوید.
آنچه خواهید ساخت
شما یک مدل طبقهبندی دادههای تصویر با BQML ایجاد خواهید کرد که موارد زیر را پوشش میدهد:
- یک مجموعه داده BigQuery برای شامل کردن اجزای جدول و مدل
- سطل ذخیرهسازی ابری گوگل (GCS) برای ذخیره تصاویر یوگا برای مدل
- یک جدول خارجی برای دسترسی به تصاویر ذخیرهسازی ابری
- یک اتصال BigLake برای جدول خارجی جهت دسترسی به تصاویر موجود در GCS
- مدل ResNet در BigQuery ML
- استنتاج با استفاده از مدل ایجاد شده
- BigQuery SQL برای تجزیه و تحلیل دادههای تصویر
- BigQuery SQL برای جستجوی دادههای ساختاریافته و بدون ساختار با هم
آنچه یاد خواهید گرفت
- نحوه ایجاد یک فضای ذخیرهسازی ابری و ذخیره تصاویر
- نحوه ایجاد مجموعه داده، جدول و اتصال BigQuery
- نحوه ایجاد یک مدل طبقهبندی دادههای تصویر با استفاده از BQML
- نحوه پیشبینی با مدل ایجاد شده با استفاده از BigQuery ML
- نحوه پرس و جو از تصاویر و ترکیب آنها با دادههای ساختار یافته با استفاده از BigQuery SQLs
۲. الزامات
۳. ایجاد مجموعه داده و اتصال BigLake
برای مورد استفاده ما که تشخیص تصویر ۵ حالت یوگا است، از مجموعه دادههای عمومی استفاده کردهام و شما میتوانید از این مخزن به مجموعه دادهها دسترسی داشته باشید. حالتهای یوگایی که ما شناسایی میکنیم محدود به Downdog، Goddess، Plank، Tree و Warrior2 هستند. قبل از شروع ایجاد مجموعه دادههای BigQuery، مطمئن شوید که یک پروژه Google Cloud را انتخاب یا ایجاد کردهاید و بررسی کنید که آیا پرداخت در پروژه فعال است یا خیر. BigQuery API و BigQuery Connection API را فعال کنید . لطفاً توجه داشته باشید که تمام سرویسهای مورد استفاده در این پیادهسازی باید در همان منطقه انتخابی باشند.
الف. مجموعه داده "yoga_set" را با استفاده از مراحل نشان داده شده در زیر ایجاد کنید:
به ویرایشگر BigQuery بروید و دستور زیر را تایپ کنید:
CREATE SCHEMA `<<project_id>>.yoga_set`;
ب. اتصال BigLake به ما این امکان را میدهد که ضمن حفظ کنترل دسترسی و امنیت دقیق BigQuery، به منبع داده خارجی متصل شویم، که در مورد ما، فضای ذخیرهسازی ابری برای دادههای تصویر است. ما از این اتصال برای خواندن اشیاء از فضای ذخیرهسازی ابری استفاده خواهیم کرد. برای ایجاد اتصال BigLake، مراحل زیر را دنبال کنید.
روی افزودن داده (ADD DATA) در پنل اکسپلورر صفحه BigQuery کلیک کنید:
صفحه "افزودن دادههای خارجی" در BigQuery
روی Connections to external data sources کلیک کنید و گزینه BigLake and Remote functions را انتخاب کنید:
پیکربندی اتصال منبع داده خارجی
شناسه اتصال را وارد کرده و اتصال را ایجاد کنید. به یاد داشته باشید که شناسه حساب سرویس را که پس از ایجاد اتصال روی صفحه نمایش داده میشود، یادداشت کنید <<SERVICE_ACCOUNT>>. در مثال ما، شناسه اتصال "yoga-pose-conn" است. به یاد داشته باشید که منطقه را یادداشت کنید.
۴. ایجاد سطل ذخیرهسازی ابری گوگل و اعطای مجوزها
ما قصد داریم از مخزن ذخیرهسازی ابری گوگل (Google Cloud Storage bucket) برای نگهداری فایلهای تصویری حرکات یوگا که میخواهیم مدل را روی آنها ایجاد کنیم، استفاده کنیم. مخزنها، محفظههای ذخیرهسازی ابری هستند که تصاویری را که قرار است تجزیه و تحلیل کنیم، در خود جای میدهند.
الف) با جستجوی عبارت «Google Cloud Storage» در کنسول، به آن بروید و سپس روی «Buckets» کلیک کنید تا به صفحه اصلی «Buckets» هدایت شوید و روی «CREATE» کلیک کنید.
صفحه سطلهای ذخیرهسازی ابری گوگل
ب. در صفحه ایجاد یک سطل، اطلاعات سطل خود (یک نام منحصر به فرد) را وارد کنید و ادامه دهید، مطمئن شوید که در همان منطقه مجموعه داده و اتصال مورد بحث در مراحل بالا قرار دارد و روی ایجاد کلیک کنید
فضای ذخیرهسازی ابری گوگل (Google Cloud Storage) یک صفحه باکت (Bucket Page) ایجاد کنید
قبل از رفتن به مرحله بعدی، مطمئن شوید که حساب سرویس، نام باکت و مسیر خود را یادداشت کردهاید.
ج. پس از ایجاد سطل، تصاویر خود را (از طریق کنسول یا دستورات Cloud Shell یا به صورت برنامهنویسی) ذخیره کنید و مجوزهای لازم را برای حساب سرویس اتصال (که قبلاً ذخیره کردیم) برای دسترسی به تصاویر اعطا کنید.
> export sa=<<"SERVICE_ACCOUNT">>
> gsutil iam ch serviceAccount:$sa:objectViewer "gs://<<bucket>>"
۵. ایجاد یک جدول اشیاء
یک جدول شیء خارجی از BigQuery ایجاد کنید تا با استفاده از اتصالی که ایجاد کردیم به دادههای بدون ساختار موجود در سطل دسترسی پیدا کنید. دستور CREATE SQL زیر را از ویرایشگر BigQuery اجرا کنید:
CREATE OR REPLACE EXTERNAL TABLE `<<dataset>>.<<table_name>>`
WITH CONNECTION `us.<<connection-name>>`
OPTIONS(
object_metadata="SIMPLE", uris=["gs://<<bucket>>/<<folder_if_exists>>/*.jpg"]);
جدول خارجی مطابق شکل زیر ایجاد میشود:

بیایید به سرعت یک پوز را از جدول خارجی تازه ایجاد شده پرس و جو کنیم:
SELECT data , uri
FROM `yoga_set.yoga_poses`
WHERE REGEXP_CONTAINS(uri, 'gs://yoga_images/Downdog')
Limit 1;
همانطور که در تصویر زیر مشاهده میکنید، میتوانید تصاویر بدون ساختار را طوری ایجاد و روی آنها کار کنید که انگار دادههای ساختاریافته هستند:

حالا بیایید نتیجه کوئری بالا را به یک قطعه کد کوچک پایتون تبدیل کنیم تا نتیجه را به صورت بصری مشاهده کنیم:
روی ذخیره نتایج کلیک کنید و گزینه "CSV Localfile" را برای خروجی گرفتن از نتیجه انتخاب کنید. سپس دفترچه یادداشت Colab خود را باز کنید (یا یکی ایجاد کنید ) و کد زیر را تایپ کنید
from IPython.display import display
from PIL import Image
import io
import pandas as pd
import base64
df = pd.read_csv('/content/sample_data/<<your_csv>>')
imgdata = base64.b64decode(str(df.data[0]))
image = Image.open(io.BytesIO(imgdata))
display(image)
برای مشاهده نتیجه به صورت زیر اجرا کنید:

اکنون که جدول خارجی را ایجاد کردهایم و فقط با استفاده از کوئریهای SQL به تصاویر از فضای ذخیرهسازی ابری دسترسی پیدا کردهایم، به بخش بعدی که ایجاد مدل طبقهبندی است، میرویم.
۶. مدل را ایجاد کنید و آن را در فضای ذخیرهسازی ابری گوگل آپلود کنید
برای این پیادهسازی، ما قصد داریم از مدل ResNet 50 از پیش آموزشدیده برای اجرای استنتاج روی جدول شیء که اخیراً ایجاد کردهایم، استفاده کنیم. مدل ResNet 50 فایلهای تصویر را تجزیه و تحلیل میکند و دستهای از بردارها را که نشاندهنده احتمال تعلق یک تصویر به کلاس مربوطه (logits) هستند، خروجی میدهد.
قبل از رفتن به این مرحله، مطمئن شوید که تمام مجوزهای لازم را دارید. سپس مراحل زیر را دنبال کنید:
- مدل را از این مکان دانلود کنید و آن را در سیستم محلی خود ذخیره کنید
- باید در saved_model.pb و پوشهی variables از حالت فشرده خارج شود.
- این دو (فایل و پوشه) را در باکتی که در بخش قبلی ایجاد کردیم، آپلود کنید.
سطل ذخیرهسازی ابری گوگل با نام "yoga_images" که فایلهای مدل ResNet در آن آپلود شدهاند
پس از تکمیل این مرحله، فایلهای مربوط به مدل شما باید در همان پوشهای که تصاویر شما در تصویر بالا نشان داده شدهاند، قرار داشته باشند.
۷. مدل را در BQML بارگذاری کنید و Infer را اجرا کنید
در این مرحله، ما قصد داریم مدل را در همان مجموعه داده BigQuery که جدول خارجی قبلاً ایجاد کردهایم، بارگذاری کنیم و آن را برای تصاویری که در فضای ذخیرهسازی ابری ذخیره کردهایم، اعمال کنیم.
الف) از ویرایشگر BigQuery، دستور SQL زیر را اجرا کنید
CREATE MODEL `<<Dataset>>.<<Model_Name>>`
OPTIONS(
model_type = 'TENSORFLOW',
model_path = 'gs://<<Bucket>>/*');
پس از اتمام اجرا (که بسته به مجموعه داده شما ممکن است مدتی طول بکشد)، مدل فهرست شده در بخش مجموعه داده خود در BigQuery را مشاهده خواهید کرد.
مجموعه داده BigQuery که مدل ایجاد شده را فهرست میکند
ب. مدل را بررسی کنید تا فیلدهای ورودی و خروجی آن را ببینید.
مجموعه دادهها را باز کنید و روی مدلی که تازه ایجاد کردهایم "yoga_poses_resnet" کلیک کنید. روی تب Schema کلیک کنید:
تب طرحواره تعریف مدل BigQuery
در بخش برچسبها، فیلد "activation_49" را میبینید که نشاندهنده فیلد خروجی است. در بخش ویژگیها، میتوانید "input_1" را ببینید که نشاندهنده فیلدی است که انتظار میرود به عنوان ورودی به مدل وارد شود. شما در پرسوجوی استنتاج (یا پرسوجوی پیشبینی) خود، به "input_1" به عنوان فیلدی که برای دادههای "آزمایشی" خود ارسال میکنید، ارجاع خواهید داد.
ج) حالت یوگای خود را حدس بزنید!
بیایید از مدلی که تازه ایجاد کردهایم برای طبقهبندی دادههای تصویر آزمایشی خود استفاده کنیم. مطمئن شوید که چند تصویر آزمایشی (حرکات یوگا) از سطل ذخیرهسازی ابری خود که هنگام ایجاد جدول خارجی به آن راه یافتهاند، شناسایی کردهاید. ما قصد داریم به صورت انتخابی برای آن تصاویر آزمایشی در BigQuery پرسوجو کنیم تا با استفاده از مدل BQML که تازه ایجاد کردهایم، استنتاج را انجام دهیم. از پرسوجوی زیر برای شروع آزمون استفاده کنید.
SELECT *
FROM ML.PREDICT(
MODEL yoga_set.yoga_poses_resnet,
(SELECT uri, ML.DECODE_IMAGE(data) AS input_1
FROM yoga_set.yoga_poses where REGEXP_CONTAINS(uri,
'gs://yoga_images/Downdog/00000097.jpg')));
در پرسوجوی بالا، ما یک تصویر آزمایشی را انتخاب میکنیم که مشخص شده حاوی یک مقدار URI خاص (00000097.jpg) در جدول خارجی است. همچنین، بخش SELECT از ساختار ML.DECODE_IMAGE به عنوان فیلد "input_1" استفاده میکند تا تابع ML.PREDICT بتواند کار کند.
پس از اتمام اجرا، نتیجه را مطابق شکل زیر مشاهده خواهید کرد:

حالا برای کسانی که مدل ResNet را عمیقاً میشناسند، این باید به درک طبقهبندی کمک کند. در غیر این صورت، بیایید یک قطعه کد کوچک بنویسیم تا طبقهبندی را به صورت بصری درک کنیم.
د. مسطح کردن نتیجه
یکی از راههای نمایش خروجی فوق، مسطح کردن مقادیر فیلد activation_49 با استفاده از ساختار UNNEST در BigQuery SQL است. لطفاً برای مسطح کردن نتیجه از مرحله قبل، به کوئری زیر مراجعه کنید. اگر میخواهید کلاس حاصل را بیشتر برچسبگذاری متنی کنید، میتوانید منطق را به جای <<LABEL_LOGIC>> در کوئری وارد کنید (هنگام استفاده، آن را از حالت کامنت خارج کنید).
with predictions as (
SELECT
Uri, data, SPLIT(uri, "/")[OFFSET(ARRAY_LENGTH(SPLIT(uri, "/")) - 1)] as img,
i as label_i,
<<LABEL_LOGIC>> label,
Score
FROM ML.PREDICT(
MODEL yoga_set.yoga_poses_resnet,
(SELECT data, uri, ML.DECODE_IMAGE(data) AS input_1
FROM yoga_set.yoga_poses
WHERE
REGEXP_CONTAINS(uri,'gs://yoga_images/Goddess/00000007.jpg'))),
UNNEST(activation_49) as score WITH OFFSET i)
SELECT * FROM predictions
ORDER BY score DESC
LIMIT 5;
بدون منطق برچسبگذاری کلاس، خروجی کوئری به صورت زیر است:

با این حال، در مورد من، یک منطق نمونه اعمال کردهام و نتیجه در زیر آمده است:

میتوانید درباره مدل بیشتر بخوانید و منطقی را که با دادهها و خروجی مدل شما بهترین عملکرد را دارد، اعمال کنید.
ه. تجسم استنتاج
در نهایت، یک قطعه کد پایتون سریع برای نمایش بصری نتیجه حاصل از طبقهبندی! نتیجه کوئری بالا را به یک فایل CSV اکسپورت کنید و آن را در کد پایتون ارجاع دهید.

خروجی تصویر بالا به حرکت یوگای "سگ رو به پایین" اشاره دارد که دقیقاً همان ورودی آزمایشی است که ما برای طبقهبندی با استفاده از BQML به کوئری ML.PREDICT ارسال کردیم!
۸. یکپارچهسازی دادههای ساختاریافته و بدون ساختار
در نهایت، بخش مورد علاقه من در این پیادهسازی، یکپارچهسازی فیلدهای جدول رابطهای ساختاریافتهام با این دادههای تصویر بدون ساختار است. من یک جدول BigQuery ساختاریافته در همان مجموعه داده جدول خارجی ایجاد کردم تا ژست و دادههای مرتبط با سلامت آن را در خود نگه دارد.
طرحواره جدول ساختاریافته BigQuery با عنوان "yoga_health"
تصویر بالا طرح جدول دادههای ساختاریافته با نام "yoga_health" را نشان میدهد و فیلدهای آن عبارتند از pose، focus، health_benefit و breath. کوئری زیر دادههای ساختاریافته و بدون ساختار را به هم متصل میکند:
SELECT SPLIT(uri, "/")[OFFSET(ARRAY_LENGTH(SPLIT(uri, "/")) - 2)] as pose,
a.health_benefit, breath, focus, data
FROM `abis-345004.yoga_set.yoga_health` a, yoga_set.yoga_poses b
WHERE a.pose = SPLIT(uri, "/")[OFFSET(ARRAY_LENGTH(SPLIT(uri, "/")) - 2)];
نتیجه در زیر آمده است:

توجه: تمام کوئریهایی که در این وبلاگ پوشش دادهایم را میتوان مستقیماً از نوتبوک پایتون شما با استفاده از دستورات BigQuery Magic اجرا کرد.
۹. تمیز کردن
برای جلوگیری از تحمیل هزینه به حساب Google Cloud خود برای منابع استفاده شده در این پست، این مراحل را دنبال کنید.
- در کنسول گوگل کلود، به صفحه مدیریت منابع بروید
- در لیست پروژهها، پروژهای را که میخواهید حذف کنید انتخاب کنید و سپس روی «حذف» کلیک کنید.
- در کادر محاورهای، شناسه پروژه را تایپ کنید و سپس برای حذف پروژه، روی خاموش کردن کلیک کنید.
۱۰. تبریک
تبریک! شما با موفقیت دادههای بدون ساختار را در BigQuery ذخیره و جستجو کردید، یک مدل طبقهبندی با استفاده از BQML ایجاد کردید و با استفاده از مدل، حالتهای یوگای آزمایشی را پیشبینی کردید. اگر مایل به پیادهسازی این موارد هستید، پروژه Google Cloud خود را شروع کنید. همچنین، اگر مایل به کسب اطلاعات بیشتر در مورد پایگاههای داده یا سایر پیادهسازیهای برنامههای کاربردی سرتاسری در Google Cloud هستید، لطفاً به وبلاگهای من سر بزنید.