救救小王吧!如何快速搞定影象相似性檢測問題?
相似性影象檢測,是模型訓練過程中常出現的問題,本文介紹了 4 個常用的雜湊演算法,並透過 Colab 程式碼,展示了完整的訓練過程。
新晉煉丹師小王最近遇到了一個難題,愁的頭髮掉了好幾根兒。
一問才知道,原來是他師傅給他分配了一個深度學習模型訓練的任務,但是訓練模型的影象資料集,略微有那麼一絲絲複雜:
裡邊除了已有的公開資料集外,還包含一些從 Google、Bing 等網站上爬取的影象。
重複影象的存在,使得模型效能變得十分不可靠,畢竟:
* 重複影象將 bias 引入資料集,使得深度學習模型不得不學習重複影象的特定模式;
* 特定的學習模式,會使得深度學習模型概括新影象的能力下降。
手動刪除重複影象,絕對不是最優解,原因是資料集中的影象數量動輒成百上千萬,手動檢查和刪除會是一個非(喪)常(心)繁(病)瑣(狂)的過程,將會耗費大量時間。
雜湊演算法成為小王最先想到的解決方案。
影象相似性檢索,「雜湊」一下
雜湊演算法是解決影象相似性檢索的「魔法工具」,它可以對任意一組輸入資料進行計算,得到一個固定長度的輸出摘要(字串)。
比較輸出摘要,結果越接近,就說明影象越相似。
雜湊演算法具有以下特點:
* 相同的輸入一定得到相同的輸出;
* 不同的輸入大機率得到不同的輸出;
注意: 哪怕兩張輸入影象之間,只有一個位元組之差,輸出的雜湊值也可能天差地別。
ImageHash Python 庫中,
常用的雜湊演算法包括 aHash、pHash、dHash 及 wHash。
Average Hash (aHash):
均值雜湊演算法,將影象切割成 8x8 的灰度影象,並依據畫素值是否大於影象所有顏色的平均值,來設定雜湊值中的 64 位。
aHash 計算速度快,不受影象尺寸大小影響,但對均值敏感,例如對影象進行伽馬校正或直方圖均衡會影響均值,從而導致報率,準確度無法保證。
aHash 影象處理效果展示
Perceptual Hash (pHash):
感知雜湊演算法,與 aHash 類似,區別是 pHash 不依賴 average color,而是依賴離散餘弦變換 (DCT),並依據頻率 (frequency) 而非顏色值 (color value) 進行比較。
pHash 能避免伽馬校正或顏色直方圖被調整帶來的影響,它準確率高、誤報少,但計算速度比較慢。
pHash 影象處理效果展示
Difference Hash (dHash):
差異值雜湊演算法與 aHash 原理類似,只是不使用平均顏色值的資訊,而是使用梯度(相鄰畫素的差異)。
dHash 演算法執行速度與 aHash 相當,但誤報率非常低。
dHash 影象處理效果展示
Wavelet Hash (wHash):
小波雜湊演算法,與 pHash 非常相似,但是 wHash 使用的是離散小波變換 (discrete wavelet transformation),而非 DCT。
wHash 比 pHash 更迅速,更準確,誤報更少。
wHash 影象處理效果展示
不同雜湊演算法效果對比詳見:TESTING DIFFERENT IMAGE HASH FUNCTIONS
善用輪子:用現成模組進行相似影象檢測
作為一名合格的工程師,避免重複造輪子、提高開發效率,是小王一貫的追求。
經過搜尋查詢,
小王發現了 Jina Hub 的
ImageHasher Executor
。
查閱相關文件後小王發現,
Executor 對應神經搜尋系統中的不同模組,實現資料處理的核心功能,可以直接使用。
Flow 則對應整套神經搜尋系統,它將多個 Executor 連線起來,構建成一套完整的搜尋系統,輕鬆實現相似影象檢測。
直接上程式碼:
!gdown ——id 1wPg_Yx2ydcgsDA3BYO-Lw8ym5vjT0oQ3
!unzip data。zip -d images
! mkdir index
! mv images/*1。* index/
! mkdir query
!mv images/*。* query/
!pip install jina imagehash
建立一個索引 Document 的 Flow:
from jina import Flow
from docarray import Document, DocumentArray
import matplotlib。pyplot as plt
!rm -rf workspace
包含影象的 Document 將被編碼成雜湊值,接下來可以使用上述 4 種雜湊演算法中的任何一種,並用 SimpleIndexer 進行儲存:
# Creating a DocumentArray object
docs_index = DocumentArray。from_files(‘index/*’)
docs_index = [doc。load_uri_to_image_tensor() for doc in docs_index]
# Creating the indexing flow with ImageHasher and SimpleIndexer
flow = (
Flow()
。add(uses=‘jinahub://ImageHasher/v0。2’, uses_metas={‘hash_type’: ‘dhash’})
。add(
uses=‘jinahub://SimpleIndexer’,
uses_metas={‘workspace’: ‘workspace’},
uses_with={
‘match_args’: {‘limit’: 1, ‘metric’: ‘euclidean’, ‘use_scipy’: True}
},
)
)
# Indexing the Documents using the flow
with flow:
flow。post(on=‘/index’, inputs=docs_index)
def print_matches(resp):
for idx, doc in enumerate(resp。docs):
print(‘-’*50)
print(f‘Query {idx + 1}’)
plt。imshow(doc。tensor)
plt。show()
for match in doc。matches:
print(‘Matching query ——>’)
plt。imshow(match。tensor)
plt。show()
查詢任何一個新的 Document,並在索引資料中找到匹配的 Document:
docs_query = DocumentArray。from_files(‘query/*’)
docs_query = [doc。load_uri_to_image_tensor() for doc in docs_query]
# Using the same flow to find matches
# Opening the flow for incoming queries
with flow:
flow。post(
on=‘/search’,
inputs=docs_query,
on_done=print_matches,
)
整個過程跑下來,一起來看看小王的相似影象檢測結果吧!
即使影象只是畫素、濾鏡或尺寸不同,也可以利用雜湊演算法檢測出來
煉丹師小王利用 Jina Hub ImageHasher Executor,終於解決了資料集中的相似影象問題,並將程式碼都放到了 Colab 上,參與更多深度學習、雜湊演算法相關討論→找到組織。
熱心小王期待大家的加入!
參考文獻:
Imagehashing--Find duplicates
完整 Colab
ImageHasher Executor
廖雪峰的官方網站--
雜湊演算法
相似影象檢測方法
Testing different image hash functions
An image hashing library written in Python