引言
一直以來,人們試圖手工編寫算法來理解人工生成的內(nèi)容,但是成功率極低。例如,計算機很難“掌握”圖像的語義內(nèi)容。對于這類問題,AI科學(xué)家已經(jīng)嘗試通過分析汽車、貓、外套等低級像素來解決,但結(jié)果并不理想。盡管顏色直方圖和特征檢測器在一定程度上發(fā)揮了作用,但在大多數(shù)實際應(yīng)用中它們的準確率仍然極低。
在過去十年中,大數(shù)據(jù)和深度學(xué)習(xí)的結(jié)合從根本上改變了我們處理計算機視覺、自然語言處理和其他機器學(xué)習(xí)(ML)應(yīng)用程序的方式。例如,從垃圾郵件檢測到真實的文本再到視頻合成等任務(wù)都取得了驚人的進步,在這些具體應(yīng)用中準確率指標已經(jīng)達到了超人的水平。但是,這些改進伴隨而來的一個顯著的副作用是嵌入向量的使用增加,即通過在深度神經(jīng)網(wǎng)絡(luò)中獲取中間結(jié)果而產(chǎn)生的模型組件。OpenAI相關(guān)的Web頁面上提供了下面這樣一段比較貼切的概述:
“嵌入是一種特殊的數(shù)據(jù)表示格式,無論機器學(xué)習(xí)模型還是相關(guān)算法都很容易使用它。嵌入是文本語義的信息密集表示。每個嵌入都可以表示為一個浮點數(shù)向量;因此,向量空間中兩個嵌入之間的距離與原始格式中兩個輸入之間的語義相似性是相關(guān)的。例如,如果兩個文本相似,那么它們的向量表示也應(yīng)該相似?!?/strong>
下表顯示了三個查詢圖像以及它們在嵌入空間中對應(yīng)的前五個圖像。在此,我使用了Unsplash Lite網(wǎng)站提供的前1000個圖像作為數(shù)據(jù)集。
訓(xùn)練嵌入任務(wù)的新模型
從理論上講,訓(xùn)練一個新的ML模型并生成嵌入聽起來很簡單:采用最新的體系結(jié)構(gòu)支持的預(yù)構(gòu)建模型,并用一些數(shù)據(jù)對其進行訓(xùn)練。
從表面上看,使用最新的模型架構(gòu)似乎很容易達到最先進的效果。然而,這與事實相距甚遠。下面,不妨讓我們先回顧一下與訓(xùn)練嵌入模型相關(guān)的一些常見陷阱(這些也適用于一般的機器學(xué)習(xí)模型):
1. 數(shù)據(jù)不足:在沒有足夠數(shù)據(jù)的情況下從頭開始訓(xùn)練一個新的嵌入模型,這容易導(dǎo)致一種稱為過度擬合的現(xiàn)象。事實上,只有最大的全球性組織才有足夠的數(shù)據(jù)讓訓(xùn)練從零開始成為一種新模型;其他公司或者個人則必須依靠反復(fù)微調(diào)。這種微調(diào)實際上對應(yīng)一個過程;在這個過程中,一般都是基于一個已經(jīng)訓(xùn)練過的包含大量數(shù)據(jù)的模型,并在此基礎(chǔ)上使用一個較小的數(shù)據(jù)集進行不斷的提取操作。
2. 超參數(shù)選擇不當(dāng):超參數(shù)是用于控制訓(xùn)練過程的常數(shù),例如模型學(xué)習(xí)的速度或單個批次中用于訓(xùn)練的數(shù)據(jù)量。在微調(diào)模型時,選擇一組合適的超參數(shù)非常重要,因為對特定值的微小更改可能會導(dǎo)致截然不同的結(jié)果。近期研究表明,ImageNet-1k的精度提高了5%以上(這是很大的),這一成果是通過改進訓(xùn)練程序并從頭開始訓(xùn)練同一模型實現(xiàn)的。
3. 高估自我監(jiān)督模型:自我監(jiān)督(self-supervision)一詞指的是一種訓(xùn)練過程,其中輸入數(shù)據(jù)的“基礎(chǔ)”是通過利用數(shù)據(jù)本身而不是標簽來學(xué)習(xí)的。一般來說,自監(jiān)督方法非常適合預(yù)訓(xùn)練(在使用較小的標記數(shù)據(jù)集對模型進行微調(diào)之前,使用大量未標記數(shù)據(jù)以自監(jiān)督方式訓(xùn)練模型),但直接使用自監(jiān)督嵌入可能會導(dǎo)致次優(yōu)性能。
4. 解決上述三個問題的一種常見方法是,在根據(jù)標記數(shù)據(jù)微調(diào)模型之前,使用大量數(shù)據(jù)訓(xùn)練自監(jiān)督模型。這已經(jīng)被證明對NLP非常有效,但對CV(計算機視覺)并不是很有效。
這里展示的是Meta公司的data2vec訓(xùn)練技術(shù)的例子。這是一種自我監(jiān)督的方法,用于跨各種非結(jié)構(gòu)化數(shù)據(jù)類型訓(xùn)練深層神經(jīng)網(wǎng)絡(luò)。(來源:元人工智能博客)
使用嵌入模型的缺陷
在訓(xùn)練嵌入模型的過程中經(jīng)常出現(xiàn)一些相關(guān)的常見錯誤。常見的情況是,許多希望使用嵌入的開發(fā)人員會立即在學(xué)術(shù)類數(shù)據(jù)集上使用預(yù)先訓(xùn)練好的模型,例如ImageNet(用于圖像分類)和SQuAD(用于問答)。然而,盡管目前存在大量經(jīng)過預(yù)訓(xùn)練的模型可用,但要獲得最大的嵌入性能,還是應(yīng)該避免以下陷阱:
1. 訓(xùn)練和推理數(shù)據(jù)不匹配:使用由其他組織訓(xùn)練的現(xiàn)成模型已成為開發(fā)ML應(yīng)用程序的一種流行方式,而無需再耗費數(shù)千個GPU/TPU小時去重復(fù)訓(xùn)練。理解特定嵌入模型的局限性,以及它如何影響應(yīng)用程序性能,這一點是非常重要的;如果不了解模型的訓(xùn)練數(shù)據(jù)和方法,則很容易誤解結(jié)果。例如,訓(xùn)練嵌入音樂的模型在應(yīng)用于實際的語音應(yīng)用程序時往往效果不佳;反之,亦然。
2. 層選擇不當(dāng):當(dāng)使用完全監(jiān)督的神經(jīng)網(wǎng)絡(luò)作為嵌入模型時,特征通常取自激活的第二到最后一層(一般稱為倒數(shù)第二層)。但是,這可能會導(dǎo)致性能不理想;當(dāng)然,具體情形還要取決于實際的應(yīng)用程序。例如,當(dāng)使用經(jīng)過圖像分類訓(xùn)練的模型嵌入徽標和/或品牌的圖像時,使用早期激活可能會提高性能。這是因為這種方案更好地保留了對那些并不是很復(fù)雜的圖像分類至關(guān)重要的一些低級特征(邊和角)。
3. 不相同的推理條件:為了從嵌入模型中提取最大性能,訓(xùn)練和推理條件必須相同。實際上,情況往往并非如此。例如,在使用TorchVision的標準resnet50模型的過程中,當(dāng)使用雙三次插值和最近鄰插值進行下采樣(downsample)時,會生成兩個完全不同的結(jié)果(見下文)。
BICUBIC INTERPOLATION | NEAREST INTERPOLATION | |
預(yù)測類 | coucal | robin, American robin, Turdus migratorius |
概率 | 27.28% | 47.65% |
嵌入向量 | [0.1392, 0.3572, 0.1988, ..., 0.2888, 0.6611, 0.2909] | [0.3463, 0.2558, 0.5562, ..., 0.6487, 0.8155, 0.3422] |
部署嵌入模型
一旦你順利通過前面的訓(xùn)練并克服與驗證模型相關(guān)的所有障礙,那么,接下來的一個關(guān)鍵步驟就是擴展和部署程序。但嵌入模型部署說起來容易,做起來卻非易事。MLOps是與DevOps相關(guān)的一個領(lǐng)域,專門用于實現(xiàn)這一目的。
1. 選擇合適的硬件:嵌入模型與大多數(shù)其他ML模型類似,可以在各種類型的硬件上運行,從標準的日常CPU到可編程邏輯(FPGA)。幾乎所有的網(wǎng)站上發(fā)布的研究論文都集中在分析成本與效率之間的權(quán)衡,并強調(diào)大多數(shù)組織在解決這方面問題時所面臨的困難。
2. 模型部署方面已經(jīng)有許多現(xiàn)成的MLOP和分布式計算平臺(包括許多開源平臺)可用。不過,弄清楚這些內(nèi)容的工作邏輯并搞清它們?nèi)绾芜m合您的應(yīng)用程序本身就是一個挑戰(zhàn)。
3. 嵌入向量的存儲方案:隨著應(yīng)用程序的擴展,您需要為嵌入向量找到一個可擴展且更持久的存儲解決方案。這正是矢量數(shù)據(jù)庫出現(xiàn)的原因。
一切由我自己來做!
如果真是這樣,請記住幾件至關(guān)重要的事情:
首先,ML與軟件工程非常不同:傳統(tǒng)的機器學(xué)習(xí)起源于統(tǒng)計學(xué),這是一個與軟件工程非常不同的數(shù)學(xué)分支。正則化和特征選擇等重要的機器學(xué)習(xí)概念在數(shù)學(xué)中有很強的基礎(chǔ)。雖然用于訓(xùn)練和推理的現(xiàn)代庫使得訓(xùn)練和生成嵌入模型變得非常容易,但了解不同的超參數(shù)和訓(xùn)練方法如何影響嵌入模型的性能仍然至關(guān)重要。
其次,學(xué)習(xí)使用PyTorch或Tensorflow等框架可能并不簡單。的確,這些庫大大加快了現(xiàn)代ML模型的訓(xùn)練、驗證和部署;而且,另一方面,對于經(jīng)驗豐富的ML開發(fā)人員或熟悉HDL的程序員來說,構(gòu)建新模型或?qū)崿F(xiàn)現(xiàn)有模型也是很直觀的。但是,盡管如此,對于大多數(shù)軟件開發(fā)人員來說,此領(lǐng)域涉及的基本概念本身可能就很難掌握。當(dāng)然,還有一個問題就是選擇哪個框架的問題,因為這兩個框架使用的執(zhí)行引擎存在很多不同(我推薦你使用PyTorch)。
最后,找到一個適合你的代碼庫的MLOps平臺也需要時間??傊袛?shù)百種不同的選擇可供你選擇。當(dāng)然,僅僅評估每種選擇方案的利弊本身就可能是一個長達數(shù)年的研究項目。
說到這里,我不建議你學(xué)習(xí)ML和MLOps;因為這是一個相對漫長而乏味的過程,可能會從你手頭最重要的事情上爭奪時間。
用Towhee加速數(shù)據(jù)科學(xué)應(yīng)用開發(fā)
Towhee是一個開源項目,旨在幫助軟件工程師開發(fā)和部署只需幾行代碼就可以利用嵌入模型的應(yīng)用程序。Towhee項目為軟件開發(fā)人員提供了構(gòu)建其ML應(yīng)用程序的自由和靈活性,而無需深入嵌入模型和機器學(xué)習(xí)。
一個簡單的例子
一個管道(Pipeline)是由多個子任務(wù)(在Towhee中也稱為操作符)組成的單個嵌入生成任務(wù)。通過在管道中抽象整個任務(wù),Towhee可以幫助用戶避免上面提到的許多嵌入生成時遇到的許多陷阱。
>>> from towhee import pipeline
>>> embedding_pipeline = pipeline('image-embedding-resnet50')
>>> embedding = embedding_pipeline('https://docs.towhee.io/img/logo.png')
在上面的例子中,圖像解碼、圖像變換、特征提取和嵌入規(guī)范化是編譯到單個管道中的四個子步驟——開發(fā)人員無需擔(dān)心模型和推理細節(jié)。此外,Towhee還為各種任務(wù)提供預(yù)構(gòu)建的嵌入管道,包括音頻/音樂嵌入、圖像嵌入、面部嵌入等。
方法鏈式API調(diào)用
Towhee還提供了一個名為DataCollection的Python非結(jié)構(gòu)化數(shù)據(jù)處理框架。簡而言之,DataCollection是一種方法鏈接式API,它允許開發(fā)人員在真實數(shù)據(jù)上快速原型化嵌入和其他ML模型。在下面的示例中,我們使用resnet50嵌入模型來使用DataCollection計算嵌入。
在本例中,我們將構(gòu)建一個簡易應(yīng)用程序。此程序中,我們可以使用1位數(shù)字3來過濾素數(shù):
>>> from towhee.functional import DataCollection
>>> def is_prime(x):
... if x <= 1:
... return False
... for i in range(2, int(x/2)+1):
... if not x % i:
... return False
... return True
...
>>> dc = (
... DataCollection.range(100)
... .filter(is_prime) #第一階段:查找素數(shù)
... .filter(lambda x: x%10 == 3) #第二階段:查找以3結(jié)尾的素數(shù)
... .map(str) #第二階段:轉(zhuǎn)換成字符串
... )
...
>>> dc.to_list()
借助DataCollection,你可以使用僅僅一行代碼來開發(fā)整個應(yīng)用程序。例如,下面內(nèi)容中將向你展示如何開發(fā)一個反向圖像搜索應(yīng)用程序。
Towhee訓(xùn)練
如上所述,完全或自我監(jiān)督的訓(xùn)練模型通常擅長用于完成一般性任務(wù)。然而,有時你會想要創(chuàng)建一個嵌入模型,它擅長于某些特定的東西,例如區(qū)分貓和狗。為此,Towhee專門提供了一個訓(xùn)練/微調(diào)框架:
>>> from towhee.trainer.training_config import TrainingConfig
>>> training_config = TrainingConfig(
... batch_size=2,
... epoch_num=2,
... output_dir='quick_start_output'
... )
您還需要指定一個要訓(xùn)練的數(shù)據(jù)集:
>>> train_data = dataset('train', size=20, transform=my_data_transformer)
>>> eval_data = dataset('eval', size=10, transform=my_data_transformer)
一切就緒后,從現(xiàn)有操作符訓(xùn)練一個新的嵌入模型就是小菜一碟了:
>>> op.train(
... training_config,
... train_dataset=train_data,
... eval_dataset=eval_data
... )
一旦完成上面代碼后,您可以在應(yīng)用程序中使用相同的運算符,而無需更改其余代碼。
上圖中顯示的是一幅嵌入模型試圖編碼的圖像核心區(qū)域的注意力熱圖。在Towhee的未來版本中,我們會直接將注意力熱圖和其他可視化工具集成到我們的微調(diào)框架中。
示例應(yīng)用程序:反向圖像搜索
為了演示如何使用Towhee,讓我們快速構(gòu)建一個小型反向圖像搜索應(yīng)用程序。反向圖像搜索是眾所周知的。所以,我們不再贅述有關(guān)細節(jié),而是直接切入主題:
>>> import towhee
>>> from towhee.functional import DataCollection
我們將使用一個小數(shù)據(jù)集和10個查詢圖像。程序中,我們使用DataCollection實現(xiàn)加載數(shù)據(jù)集和查詢圖像:
>>> dataset = DataCollection.from_glob('./image_dataset/dataset/*.JPEG').unstream()
>>> query = DataCollection.from_glob('./image_dataset/query/*.JPEG').unstream()
下一步是在整個數(shù)據(jù)集集合上計算嵌入:
>>> dc_data = (
... dataset.image_decode.cv2()
... .image_embedding.timm(model_name='resnet50')
... )
...
這一步創(chuàng)建了一組局部的嵌入向量——每個向量對應(yīng)于數(shù)據(jù)集中的一個圖像。現(xiàn)在階段,我們就可以查詢最近的鄰居數(shù)據(jù)了:
>>> result = (
... query.image_decode.cv2() #解碼查詢集中的所有圖像
... .image_embedding.timm(model_name='resnet50') #使用'resnet50'嵌入模型計算嵌入
... .towhee.search_vectors(data=dc_data, cal='L2', topk=5) #搜索數(shù)據(jù)集
... .map(lambda x: x.ids) #獲取類似結(jié)果的ID(文件路徑)
... .select_from(dataset) #獲取結(jié)果圖像
... )
...
此外,我們還提供了一種使用Ray框架部署應(yīng)用程序的方法。為此,你只需要調(diào)用一下命令query.set_engine('ray'),其他一切就好辦了!
總結(jié)
最后,我們不認為Towhee項目是一個成熟的端到端模型服務(wù)或MLOps平臺,而且這也不是我們打算實現(xiàn)的目標。相反,我們的目標是加速需要嵌入和其他ML任務(wù)的應(yīng)用程序的開發(fā)。不過,借助Towhee開源項目,我們希望能夠在本地機器(Pipeline+Trainer)上實現(xiàn)嵌入模型和管道的快速原型化,特別是只需幾行代碼就可以開發(fā)以ML為中心的應(yīng)用程序(數(shù)據(jù)收集),并允許輕松快速地部署到集群(通過Ray框架)上。
譯者介紹
朱先忠,51CTO社區(qū)編輯,51CTO專家博客、講師,濰坊一所高校計算機教師,自由編程界老兵一枚。早期專注各種微軟技術(shù)(編著成ASP.NET AJX、Cocos 2d-X相關(guān)三本技術(shù)圖書),近十多年投身于開源世界(熟悉流行全棧Web開發(fā)技術(shù)),了解基于OneNet/AliOS+Arduino/ESP32/樹莓派等物聯(lián)網(wǎng)開發(fā)技術(shù)與Scala+Hadoop+Spark+Flink等大數(shù)據(jù)開發(fā)技術(shù)。
原文標題:Making Machine Learning More Accessible for Application Developers,作者:Frank Liu
鏈接:https://dzone.com/articles/making-machine-learning-more-accessible-for-applic-1