邊學邊做:圖片識別技術的學習與應用
1 寫在前面
2 學習圖片相似度的基礎知識
2.1 從向量開始理解
2.2 向量化算法的學習
2.3 向量數據庫的學習
2.4 HNSW索引算法的理解
2.5 相似性度量:從語義理解到數學計算
3 解決實際應用問題
3.1 目標檢測的必要性
3.2 數據標注的挑戰
3.3 訓練實踐經驗
4 未來規劃
4.1 理想中的系統架構
4.2 當前進展與挑戰
5 寫在最后
1.寫在前面
最近在做二次元商品項目,遇到了拍照識別商品的需求。一開始完全不懂,只能邊學邊做。這篇文章記錄了學習和實踐過程,希望能給同樣在探索圖片識別技術的朋友一些參考。
2.學習圖片相似度的基礎知識
在開始動手之前,我花了不少時間去理解圖片相似度是怎么回事。
2.1 從向量開始理解
最初不理解圖片和向量的關系,后來發現就是把圖片轉換成數字。計算機視覺中,圖片需要轉換為數學形式才能處理。向量化是將圖片轉換為高維數值向量的過程,每個向量包含圖片的特征信息。
圖片向量通常包含512維、1024維或更高維度的特征,每一維代表圖片的某個特征屬性,如顏色、紋理、形狀等。通過向量化,圖片相似度問題轉化為向量相似度問題。
小卡向量示意圖
說明:為了便于理解,上圖簡化為3維向量展示。實際應用中,每張圖片會被轉換為512維或1024維的高維向量,包含顏色、紋理、形狀、邊緣等數百個特征維度。
2.2 向量化算法的學習
這部分是我學習曲線最陡峭的地方。CNN(卷積神經網絡)聽起來很高大上,但當我深入了解后發現,它的核心思想其實很直觀。
卷積層是CNN的核心組件,它通過一系列可學習的濾波器(卷積核)在圖片上滑動,提取不同的特征。
卷積層計算過程
每個卷積核就像一個特征檢測器,通過多層卷積的堆疊,CNN模型能夠從簡單的像素信息中逐步提取出高層的語義特征。
強烈推薦 Image Kernels Explained Visually,你可以實時看到不同卷積核(模糊、銳化、邊緣檢測等)對圖片的處理效果。
在實際應用中,我選擇了市面上常用的預訓練模型ResNet。使用ResNet-50作為特征提取器,能夠將輸入的圖片轉換為一個2048維的特征向量。
下面是一個簡單的代碼示例,展示如何使用ResNet提取圖片特征:
import torch
from torchvision.models import resnet50, ResNet50_Weights
from torchvision import transforms
from PIL import Image
# 加載預訓練模型,去掉分類層
model = resnet50(weights=ResNet50_Weights.IMAGENET1K_V1)
model = torch.nn.Sequential(*list(model.children())[:-1])
model.eval()
# 預處理圖片
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
])
# 提取特征
image = Image.open('小卡.png')
image_tensor = transform(image).unsqueeze(0)
features = model(image_tensor)
print(f"特征向量維度: {features.shape}") # 輸出: (1, 2048, 1, 1)2.3 向量數據庫的學習
在圖片相似度檢索中,傳統關系型數據庫無法勝任。向量數據庫專門為高維向量的相似度搜索而優化,能在千萬級數據中快速響應,這是傳統數據庫無法比擬的。
在實際應用中,我選擇了Milvus作為向量數據庫。除了Milvus,市面上還有其他不錯的選擇:
- Pinecone: 云原生向量數據庫服務
- Weaviate: 支持多模態搜索的向量數據庫
- Qdrant: 高性能的向量搜索引擎
2.4 HNSW索引算法的理解
在深入了解向量數據庫時,我發現了一個關鍵技術:HNSW(Hierarchical Navigable Small World)索引。需要說明的是,HNSW并不保證100%精確的結果,它是一種近似最近鄰搜索算法,通過犧牲少量精度來換取巨大的性能提升。
HNSW索引結構示意圖
HNSW索引結構示意圖
如上圖所示,HNSW構建了多層圖結構:
- 頂層(Layer 2):少量節點,紅色路徑快速縮小搜索范圍
- 中層(Layer 1):節點適中,進一步細化搜索
- 底層(Layer 0):包含所有數據點,進行精確搜索
搜索過程沿著紅色路徑:從頂層入口快速跳躍到目標區域,然后逐層下降細化搜索。這種"先粗后細"的策略實現了亞秒級的相似度檢索。
2.5 相似性度量:從語義理解到數學計算
在學習過程中,我發現了一個很有意思的轉換:如何將人類對圖片相似性的主觀判斷轉換為計算機可以處理的數學問題。
經過網上搜索和學習,我找到了幾種常用的向量距離計算算法,并做了對比分析:
算法名稱 | 計算原理 | 特點 | 適用場景 |
余弦相似度(Cosine) | 計算向量夾角余弦值 | 不受向量長度影響,關注方向性 | 文本相似度、圖片特征匹配 |
歐幾里得距離(L2) | 計算兩點間直線距離 | 幾何意義明確,高維空間易受維度詛咒影響 | 低維數據、精確匹配 |
曼哈頓距離(L1) | 計算坐標軸方向距離之和 | 計算簡單,對異常值魯棒,不考慮對角線距離 | 網格化數據、城市距離 |
內積相似度(IP) | 計算向量內積 | 計算高效,同時考慮方向和大小,受向量長度影響 | 推薦系統、特征權重敏感場景 |
漢明距離(Hamming) | 計算不同位置的數量 | 適合二進制數據,僅限等長序列 | 二進制特征、錯誤檢測 |
通過這種"語義→向量→數學計算"的轉換,我們成功地將人類的視覺判斷能力賦予了計算機系統,實現了從主觀的"像不像"到客觀的數值計算。
3.解決實際應用問題
3.1 目標檢測的必要性
在實際測試中,我發現用戶上傳的圖片往往包含大量無關信息。比如識別小卡時,圖片中還有桌子、手機等干擾元素。直接對整張圖片向量化,識別效果很差。
需要先把商品從復雜背景中"摳"出來,再進行相似度計算。經過調研,我選擇了YOLO(You Only Look Once)作為目標檢測的解決方案,YOLO能夠在保證準確性的同時實現實時檢測。
下面是一個簡單的YOLO目標檢測代碼示例:
from ultralytics import YOLO
model = YOLO('yolov8n.pt')
# 檢測圖片中的物體
results = model('小卡.png')
# 顯示結果
results[0].show()
yolo目標檢測
3.2 數據標注的挑戰
我們的業務場景比較特殊,主要是二次元相關物品(明星小卡、手辦、徽章等),通用模型識別不了,只能自己標注數據。
選擇了Label Studio作為標注工具:
- 界面直觀,學習成本低
- 支持團隊協作
- 導出格式兼容YOLO
# 1. 安裝Label Studio
pip install label-studio
# 2. 啟動服務
label-studio start
# 3. 瀏覽器訪問 http://localhost:8080
# 首次使用需要注冊賬號
Label Studio標注演示
標注了大概200張圖片后,發現這活兒比想象中累多了,簡直是"鼠標點到手抽筋"?? 標注工作完成后就可以進行數據導出了,為后續模型訓練提供基礎。
Label Studio數據導出
3.3 訓練實踐經驗
有了標注數據后,就可以開始訓練了。說實話,之前看到YOLO訓練的教程都覺得很復雜,各種參數配置讓人頭大。但實際動手后發現,核心代碼其實很簡潔:
from ultralytics import YOLO
# 準備訓練和驗證數據集(整理圖片和標注文件)
prepare_dataset()
# 開始訓練
model = YOLO('yolov8n.pt')
results = model.train(
data='dataset/dataset.yaml', # 數據集配置文件
epochs=200, # 訓練輪數
imgsz=640, # 輸入圖片尺寸
batch=32, # 批次大小
device=0, # GPU設備號(0=第一塊GPU, 'cpu'=使用CPU)
patience=20 # 早停輪數
)
yolo訓練日志輸出
第一次運行的時候心情還挺忐忑的,畢竟只有200多張圖片,不知道能不能訓練出什么效果。結果讓我挺意外的:
- 訓練速度比想象中快,RTX 4090跑了2分多鐘就完成了
- 最終mAP達到了97.6%,這個數字看起來還不錯
- 模型文件只有6MB左右,很輕量
關于訓練速度:一開始用CPU訓練,慢得我懷疑程序卡死了?? 后來花幾塊錢租了個GPU,嘿,2分鐘搞定!果然貧窮限制了想象力...
關于mAP指標:mAP可以理解為檢測準確率,97.6%意味著模型在識別小卡方面表現很優秀,90%以上就算是實用級別了。
訓練完成后,迫不及待地測試了一下效果。寫了個簡單的檢測腳本:
from ultralytics import YOLO
model = YOLO('best.pt')
results = model('test_model_image.jpg')
results[0].show() # 顯示檢測結果
yolo訓練后結果
看到檢測框準確地框出了小卡,那一刻還是挺有成就感的。雖然數據量不大,但至少證明了這個思路是可行的。
第一次訓練的幾個收獲:
- 數據質量比數量重要 - 200張精心標注的圖片效果已經不錯
- GPU確實快 - 相比CPU訓練,速度提升明顯
- YOLO真的很好用 - 幾行代碼就能完成整個訓練流程
4.未來規劃
學完了這些技術,腦子里已經有了一個完整系統的雛形。雖然現在還停留在理論和實驗階段,但我覺得可以分享一下我的規劃思路。
4.1 理想中的系統架構
我畫了一個理想化的系統流程圖,把前面學到的技術都串聯起來:
商品拍圖識款系統完整流程圖
整個系統分成四個核心環節:
- 模型訓練環節:通過Label Studio標注數據,訓練出專門的YOLO檢測模型
- 數據預處理環節:用訓練好的模型批量處理存量商品圖片,提取特征向量存入向量數據庫
- 實時檢索環節:用戶上傳圖片時,先用YOLO檢測出商品區域,再提取特征進行相似度搜索
- 反饋優化環節:收集用戶反饋,分析錯誤樣本,持續優化模型效果
這個架構看起來挺完美的,但實際落地肯定會遇到各種意想不到的問題。
4.2 當前進展與挑戰
坦率地說,目前這些都還是紙上談兵。雖然各個技術環節我都單獨跑通了,但要組裝成一個穩定可用的系統,還有很多工作要做:
技術挑戰:
- 數據質量瓶頸:200張標注數據還是太少,需要更多樣化的訓練樣本
- 訓練參數調優:學習率、批次大小、數據增強策略等超參數需要反復試驗,這個過程很耗時間和算力
- 模型泛化:目前只在小卡上測試過,其他商品類型的效果未知
- 邊界case處理:模糊圖片、遮擋嚴重、光線不足等極端情況下的識別準確率還需要提升
- 性能優化:向量檢索在大規模數據下的響應速度還需要優化
每解決一個技術問題,就感覺離目標更近了一步。雖然現在還在實驗室階段,但我相信距離真正可用的產品不會太遠。
到時候真實用戶的使用場景肯定比我閉門造車想象的更復雜,也能發現很多現在想不到的問題。這才是最有價值的學習機會!
5 寫在最后
這次的學習和實踐讓我對圖片識別技術的應用有了更深的理解。雖然過程中遇到了很多困難,但邊學邊做的過程還是很有收獲的。
這篇文章記錄的只是我個人的學習過程和思考,肯定有很多不足的地方。如果有經驗更豐富的朋友看到了,歡迎指正和交流!
我們也會持續分享更多的技術實踐經驗,希望能和大家一起進步。
關于作者:曹建濤,轉轉C2C&寄賣業務研發工程師


























