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 Cloud Platform، وتحليل مجموعات البيانات، وتجربة تقنيات نمذجة مختلفة، وتفعيل النماذج المدرَّبة في بيئة الإنتاج، وإدارة عمليات تعلُّم الآلة من خلال دورة حياة النموذج.
3- نظرة عامة على حالة الاستخدام
في هذا الدرس التطبيقي، ستستكشف مجموعة بيانات تأجير الدراجات في لندن. تحتوي هذه البيانات على معلومات حول رحلات الدراجات من برنامج مشاركة الدراجات العامة في لندن منذ عام 2011. ستبدأ باستكشاف مجموعة البيانات هذه في BigQuery من خلال موصّل BigQuery في Vertex AI Workbench. بعد ذلك، ستحمّل البيانات إلى دفتر ملاحظات Jupyter باستخدام مكتبة 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 وطلبها بسهولة. بالإضافة إلى أي مجموعات بيانات في مشروعك، يمكنك استكشاف مجموعات البيانات في مشاريع أخرى من خلال النقر على الزر إضافة مشروع.

في هذا المختبر، ستستخدم بيانات من مجموعات البيانات العامة في BigQuery. انتقِل للأسفل إلى أن تجد مجموعة بيانات london_bicycles. ستلاحظ أنّ مجموعة البيانات هذه تتضمّن جدولَين، هما cycle_hire وcycle_stations. لنستكشف كلّ منها.

أولاً، انقر مرّتين على جدول cycle_hire. سيظهر الجدول في علامة تبويب جديدة مع مخطّط الجدول بالإضافة إلى البيانات الوصفية، مثل عدد الصفوف والحجم.

إذا نقرت على علامة التبويب معاينة، سيصبح بإمكانك الاطّلاع على عيّنة من البيانات. لننفّذ طلب بحث بسيطًا لمعرفة الرحلات الرائجة. أولاً، انقر على الزر جدول طلبات البحث.

بعد ذلك، ألصِق ما يلي في محرّر 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
من نتائج طلب البحث، ستلاحظ أنّ رحلات الدراجات من محطة "هايد بارك كورنر" وإليها كانت الأكثر رواجًا.

بعد ذلك، انقر نقرًا مزدوجًا على الجدول 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.
إنشاء DataFrame
بعد تنفيذ الاستعلام، انقر على "نسخ الرمز لـ DataFrame". سيسمح لك ذلك بلصق رمز 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 في Python. بدلاً من استخدام هذا 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))
افحص الصفوف القليلة الأولى من DataFrame المنسَّق. بالنسبة إلى كل رحلة بالدراجة، تتوفّر الآن بيانات عن يوم الأسبوع وساعة اليوم التي تمّت فيها الرحلة، بالإضافة إلى المسافة المقطوعة. من هذه المعلومات، ستحاول توقّع المدة التي استغرقتها الرحلة.
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 Functional 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: تحوّل القيم الفئوية الصحيحة إلى فهارس صحيحة.
- طبقة CategoryEncoding: تحوّل الميزات الفئوية الصحيحة إلى تمثيلات كثيفة أحادية أو متعددة أو 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 تغيير الأجهزة بدون إيقاف الجهاز الظاهري. من خلال إضافة وحدة معالجة الرسومات فقط عند الحاجة إليها، يمكنك إبقاء التكاليف منخفضة.
لتغيير ملف الأجهزة، انقر على نوع الجهاز في أعلى يسار الصفحة واختَر تعديل الأجهزة.

انقر على "ربط وحدات معالجة الرسومات" (Attach GPUs) واختَر وحدة معالجة رسومات NVIDIA T4 Tensor Core.

سيستغرق إعداد الجهاز حوالي خمس دقائق. بعد اكتمال العملية، لندرّب النموذج لفترة أطول قليلاً. ستلاحظ أنّ كل حقبة تستغرق وقتًا أقل الآن.
model.fit(train_dataset, validation_data = validation_dataset, epochs = 5)
🎉 تهانينا! 🎉
تعرّفت على كيفية استخدام Vertex AI Workbench لإجراء ما يلي:
- استكشاف البيانات في BigQuery
- استخدام برنامج BigQuery للعميل لتحميل البيانات إلى Python
- تدريب نموذج TensorFlow باستخدام "طبقات المعالجة المُسبقة" في Keras ووحدة معالجة الرسومات
لمزيد من المعلومات عن الأجزاء المختلفة من Vertex AI، اطّلِع على المستندات.
7. تنظيف
بما أنّنا ضبطنا دفتر الملاحظات على أن تنتهي مهلة عدم النشاط بعد 60 دقيقة، لسنا بحاجة إلى إيقاف الجهاز الظاهري. إذا أردت إيقاف الجهاز الافتراضي يدويًا، انقر على الزر "إيقاف" في قسم Vertex AI Workbench في وحدة التحكّم. إذا أردت حذف دفتر الملاحظات بالكامل، انقر على زر "حذف".
