VisDrone 資料集提供無人機視角的物件偵測資料,理解其結構對於模型訓練至關重要。首先,使用 Pandas DataFrame 載入影像、邊界框和標籤資料,並將影像轉換為位元組格式儲存以節省記憶體。接著,分析資料集中的標籤類別,包含行人、車輛等道路參與者。然後,利用 OpenCV 和 PIL 函式庫將影像轉換為 RGB 格式並顯示,同時繪製邊界框以視覺化物件偵測結果。最後,為了實作多模態查詢,需建立向量索引和查詢引擎,以便根據使用者輸入檢索相關影像和文字資訊。

多模態資料集的載入與視覺化處理

在進行物件偵測任務時,理解資料集的結構與內容至關重要。本章節將介紹如何載入VisDrone資料集,並對其進行視覺化處理。

載入VisDrone資料集

VisDrone資料集是一個用於無人機視角下物件偵測的資料集,包含了豐富的影像資料及其對應的標註資訊。首先,我們需要將資料集載入並轉換為適合處理的格式。

import pandas as pd

# 建立一個空的DataFrame用於儲存影像、邊界框和標籤資料
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()['text']
    df.loc[i, 'labels'] = label_data

內容解密:

  1. df = pd.DataFrame(columns=['image', 'boxes', 'labels']):建立一個包含三列的DataFrame,分別用於儲存影像資料、邊界框資料和標籤資料。
  2. sample.images.tobytes():將影像資料轉換為位元組格式儲存,這是一種壓縮表示法,有助於減少記憶體使用量。
  3. sample.boxes.numpy(aslist=True):將邊界框資料轉換為NumPy陣列,並以列表形式儲存每個邊界框的座標。
  4. sample.labels.data()['text']:提取標籤資料中的文字標籤。

資料集內容分析

載入資料集後,我們可以檢視其內容和結構。

# 顯示資料集中的標籤列表
labels_list = ds.labels.info['class_names']
print(labels_list)

