指南)
簡介Caffe 是伯克利視覺與學習中心開發(fā)的流行深度學習框架caffe-windows 壓縮包面向需要在 Windows 平臺使用 Caffe 的開發(fā)者省去自行編譯的復雜過程降低環(huán)境搭建門檻。包內(nèi)共有 888 個文件涵蓋 cpp、hpp、cu 等源碼與頭文件cmake、vcxproj、sln 等工程構(gòu)建配置prototxt 模型定義、Python 訓練與轉(zhuǎn)換腳本、Markdown 說明文檔和示例圖片等整體約 8.67MB目錄組織清晰便于按模塊查閱也能快速定位需要的源碼、配置或模型文件。已有 292 人學習下載。資源圍繞 Windows 下的安裝使用展開梳理了 Visual Studio、CMake、CUDA、cuDNN、Python 與 NumPy 等組件的配置要點并給出從源碼獲取、配置修改、編譯構(gòu)建到功能測試的完整思路可以幫助讀者規(guī)避常見錯誤。對于需要在 Windows 上訓練或部署 Caffe 模型的初學者和研發(fā)人員這份整理好的包體與配套注意點很有參考價值也能為后續(xù)自定義網(wǎng)絡(luò)結(jié)構(gòu)提供基礎(chǔ)。 Caffe 在 Windows 上一直是個讓人又愛又恨的話題。這個框架本身是伯克利視覺實驗室的產(chǎn)物當年在 CV 領(lǐng)域幾乎是標配特別是那些經(jīng)典的 ResNet、VGG、SSD 模型的 prototxt 和 caffemodel到現(xiàn)在還在各種老項目里躺著。但官方源碼壓根不提供 Windows 支持所謂 caffe-windows 全靠社區(qū)分支硬撐。這篇東西就圍繞“怎么在 Windows 上把 Caffe 跑起來”這個主題把我踩過的坑、驗證過的方案、排查思路全部攤開來講適合需要復現(xiàn)老模型、對比論文結(jié)果、或者因為項目歷史包袱不得不留在 Caffe 生態(tài)里的同學。我默認你的場景是Windows 10/11 系統(tǒng)想用 Caffe 訓練或推理一個已有的深度模型但不想為此專門裝雙系統(tǒng)或虛擬機。如果你屬于這種情況這篇內(nèi)容應該能幫你省下不少時間。1. 方案選型不是所有 Caffe-Windows 都長一個樣1.1 官方不支持時我們有哪些路可以走Caffe 官方倉庫的 README 寫得很清楚僅支持 Linux 和 macOS。Windows 用戶想用不外乎三條路一是用微軟維護的 BVLC/caffe 的 Windows 分支二是用 conda 直接裝編譯好的包三是找第三方預編譯包或自己編譯。三條路各有代價。微軟那個分支當年確實是福音能在 Visual Studio 里打開 Caffe.sln 直接編譯但問題也明顯它停更太久綁定的依賴版本停留在 VS2013/2015 時代。如果你現(xiàn)在的機器裝的是 VS2022光是改平臺工具集就能折騰半天。而 conda 裝 caffe 或 caffe-gpu 是最快的路子一條命令搞定但包管理器里的版本比較老而且如果你需要改動 Caffe 源碼、加自定義層這條路就走不通了。我的建議很直接如果你只是想跑通一個已有的模型做推理優(yōu)先試 conda如果你要基于 Caffe 改網(wǎng)絡(luò)結(jié)構(gòu)、加自定義 Python 層那就老老實實自己編譯。我自己兩種方式都試過后來因為要改 SS 的檢測頭還是走回了源碼編譯這條路。1.2 分支選擇決定了你的痛苦程度確定要自己編譯后下一個問題就是選哪個倉庫。在 Windows 上比較常見的兩個來源BVLC/caffe 的 Windows 分支官方賬號下維護的 windows 分支年代久遠但相對穩(wěn)定支持 VS2013/2015。willyd/caffe-windows社區(qū)維護者 willyd 的分支更新一些對 VS2015/2017 以及新版本 CUDA 兼容性更好。我自己用的是 willyd 這個分支原因很簡單它能支持 CUDA 10.0 和 cuDNN 7.x這個組合在 2018 年以后很長一段時間里是 Windows 深度學習環(huán)境的主流搭配能找到的資料也最多。如果你機器顯卡太新比如 RTX 30 系以后那就得注意 CUDA 版本兼容問題了這屬于另一個坑后面會提到。選分支時還有一個判斷技巧去 GitHub 看最近的 commit 時間和 Issues 內(nèi)容。如果最近一兩年都沒人維護說明用的人少、踩坑資料也少出問題基本只能自己啃源碼。2. 編譯前環(huán)境準備這幾項不做好會浪費一整天2.1 Visual Studio、CUDA、cuDNN 版本怎么搭配先說結(jié)論這是我在多臺機器上驗證過最省心的一套組合組件推薦版本備注Visual Studio2015 或 2017不要直接用 VS2022 嘗試老分支CUDA10.0 或 9.2驅(qū)動升級不影響工具包版本要匹配cuDNN7.4 或 7.6要和 CUDA 一一對應Python3.5 或 3.6編譯 pycaffe 接口時建議使用OpenCV3.4.x盡量不要用 4.x接口變了選這套組合的原因很實際Caffe 的 Windows 分支源碼依賴較老新編譯器對老代碼的強類型檢查會導致大量“無法解析的外部符號”“未知類型名”這類編譯錯誤。VS2015 對老代碼的容忍度最高而 CUDA 10.0 之后的版本從編譯角度看變化不大但 Caffe 源碼里的 caffe.pb.h 是拿 protobuf 生成的protobuf 版本太新會和源碼里的舊文件沖突。這里有個細節(jié)如果你用的是 30 系以后顯卡CUDA 10.0 裝倒是能裝但驅(qū)動不認舊版工具包的可能性很大編譯出來跑不起來。這種情況可以試試 CUDA 11.x 手動修源碼兼容但工作量會大不少建議評估一下是不是直接用 conda 預編譯包更劃算。2.2 依賴庫下載別一股腦全裝Caffe 依賴的東西不少OpenCV、protobuf、glog、gflags、lmdb、leveldb、hdf5、boost。Windows 上沒有 apt-get你得一個個下載源碼或二進制包。先說 OpenCV官方源碼下載后你需要把它編譯成 static 庫。Windows 分支要求 OpenCV 必須是 static build也就是說要讓 Caffe 把圖像編解碼能力直接編進去而不是運行時找 dll。你的 OpenCV 源碼編譯時對著 CMake 配置把 BUILD_SHARED_LIBS 關(guān)掉即可。protobuf 這塊我特別提醒一下Caffe 用的是 protobuf 的 C 運行時來讀寫模型結(jié)構(gòu)文件。如果你裝的是 protobuf 3.6 以上版本編譯 Caffe 時大概率會遇到“protobuf 版本不匹配”的報錯因為 Caffe 源碼里預生成的 .pb.cc 文件是拿舊版 protobuf 生成的。解決辦法只有一個就是在 Caffe 的 src/caffe/proto 目錄下重新生成一次 .pb.cc 和 .pb.h這要求你的 protobuf 編譯器版本和運行庫一致。其他依賴用一種比較笨但有效的方式處理直接把庫文件放到 Caffe 源碼的 dependencies 目錄里然后修改 CommonSettings.props 指定路徑。不用刻意追求目錄清爽能編過就是勝利。2.3 Python 接口的版本陷阱很多人編譯 Caffe 的 Python 接口時會踩這個坑裝好 Anaconda設(shè)好 PYTHON_INCLUDE、PYTHON_LIB 路徑編譯時卻報“無法打開 Python.h”。原因通常是 VS 默認找的是 64 位 Python而你環(huán)境里裝的是 32 位或者反之。我的建議是給 Python 接口專門建一個獨立的 conda 環(huán)境不要用 base。命令無非是 conda create -n py36 python3.6然后在 CommonSettings.props 里把 Python 相關(guān)路徑指到這個環(huán)境。這個環(huán)境保持干凈除了 numpy 之外什么都別裝避免依賴沖突。3. 編譯實操從下載源碼到跑通示例3.1 源碼準備和關(guān)鍵配置項首先把倉庫克隆到本地路徑有個硬性要求不能有中文不能有空格。我見過有人把工程放到“C:\Users\張三\我的項目\caffe-windows”結(jié)果是編譯器各種詭異的路徑錯誤折騰一晚上才發(fā)現(xiàn)是路徑問題。建議直接放到 C:\caffe 這種短路徑下。打開 windows 目錄下的 CommonSettings.props主要改這幾個地方!-- CPU_ONLY 設(shè)為 true 時只編譯 CPU 版本不依賴 CUDA -- CpuOnlyBuildfalse/CpuOnlyBuild !-- 開啟 Python 接口 -- PythonSupporttrue/PythonSupport !-- CUDA 目錄按實際安裝路徑填 -- CudaVersion10.0/CudaVersion PythonDirD:\Anaconda3\envs\py36\/PythonDir另一個重要配置是 cuDNN 的路徑。把解壓后的 cuDNN 文件夾里的 cuda 目錄內(nèi)容復制到 CUDA 安裝目錄對應位置然后確認 CommonSettings.props 里的CuDnnPath指向 CUDA 安裝根目錄。3.2 Visual Studio 編譯流程詳解用 VS2015 打開 Caffe.sln首先要做的事是檢查解決方案里的項目依賴關(guān)系。默認會包含 libcaffe、caffe、pycaffe 等幾個項目。右鍵解決方案選擇“配置管理器”確認當前是 Release x64 模式然后直接生成。第一次編譯耗時比較長通常在 20~40 分鐘取決于機器性能。需要提醒的是編譯過程中如果報錯不要急著改代碼。很多錯誤屬于配置層面的比如找不到 libcaffe.lib其實是編譯順序不對caffe.exe 項目依賴的 libcaffe 還沒有生成。調(diào)整項目依賴關(guān)系或者先單獨編譯 libcaffe 項目即可。編譯完成后你會在 x64\Release 目錄下看到 caffe.exe、libcaffe.lib 以及 pycaffe 目錄下的 caffe 包。這時候可以快速驗證一下 C 版本是否可用把該目錄加入系統(tǒng) PATH然后打開命令行執(zhí)行 caffe。如果輸出版本信息說明編譯成功。3.3 Python 接口安裝和環(huán)境變量配置pycaffe 的安裝方式和普通 Python 包不太一樣。你不需要執(zhí)行 pip install直接把編譯生成的 pycaffe 目錄添加到環(huán)境變量 PYTHONPATH 即可。我的具體做法是在系統(tǒng)環(huán)境變量里新建一個 PYTHONPATH值填 C:\caffe\Build\x64\Release\pycaffe。然后在 Python 里嘗試 import caffe能成功就說明接口通了。如果不成功優(yōu)先檢查你是否在同一個 conda 環(huán)境里執(zhí)行以及 numpy 版本是否是 1.16 左右的舊版本——numpy 1.17 以后某些 API 變化會導致 import 報錯這算是比較常見的坑。4. 常見問題排查這些坑幾乎每個人都會遇到4.1 命令行運行 caffe 時閃退或提示找不到 dll原因基本只有兩個依賴的 dll 不在 PATH 里或者 cuda 運行時庫版本不匹配。前者好辦把 OpenCV 的 dll、CUDA 的 bin 目錄都加進 PATH 試一遍后者就得用工具查看 exe 到底依賴哪些 cudart64_*.dll再比對系統(tǒng)里裝的是哪個版本。排查這類問題我推薦用 Dependencies 這個工具比老舊的 Dependency Walker 更直觀能顯示 dll 依賴樹和缺少的模塊。順著紅色標記找?guī)缀趿⒖潭ㄎ粏栴}。4.2 Check failed: registry.count(type) 1 這個報錯怎么處理這個報錯在跑模型時非常常見意思是 prototxt 網(wǎng)絡(luò)定義文件里寫了某個 layer type但 Caffe 里沒有注冊這個層。出現(xiàn)這種情況通常是三類原因一是拼寫錯誤比如把 Convolution 寫成 Convoution二是用了 Caffe 本身沒有的自定義層比如某些老項目里寫的 NormalizeLayer 其實是某個特定分支才有的三是這個層的實現(xiàn)寫在了 Python 層里部署時沒有把對應的 Python 模塊路徑加進來。排查思路很直接先把 prototxt 里的 layer type 和源碼 src/caffe/layers 目錄下的文件名對照一遍。如果發(fā)現(xiàn)確實只有老版本 Caffe 才有這個層那只能切換分支或者把該層的實現(xiàn)手動移植過來。4.3 編譯報錯 MSB8036 找不到 Windows SDK 版本微軟分支的工程文件默認指定了某一年份的 SDK而新裝的 VS 不一定帶那個版本。解法是在工程屬性里把 Windows SDK 版本改成你機器上實際安裝的版本。操作路徑右鍵項目 - 屬性 - 配置屬性 - 常規(guī) - Windows SDK 版本下拉選擇最新安裝的那個。還有一個比較隱蔽的類似問題是平臺工具集版本不匹配比如工程默認是 v140VS2015而你用的是 VS2017 的 v141。這種情況經(jīng)常伴隨一堆莫名其妙的編譯錯誤把平臺工具集改對就全好了。4.4 老代碼和新編譯器的兼容性問題如果你實在沒辦法只能用 VS2017 或更高版本編譯老 Caffe 分支會遇到一類很統(tǒng)一的報錯源碼里某個頭文件里用了一個老編譯器允許但新編譯器不認的語法。最典型的是 unknown type name uint8_t。這個報錯本質(zhì)是 Caffe 源碼沒有主動包含標準庫的 頭文件。工程里 caffe.pb.h 生成時可能也沒帶上。解決辦法是全局搜索一下哪個文件用了 uint8_t 但沒有 include 需要的頭手動補上就行。不要試圖靠更改編譯器級別規(guī)避治標不治本。4.5 模型訓練時 loss 一直是 NaN 或輸出全零這個問題和 Windows 本身關(guān)系不大但我在 Windows 平臺上遇到過太多次還是提一嘴。如果你用的是自定義數(shù)據(jù)且通過 lmdb 格式輸入大概率是數(shù)據(jù)預處理環(huán)節(jié)出了問題比如圖片均值文件沒有生成、mean.binaryproto 格式和 prototxt 里的配置不匹配。更隱蔽的是 GPU 模式下的浮點計算問題。某些老分支的 Caffe 在特定 CUDA 版本下BatchNorm 層的實現(xiàn)會踩到 cuDNN 的 bug導致訓練數(shù)值不穩(wěn)定。這種問題排查起來很難受我的建議是先用 CPU 模式跑幾十個迭代如果 CPU 正常而 GPU 異常十有八九是 cuDNN 版本匹配問題換個版本重編一次即可。5. 實操驗證跑通一個真實的推理任務(wù)5.1 準備模型文件和測試圖片編譯成功不等于萬事大吉強烈建議跑一個完整的推理流程做驗證。最簡單的方式是用官方訓練好的 CaffeNet 或 ResNet-50 模型。需要準備三個文件網(wǎng)絡(luò)定義 prototxt、訓練好的 caffemodel、以及一張測試圖片。模型文件去對應項目官方頁面下載即可。這里提醒一下有些老模型的 caffemodel 是從 Caffe 的 GitHub 倉庫發(fā)布頁下載的格式?jīng)]問題但對應的 prototxt 可能依賴一個老版本的 Deploy 頭直接跑可能報 Input layer 相關(guān)錯誤。遇到的話把測試圖片的尺寸、通道數(shù)、均值參數(shù)改對就行。5.2 用 caffe.exe 命令行和 Python 接口分別驗證命令行驗證最簡單執(zhí)行一條類似這樣的命令caffe.exe test -model deploy.prototxt -weights bvlc_reference_caffenet.caffemodel -gpu 0 -iterations 1如果能看到測試 loss 和 accuracy 輸出說明 C 版本鏈路正常。Python 接口驗證更靈活核心代碼就幾行import caffe import numpy as np net caffe.Net(deploy.prototxt, bvlc_reference_caffenet.caffemodel, caffe.TEST) transformer caffe.io.Transformer({data: net.blobs[data].data.shape}) transformer.set_transpose(data, (2, 0, 1)) transformer.set_mean(data, np.load(ilsvrc_2012_mean.npy).mean(1).mean(1)) transformer.set_raw_scale(data, 255) net.blobs[data].reshape(1, 3, 227, 227) img caffe.io.load_image(test.jpg) net.blobs[data].data[...] transformer.preprocess(data, img) out net.forward() print(out[prob][0].argmax())這段能跑出指數(shù)結(jié)果說明 pycaffe 接口的預處理、前向推理、模型文件讀取鏈路都正常。很多人編譯成功后跑 Python 報錯多數(shù)都卡在 transformer 的均值和縮放參數(shù)上這一步值得單獨驗證。5.3 把 Windows 上的 Caffe 模型轉(zhuǎn)到其他框架如果你留 Caffe 是為了老模型遷移那有一個重要步驟導出模型。Caffe 模型轉(zhuǎn)成 ONNX 是常見做法網(wǎng)上工具不少但先在 Windows 本地把 Caffe 跑通是第一步。這就能體現(xiàn)自己編譯的好處了轉(zhuǎn)換工具多半是一段 Python 腳本依賴 pycaffe 接口只有編譯過 pycaffe 的環(huán)境才能運行。轉(zhuǎn)換的時候有個很常見的坑Caffe 模型的 blob 命名和 ONNX 期望的不一致。比如 Concat 層的 output 參數(shù)Caffe 里默認是空ONNX 要求顯示聲明。這類問題沒有通用解法基本上就是按照報錯信息一個個改 prototxt再重新加載驗證。6. 注意事項與最終建議整個 Caffe-Windows 的折騰過程本質(zhì)上是在跟舊代碼、舊工具鏈、舊依賴做斗爭。有幾條經(jīng)驗我覺得值得單獨拎出來強調(diào)一下。第一不要追求新版本。很多人在 Windows 上裝 Caffe 習慣性地裝最新 CUDA、最新 VS、最新 Python這其實適得其反。Caffe-Windows 的源碼綁定了一組特定版本你只要換掉其中一個連鎖反應會接踵而至。整套環(huán)境盡量按老版本配齊越接近當時作者的開發(fā)環(huán)境越容易成功。第二備份好編譯產(chǎn)物。編譯一次 Caffe 至少要二三十分鐘如果調(diào)試中某個環(huán)節(jié)把 libcaffe.lib 弄壞了重新編譯非常浪費時間。我在踩過一次坑之后每次成功編譯完都會把整個 x64\Release 目錄壓縮備份一份后續(xù)出了任何問題直接解壓恢復省下的時間完全值得。第三盡量在 conda 虛擬環(huán)境里操作 Python 相關(guān)的內(nèi)容。之前說了pycaffe 對 numpy 版本有要求虛擬環(huán)境隔離后不會影響你日常用 Python 干活反過來日常升級包也不會把 pycaffe 弄崩。如果問我在實際項目中怎么評價 Caffe-Windows 這套方案我的體會是它確實老、確實折騰、確實有不少歷史遺留問題但考慮到大量老模型和學術(shù)代碼都長在 Caffe 的生態(tài)里能在 Windows 下多保留一套可用的 Caffe 環(huán)境往往能在關(guān)鍵時刻解決問題。至于后續(xù)的新項目我會建議盡快轉(zhuǎn)向更現(xiàn)代、跨平臺支持更好的框架但這就是另一個話題了。最后再分享一個小技巧如果你只是偶爾跑一下 Caffe 模型不需要每天開發(fā)完全可以把編譯好的整個 Caffe 目錄拷貝到一個移動硬盤或者網(wǎng)絡(luò)存儲上。這樣換機器后只需要把 CUDA 運行時庫、依賴 dll 配好直接就能用不需要每次重新編譯。這個方法我用了很久相當省心。本文還有配套的精品資源點擊獲取