Gjeneroni dalje PaliGemma me Keras

Modelet PaliGemma kanë aftësi multimodale , duke ju lejuar të gjeneroni rezultate duke përdorur të dhëna hyrëse të tekstit dhe imazhit. Ju mund të përdorni të dhënat e imazheve me këto modele për të ofruar kontekst shtesë për kërkesat tuaja, ose përdorni modelin për të analizuar përmbajtjen e imazheve. Ky tutorial ju tregon se si të përdorni PaliGemma me Keras për të analizuar imazhet dhe për t'iu përgjigjur pyetjeve rreth tyre.

Çfarë ka në këtë fletore

Kjo fletore përdor PaliGemma me Keras dhe ju tregon se si të:

  • Instaloni Keras dhe varësitë e kërkuara
  • Shkarko PaliGemmaCausalLM , një variant PaliGemma i trajnuar paraprakisht për modelimin shkakor të gjuhës vizuale, dhe përdore atë për të krijuar një model
  • Testoni aftësinë e modelit për të nxjerrë informacione rreth imazheve të ofruara

Para se të filloni

Përpara se të kaloni nëpër këtë fletore, duhet të njiheni me kodin Python, si dhe me mënyrën se si trajnohen modelet e mëdha të gjuhës (LLM). Ju nuk keni nevojë të jeni të njohur me Keras, por njohuritë bazë rreth Keras janë të dobishme kur lexoni kodin e shembullit.

Konfigurimi

Seksionet e mëposhtme shpjegojnë hapat paraprak për marrjen e një fletoreje për të përdorur një model PaliGemma, duke përfshirë aksesin në model, marrjen e një çelësi API dhe konfigurimin e kohës së funksionimit të fletores.

Merrni akses në PaliGemma

Përpara se të përdorni PaliGemma për herë të parë, duhet të kërkoni qasje në model përmes Kaggle duke kryer hapat e mëposhtëm:

  1. Hyni në Kaggle ose krijoni një llogari të re Kaggle nëse nuk e keni tashmë një të tillë.
  2. Shkoni te karta e modelit PaliGemma dhe klikoni " Kërkoni qasje" .
  3. Plotësoni formularin e pëlqimit dhe pranoni termat dhe kushtet.

Konfiguro çelësin tënd API

Për të përdorur PaliGemma, duhet të jepni emrin tuaj të përdoruesit Kaggle dhe një çelës Kaggle API.

Për të gjeneruar një çelës Kaggle API, hapni faqen e Cilësimeve në Kaggle dhe klikoni Krijo Token të Ri . Kjo shkakton shkarkimin e një skedari kaggle.json që përmban kredencialet tuaja API.

Më pas, në Colab, zgjidhni Secrets (🔑) në panelin e majtë dhe shtoni emrin tuaj të përdoruesit Kaggle dhe çelësin Kaggle API. Ruani emrin tuaj të përdoruesit nën emrin KAGGLE_USERNAME dhe çelësin tuaj API nën emrin KAGGLE_KEY .

Zgjidhni kohën e ekzekutimit

Për të përfunduar këtë tutorial, do t'ju duhet të keni një kohë ekzekutimi Colab me burime të mjaftueshme për të ekzekutuar modelin PaliGemma. Në këtë rast, mund të përdorni një GPU T4:

  1. Në këndin e sipërm djathtas të dritares së Colab, klikoni menunë rënëse ▾ (Opsione shtesë të lidhjes) .
  2. Zgjidhni Ndrysho llojin e kohës së funksionimit .
  3. Nën Përshpejtuesi i harduerit , zgjidhni T4 GPU .

Vendosni variablat e mjedisit

Cakto variablat e mjedisit për KAGGLE_USERNAME , KAGGLE_KEY dhe 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"

Instaloni Keras

Ekzekutoni qelizën e mëposhtme për të instaluar Keras.

pip install -U -q keras-nlp keras-hub kagglehub

Importoni varësitë dhe konfiguroni Keras

Instaloni varësitë e nevojshme për këtë fletore dhe konfiguroni backend-in e Keras. Ju gjithashtu do të vendosni Keras të përdorë bfloat16 në mënyrë që korniza të përdorë më pak memorie.

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")

Ngarkoni modelin

Tani që keni vendosur gjithçka, mund të shkarkoni modelin e trajnuar paraprakisht dhe të krijoni disa metoda të dobishme për të ndihmuar modelin tuaj të gjenerojë përgjigjet e tij. Në këtë hap, ju shkarkoni një model duke përdorur PaliGemmaCausalLM nga Keras Hub. Kjo klasë ju ndihmon të menaxhoni dhe ekzekutoni strukturën e modelit të gjuhës vizuale shkakësore të PaliGemma. Një model i gjuhës pamore kauzale parashikon shenjën tjetër bazuar në shenjat e mëparshme. Keras Hub ofron implementime të shumë arkitekturave të modeleve të njohura.