輸出結果為:['ignored regions', 'pedestrian', 'people', 'bicycle', 'car', 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor', 'others']

內容解密:

  1. ds.labels.info['class_names']:取得資料集中的標籤類別名稱。
  2. 標籤類別:資料集包含12種類別的標籤,涵蓋了各種道路參與者,如行人、車輛等。

影像視覺化與邊界框新增

接下來,我們將選擇資料集中的一張影像,並在其上新增邊界框以視覺化物件偵測結果。

import cv2
from PIL import Image
import io
from PIL import ImageDraw

# 選擇第一張影像
ind = 0
image_data = ds.images[ind].tobytes()

# 顯示原始影像
image = ds.images[ind].numpy()
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
img = Image.fromarray(image_rgb)
display(img)

# 取得標籤和邊界框資料
labels = ds.labels[ind].data()['value']
bboxes = ds.boxes[ind].numpy()

# 定義函式用於在影像上新增邊界框
def display_image_with_bboxes(image_data, bboxes, labels, label_name):
    # ...
    # 篩選特定標籤的邊界框並繪製
    # ...

# 新增邊界框並顯示
label_name = "truck"
display_image_with_bboxes(image_data, bboxes, labels, label_name)

內容解密:

  1. cv2.cvtColor(image, cv2.COLOR_BGR2RGB):將OpenCV讀取的BGR格式影像轉換為PIL支援的RGB格式。
  2. ImageDraw.Draw(img):在PIL影像上繪製邊界框和標籤。
  3. label_name = "truck":選擇特定的標籤類別(例如卡車)來新增邊界框。

多模態查詢引擎建置

在完成資料集的載入和視覺化後,我們將進一步建置一個多模態查詢引擎,用於根據使用者輸入檢索相關影像並提供文字回應。

查詢引擎建置步驟:

  1. 建立向量索引:為DataFrame中的每一行資料建立向量索引,以便快速檢索。
  2. 建立查詢引擎:利用文字資料進行查詢,檢索相關影像資訊並提供文字回應。
  3. 解析查詢結果:提取查詢結果中的關鍵字和來源影像。

透過上述步驟,我們可以實作一個強大的多模態查詢系統,結合影像和文字資訊進行高效檢索。

  graph LR;
    A[載入VisDrone資料集] --> B[視覺化影像與邊界框];
    B --> C[建置多模態查詢引擎];
    C --> D[檢索相關影像與文字回應];

圖表翻譯: 此圖表展示了從載入VisDrone資料集到建置多模態查詢引擎的流程。首先載入資料集,接著對影像進行視覺化處理並新增邊界框,最後建立查詢引擎以實作多模態檢索功能。

多模態模組化摘要與應用實務

在前述章節中,我們逐步建立了一個多模態模組化程式。現在,我們將其彙總成一個完整的函式,以提供使用者輸入的來源影像、列印使用者輸入與大語言模型(LLM)的輸出,並顯示多模態的回應結果。

建立來源影像顯示函式

首先,我們建立一個函式來顯示由多模態檢索引擎儲存的來源影像:

def display_multimodal_response(user_input, llm_response, image_path):
    # 1. 列印使用者輸入
    print(user_input)
    # 2. 列印LLM回應
    print(textwrap.fill(str(llm_response), 100))
    # 3. 顯示多模態回應
    display_source_image(image_path)

內容解密:

  • display_multimodal_response 函式接收三個引數:user_input(使用者輸入)、llm_response(LLM回應)和 image_path(影像路徑)。
  • 函式首先列印 user_input,接著列印經過格式化的 llm_response
  • 最後,函式呼叫 display_source_image 來顯示位於 image_path 的影像。

應使用案例項

接著,我們將上述函式應用於實際的多模態查詢中:

# 使用者輸入範例
user_input = "無人機如何識別卡車?"
# 假設 llm_response 是由 LLM 產生的回應
llm_response = "無人機使用視覺檢測和追蹤方法來識別卡車。"
image_path = "/content/boxed_image.jpg"

# 呼叫函式顯示多模態回應
display_multimodal_response(user_input, llm_response, image_path)

內容解密:

  • 在此範例中,我們定義了一個 user_input 變數,代表使用者的查詢。
  • 我們假設 llm_response 是由 LLM 針對該查詢產生的回應。
  • image_path 指定了儲存的影像檔案路徑。
  • 透過呼叫 display_multimodal_response 函式,我們可以同時顯示文字回應和相關的影像輸出。

圖表翻譯:

  graph LR;
    A[使用者輸入] --> B[LLM 回應];
    B --> C[顯示來源影像];
    C --> D[多模態回應];

圖表翻譯: 此圖示展示了從使用者輸入到最終多模態回應的處理流程。首先,使用者輸入被送入LLM以取得回應,接著系統顯示相關的來源影像,最終呈現完整的多模態回應結果。

多模態RAG輸出增強的效能評估方法

多模態RAG輸出增強透過在輸入和輸出中新增資訊來豐富生成式AI。然而,與所有AI程式一樣,設計效能指標需要高效的影像識別功能。

效能指標

評估多模態模組化RAG的效能需要兩種型別的測量:文字和影像。測量文字是直接的,但測量影像則是一個挑戰。

LLM效能指標

LlamaIndex透過其查詢引擎無縫呼叫OpenAI模型(如GPT-4),並在其回應中提供文字內容。對於文字回應,我們將使用與第2章“用餘弦相似度評估輸出”和第3章“向量儲存索引查詢引擎”部分相同的餘弦相似度指標。

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from sentence_transformers import SentenceTransformer

model = SentenceTransformer('all-MiniLM-L6-v2')

def calculate_cosine_similarity_with_embeddings(text1, text2):
    embeddings1 = model.encode(text1)
    embeddings2 = model.encode(text2)
    similarity = cosine_similarity([embeddings1], [embeddings2])
    return similarity[0][0]

llm_similarity_score = calculate_cosine_similarity_with_embeddings(user_input, llm_response)
print(f"Cosine Similarity Score: {llm_similarity_score:.3f}")

多模態效能指標

為了評估傳回的影像,我們不能簡單地依賴資料集中的標籤。對於小型資料集,我們可以手動檢查影像,但當系統擴充套件時,需要自動化。在本文中,我們將使用GPT-4o的電腦視覺功能來分析影像,解析它以找到我們正在尋找的物件,並提供該影像的描述。然後,我們將餘弦相似度應用於GPT-4o提供的描述和它應該包含的標籤。

import base64

def encode_image(image_path):
    with open(image_path, "rb") as image_file:
        return base64.b64encode(image_file.read()).decode("utf-8")

base64_image = encode_image(IMAGE_PATH)

from openai import OpenAI

client = OpenAI(api_key=openai.api_key)
MODEL = "gpt-4o"

response = client.chat.completions.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": f"You are a helpful assistant"},
        {"role": "user", "content": [
            {"type": "text", "text": f"Analyze the following image"},
            {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{base64_image}"}}
        ]}
    ],
    temperature=0.0,
)

response_image = response.choices[0].message.content
print(response_image)

多模態模組化RAG效能指標

