目前業界廣泛使用大語言模型(LLM)建構問答系統,但大多侷限於純文字資料。本篇文章將探討如何結合影像和文字資料,構建一個多模態模組化檢索增強生成(RAG)系統。此係統利用 LlamaIndex 建立多模態查詢引擎,並使用 OpenAI GPT 模型生成更豐富的答案。透過 VisDrone 無人機資料集,我們示範如何將影像和文字資訊整合,並利用邊界框技術精確標示影像中的物體,最終實作更精準、更直觀的問答體驗。系統設計重點在於如何有效地結合不同模態的資料,並利用深度學習技術提升模型的理解和推理能力。

查詢文字資料集

一旦文字資料集被載入,查詢引擎被建立,使用者輸入被定義為基準查詢,過程就會繼續:玄貓。

(G1)、(G2) 和 (G4) 在同一無縫的 LlamaIndex 過程中重疊,該過程既檢索資料又生成內容。 回應被儲存為 llm_response,在會話期間保持有效。

查詢多模態 VisDrone 資料集

多模態 VisDrone 資料集將被載入記憶體並查詢:

(D4) 多模態過程從玄貓開始,然後選擇一張影像並新增邊界框。

建立多模態查詢引擎

(D4) 使用 LlamaIndex 建立多模態查詢引擎,該過程與 (G4) 重疊,因為它既作為檢索器又作為生成器,使用 OpenAI GPT 模型。

(G1) 多模態查詢引擎的使用者輸入與多模態模組化 RAG 的使用者輸入相同,因為它同時用於 LLM 查詢引擎(針對文字資料集)和多模態查詢引擎(針對 VisDrone 資料集)。

處理回應

(G1)、(G2) 和 (G4) 在同一無縫的 LlamaIndex 查詢中重疊,執行在 VisDrone 多模態資料集上的查詢。

處理回應 (G4) 以找到源節點並檢索其影像,導致傳回 (D4) 進行影像檢索。這導致選擇和處理源節點的影像。

合併輸出

(G4) 我們呈現了一個合併輸出,包含 LLM 回應和多模態 回應的增強輸出,在一個多模態模組化摘要中。

(E) 最後,我們建立了一個 LLM 效能指標和一個多模態效能指標。然後,我們將它們加起來作為一個多模態模組化 RAG 效能指標。

多模態模組化問答系統

系統概覽

多模態模組化問答系統是一種可以回答關於無人機技術的問題,並使用文字和影像進行回答的系統。該系統使用邊界框(bounding boxes)來顯示影像和識別影像中的物體。

效能指標

系統的效能指標包括影像分析的準確性,使用GPT-4等模型進行影像分析和文字回答。這些指標用於評估系統的多模態模組化回答的準確性。

資料集

在本章中,我們將使用在第2章中建立的LLM資料集。請確保您已經建立了這個資料集,因為我們將在本章中載入它。

實作步驟

以下是實作多模態模組化問答系統的步驟:

  1. 載入LLM資料集:我們將載入在第3章中建立的無人機資料集。請確保插入您的資料集路徑。
import deeplake

dataset_path_llm = "hub://denis76/drone_v2"

ds_llm = deeplake.load(dataset_path_llm)
  1. 建立字典和載入資料:我們將建立一個字典來持有資料,並將其載入到一個pandas DataFrame中以進行視覺化。
import json
import pandas as pd
import numpy as np

# 建立字典來持有資料
data_llm = {}

圖表翻譯

以下是圖表的視覺化表示:

  flowchart TD
    A[載入LLM資料集] --> B[建立字典和載入資料]
    B --> C[視覺化資料]
    C --> D[回答問題]

圖表解釋

此圖表顯示了多模態模組化問答系統的工作流程。首先,我們載入LLM資料集,然後建立一個字典來持有資料並將其載入到一個pandas DataFrame中。最後,我們使用此資料來回答問題。

內容解密

以下是程式碼的詳細解釋:

  • 我們使用deeplake函式庫來載入LLM資料集。
  • 我們建立一個字典data_llm來持有資料。
  • 我們使用pandas函式庫來將資料載入到一個DataFrame中。

