無人機技術的快速發展為各產業帶來了前所未有的應用可能性,從農業監測、基礎設施檢查到物流配送,無人機正在重塑傳統作業模式。然而,單純依靠影像擷取的無人機系統已無法滿足現代智慧化需求,整合多模態資訊成為提升無人機應用智慧化程度的關鍵技術方向。本文將深入探討如何運用 LlamaIndex、Deep Lake 與 OpenAI GPT-4 Vision 等先進技術,建構一個具備文字理解與影像辨識能力的多模態無人機應用系統,讓無人機能夠更精準地識別目標物體並拓展更多應用場景。
傳統的無人機視覺系統主要依賴預訓練的物件偵測模型,這些模型雖然能夠識別特定類別的物體,但缺乏語義理解能力與彈性擴展性。當使用者需要查詢特定類型的目標時,系統往往需要重新訓練模型才能滿足需求。多模態 AI 技術的出現改變了這一局面,透過整合大型語言模型的語義理解能力與電腦視覺模型的影像分析能力,系統能夠根據自然語言描述動態檢索相關影像,並提供更具脈絡的分析結果。
本文採用的技術架構結合了三個核心元件。LlamaIndex 負責建構高效的向量儲存索引,讓系統能夠根據語義相似度快速檢索相關文件與影像元資料。Deep Lake 作為多模態資料管理平台,統一儲存影像、邊界框標註與類別標籤等異質資料。OpenAI GPT-4 Vision 則提供強大的影像理解能力,能夠分析影像內容並生成自然語言描述,實現真正的多模態互動。
@startuml
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 14
skinparam minClassWidth 100
title 多模態無人機視覺系統架構
|使用者介面|
start
:使用者提交自然語言查詢;
|LlamaIndex 向量引擎|
:接收查詢請求;
:將查詢轉換為向量表示;
note right
建構向量索引
支援語義相似度搜尋
end note
:執行語義檢索;
|Deep Lake 資料層|
fork
:載入影像資料;
fork again
:載入邊界框標註;
fork again
:載入類別標籤;
end fork
:資料集管理整合;
:根據檢索結果擷取影像;
|GPT-4 Vision 分析|
:接收檢索到的影像;
:執行影像內容理解;
note right
影像內容理解
生成自然語言描述
end note
:產生影像分析結果;
|回應整合|
fork
:整合文字回應;
fork again
:整合影像分析結果;
end fork
:產生多模態回應;
:回傳給使用者;
stop
@enduml上方架構圖呈現了多模態無人機視覺系統的完整組成。使用者透過自然語言提出查詢後,LlamaIndex 向量引擎會根據語義相似度檢索相關的影像元資料。Deep Lake 資料層統一管理影像、邊界框標註與類別標籤等多模態資料。檢索到的影像會傳送至 GPT-4 Vision 進行深度分析,最後系統整合文字回應與影像分析結果,產生完整的多模態回應。
向量儲存索引建構與查詢引擎
建構高效的向量儲存索引是多模態檢索系統的基礎。LlamaIndex 提供了完整的工具鏈,讓開發者能夠輕鬆將文字資料轉換為向量表示,並建立支援語義相似度搜尋的索引結構。相較於傳統的關鍵字比對,向量檢索能夠捕捉文字的語義意涵,即使查詢詞彙與文件內容不完全相同,只要語義相近就能夠被檢索到。
向量索引的建構過程從準備文件集合開始。每個文件會經過嵌入模型處理,轉換為高維度的向量表示。這些向量會被組織成高效的索引結構,通常採用近似最近鄰演算法以平衡檢索精度與速度。當使用者提出查詢時,查詢文字同樣會被轉換為向量,然後在索引中搜尋最相似的文件向量。
# 匯入 LlamaIndex 核心元件
# GPTVectorStoreIndex 用於建構向量儲存索引
# Document 類別用於封裝文件資料
from llama_index.core import GPTVectorStoreIndex, Document
# 假設 documents_llm 是預先準備好的文件集合
# 每個文件包含無人機相關的技術說明或操作指南
# 文件內容會被嵌入模型轉換為向量表示
documents_llm = [
Document(text="無人機透過電腦視覺技術識別地面上的車輛,包括卡車、轎車和機車等。"),
Document(text="物件偵測模型會為每個識別到的物體繪製邊界框,並標示類別名稱。"),
Document(text="無人機搭載的攝影機具備高解析度影像擷取能力,支援即時串流傳輸。"),
]
# 從文件集合建立向量儲存索引
# from_documents 方法會自動處理文件嵌入與索引建構
# 預設使用 OpenAI 的嵌入模型進行向量轉換
vector_store_index_llm = GPTVectorStoreIndex.from_documents(documents_llm)
# 將索引轉換為查詢引擎
# 查詢引擎提供了便捷的介面進行語義檢索
# similarity_top_k 參數控制回傳最相似的前 k 個結果
vector_query_engine_llm = vector_store_index_llm.as_query_engine(
similarity_top_k=3 # 回傳最相似的前 3 個文件
)
print("向量儲存索引建構完成,查詢引擎已就緒")
上述程式碼展示了建構向量儲存索引的基本流程。GPTVectorStoreIndex.from_documents 方法會自動處理文件的嵌入轉換與索引建構,開發者無需手動管理這些細節。轉換為查詢引擎後,系統就能接受自然語言查詢並回傳語義最相關的文件。
查詢引擎建立後,可以直接使用自然語言進行檢索。系統會將查詢轉換為向量,在索引中搜尋最相似的文件,並根據檢索結果生成回應。這個過程整合了檢索與生成,讓使用者能夠獲得完整的答案而非僅是相關文件的列表。
# 匯入時間模組用於測量查詢效能
import time
# 定義使用者查詢
# 這個查詢詢問無人機如何識別特定類型的車輛
user_input = "無人機如何識別卡車?"
# 記錄查詢開始時間
start_time = time.time()
# 執行向量查詢
# query 方法會進行語義檢索並生成回應
# 回應包含根據檢索結果生成的答案
response = vector_query_engine_llm.query(user_input)
# 記錄查詢結束時間並計算執行時間
end_time = time.time()
elapsed_time = end_time - start_time
# 輸出查詢結果與效能指標
print(f"查詢: {user_input}")
print(f"執行時間: {elapsed_time:.4f} 秒")
print(f"回應: {response}")
這段程式碼展示了如何使用查詢引擎進行語義檢索。query 方法接受自然語言查詢,回傳整合檢索結果的回應。同時記錄執行時間有助於評估系統效能,在實際應用中可以根據延遲要求調整索引配置。
@startuml
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 14
skinparam minClassWidth 100
participant "使用者" as user
participant "查詢引擎" as engine
participant "嵌入模型" as embed
participant "向量索引" as index
participant "LLM" as llm
user -> engine: 提交自然語言查詢
activate engine
engine -> embed: 轉換查詢為向量
activate embed
embed --> engine: 查詢向量
deactivate embed
engine -> index: 搜尋相似文件
activate index
index --> engine: 相關文件列表
deactivate index
engine -> llm: 生成回應
activate llm
llm --> engine: 整合回應
deactivate llm
engine --> user: 回傳查詢結果
deactivate engine
@enduml上方時序圖清楚呈現了查詢引擎處理使用者查詢的完整流程。從使用者提交查詢開始,系統會將查詢轉換為向量、在索引中搜尋相似文件,最後透過 LLM 生成整合回應。這種檢索增強生成的架構讓系統能夠基於實際資料提供準確答案。
Deep Lake 多模態資料集管理
Deep Lake 是專為機器學習設計的資料湖平台,特別適合管理多模態資料集。它支援影像、影片、文字、音訊等多種資料類型,並提供高效的資料載入與存取介面。對於無人機視覺應用,Deep Lake 能夠統一管理影像資料、邊界框標註與類別標籤,讓開發者能夠方便地存取完整的訓練與評估資料。
VisDrone 資料集是無人機視覺領域的標準基準資料集,包含大量從無人機視角拍攝的影像與對應的物件標註。這個資料集涵蓋了行人、車輛、自行車等多種類別,非常適合用於訓練與評估無人機物件偵測模型。透過 Deep Lake,我們可以便捷地載入這個資料集並進行視覺化分析。
# 匯入 Deep Lake 函式庫
# deeplake 提供了便捷的資料集管理介面
import deeplake
# 定義資料集路徑
# hub://activeloop/visdrone-det-train 是 VisDrone 訓練集的 Deep Lake 路徑
# 這個資料集包含從無人機視角拍攝的影像與物件標註
dataset_path = 'hub://activeloop/visdrone-det-train'
# 載入資料集
# load 方法會從 Deep Lake Hub 下載並載入資料集
# 載入後的資料集物件提供了存取各種資料的介面
ds = deeplake.load(dataset_path)
# 顯示資料集摘要資訊
# summary 方法會輸出資料集的結構資訊
# 包括各個 tensor 的型別、形狀和壓縮方式
print("資料集摘要:")
ds.summary()
# 取得資料集大小
print(f"\n資料集包含 {len(ds)} 個樣本")
這段程式碼展示了如何載入 Deep Lake 資料集。load 方法會自動從 Hub 下載資料集並建立本地快取,後續存取會直接使用快取以加速讀取。summary 方法提供了資料集結構的詳細資訊,幫助開發者理解資料的組織方式。
資料集載入後,可以透過視覺化介面直觀地檢視影像與標註。Deep Lake 提供了內建的視覺化功能,能夠在 Jupyter Notebook 環境中顯示影像及其對應的邊界框。這對於快速檢查資料品質與理解資料分布非常有幫助。
# 視覺化資料集
# visualize 方法會在 Jupyter Notebook 中顯示互動式視覺化介面
# 可以瀏覽影像、檢視邊界框和標籤
ds.visualize()
# 取得標籤類別列表
# labels tensor 的 info 屬性包含類別名稱等元資料
labels_list = ds.labels.info['class_names']
print("資料集類別:")
print(labels_list)
# 預期輸出:
# ['ignored regions', 'pedestrian', 'people', 'bicycle', 'car',
# 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor', 'others']
上述程式碼展示了資料集的視覺化與類別資訊取得。VisDrone 資料集包含 12 個類別,涵蓋了無人機視角下常見的物體類型。這些類別資訊在後續的物件偵測與查詢中會被使用。
為了更深入地分析資料,可以將資料集轉換為 Pandas DataFrame 格式。這樣可以使用熟悉的資料分析工具進行統計與篩選。以下程式碼展示了如何提取影像、邊界框與標籤資訊並組織為 DataFrame。
# 匯入 pandas 用於資料分析
import pandas as pd
# 建立空的 DataFrame 用於儲存資料集資訊
# 包含影像資料、邊界框坐標和標籤文字
df = pd.DataFrame(columns=['image', 'boxes', 'labels', 'doc_id'])
# 限制處理的樣本數量以加速示範
# 實際應用中可以處理完整資料集
num_samples = min(100, len(ds))
# 迭代資料集中的每個樣本
# 提取影像、邊界框和標籤資訊
for i in range(num_samples):
sample = ds[i]
# 將影像資料轉換為位元組格式儲存
df.loc[i, 'image'] = sample.images.tobytes()
# 提取邊界框坐標
# boxes tensor 包含 [x, y, width, height] 格式的坐標
boxes_list = sample.boxes.numpy(aslist=True)
df.loc[i, 'boxes'] = [box.tolist() for box in boxes_list]
# 提取標籤資訊
# labels tensor 包含每個邊界框對應的類別索引
label_data = sample.labels.data()
df.loc[i, 'labels'] = label_data.get('text', [])
# 為每個樣本分配唯一識別碼
df.loc[i, 'doc_id'] = str(i)
print(f"已處理 {len(df)} 個樣本")
print(df.head())
這段程式碼將 Deep Lake 資料集轉換為 Pandas DataFrame 格式。每個樣本的影像資料、邊界框坐標和標籤都被提取並組織到對應的欄位中。doc_id 欄位用於後續建立向量索引時識別文件來源。
影像邊界框繪製與視覺化
物件偵測的核心任務是在影像中定位目標物體並標示其類別。邊界框是表示物體位置的標準方式,它使用一個矩形框選出物體的範圍。視覺化邊界框不僅有助於驗證偵測結果的正確性,也讓使用者能夠直觀地理解系統的輸出。
以下程式碼定義了一個函式,用於在影像上繪製邊界框並標示對應的標籤。這個函式會根據指定的標籤名稱篩選需要顯示的邊界框,讓使用者能夠聚焦於特定類別的物體。
# 匯入影像處理相關函式庫
import io
from PIL import Image, ImageDraw, ImageFont
def display_image_with_bboxes(image_data, bboxes, labels, target_label):
"""
在影像上繪製特定類別的邊界框並顯示
這個函式接受影像位元組資料、邊界框坐標列表和標籤列表,
然後篩選出符合目標標籤的邊界框並繪製在影像上。
邊界框使用紅色矩形表示,並在左上角標示類別名稱。
參數:
image_data: 影像的位元組資料
bboxes: 邊界框坐標列表,每個邊界框為 [x, y, width, height] 格式
labels: 標籤列表,與邊界框一一對應
target_label: 要顯示的目標標籤名稱
回傳:
PIL Image 物件,包含繪製邊界框後的影像
"""
# 將位元組資料轉換為 PIL Image 物件
# io.BytesIO 將位元組資料包裝為檔案物件
image_bytes = io.BytesIO(image_data)
img = Image.open(image_bytes)
# 建立繪圖物件
# ImageDraw 提供了在影像上繪製圖形和文字的功能
draw = ImageDraw.Draw(img)
# 計數符合目標標籤的邊界框數量
match_count = 0
# 迭代每個邊界框與對應標籤
for idx, box in enumerate(bboxes):
# 檢查當前標籤是否包含目標標籤
# labels[idx] 可能是字串或列表格式
current_label = labels[idx] if idx < len(labels) else ""
# 判斷是否符合目標標籤
if target_label.lower() in str(current_label).lower():
# 解析邊界框坐標
# 格式為 [x, y, width, height]
x, y, w, h = box
x1, y1 = x, y
x2, y2 = x + w, y + h
# 繪製紅色矩形邊界框
# outline 指定框線顏色,width 指定框線寬度
draw.rectangle([x1, y1, x2, y2], outline="red", width=2)
# 在邊界框左上角標示類別名稱
draw.text((x1, y1 - 15), target_label, fill="red")
match_count += 1
print(f"找到 {match_count} 個 '{target_label}' 物件")
return img
# 使用範例
# 從資料集中取得第一個樣本
sample_index = 0
image_data = df.loc[sample_index, 'image']
bboxes = df.loc[sample_index, 'boxes']
labels = df.loc[sample_index, 'labels']
# 指定要顯示的目標標籤
target_label = "truck"
# 繪製邊界框並顯示影像
result_image = display_image_with_bboxes(image_data, bboxes, labels, target_label)
# 儲存結果影像
save_path = "boxed_image.jpg"
result_image.save(save_path)
print(f"結果影像已儲存至 {save_path}")
# 在 Jupyter Notebook 中顯示影像
# display(result_image)
這段程式碼實現了完整的邊界框繪製功能。函式會篩選符合目標標籤的邊界框,使用紅色矩形框選物體並標示類別名稱。這種視覺化方式讓使用者能夠清楚看到系統識別到的目標物體位置。
@startuml
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 14
skinparam minClassWidth 100
start
:載入原始影像;
:取得邊界框與標籤資料;
:指定目標標籤;
while (遍歷所有邊界框) is (還有邊界框)
if (標籤符合目標?) then (是)
:解析邊界框坐標;
:繪製紅色矩形框;
:標示類別名稱;
else (否)
:跳過此邊界框;
endif
endwhile (完成)
:儲存標記後的影像;
:顯示結果;
stop
@enduml上方活動圖呈現了邊界框繪製的完整流程。從載入原始影像開始,系統會遍歷所有邊界框,篩選符合目標標籤的項目並進行繪製。這種篩選機制讓使用者能夠聚焦於特定類別的物體,提升視覺化的實用性。
多模態查詢引擎整合
建構多模態查詢引擎的核心在於整合文字檢索與影像處理能力。系統需要能夠理解使用者的自然語言查詢,檢索相關的影像資料,並提供結合文字說明與視覺呈現的多模態回應。以下程式碼展示了如何將 Deep Lake 資料集與 LlamaIndex 整合,建構支援影像檢索的查詢引擎。
# 匯入必要的函式庫
from llama_index.core import GPTVectorStoreIndex, Document
# 建立文件列表用於向量索引
# 每個文件包含樣本的標籤資訊
documents = []
# 迭代 DataFrame 中的每一行
# 將標籤文字轉換為 Document 物件
for idx, row in df.iterrows():
# 取得標籤列表並轉換為文字
text_labels = row['labels']
# 處理標籤格式
# 標籤可能是列表或其他格式
if isinstance(text_labels, list):
text = " ".join(str(label) for label in text_labels)
else:
text = str(text_labels)
# 建立 Document 物件
# doc_id 用於後續追蹤文件來源
document = Document(
text=text,
doc_id=row['doc_id'],
metadata={'sample_index': idx}
)
documents.append(document)
print(f"已建立 {len(documents)} 個文件")
# 建立向量儲存索引
# 索引會根據標籤文字的語義建立
vector_store_index = GPTVectorStoreIndex.from_documents(documents)
# 設定查詢引擎
# similarity_top_k=1 表示只回傳最相關的一個結果
vector_query_engine = vector_store_index.as_query_engine(similarity_top_k=1)
print("多模態查詢引擎建構完成")
這段程式碼建構了基於影像標籤的向量索引。每個影像樣本的標籤被轉換為文件,建立向量索引後系統就能根據標籤的語義相似度檢索影像。這種設計讓使用者能夠使用自然語言描述來搜尋影像。
查詢引擎建立後,可以實現完整的多模態檢索流程。當使用者提出查詢時,系統會檢索最相關的影像,提取該影像的邊界框資訊,並在影像上繪製對應的標註。
import time
def multimodal_query(query_text, target_label=None):
"""
執行多模態查詢並回傳結果
這個函式整合了文字檢索與影像處理,
根據使用者查詢檢索相關影像並繪製邊界框。
參數:
query_text: 使用者的自然語言查詢
target_label: 要標示的目標標籤,若為 None 則自動從查詢推斷
回傳:
dict: 包含查詢結果的字典
"""
# 記錄執行時間
start_time = time.time()
# 執行向量查詢
response = vector_query_engine.query(query_text)
# 解析回應取得來源文件資訊
# source_nodes 包含檢索到的文件節點
if hasattr(response, 'source_nodes') and response.source_nodes:
source_node = response.source_nodes[0]
doc_id = source_node.node.doc_id
# 根據 doc_id 找到對應的 DataFrame 行
sample_index = int(doc_id)
# 取得影像與標註資料
image_data = df.loc[sample_index, 'image']
bboxes = df.loc[sample_index, 'boxes']
labels = df.loc[sample_index, 'labels']
# 如果未指定目標標籤,嘗試從查詢推斷
if target_label is None:
# 簡單的關鍵字比對
for label in labels_list:
if label.lower() in query_text.lower():
target_label = label
break
if target_label is None:
target_label = "car" # 預設標籤
# 繪製邊界框
result_image = display_image_with_bboxes(
image_data, bboxes, labels, target_label
)
# 計算執行時間
elapsed_time = time.time() - start_time
return {
'query': query_text,
'response': str(response),
'target_label': target_label,
'image': result_image,
'elapsed_time': elapsed_time,
'sample_index': sample_index
}
else:
return {
'query': query_text,
'response': "未找到相關影像",
'elapsed_time': time.time() - start_time
}
# 測試多模態查詢
result = multimodal_query("請找出包含卡車的影像", target_label="truck")
print(f"查詢: {result['query']}")
print(f"目標標籤: {result['target_label']}")
print(f"執行時間: {result['elapsed_time']:.4f} 秒")
print(f"文字回應: {result['response']}")
# 儲存結果影像
if 'image' in result:
result['image'].save("multimodal_result.jpg")
print("結果影像已儲存至 multimodal_result.jpg")
這段程式碼實現了完整的多模態查詢功能。系統會根據查詢文字檢索最相關的影像,自動推斷目標標籤,並在影像上繪製對應的邊界框。回傳結果包含文字回應、標註後的影像與執行時間等資訊。
效能評估與相似度計算
評估多模態系統的效能需要同時考量文字與影像兩個面向。對於文字部分,可以使用餘弦相似度來衡量系統回應與使用者查詢的相關性。對於影像部分,則需要更創新的方法來評估檢索結果的準確性。
餘弦相似度是衡量兩個向量方向相似程度的指標,值域為 -1 到 1,越接近 1 表示越相似。透過將文字轉換為向量表示,我們可以量化計算兩段文字的語義相似度。
# 匯入相似度計算相關函式庫
from sklearn.metrics.pairwise import cosine_similarity
from sentence_transformers import SentenceTransformer
# 初始化 SentenceTransformer 模型
# all-MiniLM-L6-v2 是輕量級但效能良好的嵌入模型
# 適合用於計算文字語義相似度
model = SentenceTransformer('all-MiniLM-L6-v2')
def calculate_cosine_similarity(text1, text2):
"""
計算兩個文字之間的餘弦相似度
使用 SentenceTransformer 將文字轉換為向量表示,
然後計算兩個向量之間的餘弦相似度。
參數:
text1: 第一個文字字串
text2: 第二個文字字串
回傳:
float: 餘弦相似度分數,範圍為 -1 到 1
"""
# 將兩個文字轉換為向量表示
# encode 方法使用預訓練模型生成嵌入向量
embeddings1 = model.encode(text1)
embeddings2 = model.encode(text2)
# 計算餘弦相似度
# cosine_similarity 期望輸入為二維陣列
similarity = cosine_similarity([embeddings1], [embeddings2])
return similarity[0][0]
# 測試相似度計算
user_query = "無人機如何識別卡車?"
system_response = "無人機透過電腦視覺技術和物件偵測模型識別地面上的卡車。"
similarity_score = calculate_cosine_similarity(user_query, system_response)
print(f"使用者查詢: {user_query}")
print(f"系統回應: {system_response}")
print(f"餘弦相似度: {similarity_score:.4f}")
這段程式碼實現了基於 SentenceTransformer 的餘弦相似度計算。透過將文字轉換為嵌入向量,我們可以量化衡量查詢與回應之間的語義相關性。相似度分數可以作為系統效能的評估指標。
對於影像評估,可以利用 GPT-4 Vision 的能力來分析影像內容。GPT-4 Vision 能夠理解影像並生成自然語言描述,這些描述可以與預期標籤進行比較,從而評估影像檢索的準確性。
# 匯入 OpenAI 函式庫
import openai
import base64
def analyze_image_with_gpt4v(image_path, prompt):
"""
使用 GPT-4 Vision 分析影像
將影像傳送至 GPT-4 Vision API 進行分析,
並根據提示詞生成影像描述。
參數:
image_path: 影像檔案路徑
prompt: 分析提示詞
回傳:
str: GPT-4 Vision 生成的影像描述
"""
# 讀取影像並轉換為 base64 編碼
with open(image_path, "rb") as image_file:
image_base64 = base64.b64encode(image_file.read()).decode('utf-8')
# 建構 API 請求
# GPT-4 Vision 支援影像輸入
response = openai.ChatCompletion.create(
model="gpt-4-vision-preview",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{image_base64}"
}
}
]
}
],
max_tokens=500
)
return response.choices[0].message.content
def evaluate_image_retrieval(image_path, expected_label):
"""
評估影像檢索結果的準確性
使用 GPT-4 Vision 分析影像內容,
並計算分析結果與預期標籤的相似度。
參數:
image_path: 影像檔案路徑
expected_label: 預期應該在影像中出現的標籤
回傳:
dict: 包含分析結果和相似度分數的字典
"""
# 定義分析提示詞
prompt = f"請描述這張影像中的主要物體,特別關注是否有 {expected_label}。"
# 使用 GPT-4 Vision 分析影像
image_description = analyze_image_with_gpt4v(image_path, prompt)
# 計算描述與預期標籤的相似度
similarity = calculate_cosine_similarity(image_description, expected_label)
return {
'description': image_description,
'expected_label': expected_label,
'similarity': similarity
}
# 測試影像評估(需要有效的 OpenAI API 金鑰)
# result = evaluate_image_retrieval("multimodal_result.jpg", "truck")
# print(f"影像描述: {result['description']}")
# print(f"預期標籤: {result['expected_label']}")
# print(f"相似度: {result['similarity']:.4f}")
這段程式碼展示了如何使用 GPT-4 Vision 評估影像檢索結果。系統會將檢索到的影像傳送至 GPT-4 Vision 進行分析,生成的描述與預期標籤進行比較,從而量化評估檢索的準確性。
@startuml
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 14
skinparam minClassWidth 100
title 多模態效能評估架構
|文字評估|
start
:接收使用者查詢;
:接收系統回應;
:使用嵌入模型轉換為向量;
:計算餘弦相似度;
:產生文字相似度分數;
|影像評估|
:接收檢索影像;
:傳送至 GPT-4 Vision 分析;
:產生影像描述;
:載入預期標籤;
:執行描述與標籤比對;
:產生影像準確度分數;
|綜合評估|
fork
:整合文字相似度分數;
fork again
:整合影像準確度分數;
end fork
:計算綜合效能指標;
:輸出評估報告;
stop
@enduml上方架構圖呈現了多模態效能評估的完整架構。文字評估使用嵌入模型與餘弦相似度計算查詢與回應的相關性。影像評估則利用 GPT-4 Vision 分析影像內容,並與預期標籤比對。兩個面向的評估結果可以整合為綜合效能指標。
混合自適應 RAG 架構應用
混合自適應 RAG 是一種進階的檢索增強生成架構,它整合了自動檢索與人工回饋機制。在無人機客服系統等應用場景中,這種架構能夠根據使用者需求的複雜度動態調整回應策略,對於簡單問題直接回答,對於複雜問題則檢索相關文件或引入專家回饋。
這種架構的核心是排名機制,系統會根據使用者提問的特徵評估其複雜度,並據此決定採用何種回應策略。低排名的問題使用標準回應,中等排名的問題引入專家回饋,高排名的問題則使用完整的 RAG 流程。
def adaptive_response(user_query, ranking):
"""
根據排名自適應選擇回應策略
這個函式實現了混合自適應 RAG 的核心邏輯,
根據使用者提問的排名選擇不同的回應策略。
參數:
user_query: 使用者的提問
ranking: 提問的複雜度排名(1-10)
回傳:
dict: 包含回應策略和結果的字典
"""
# 判斷回應策略
if ranking < 3:
# 低排名:使用標準回應
strategy = "standard"
response = generate_standard_response(user_query)
source = "預設知識庫"
elif 3 <= ranking < 5:
# 中等排名:引入專家回饋
strategy = "human_feedback"
expert_content = load_expert_feedback()
response = generate_response_with_context(user_query, expert_content)
source = "專家回饋"
else:
# 高排名:完整 RAG 流程
strategy = "rag"
retrieved_docs = retrieve_documents(user_query)
response = generate_response_with_context(user_query, retrieved_docs)
source = "RAG 檢索"
return {
'query': user_query,
'ranking': ranking,
'strategy': strategy,
'response': response,
'source': source
}
def generate_standard_response(query):
"""
生成標準回應
對於簡單問題,直接使用預設知識生成回應。
參數:
query: 使用者查詢
回傳:
str: 生成的回應
"""
# 簡化實作,實際應用中會使用 LLM 生成
return f"關於「{query}」的標準回應:請參考使用手冊或聯繫客服。"
def load_expert_feedback():
"""
載入專家回饋內容
從專家知識庫中載入相關的回饋內容。
回傳:
str: 專家回饋內容
"""
# 簡化實作,實際應用中會從資料庫載入
return """
無人機視覺系統採用深度學習物件偵測模型,
能夠識別多種地面目標包括車輛、行人和建築物。
系統會為每個識別到的物體標示邊界框和類別名稱。
"""
def retrieve_documents(query):
"""
檢索相關文件
使用向量檢索取得與查詢相關的文件。
參數:
query: 使用者查詢
回傳:
str: 檢索到的文件內容
"""
# 使用先前建構的查詢引擎
response = vector_query_engine_llm.query(query)
return str(response)
def generate_response_with_context(query, context):
"""
根據上下文生成回應
將檢索到的上下文與查詢結合,生成完整的回應。
參數:
query: 使用者查詢
context: 上下文內容
回傳:
str: 生成的回應
"""
# 簡化實作,實際應用中會使用 LLM 生成
return f"根據相關資料回答「{query}」:\n{context[:500]}..."
# 測試自適應回應
test_cases = [
("無人機的電池續航時間是多少?", 2),
("如何設定無人機的物件偵測參數?", 4),
("無人機如何在複雜環境中進行自主避障?", 7)
]
for query, ranking in test_cases:
result = adaptive_response(query, ranking)
print(f"\n查詢: {result['query']}")
print(f"排名: {result['ranking']}")
print(f"策略: {result['strategy']}")
print(f"來源: {result['source']}")
print(f"回應: {result['response'][:100]}...")
這段程式碼實現了混合自適應 RAG 的核心邏輯。系統根據使用者提問的排名選擇不同的回應策略,確保簡單問題能夠快速回答,複雜問題則能獲得更詳細的解答。這種設計在提升回應品質的同時也控制了運算成本。
多模態 AI 技術為無人機視覺應用帶來了革命性的改變。透過整合 LlamaIndex 向量檢索、Deep Lake 多模態資料管理與 GPT-4 Vision 影像理解,系統能夠根據自然語言查詢智慧檢索相關影像,並提供豐富的多模態回應。混合自適應 RAG 架構則進一步提升了系統的彈性,能夠根據使用者需求動態調整回應策略。這些技術的結合為建構下一代智慧無人機應用奠定了堅實的基礎,讓無人機能夠更好地理解周圍環境並執行複雜任務。