تتمتع نماذج PaliGemma بإمكانات متعددة الوسائط، ما يتيح لك إنشاء مخرجات باستخدام بيانات إدخال النصوص والصور. يمكنك استخدام بيانات الصور مع هذه النماذج لتقديم سياق إضافي لطلباتك، أو استخدام النموذج لتحليل محتوى الصور. يوضّح لك هذا البرنامج التعليمي كيفية استخدام PaliGemma مع Keras لتحليل الصور والإجابة عن الأسئلة حولها.
محتوى دفتر الملاحظات هذا
يستخدم دفتر البيانات هذا PaliGemma مع Keras ويوضّح لك كيفية تنفيذ ما يلي:
- تثبيت Keras والموارد التابعة المطلوبة
- نزِّل
PaliGemmaCausalLM
، وهو أحد أنواع PaliGemma المدرَّبة مسبقًا لوضع نماذج للغة المرئية السببية، واستخدِمه لإنشاء نموذج. - اختبار قدرة النموذج على استنتاج معلومات عن الصور المقدَّمة
قبل البدء
قبل الاطّلاع على دفتر الملاحظات هذا، يجب أن تكون على دراية برمز Python، بالإضافة إلى كيفية تدريب النماذج اللغوية الكبيرة. لست بحاجة إلى معرفة Keras، ولكن المعرفة الأساسية حول Keras تكون مفيدة عند قراءة مثال على الرمز البرمجي.
ضبط إعدادات الجهاز
توضِّح الأقسام التالية الخطوات الأولية للحصول على دفتر ملاحظات لاستخدام نموذج PaliGemma، بما في ذلك الوصول إلى النموذج والحصول على مفتاح واجهة برمجة التطبيقات وضبط وقت تشغيل دفتر الملاحظات.
الحصول على إذن بالوصول إلى PaliGemma
قبل استخدام PaliGemma للمرة الأولى، يجب طلب الوصول إلى النموذج من خلال Kaggle من خلال إكمال الخطوات التالية:
- سجِّل الدخول إلى Kaggle، أو أنشِئ حسابًا جديدًا على Kaggle إذا لم يكن لديك حساب.
- انتقِل إلى بطاقة نموذج PaliGemma وانقر على طلب الوصول.
- أكمِل نموذج الموافقة واقبل الأحكام والشروط.
ضبط مفتاح واجهة برمجة التطبيقات
لاستخدام PaliGemma، يجب تقديم اسم المستخدم الخاص بك على Kaggle ومفتاح Kaggle API.
لإنشاء مفتاح واجهة برمجة التطبيقات Kaggle API، افتح صفحة الإعدادات في Kaggle وانقر على إنشاء رمز مميّز جديد. يؤدي ذلك إلى تنزيل ملف kaggle.json
يحتوي على بيانات اعتماد واجهة برمجة التطبيقات.
بعد ذلك، في Colab، اختَر السرّ (🔑) في اللوحة اليمنى وأضِف اسم المستخدم وعنوان مفتاح Kaggle API في Kaggle. احفظ اسم المستخدم الخاص بك باسم KAGGLE_USERNAME
ومفتاح واجهة برمجة التطبيقات باسم KAGGLE_KEY
.
اختيار وقت التشغيل
لإكمال هذا الدليل التعليمي، ستحتاج إلى بيئة تشغيل Colab تتضمّن موارد كافية لتشغيل نموذج PaliGemma. في هذه الحالة، يمكنك استخدام وحدة معالجة الرسومات T4:
- في أعلى يسار نافذة Colab، انقر على القائمة المنسدلة ▾ (خيارات اتصال إضافية).
- انقر على تغيير نوع بيئة التشغيل.
- ضمن مسرِّع الأجهزة، اختَر وحدة معالجة الرسومات T4.
ضبط متغيّرات البيئة
اضبط متغيّرات البيئة لكلّ من KAGGLE_USERNAME
وKAGGLE_KEY
وKERAS_BACKEND
.
import os
from google.colab import userdata
# Set up environmental variables
os.environ["KAGGLE_USERNAME"] = userdata.get('KAGGLE_USERNAME')
os.environ["KAGGLE_KEY"] = userdata.get('KAGGLE_KEY')
os.environ["KERAS_BACKEND"] = "jax"
تثبيت Keras
شغِّل الخلية أدناه لتثبيت Keras.
pip install -U -q keras-nlp keras-hub kagglehub
استيراد المكوّنات الإضافية وضبط Keras
ثبِّت العناصر التابعة المطلوبة لهذا المفكرة وضبط الخلفية في Keras. ستضبط أيضًا Keras لاستخدام bfloat16
لكي يستخدم إطار العمل مساحة ذاكرة أقل.
import keras
import keras_hub
import numpy as np
import PIL
import requests
import io
import matplotlib
import re
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image
keras.config.set_floatx("bfloat16")
تحميل النموذج
بعد الانتهاء من إعداد كل شيء، يمكنك تنزيل النموذج المدّرب مسبقًا وإنشاء بعض طرق المساعدة لمساعدة النموذج في إنشاء ردود.
في هذه الخطوة، يتم تنزيل نموذج باستخدام PaliGemmaCausalLM
من Keras Hub. تساعدك هذه الفئة في إدارة بنية نموذج اللغة المرئية السببية في PaliGemma وتشغيلها. يتنبّأ نموذج اللغة المرئية السببية بالعنصر التالي استنادًا إلى العناصر السابقة. يوفّر Keras Hub عمليات تنفيذ للعديد من هياكل النماذج الشائعة.
أنشئ النموذج باستخدام الطريقة from_preset
واطبع ملخّصه. سيستغرق إكمال هذه العملية دقيقة واحدة تقريبًا.
paligemma = keras_hub.models.PaliGemmaCausalLM.from_preset("kaggle://keras/paligemma2/keras/pali_gemma2_mix_3b_224")
paligemma.summary()
إنشاء طرق مساعدة
لمساعدتك في إنشاء ردود من النموذج، أنشئ طريقتَي مساعدة:
-
crop_and_resize
: طريقة مساعدة لـread_img
تقتطع هذه الطريقة الصورة وتغيّر حجمها إلى الحجم الذي تم تمريره حتى يتم تغيير حجم الصورة النهائية بدون تشويه نسب الصورة. -
read_img
: طريقة مساعدة لـread_img_from_url
وهذه الطريقة هي التي تفتح الصورة وتغيّر حجمها لتتلاءم مع قيود النموذج، وتضعها في صفيف يمكن للنموذج تفسيره. -
read_img_from_url
: يتم إدخال صورة من خلال عنوان URL صالح. تحتاج إلى هذه الطريقة لتمرير الصورة إلى النموذج.
ستستخدم read_img_from_url
في الخطوة التالية من دفتر البيانات هذا.
def crop_and_resize(image, target_size):
width, height = image.size
source_size = min(image.size)
left = width // 2 - source_size // 2
top = height // 2 - source_size // 2
right, bottom = left + source_size, top + source_size
return image.resize(target_size, box=(left, top, right, bottom))
def read_image(url, target_size):
contents = io.BytesIO(requests.get(url).content)
image = PIL.Image.open(contents)
image = crop_and_resize(image, target_size)
image = np.array(image)
# Remove alpha channel if necessary.
if image.shape[2] == 4:
image = image[:, :, :3]
return image
def parse_bbox_and_labels(detokenized_output: str):
matches = re.finditer(
'<loc(?P<y0>\d\d\d\d)><loc(?P<x0>\d\d\d\d)><loc(?P<y1>\d\d\d\d)><loc(?P<x1>\d\d\d\d)>'
' (?P<label>.+?)( ;|$)',
detokenized_output,
)
labels, boxes = [], []
fmt = lambda x: float(x) / 1024.0
for m in matches:
d = m.groupdict()
boxes.append([fmt(d['y0']), fmt(d['x0']), fmt(d['y1']), fmt(d['x1'])])
labels.append(d['label'])
return np.array(boxes), np.array(labels)
def display_boxes(image, boxes, labels, target_image_size):
h, l = target_size
fig, ax = plt.subplots()
ax.imshow(image)
for i in range(boxes.shape[0]):
y, x, y2, x2 = (boxes[i]*h)
width = x2 - x
height = y2 - y
# Create a Rectangle patch
rect = patches.Rectangle((x, y),
width,
height,
linewidth=1,
edgecolor='r',
facecolor='none')
# Add label
plt.text(x, y, labels[i], color='red', fontsize=12)
# Add the patch to the Axes
ax.add_patch(rect)
plt.show()
def display_segment_output(image, bounding_box, segment_mask, target_image_size):
# Initialize a full mask with the target size
full_mask = np.zeros(target_image_size, dtype=np.uint8)
target_width, target_height = target_image_size
for bbox, mask in zip(bounding_box, segment_mask):
y1, x1, y2, x2 = bbox
x1 = int(x1 * target_width)
y1 = int(y1 * target_height)
x2 = int(x2 * target_width)
y2 = int(y2 * target_height)
# Ensure mask is 2D before converting to Image
if mask.ndim == 3:
mask = mask.squeeze(axis=-1)
mask = Image.fromarray(mask)
mask = mask.resize((x2 - x1, y2 - y1), resample=Image.NEAREST)
mask = np.array(mask)
binary_mask = (mask > 0.5).astype(np.uint8)
# Place the binary mask onto the full mask
full_mask[y1:y2, x1:x2] = np.maximum(full_mask[y1:y2, x1:x2], binary_mask)
cmap = plt.get_cmap('jet')
colored_mask = cmap(full_mask / 1.0)
colored_mask = (colored_mask[:, :, :3] * 255).astype(np.uint8)
if isinstance(image, Image.Image):
image = np.array(image)
blended_image = image.copy()
mask_indices = full_mask > 0
alpha = 0.5
for c in range(3):
blended_image[:, :, c] = np.where(mask_indices,
(1 - alpha) * image[:, :, c] + alpha * colored_mask[:, :, c],
image[:, :, c])
fig, ax = plt.subplots()
ax.imshow(blended_image)
plt.show()
إنشاء الإخراج
بعد تحميل النموذج وإنشاء طرق مساعدة، يمكنك إرسال بيانات الصور والنصوص إلى النموذج لإنشاء الردود. يتم تدريب نماذج PaliGemma باستخدام بنية طلبات محدّدة لمهام محدّدة، مثل answer
وcaption
وdetect
. لمزيد من المعلومات عن بنية مهمة طلب PaliGemma، يُرجى الاطّلاع على تعليمات نظام PaliGemma وطلباته.
حضِّر صورة لاستخدامها في طلب إنشاء باستخدام الرمز البرمجي التالي لتحميل صورة اختبارية في عنصر:
target_size = (224, 224)
image_url = 'https://storage.googleapis.com/keras-cv/models/paligemma/cow_beach_1.png'
cow_image = read_image(image_url, target_size)
matplotlib.pyplot.imshow(cow_image)
الإجابة بلغة معيّنة
يوضّح الرمز البرمجي النموذجي التالي كيفية طلب معلومات من نموذج PaliGemma عن عنصر يظهر في صورة مقدَّمة. يستخدم هذا المثال بنية answer {lang}
ويعرض أسئلة إضافية بلغات أخرى:
prompt = 'answer en where is the cow standing?\n'
# prompt = 'svar no hvor står kuen?\n'
# prompt = 'answer fr quelle couleur est le ciel?\n'
# prompt = 'responda pt qual a cor do animal?\n'
output = paligemma.generate(
inputs={
"images": cow_image,
"prompts": prompt,
}
)
print(output)
استخدام طلب detect
يستخدم الرمز البرمجي النموذجي التالي بنية طلب detect
لتحديد موقع عنصر في الصورة المقدَّمة. يستخدم الرمز الدالتَين parse_bbox_and_labels()
وdisplay_boxes()
المحدّدتَين سابقًا لتفسير مخرجات النموذج وعرض المربّعات الحدودية التي تم إنشاؤها.
prompt = 'detect cow\n'
output = paligemma.generate(
inputs={
"images": cow_image,
"prompts": prompt,
}
)
boxes, labels = parse_bbox_and_labels(output)
display_boxes(cow_image, boxes, labels, target_size)
استخدام طلب segment
يستخدم الرمز البرمجي التالي بنية طلب segment
لتحديد موقع منطقة الصورة التي يشغلها عنصر. ويستخدم هذا الإجراء مكتبة big_vision
من Google لتفسير مخرجات النموذج وإنشاء قناع للجسم المقسّم.
قبل البدء، ثبِّت مكتبة big_vision
ومواردها التابعة، كما هو موضّح في مثال الرمز البرمجي التالي:
import os
import sys
# TPUs with
if "COLAB_TPU_ADDR" in os.environ:
raise "It seems you are using Colab with remote TPUs which is not supported."
# Fetch big_vision repository if python doesn't know about it and install
# dependencies needed for this notebook.
if not os.path.exists("big_vision_repo"):
!git clone --quiet --branch=main --depth=1 \
https://github.com/google-research/big_vision big_vision_repo
# Append big_vision code to python import path
if "big_vision_repo" not in sys.path:
sys.path.append("big_vision_repo")
# Install missing dependencies. Assume jax~=0.4.25 with GPU available.
!pip3 install -q "overrides" "ml_collections" "einops~=0.7" "sentencepiece"
في مثال التقسيم هذا، حمِّل صورة مختلفة تتضمّن قطة وأعدّها.
cat = read_image('https://big-vision-paligemma.hf.space/file=examples/barsik.jpg', target_size)
matplotlib.pyplot.imshow(cat)
في ما يلي دالة للمساعدة في تحليل ناتج المقطع من PaliGemma.
import big_vision.evaluators.proj.paligemma.transfers.segmentation as segeval
reconstruct_masks = segeval.get_reconstruct_masks('oi')
def parse_segments(detokenized_output: str) -> tuple[np.ndarray, np.ndarray]:
matches = re.finditer(
'<loc(?P<y0>\d\d\d\d)><loc(?P<x0>\d\d\d\d)><loc(?P<y1>\d\d\d\d)><loc(?P<x1>\d\d\d\d)>'
+ ''.join(f'<seg(?P<s{i}>\d\d\d)>' for i in range(16)),
detokenized_output,
)
boxes, segs = [], []
fmt_box = lambda x: float(x) / 1024.0
for m in matches:
d = m.groupdict()
boxes.append([fmt_box(d['y0']), fmt_box(d['x0']), fmt_box(d['y1']), fmt_box(d['x1'])])
segs.append([int(d[f's{i}']) for i in range(16)])
return np.array(boxes), np.array(reconstruct_masks(np.array(segs)))
طلب البحث من PaliGemma لتقسيم القطة في الصورة
prompt = 'segment cat\n'
output = paligemma.generate(
inputs={
"images": cat,
"prompts": prompt,
}
)
عرض القناع الذي تم إنشاؤه من PaliGemma
bboxes, seg_masks = parse_segments(output)
display_segment_output(cat, bboxes, seg_masks, target_size)
طلبات مجمّعة
يمكنك تقديم أكثر من طلب واحد في طلب واحد كمجموعة من التعليمات. يوضّح المثال التالي كيفية تنظيم نص الطلب لتقديم تعليمات متعدّدة.
prompts = [
'answer en where is the cow standing?\n',
'answer en what color is the cow?\n',
'describe en\n',
'detect cow\n',
'segment cow\n',
]
images = [cow_image, cow_image, cow_image, cow_image, cow_image]
outputs = paligemma.generate(
inputs={
"images": images,
"prompts": prompts,
}
)
for output in outputs:
print(output)