多模態模組化問答系統有廣泛的應用前景,包括但不限於:

  • 無人機技術問答
  • 影像分析和識別
  • 自然語言處理和生成

執行多模態模組化RAG系統

在本文中,我們將探討如何執行多模態模組化RAG(Retrieval-Augmented Generation)系統。首先,我們需要對資料集進行預處理,包括將張量資料轉換為適合的格式。

預處理資料集

import numpy as np
import pandas as pd

# 載入資料集
ds_llm =...

# 初始化空字典來儲存預處理後的資料
data_llm = {}

# 迭代張量資料
for tensor_name in ds_llm.tensors:
    tensor_data = ds_llm[tensor_name].numpy()
    
    # 檢查張量是否為多維
    if tensor_data.ndim > 1:
        # 將多維張量扁平化
        data_llm[tensor_name] = [np.array(e).flatten().tolist() for e in tensor_data]
    else:
        # 將1D張量直接轉換為列表
        if tensor_name == "text":
            data_llm[tensor_name] = [t.tobytes().decode('utf-8') for t in tensor_data]
        else:
            data_llm[tensor_name] = tensor_data.tolist()

# 建立Pandas DataFrame
df_llm = pd.DataFrame(data_llm)

初始化LLM查詢引擎

接下來,我們需要初始化LLM查詢引擎。這涉及建立一個向量儲存索引從檔案集合中,並組態它為查詢引擎。

from llama_index import VectorStoreIndex, GPTVectorStoreIndex

# 載入檔案集合
documents_llm =...

# 建立向量儲存索引
vector_store_index_llm = GPTVectorStoreIndex.from_documents(documents_llm)

# 組態查詢引擎
vector_query_engine_llm = vector_store_index_llm.as_query_engine()

使用者輸入

現在,我們需要定義使用者輸入,以便於評估系統的能力。這個輸入將作為查詢的基礎,允許系統生成全面和準確的回應。

user_input = "How do drones identify a truck?"

查詢文字資料集

最後,我們可以執行向量查詢引擎請求,以便從文字資料集中檢索相關資訊。

import time
import textwrap

# 執行查詢請求
start_time = time.time()
result = vector_query_engine_llm.query(user_input)
end_time = time.time()

# 處理查詢結果
print("Query Result:")
print(textwrap.fill(result, width=80))
print(f"Query Time: {end_time - start_time} seconds")

這樣,我們就完成了多模態模組化RAG系統的執行,包括預處理資料集、初始化LLM查詢引擎、定義使用者輸入和查詢文字資料集。

使用 Deeplake 載入和探索 VisDrone 多模態無人機資料集

在本文中,我們將使用 Deeplake 載入和探索 VisDrone 多模態無人機資料集。VisDrone 是一個公開的無人機檢測資料集,包含了大量的無人機影像和相關的標註資訊。

載入資料集

首先,我們需要載入 VisDrone 資料集。Deeplake 提供了一個簡單的方式來載入資料集:

import deeplake

dataset_path = 'hub://activeloop/visdrone-det-train'
ds = deeplake.load(dataset_path)

這段程式碼載入了 VisDrone 資料集,並傳回一個 Deeplake Dataset 物件。

探索資料集

載入資料集後,我們可以使用 summary() 方法來探索資料集的結構和內容:

ds.summary()

這段程式碼會輸出資料集的摘要資訊,包括資料集的路徑、只讀模式、tensor 的型別、形狀、資料型別和壓縮資訊等。

顯示資料集摘要

以下是資料集摘要的輸出:

Dataset(path='hub://activeloop/visdrone-det-train', read_only=True)
tensor  htype  shape  dtype  compressi
------  -----  -----  -----  --------
boxes   bbox  (6471, 1:914, 4)  float32  No
images  image  (6471, 360:1500, 3)  uint8  No

