1. نظرة عامة
في هذا الدرس العملي، ستتعرّف على كيفية استخدام Vertex AI Workbench لاستكشاف البيانات وتدريب نماذج تعلُّم الآلة.
المعلومات التي تطّلع عليها
وستتعرّف على كيفية:
- إنشاء مثيل Vertex AI Workbench وإعداده
- استخدام أداة ربط BigQuery في Vertex AI Workbench
- تدريب نموذج على نواة Vertex AI Workbench
تبلغ التكلفة الإجمالية لتنفيذ هذا البرنامج التدريبي على Google Cloud حوالي 1 دولار أمريكي.
2. مقدّمة عن Vertex AI
يستخدم هذا المختبر أحدث منتجات الذكاء الاصطناعي المتاحة على Google Cloud. تدمج Vertex AI عروض تعلُّم الآلة في Google Cloud في تجربة تطوير سلسة. في السابق، كان بالإمكان الوصول إلى النماذج المدربة باستخدام AutoML والنماذج المخصّصة من خلال خدمات منفصلة. ويدمج العرض الجديد كلاً من واجهة برمجة تطبيقات واحدة مع منتجات جديدة أخرى. يمكنك أيضًا نقل المشاريع الحالية إلى Vertex AI.
تتضمّن Vertex AI العديد من المنتجات المختلفة لدعم سير عمل تعلُّم الآلة من البداية إلى النهاية. سيركز هذا الدرس التطبيقي على Vertex AI Workbench.
تساعد أداة Vertex AI Workbench المستخدمين في إنشاء سير عمل مستندة إلى دفاتر ملاحظات بشكلٍ سريع من خلال الدمج المكثّف مع خدمات البيانات (مثل Dataproc وDataflow وBigQuery وDataplex) وVertex AI. ويتيح هذا الإطار لعلماء البيانات الاتصال بخدمات بيانات "خدمات Google للسحابة الإلكترونية" وتحليل مجموعات البيانات وتجربة تقنيات نمذجة مختلفة ونشر النماذج المدربة في مرحلة الإنتاج وإدارة عمليات MLOps خلال دورة حياة النموذج.
3- نظرة عامة على حالة الاستخدام
في هذا الدرس التطبيقي، ستستكشف مجموعة بيانات تأجير الدراجات في لندن. تحتوي هذه البيانات على معلومات عن رحلات الدراجات من برنامج مشاركة الدراجات العامة في لندن منذ عام 2011. ستبدأ باستكشاف مجموعة البيانات هذه في BigQuery من خلال أداة ربط BigQuery في Vertex AI Workbench. بعد ذلك، ستحمِّل البيانات إلى Jupyter Notebook باستخدام pandas وتُدرِّب نموذج TensorFlow لتوقع مدة رحلة الدراجة استنادًا إلى وقت حدوث الرحلة والمسافة التي قطعها الشخص بالدراجة.
يستخدِم هذا البرنامج التعليمي طبقات المعالجة المُسبَقة في Keras لتحويل بيانات الإدخال وإعدادها لتدريب النموذج. تسمح لك واجهة برمجة التطبيقات هذه بإنشاء عمليات المعالجة المسبقة مباشرةً في الرسم البياني لنموذج TensorFlow، ما يقلّل من مخاطر انحراف التطبيق/العرض عن طريق التأكّد من خضوع بيانات التدريب وبيانات العرض لعمليات تحويل متطابقة. يُرجى العِلم أنّ واجهة برمجة التطبيقات هذه أصبحت مستقرة اعتبارًا من الإصدار 2.6 من TensorFlow. إذا كنت تستخدم إصدارًا قديمًا من TensorFlow، عليك استيراد الرمز التجريبي.
4. إعداد البيئة
ستحتاج إلى مشروع Google Cloud Platform مع تفعيل الفوترة لتشغيل هذا الدرس التطبيقي حول الترميز. لإنشاء مشروع، يُرجى اتّباع التعليمات هنا.
الخطوة 1: تفعيل واجهة برمجة التطبيقات Compute Engine API
انتقِل إلى Compute Engine (محرك الحوسبة) واختَر تفعيل إذا لم يكن مفعّلاً.
الخطوة 2: تفعيل Vertex AI API
انتقِل إلى قسم Vertex AI في Cloud Console وانقر على تفعيل واجهة برمجة التطبيقات Vertex AI API.
الخطوة 3: إنشاء مثيل Vertex AI Workbench
من قسم Vertex AI في Cloud Console، انقر على Workbench:
فعِّل Notebooks API إذا لم يسبق لك تفعيلها.
بعد تفعيل هذه الميزة، انقر على دفاتر الملاحظات المُدارة:
بعد ذلك، اختَر دفتر ملاحظات جديد.
أدخِل اسمًا لدفتر الملاحظات، وضمن الإذن، اختَر حساب الخدمة.
انقر على الإعدادات المتقدّمة.
ضمن الأمان، اختَر "تفعيل الوحدة الطرفية" إذا لم يسبق لك تفعيلها.
يمكنك ترك جميع الإعدادات المتقدّمة الأخرى كما هي.
بعد ذلك، انقر على إنشاء.
بعد إنشاء المثيل، اختَر فتح JUPYTERLAB.
5- استكشاف مجموعة البيانات في BigQuery
في مثيل Vertex AI Workbench، انتقِل إلى الجانب الأيمن وانقر على أداة الربط BigQuery في دفاتر البيانات.
يسمح لك موصل BigQuery باستكشاف مجموعات بيانات BigQuery والاستعلام عنها بسهولة. بالإضافة إلى أي مجموعات بيانات في مشروعك، يمكنك استكشاف مجموعات البيانات في مشاريع أخرى من خلال النقر على الزر Add Project (إضافة مشروع).
في هذا المختبر، ستستخدم بيانات من مجموعات البيانات العامة في BigQuery. انتقِل للأسفل إلى أن تعثر على مجموعة البيانات london_bicycles. ستلاحظ أنّ مجموعة البيانات هذه تتضمّن جدولَين، cycle_hire وcycle_stations. لنستكشف كلًّا منها.
أولاً، انقر مرّتين على الجدول cycle_hire. سيظهر لك أنّ الجدول يفتح كعلامة تبويب جديدة تتضمّن مخطط الجدول بالإضافة إلى بيانات وصفية مثل عدد الصفوف والحجم.
في حال النقر على علامة التبويب Preview (معاينة)، يمكنك الاطّلاع على عيّنة من البيانات. لنجري طلب بحث بسيطًا لمعرفة الرحلات الرائجة. أولاً، انقر على الزر جدول طلبات البحث.
بعد ذلك، الصِق ما يلي في محرِّر SQL وانقر على إرسال طلب بحث.
SELECT
start_station_name,
end_station_name,
IF(start_station_name = end_station_name,
TRUE,
FALSE) same_station,
AVG(duration) AS avg_duration,
COUNT(*) AS total_rides
FROM
`bigquery-public-data.london_bicycles.cycle_hire`
GROUP BY
start_station_name,
end_station_name,
same_station
ORDER BY
total_rides DESC
من نتائج الطلب، ستلاحظ أنّ رحلات الدراجات من وإلى محطة Hyde Park Corner كانت الأكثر رواجًا.
بعد ذلك، انقر مرّتين على الجدول cycle_stations الذي يوفر معلومات حول كل محطة.
نريد دمج جدولَي cycle_hire وcycle_stations. يحتوي جدول cycle_stations على خطي الطول والعرض لكل محطة. ستستخدم هذه المعلومات لتقدير المسافة المقطوعة في كل رحلة بالدراجة من خلال حساب المسافة بين محطتي البداية والنهاية.
لإجراء هذا الحساب، ستستخدم دوالّ BigQuery الجغرافية. على وجه التحديد، ستحوّل كل سلسلة من سلاسل خطوط الطول/العرض إلى ST_GEOGPOINT وستستخدِم الدالة ST_DISTANCE لاحتساب المسافة المستقيمة بالكيلومترات بين النقطتَين. ستستخدم هذه القيمة كبديل للمسافة المقطوعة في كل رحلة بالدراجة.
انسخ طلب البحث التالي في محرِّر SQL، ثم انقر على "إرسال طلب البحث". لاحظ أن هناك ثلاثة جداول في شرط JOIN لأننا نحتاج إلى ضم جدول المحطات مرتين للحصول على خطوط الطول/العرض لكل من محطة بداية الدورة ومحطة النهاية.
WITH staging AS (
SELECT
STRUCT(
start_stn.name,
ST_GEOGPOINT(start_stn.longitude, start_stn.latitude) AS POINT,
start_stn.docks_count,
start_stn.install_date
) AS starting,
STRUCT(
end_stn.name,
ST_GEOGPOINT(end_stn.longitude, end_stn.latitude) AS point,
end_stn.docks_count,
end_stn.install_date
) AS ending,
STRUCT(
rental_id,
bike_id,
duration, --seconds
ST_DISTANCE(
ST_GEOGPOINT(start_stn.longitude, start_stn.latitude),
ST_GEOGPOINT(end_stn.longitude, end_stn.latitude)
) AS distance, --meters
start_date,
end_date
) AS bike
FROM `bigquery-public-data.london_bicycles.cycle_stations` AS start_stn
LEFT JOIN `bigquery-public-data.london_bicycles.cycle_hire` as b
ON start_stn.id = b.start_station_id
LEFT JOIN `bigquery-public-data.london_bicycles.cycle_stations` AS end_stn
ON end_stn.id = b.end_station_id
LIMIT 700000)
SELECT * from STAGING
6- تدريب نموذج تعلُّم آلة على نواة TensorFlow
تتضمّن Vertex AI Workbench طبقة توافق مع وحدات الحساب تتيح لك تشغيل نوى TensorFlow وPySpark وR وغيرها، وكل ذلك من مثيل دفتر ملاحظات واحد. في هذا الدرس التطبيقي، ستُنشئ دفتر ملاحظات باستخدام نواة TensorFlow.
إنشاء إطار بيانات
بعد تنفيذ الاستعلام، انقر على "نسخ رمز إطار البيانات". سيتيح لك ذلك لصق رمز Python في دفتر ملاحظات يتصل بخادم BigQuery ويستخرج هذه البيانات كجدول بيانات pandas.
بعد ذلك، ارجع إلى "مشغّل التطبيقات" وأنشِئ ورقة ملاحظات TensorFlow 2.
في الخلية الأولى من دفتر البيانات، الصِق الرمز الذي نسخته من "محرر الاستعلامات". من المفترض أن يظهر العنصر بالشكل التالي:
# The following two lines are only necessary to run once.
# Comment out otherwise for speed-up.
from google.cloud.bigquery import Client, QueryJobConfig
client = Client()
query = """WITH staging AS (
SELECT
STRUCT(
start_stn.name,
ST_GEOGPOINT(start_stn.longitude, start_stn.latitude) AS POINT,
start_stn.docks_count,
start_stn.install_date
) AS starting,
STRUCT(
end_stn.name,
ST_GEOGPOINT(end_stn.longitude, end_stn.latitude) AS point,
end_stn.docks_count,
end_stn.install_date
) AS ending,
STRUCT(
rental_id,
bike_id,
duration, --seconds
ST_DISTANCE(
ST_GEOGPOINT(start_stn.longitude, start_stn.latitude),
ST_GEOGPOINT(end_stn.longitude, end_stn.latitude)
) AS distance, --meters
start_date,
end_date
) AS bike
FROM `bigquery-public-data.london_bicycles.cycle_stations` AS start_stn
LEFT JOIN `bigquery-public-data.london_bicycles.cycle_hire` as b
ON start_stn.id = b.start_station_id
LEFT JOIN `bigquery-public-data.london_bicycles.cycle_stations` AS end_stn
ON end_stn.id = b.end_station_id
LIMIT 700000)
SELECT * from STAGING"""
job = client.query(query)
df = job.to_dataframe()
لأغراض هذا البرنامج التدريبي، سنقتصر على استخدام 700, 000 عنصر من مجموعة البيانات لتقليل وقت التدريب. ولكن لا تتردد في تعديل طلب البحث والتجربة مع مجموعة البيانات بأكملها.
بعد ذلك، استورِد المكتبات اللازمة.
from datetime import datetime
import pandas as pd
import tensorflow as tf
شغِّل الرمز البرمجي التالي لإنشاء إطار بيانات مُعدَّل يحتوي فقط على الأعمدة المطلوبة لجزء تعلُّم الآلة من هذا التمرين.
values = df['bike'].values
duration = list(map(lambda a: a['duration'], values))
distance = list(map(lambda a: a['distance'], values))
dates = list(map(lambda a: a['start_date'], values))
data = pd.DataFrame(data={'duration': duration, 'distance': distance, 'start_date':dates})
data = data.dropna()
عمود start_date هو datetime
في بايثون. وعند استخدام datetime
في النموذج مباشرةً، ستنشئ ميزتين جديدتين تشيران إلى اليوم من الأسبوع والساعة من اليوم التي حدثت فيها رحلة الدراجة.
data['weekday'] = data['start_date'].apply(lambda a: a.weekday())
data['hour'] = data['start_date'].apply(lambda a: a.time().hour)
data = data.drop(columns=['start_date'])
أخيرًا، يمكنك تحويل عمود المدة من ثوانٍ إلى دقائق لتسهيل فهمه.
data['duration'] = data['duration'].apply(lambda x:float(x / 60))
راجِع الصفوف القليلة الأولى من إطار البيانات المنسَّق. لكل رحلة بالدراجة، تتوفّر لك الآن بيانات عن يوم الأسبوع وساعة اليوم التي حدثت فيها الرحلة، بالإضافة إلى المسافة المقطوعة. ومن خلال هذه المعلومات، ستحاول التنبؤ بالمدة التي استغرقتها الرحلة.
data.head()
قبل أن تتمكّن من إنشاء النموذج وتدريبه، عليك تقسيم البيانات إلى مجموعات تدريب ومجموعات التحقّق.
# Use 80/20 train/eval split
train_size = int(len(data) * .8)
print ("Train size: %d" % train_size)
print ("Evaluation size: %d" % (len(data) - train_size))
# Split data into train and test sets
train_data = data[:train_size]
val_data = data[train_size:]
إنشاء نموذج TensorFlow
ستنشئ نموذج TensorFlow باستخدام Keras function API. لمعالجة بيانات الإدخال مسبقًا، ستستفيد من واجهة برمجة التطبيقات لطبقات المعالجة المُسبَقة في Keras.
ستنشئ دالة الأداة التالية tf.data.Dataset
من إطار بيانات pandas.
def df_to_dataset(dataframe, label, shuffle=True, batch_size=32):
dataframe = dataframe.copy()
labels = dataframe.pop(label)
ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))
if shuffle:
ds = ds.shuffle(buffer_size=len(dataframe))
ds = ds.batch(batch_size)
ds = ds.prefetch(batch_size)
return ds
استخدِم الدالة أعلاه لإنشاء tf.data.Dataset
َين، أحدهما للتدريب والآخر للتحقّق من الصحة. قد تظهر لك بعض التحذيرات، ولكن يمكنك تجاهلها بأمان.
train_dataset = df_to_dataset(train_data, 'duration')
validation_dataset = df_to_dataset(val_data, 'duration')
ستستخدم طبقات المعالجة المسبقة التالية في النموذج:
- طبقة التسويّة: تُجري تسوية ميزات الإدخال حسب الميزة.
- طبقة IntegerLookup: تعمل على تحويل القيم الفئوية الصحيحة إلى فهارس صحيحة.
- طبقة ترميز الفئات: تحوّل الميزات الفئوية الصحيحة إلى تمثيلات كثيفة أحادية القيمة أو متعددة القيم أو TF-IDF.
يُرجى العِلم أنّ هذه الطبقات لا يمكن تدريبها. بدلاً من ذلك، يمكنك ضبط حالة طبقة المعالجة المُسبَقة من خلال عرضها على بيانات التدريب، وذلك من خلال طريقة adapt()
.
ستنشئ الدالة التالية طبقة تسويّة يمكنك استخدامها في ميزة المسافة. ستضبط الحالة قبل ملاءمة النموذج باستخدام طريقة adapt()
على بيانات التدريب. سيؤدي هذا إلى حساب المتوسط والتباين المراد استخدامه للتسوية. لاحقًا، عند تمرير مجموعة بيانات التحقق من الصحة إلى النموذج، سيتم استخدام نفس المتوسط والتباين المحسوب على بيانات التدريب لقياس بيانات التحقق من الصحة.
def get_normalization_layer(name, dataset):
# Create a Normalization layer for our feature.
normalizer = tf.keras.layers.Normalization(axis=None)
# Prepare a Dataset that only yields our feature.
feature_ds = dataset.map(lambda x, y: x[name])
# Learn the statistics of the data.
normalizer.adapt(feature_ds)
return normalizer
وبالمثل، تنشئ الدالة التالية ترميزًا للفئة ستستخدمه في ميزتَي الساعة واليوم الأسبوعي.
def get_category_encoding_layer(name, dataset, dtype, max_tokens=None):
index = tf.keras.layers.IntegerLookup(max_tokens=max_tokens)
# Prepare a Dataset that only yields our feature
feature_ds = dataset.map(lambda x, y: x[name])
# Learn the set of possible values and assign them a fixed integer index.
index.adapt(feature_ds)
# Create a Discretization for our integer indices.
encoder = tf.keras.layers.CategoryEncoding(num_tokens=index.vocabulary_size())
# Apply one-hot encoding to our indices. The lambda function captures the
# layer so we can use them, or include them in the functional model later.
return lambda feature: encoder(index(feature))
بعد ذلك، أنشئ جزء المعالجة المُسبَقة من النموذج. أولاً، أنشئ طبقة tf.keras.Input
لكلّ ميزة.
# Create a Keras input layer for each feature
numeric_col = tf.keras.Input(shape=(1,), name='distance')
hour_col = tf.keras.Input(shape=(1,), name='hour', dtype='int64')
weekday_col = tf.keras.Input(shape=(1,), name='weekday', dtype='int64')
بعد ذلك، أنشئ طبقات تسويف البيانات وترميز الفئات، واحفظها في قائمة.
all_inputs = []
encoded_features = []
# Pass 'distance' input to normalization layer
normalization_layer = get_normalization_layer('distance', train_dataset)
encoded_numeric_col = normalization_layer(numeric_col)
all_inputs.append(numeric_col)
encoded_features.append(encoded_numeric_col)
# Pass 'hour' input to category encoding layer
encoding_layer = get_category_encoding_layer('hour', train_dataset, dtype='int64')
encoded_hour_col = encoding_layer(hour_col)
all_inputs.append(hour_col)
encoded_features.append(encoded_hour_col)
# Pass 'weekday' input to category encoding layer
encoding_layer = get_category_encoding_layer('weekday', train_dataset, dtype='int64')
encoded_weekday_col = encoding_layer(weekday_col)
all_inputs.append(weekday_col)
encoded_features.append(encoded_weekday_col)
بعد تحديد طبقات المعالجة المُسبَقة، يمكنك تحديد بقية النموذج. ستسلسل جميع ميزات الإدخال، وتُمرّرها إلى طبقة كثيفة. طبقة الإخراج هي وحدة واحدة نظرًا لأن هذه مشكلة انحدار.
all_features = tf.keras.layers.concatenate(encoded_features)
x = tf.keras.layers.Dense(64, activation="relu")(all_features)
output = tf.keras.layers.Dense(1)(x)
model = tf.keras.Model(all_inputs, output)
أخيرًا، عليك تجميع النموذج.
model.compile(optimizer = tf.keras.optimizers.Adam(0.001),
loss='mean_squared_logarithmic_error')
بعد أن حدّدت النموذج، يمكنك عرض البنية
tf.keras.utils.plot_model(model, show_shapes=True, rankdir="LR")
يُرجى العِلم أنّ هذا النموذج معقّد إلى حدٍ ما بالنسبة إلى مجموعة البيانات البسيطة هذه. وهو مخصّص لأغراض توضيحية.
لنتدرّب لمدة دورة واحدة فقط للتأكّد من أنّ الرمز ينفذ.
model.fit(train_dataset, validation_data = validation_dataset, epochs = 1)
تدريب النموذج باستخدام وحدة معالجة الرسومات
بعد ذلك، ستُجري تدريبًا على النموذج لفترة أطول وستستخدم أداة تبديل الأجهزة لتسريع عملية التدريب. يتيح لك Vertex AI Workbench تغيير الجهاز بدون إيقاف تشغيل المثيل. يمكنك خفض التكاليف من خلال إضافة وحدة معالجة الرسومات فقط عند الحاجة إليها.
لتغيير الملف الشخصي للأجهزة، انقر على نوع الجهاز في أعلى يسار الصفحة واختَر تعديل الأجهزة.
انقر على "إرفاق وحدات معالجة الرسومات" ثم اختَر وحدة معالجة الرسومات NVIDIA T4 Tensor Core GPU.
سيستغرق ضبط الجهاز حوالي خمس دقائق. بعد اكتمال العملية، لنتمرن على النموذج لفترة أطول قليلاً. ستلاحظ أنّ كل دورة تدريب تستغرق وقتًا أقل الآن.
model.fit(train_dataset, validation_data = validation_dataset, epochs = 5)
🎉 تهانينا. 🎉
لقد تعرّفت على كيفية استخدام Vertex AI Workbench لإجراء ما يلي:
- استكشاف البيانات في BigQuery
- استخدام برنامج BigQuery client لتحميل البيانات إلى Python
- تدريب نموذج TensorFlow باستخدام طبقات المعالجة المُسبَقة في Keras ووحدة معالجة الرسومات
لمزيد من المعلومات عن الأجزاء المختلفة من Vertex AI، اطّلِع على المستندات.
7- تنظيف
بما أنّنا ضبطنا دفتر البيانات على إيقافه بعد 60 دقيقة من عدم النشاط، لا داعي للقلق بشأن إيقافه. إذا أردت إيقاف المثيل يدويًا، انقر على زر "إيقاف" في قسم Vertex AI Workbench من وحدة التحكّم. إذا أردت حذف دفتر الملاحظات بالكامل، انقر على الزر "حذف".