Krijoni modelin duke përdorur metodën from_preset dhe printoni përmbledhjen e tij. Ky proces do të marrë rreth një minutë për të përfunduar.

paligemma = keras_hub.models.PaliGemmaCausalLM.from_preset("kaggle://keras/paligemma2/keras/pali_gemma2_mix_3b_224")
paligemma.summary()

Krijoni metoda të shërbimeve

Për t'ju ndihmuar të gjeneroni përgjigje nga modeli juaj, krijoni dy metoda të dobishme:

  • crop_and_resize : Metoda ndihmëse për read_img . Kjo metodë pret dhe ndryshon madhësinë e imazhit në madhësinë e kaluar në mënyrë që imazhi përfundimtar të ndryshohet pa anuar përmasat e imazhit.
  • read_img : Metoda ndihmëse për read_img_from_url . Kjo metodë është ajo që në fakt hap imazhin, e ndryshon atë në mënyrë që të përshtatet në kufizimet e modelit dhe e vendos atë në një grup që mund të interpretohet nga modeli.
  • read_img_from_url : Merr një imazh nëpërmjet një URL të vlefshme. Ju duhet kjo metodë për t'ia kaluar imazhin modelit.

Ju do të përdorni read_img_from_url në hapin tjetër të kësaj fletoreje.

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()

Gjeneroni prodhim

Pas ngarkimit të modelit dhe krijimit të metodave të shërbimeve, mund ta nxisni modelin me të dhëna imazhi dhe teksti për të gjeneruar një përgjigje. Modelet PaliGemma janë trajnuar me sintaksë specifike të shpejtë për detyra specifike, të tilla si answer , caption dhe detect . Për më shumë informacion në lidhje me sintaksën e detyrës së shpejtë PaliGemma, shihni udhëzimet e kërkesës dhe sistemit të PaliGemma .

Përgatitni një imazh për përdorim në një kërkesë gjenerimi duke përdorur kodin e mëposhtëm për të ngarkuar një imazh provë në një objekt:

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)

Përgjigjuni në një gjuhë të caktuar

Kodi i shembullit të mëposhtëm tregon se si të kërkohet modeli PaliGemma për informacion rreth një objekti që shfaqet në një imazh të dhënë. Ky shembull përdor sintaksën e answer {lang} dhe tregon pyetje shtesë në gjuhë të tjera:

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)

Përdorni detect e shpejtë

Kodi i shembullit të mëposhtëm përdor sintaksën e shpejtë detect për të gjetur një objekt në imazhin e dhënë. Kodi përdor funksionet e përcaktuara më parë parse_bbox_and_labels() dhe display_boxes() për të interpretuar daljen e modelit dhe për të shfaqur kutitë e krijuara kufizuese.

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)

Përdorni kërkesën e segment

Kodi i shembullit të mëposhtëm përdor sintaksën e promptit të segment për të gjetur zonën e një imazhi të zënë nga një objekt. Ai përdor bibliotekën e Google big_vision për të interpretuar daljen e modelit dhe për të gjeneruar një maskë për objektin e segmentuar.

Para se të filloni, instaloni bibliotekën big_vision dhe varësitë e saj, siç tregohet në këtë shembull kodi:

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"

Për këtë shembull segmentimi, ngarkoni dhe përgatitni një imazh tjetër që përfshin një mace.

cat = read_image('https://big-vision-paligemma.hf.space/file=examples/barsik.jpg', target_size)
matplotlib.pyplot.imshow(cat)

Këtu është një funksion për të ndihmuar në analizimin e prodhimit të segmentit nga 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)))

Pyet PaliGemma për të segmentuar macen në imazh

prompt = 'segment cat\n'
output = paligemma.generate(
    inputs={
        "images": cat,
        "prompts": prompt,
    }
)

Vizualizoni maskën e krijuar nga PaliGemma

bboxes, seg_masks = parse_segments(output)
display_segment_output(cat, bboxes, seg_masks, target_size)

Kërkesat e grupit

Ju mund të jepni më shumë se një komandë prompt brenda një prompt të vetëm si një grup udhëzimesh. Shembulli i mëposhtëm tregon se si të strukturoni tekstin tuaj të shpejtë për të dhënë udhëzime të shumta.

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)