這個輸出告訴我們,資料集包含兩個 tensor:boxesimagesboxes tensor 的形狀為 (6471, 1:914, 4),表示它包含 6471 個 bounding box,每個 bounding box 有 4 個座標(x, y, w, h)。images tensor 的形狀為 (6471, 360:1500, 3),表示它包含 6471 個影像,每個影像的大小為 360x1500,且有 3 個色彩通道(RGB)。

視覺化資料集

Deeplake 提供了一個簡單的方式來視覺化資料集。以下是使用 Jupyter Notebook 視覺化資料集的示例:

import matplotlib.pyplot as plt

# 載入第一張影像
image = ds['images'][0]

# 顯示影像
plt.imshow(image)
plt.show()

這段程式碼載入了第一張影像,並使用 Matplotlib 顯示它。

圖表翻譯:

  graph LR
    A[載入資料集] --> B[探索資料集]
    B --> C[顯示資料集摘要]
    C --> D[視覺化資料集]

這個圖表顯示了載入、探索、顯示和視覺化資料集的流程。

影像資料集分析

首先,我們需要了解資料集的結構。資料集包含影像、邊界盒和標籤。邊界盒是物體在影像中的位置和大小,標籤則描述了影像和邊界盒的內容。

資料集視覺化

為了更好地理解資料集,我們可以使用 ds.visualize() 函式來視覺化資料集。這將顯示影像和其邊界盒。

ds.visualize()

資料集內容

接下來,我們可以使用 Pandas DataFrame 來顯示資料集的內容。這將幫助我們瞭解影像、邊界盒和標籤的格式。

import pandas as pd

df = pd.DataFrame(columns=['image', 'boxes', 'labels'])

for i, sample in enumerate(ds):
    df.loc[i, 'image'] = sample.images.tobytes()
    boxes_list = sample.boxes.numpy(aslist=True)
    df.loc[i, 'boxes'] = [box.tolist() for box in boxes_list]
    label_data = sample.labels.data()
    df.loc[i, 'labels'] = label_data['text']

print(df)

資料集結構

從輸出結果中,我們可以看到資料集包含 6,471 行影像和 3 列:影像、邊界盒和標籤。

  • 影像欄位包含影像本身,以 JPEG 格式儲存。
  • 邊界盒欄位包含邊界盒的座標和尺寸,通常以 [x, y, width, height] 格式表示。
  • 標籤欄位包含邊界盒的標籤。

標籤列表

最後,我們可以顯示影像的標籤列表。

labels_list = ds.labels.info['class_names']
print(labels_list)

圖表翻譯:

  graph LR
    A[資料集] --> B[影像]
    A --> C[邊界盒]
    A --> D[標籤]
    B --> E[JPEG 格式]
    C --> F[座標和尺寸]
    D --> G[標籤列表]

內容解密:

上述程式碼展示瞭如何分析和視覺化資料集。首先,我們使用 ds.visualize() 函式來顯示影像和其邊界盒。接下來,我們使用 Pandas DataFrame 來顯示資料集的內容,包括影像、邊界盒和標籤。最後,我們顯示影像的標籤列表。這些步驟幫助我們瞭解資料集的結構和內容。

載入多模態資料集

首先,我們需要載入資料集並瞭解其結構。資料集包含多種型別的物體,包括行人、腳踏車、汽車、卡車等。載入資料集後,我們可以看到資料集中的標籤列表,該列表定義了資料集的範圍。

瀏覽多模態資料集結構

接下來,我們將選擇一張影像並使用資料集的影像欄位進行顯示。然後,我們將為選擇的影像新增所選標籤的邊界框。首先,我們選擇資料集中的第一張影像。

選擇和顯示影像

我們選擇資料集中的第一張影像,並使用以下程式碼進行顯示:

ind = 0
image = ds.images[ind].numpy()  # 取得第一張影像

然後,我們使用以下程式碼將影像顯示為RGB格式:

import cv2  # 匯入OpenCV
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # 將BGR轉換為RGB
img = Image.fromarray(image_rgb)  # 建立PIL影像
display(img)  # 顯示影像

顯示的影像包含卡車、行人和其他型別的物體。

新增邊界框和儲存影像