為了獲得系統的整體效能,我們將LLM回應和兩個多模態回應效能的總和除以2:

score = (llm_similarity_score + multimodal_similarity_score) / 2
print(f"Multimodal, Modular Score: {score:.3f}")

內容解密:

  1. LLM效能指標:使用餘弦相似度評估LLM生成的文字與輸入文字之間的相似度。
  2. 多模態效能指標:使用GPT-4o分析影像並生成描述,然後計算描述與預期標籤之間的餘弦相似度。
  3. 多模態模組化RAG效能指標:結合LLM和多模態效能指標,計算系統的整體效能。

圖表翻譯:

此圖示展示了多模態RAG系統的效能評估流程,包括文字和影像的評估方法。

提升RAG效能:結合專家級人工回饋

人工回饋(HF)對於生成式AI至關重要,尤其是在使用RAG的模型中。生成式AI模型利用多樣化檔案的資料集進行訓練,但訓練資料一旦固定在模型的引數中,除非重新訓練,否則無法更改。然而,在根據檢索的文字和多模態資料集中,我們可以觀察並調整其中的資訊。這正是HF的發揮空間。透過對AI模型從資料集中提取的內容提供回饋,HF可以直接影響未來回應的品質,使人類成為RAG發展過程中的積極參與者,為AI專案增添了新的導向:自適應RAG。

自適應RAG生態系統的定義

自適應RAG引入了人工、實用的回饋機制,以提升RAG驅動的生成式AI生態系統。生成式AI模型的核心資訊以引數形式儲存(以權重表示)。但在RAG的情境下,這些資料可以被視覺化和控制。儘管如此,仍存在諸多挑戰,例如輸出結果的準確性和相關性取決於底層資料的品質,這就需要驗證機制。自適應RAG正是為此而生,它透過引入人工回饋來改善系統。

自適應RAG的工作原理

自適應RAG的工作原理包含以下幾個關鍵步驟:

  1. 定義自適應RAG生態系統:建立一個能夠接受並整合人工回饋的RAG系統。
  2. 將自適應RAG應用於增強檢索查詢:透過人工回饋最佳化檢索過程,提高查詢結果的準確性。
  3. 利用人工回饋自動化增強生成式AI輸入:根據人工回饋調整輸入,以最佳化生成結果。
  4. 自動化終端使用者回饋排名以觸發專家級人工回饋:建立機制,讓使用者回饋能夠觸發專家級的審核和調整。
  5. 建立自動化的人工回饋系統供專家使用:為專家提供工具,以便對AI系統進行精細調整。
  6. 將人工回饋與自適應RAG結合,用於GPT-4o模型:將上述機制應用於GPT-4o模型,以提升其效能。

程式碼實作與解析

以下是一個簡化的Python程式碼範例,用於展示如何實作自適應RAG系統的一部分功能:

import numpy as np

def calculate_similarity(query_embedding, document_embeddings):
    # 計算查詢嵌入向量與檔案嵌入向量之間的餘弦相似度
    similarities = np.dot(query_embedding, document_embeddings.T) / (np.linalg.norm(query_embedding) * np.linalg.norm(document_embeddings, axis=1))
    return similarities

def get_top_documents(similarities, top_n=5):
    # 取得最相關的前N個檔案
    top_indices = np.argsort(similarities)[::-1][:top_n]
    return top_indices

# 假設query_embedding和document_embeddings已經計算好
query_embedding = np.random.rand(1, 128)  # 示例查詢嵌入向量
document_embeddings = np.random.rand(100, 128)  # 示例檔案嵌入向量

similarities = calculate_similarity(query_embedding, document_embeddings)
top_documents = get_top_documents(similarities)

#### 內容解密:
1. **`calculate_similarity`函式**計算查詢向量與檔案向量之間的餘弦相似度用於評估查詢與檔案的相關性
2. **`get_top_documents`函式**根據相似度排序選取最相關的前N個檔案以最佳化檢索結果
3. **向量計算**使用numpy進行高效的向量運算以提升效能

### 圖表說明

```mermaid
graph LR;
    A[查詢輸入] --> B[計算查詢嵌入向量];
    B --> C[計算查詢與檔案的相似度];
    C --> D[選取最相關的檔案];
    D --> E[生成最終回應];

圖表翻譯: 此圖表呈現了自適應RAG系統的工作流程。首先,系統接收查詢輸入並計算其嵌入向量。接著,系統計算查詢向量與檔案向量之間的相似度,並根據相似度選取最相關的檔案。最後,系統根據選取的檔案生成最終回應。