現在,我們已經顯示了第一張影像。接下來,我們將為選擇的影像新增邊界框。首先,我們取得選擇的影像的所有標籤:

labels = ds.labels[ind].data()  # 取得選擇的影像的標籤
print(labels)

輸出的結果包含數值索引和對應的文字標籤。我們可以使用以下程式碼將數值和文字標籤顯示在兩列中:

print("Value\tText")
for value, text in zip(labels["value"], labels["text"]):
    print(f"{value}\t{text}")

這將顯示數值索引和對應的文字標籤。

內容解密:

上述程式碼使用了以下步驟:

  1. 載入資料集並瞭解其結構。
  2. 選擇一張影像並使用資料集的影像欄位進行顯示。
  3. 為選擇的影像新增所選標籤的邊界框。
  4. 取得選擇的影像的所有標籤。
  5. 顯示數值索引和對應的文字標籤。

圖表翻譯:

以下是使用Mermaid語法建立的流程圖,展示了上述步驟:

  flowchart TD
    A[載入資料集] --> B[選擇影像]
    B --> C[顯示影像]
    C --> D[新增邊界框]
    D --> E[取得標籤]
    E --> F[顯示數值索引和文字標籤]

這個流程圖展示了上述步驟之間的邏輯關係。

資料標籤格式化與印表

問題描述

在處理影像資料時,經常需要以清晰的格式呈現影像的標籤資訊,以便於理解和分析。這個過程涉及到將標籤的索引和文字描述以對齊的方式印出,從而提高可讀性。

解決方案

為了實作這個目標,我們可以使用Python語言來進行格式化印表。以下是實作這個功能的步驟和程式碼:

步驟1:提取標籤值和文字描述

首先,我們需要從標籤資料中提取出標籤的值和對應的文字描述。

values = labels['value']
text_labels = labels['text']

步驟2:確定最大文字描述長度

為了進行正確的格式化,我們需要知道最大文字描述的長度,以便於對齊印表。

max_text_length = max(len(label) for label in text_labels)

步驟3:印表標題

接下來,我們印出標題,包括索引和標籤兩欄。

print(f"{'Index':<10}{'Label':<{max_text_length + 2}}")
print("-" * (10 + max_text_length + 2))  # 加入分隔線

步驟4:印表索引和標籤

最後,我們使用迴圈印出每個索引和其對應的標籤,保證兩欄對齊。

for index, label in zip(values, text_labels):
    print(f"{index:<10}{label:<{max_text_length + 2}}")

範例輸出

以下是執行上述程式碼後的範例輸出:

Index      Label
-------------------------------
1          pedestrian
1          pedestrian
7          tricycle
1          pedestrian
1          pedestrian
1          pedestrian
1          pedestrian

這個輸出結果清晰地展示了影像標籤的索引和文字描述,對於後續的分析和處理非常有幫助。

圖表翻譯:

  flowchart TD
    A[開始] --> B[提取標籤值和文字描述]
    B --> C[確定最大文字描述長度]
    C --> D[印表標題]
    D --> E[印表索引和標籤]
    E --> F[結束]

這個流程圖展示了實作標籤格式化印表的步驟,從提取資料到最終的印表輸出。

圖片標記與邊界框的顯示

在進行圖片標記和物體偵測時,能夠清晰地顯示圖片中的邊界框和標記是非常重要的。這可以幫助我們更好地理解圖片中的物體和場景。

顯示圖片標記

首先,我們可以使用以下程式碼來顯示圖片中的標記:

ds.labels[ind].info['class_names']  # 顯示選擇圖片的標記

這將會顯示出圖片中所有的標記,包括忽略區域、行人、腳踏車、汽車等。

新增邊界框

接下來,我們可以使用以下程式碼來新增邊界框:

def display_image_with_bboxes(image_data, bboxes, labels, label_name):
    # 顯示圖片中的邊界框
    image_bytes = io.BytesIO(image_data)
    img = Image.open(image_bytes)
    
    # 提取選擇圖片的標記
    class_names = ds.labels[ind].info['class_names']
    
    # 篩選特定的標記
    if class_names is not None:
        try:
            label_index = class_names.index(label_name)
            relevant_indices = np.where(labels == label_index)[0]
        except ValueError:
            print(f"Warning: Label '{label_name}' not found. Displaying all labels.")
            relevant_indices = range(len(labels))
    else:
        relevant_indices = []  # 沒有找到標記,顯示空白
    
    # 畫邊界框
    draw = ImageDraw.Draw(img)
    for idx, box in enumerate(bboxes):  # 列舉邊界框
        if idx in relevant_indices:  # 檢查是否相關
            x1, y1, w, h = box
            x2, y2 = x1 + w, y1 + h
            draw.rectangle([x1, y1, x2, y2], outline="red", width=2)
            draw.text((x1, y1), label_name, fill="red")
    
    # 儲存圖片
    save_path = "boxed_image.jpg"
    img.save(save_path)

這個程式碼將會新增邊界框到圖片中,並且顯示出選擇的標記。

內容解密:

  • ds.labels[ind].info['class_names']:顯示選擇圖片的標記。
  • display_image_with_bboxes 函式:顯示圖片中的邊界框。
  • class_names:提取選擇圖片的標記。
  • relevant_indices:篩選特定的標記。
  • draw.rectangle:畫邊界框。
  • draw.text:顯示標記名稱。

圖表翻譯:

  flowchart TD
    A[顯示圖片標記] --> B[新增邊界框]
    B --> C[篩選特定的標記]
    C --> D[畫邊界框]
    D --> E[顯示標記名稱]
    E --> F[儲存圖片]

這個流程圖顯示了顯示圖片標記和新增邊界框的過程。

建立多模態查詢引擎

在本文中,我們將查詢 VisDrone 資料集並檢索一個符合使用者輸入的影像。為了實作此目標,我們將:

  1. 建立向量索引:為包含 VisDrone 資料集影像、框選資料和標籤的每一行 DataFrame 建立一個向量索引。
  2. 建立查詢引擎:建立一個查詢引擎,用於查詢資料集的文字資料,檢索相關影像資訊,並提供文字回應。
  3. 解析回應節點:解析回應的節點以找到與使用者輸入相關的關鍵字。
  4. 找到源影像:解析回應的節點以找到源影像。
  5. 新增邊界框:將源影像的邊界框新增到影像中。
  6. 儲存影像

玄貓點評:多模態模組化問答系統的發展與挑戰

深入剖析多模態模組化問答系統的架構後,我們可以發現,其核心價值在於整合文字和影像資訊,提供更豐富、更直觀的答案。透過 LlamaIndex 等工具,實作了文字資料集與 VisDrone 等影像資料集的聯合查詢,並利用 GPT 模型生成整合性的答案。從終端使用者互動流程的最佳化角度,這種多模態的呈現方式顯著提升了資訊的易讀性和理解效率,尤其在無人機等視覺資訊豐富的領域更具應用價值。

然而,此技術仍面臨一些關鍵挑戰。首先,多模態資料的整合與對齊仍需進一步最佳化。如何確保文字描述與影像內容的精確匹配,避免資訊誤導,是提升系統可靠性的關鍵。其次,系統的效能瓶頸也需要關注。影像處理、特徵提取和向量搜尋等操作都較為耗時,如何提升查詢效率,降低系統延遲,是未來研究的重要方向。最後,模型的可解釋性問題同樣值得關注。如何理解模型的決策過程,確保答案的準確性和可信度,也是未來需要解決的挑戰。

展望未來,隨著深度學習技術的持續發展,多模態資料融合技術將更加成熟,系統效能也將得到提升。我們預見,這項技術將在更多領域得到廣泛應用,例如醫療診斷、教育輔助、智慧城市等,為使用者帶來更智慧、更便捷的資訊體驗。對於想要在多模態領域有所建樹的開發者,建議深入研究向量資料函式庫技術、影像處理技術和深度學習模型,並關注跨模態資訊融合的最新研究成果。玄貓認為,多模態模組化問答系統代表了未來資訊檢索和知識問答的重要發展方向,值得持續投入和關注。