0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于分類目標的預(yù)訓練卷積神經(jīng)網(wǎng)絡(luò)

新機器視覺 ? 來源:飛思實驗室 ? 作者:飛思實驗室 ? 2022-08-02 11:44 ? 次閱讀

自人類文明誕生以來,高達90%的數(shù)據(jù)是在過去兩年中產(chǎn)生的!

隨著社交媒體和物聯(lián)網(wǎng)IoT)等數(shù)字技術(shù)以及5G等速度更快的無線通信技術(shù)的普及,數(shù)據(jù)創(chuàng)建速度不斷提高。然而,創(chuàng)建的大多數(shù)新數(shù)據(jù)都是“非結(jié)構(gòu)化的”,例如文本、圖像、音頻視頻[來源]。

非結(jié)構(gòu)化數(shù)據(jù)之所以得名,是因為它不像由行和列組成的表那樣具有固有的結(jié)構(gòu)。相反,非結(jié)構(gòu)化數(shù)據(jù)包含多種可能格式之一的信息。例如,電子商務(wù)圖像、客戶評論、社交媒體帖子、監(jiān)控視頻、語音命令等都是不遵循傳統(tǒng)表格數(shù)據(jù)格式的豐富信息源。

人工智能AI)和機器學習(ML)技術(shù)的最新進展創(chuàng)造了一種通過使用“嵌入”以可伸縮的方式從非結(jié)構(gòu)化數(shù)據(jù)源中提取有用信息的方法,這種方法將非結(jié)構(gòu)化數(shù)據(jù)轉(zhuǎn)換為嵌入式數(shù)據(jù)并將其存儲在向量數(shù)據(jù)庫(如Milvus)上,實現(xiàn)了幾年前難以想象的幾個優(yōu)秀應(yīng)用程序。

一些示例應(yīng)用程序包括視覺圖像搜索、語義文本搜索、推薦引擎、打擊誤報、藥物發(fā)現(xiàn)等!

在這篇文章中,我們將討論以下內(nèi)容。

什么是嵌入

使用Kaggle API加載一些數(shù)據(jù)

展平原始像素值

基于分類目標的預(yù)訓練卷積神經(jīng)網(wǎng)絡(luò)

基于度量學習目標的預(yù)訓練卷積神經(jīng)網(wǎng)絡(luò)

基于度量學習目標的預(yù)訓練圖文多模態(tài)神經(jīng)網(wǎng)絡(luò)

結(jié)論

在這篇文章中,我們將使用Kaggle提供的Digikala產(chǎn)品顏色分類數(shù)據(jù)集來構(gòu)建一個簡單的基于電子商務(wù)圖像的類似產(chǎn)品搜索服務(wù)。該數(shù)據(jù)集是根據(jù)GPL 2許可證授權(quán)的。

什么是嵌入

我們的計算機無法像人類那樣直接理解圖像或文本。然而,計算機很擅長理解數(shù)字!

因此,為了幫助我們的計算機理解圖像或文本的內(nèi)容,我們需要將它們轉(zhuǎn)換為數(shù)字表示。例如,如果我們考慮圖像用例,我們本質(zhì)上是將圖像的上下文和場景“編碼”或“嵌入”到向量形式的一系列數(shù)字中。

“嵌入”向量是圖像數(shù)據(jù)的數(shù)字表示,以便計算機能夠理解圖像的上下文和場景。

8d62244c-0e7a-11ed-ba43-dac502259ad0.png

幾個Python庫允許我們從圖像生成嵌入。通常,我們可以將這些庫分為兩大類。

提供帶有預(yù)訓練模型的現(xiàn)成API的庫:對于許多涉及日常對象圖像的真實問題,我們可能不需要訓練任何模型。相反,我們可以依賴世界各地研究人員開放的許多高質(zhì)量的預(yù)訓練模型。研究人員已經(jīng)訓練這些模型來識別和聚類ImageNet數(shù)據(jù)集中的對象。

允許我們訓練和微調(diào)模型的庫:顧名思義,對于這些模型,我們可以從頭開始提供數(shù)據(jù)和訓練模型,或者專門針對我們的用例微調(diào)預(yù)訓練的模型。如果預(yù)訓練好的模型還沒有為我們的問題域提供良好的嵌入,那么我們只需要沿著這條路走下去。

讓我們看看這篇文章中的幾個庫。

但首先,讓我們加載一些圖像數(shù)據(jù),以定性地評估相似性搜索應(yīng)用程序中的嵌入。

加載一些數(shù)據(jù)

我們首先需要加載一些圖像數(shù)據(jù)來測試各種嵌入策略。在這篇文章中,我們使用Kaggle提供的Digikala產(chǎn)品顏色分類數(shù)據(jù)集。該數(shù)據(jù)集包含超過6K個電子商務(wù)產(chǎn)品的圖像,非常適合測試基于電子商務(wù)圖像的類似產(chǎn)品搜索服務(wù)。

步驟1:設(shè)置Kaggle環(huán)境

在kaggle上創(chuàng)建帳戶

單擊你的個人資料圖片,然后從下拉菜單中單擊“帳戶”。

向下滾動至“API”部分。

單擊下圖所示的“創(chuàng)建新API令牌”按鈕,下載一個新的令牌,作為一個JSON文件,其中包含用戶名和API密鑰。

如果你使用的是macOS或Linux,請將JSON文件復制到~/.kaggle/目錄。在Windows系統(tǒng)上,轉(zhuǎn)到根目錄,然后轉(zhuǎn)到.kaggle文件夾,并將下載的文件復制到此文件夾。如果.kaggle目錄不存在,請創(chuàng)建它并將JSON文件復制到其中。

8d7a784e-0e7a-11ed-ba43-dac502259ad0.png

步驟2:從Kaggle下載數(shù)據(jù)

我們將使用Anaconda來管理此項目的虛擬環(huán)境。你可以從這里安裝Anaconda。下載并安裝Anaconda后,我們可以建立一個名為semantic_similarity的新環(huán)境,安裝必要的庫,如kaggle和pandas,并從kaggle下載整個數(shù)據(jù)集。如果不想使用Anaconda,還可以使用python的venv為該項目創(chuàng)建和管理虛擬環(huán)境。


#Createadirectoryfornotebooksandanothertodownloaddata mkdir-psemantic_similarity/notebookssemantic_similarity/data/cv #CDintothedatadirectory cdsemantic_similarity/data/cv #Createandactivateacondaenvironment condacreate-nsemantic_similaritypython=3.8 condaactivatesemantic_similarity ##CreateVirtualEnvironmentusingvenvifnotusingconda #python-mvenvsemantic_similarity #sourcesemantic_similarity/bin/activate #Pipinstallthenecessarylibraries pipinstalljupyterlabkagglepandasmatplotlibscikit-learntqdmipywidgets #DownloaddatausingthekaggleAPI kaggledatasetsdownload-dmasouduut94/digikala-color-classification #Unzipthedataintoafashion/directory unzipdigikala-color-classification.zip-d./fashion #DeletetheZipfile rmdigikala-color-classification.zip

該數(shù)據(jù)包含超過6K張各種電子商務(wù)產(chǎn)品的圖像。我們可以在下圖中看到數(shù)據(jù)集中的一些示例圖像。正如你所注意到的,該數(shù)據(jù)集包括各種時尚產(chǎn)品,如男裝、女裝、包、珠寶、手表等。

8d880db0-0e7a-11ed-ba43-dac502259ad0.png

步驟3:將所有圖像從每個文件夾移動到父文件夾

讓我們在semantic_similarity/notebooks目錄中創(chuàng)建一個新的jupyter筆記本,以測試各種嵌入策略。首先,讓我們導入必要的庫。


frommatplotlibimportpyplotasplt importnumpyasnp importos importpandasaspd fromPILimportImage fromrandomimportrandint importshutil fromsklearn.metrics.pairwiseimportcosine_similarity importsys fromtqdmimporttqdm tqdm.pandas()

下載的圖像位于多個子文件夾中。讓我們將它們?nèi)恳苿拥街鞲改夸浿?,以便輕松獲取它們的所有路徑。


defmove_to_root_folder(root_path,cur_path): #Codefromhttps://stackoverflow.com/questions/8428954/move-child-folder-contents-to-parent-folder-in-python forfilenameinos.listdir(cur_path): ifos.path.isfile(os.path.join(cur_path,filename)): shutil.move(os.path.join(cur_path,filename),os.path.join(root_path,filename)) elifos.path.isdir(os.path.join(cur_path,filename)): move_to_root_folder(root_path,os.path.join(cur_path,filename)) else: sys.exit("Shouldneverreachhere.") #removeemptyfolders ifcur_path!=root_path: os.rmdir(cur_path) move_to_root_folder(root_path='../data/cv/fashion',cur_path='../data/cv/fashion')

步驟4:將圖像路徑加載到pandas數(shù)據(jù)幀中

接下來,讓我們將所有圖像文件路徑的列表加載到pandas數(shù)據(jù)幀中。


#Pathtoallthedownloadedimages img_path='../data/cv/fashion' #Findlistofallfilesinthepath images=[ f'../data/cv/fashion/{f}' forfinos.listdir(img_path) ifos.path.isfile(os.path.join(img_path,f)) ] #Loadthefilenamestoadataframe image_df=pd.DataFrame(images,columns=['img_path']) print(image_df.shape) image_df.head()

8e73c55c-0e7a-11ed-ba43-dac502259ad0.png

生成嵌入的策略

計算機視覺技術(shù)的最新進展開辟了許多將圖像轉(zhuǎn)換為數(shù)字嵌入的方法。讓我們看看其中的一些。

展平原始像素值

基于分類目標的卷積神經(jīng)網(wǎng)絡(luò)預(yù)訓練

基于度量學習目標的卷積神經(jīng)網(wǎng)絡(luò)預(yù)訓練

基于度量學習目標的圖文多模態(tài)神經(jīng)網(wǎng)絡(luò)預(yù)訓練

展平原始像素值

彩色圖像由三維像素陣列組成。第一個維度是圖像的高度,第二個維度是圖像的寬度,最后的第三個維度是顏色通道,統(tǒng)稱為RGB,包含紅色、綠色和藍色,如下圖所示。每個像素的值是0到255之間的整數(shù),255是可能的最高強度。

因此,(0,0,0)的RGB值是完全黑暗或純黑色像素,并且(255,255,255)是完全飽和的純白色像素。我們圖像中可見的所有其他顏色都是由這三個基本RGB值的各種組合組成的。

RapidTables網(wǎng)站上的RGB顏色代碼圖表允許你選擇任何顏色來查看其RGB值,可以點擊以下鏈接進行嘗試:

https://www.rapidtables.com/web/color/RGB_Color.html

8e8ce230-0e7a-11ed-ba43-dac502259ad0.png

如果圖像是三維數(shù)組格式的一系列數(shù)字,則使用重塑操作將其轉(zhuǎn)換為一維向量非常簡單,如下圖所示。我們還可以通過將每個像素的值除以255來規(guī)范化。我們將在代碼中執(zhí)行此操作。

8ea577be-0e7a-11ed-ba43-dac502259ad0.png


defflatten_pixels(img_path): #Loadtheimageontopython img=Image.open(img_path).convert('RGB') #Reshapetheimageto1Dandnormalizethevalues flattened_pixels=np.array(img).reshape(-1)/255. returnflattened_pixels #Applythetransformationtothedataframe #Warning!Runningonlyonasubset1Krowsofthedata, #Yourcomputermightcrashifyourunontheentiredataset! #Betterdon’trunit.Wehavemuchbetterwaystogenerateembeddings! pixels_df=image_df.sample(1_000).reset_index(drop=True).copy() pixels_df['flattened_pixels']=pixels_df['img_path'].progress_apply(flatten_pixels)

此方法的問題

雖然這種方法易于理解和實現(xiàn),但這種將圖像“嵌入”到向量中的方法存在一些嚴重的缺點。

巨大的向量:我們從Kaggle下載的圖像非常小[224 x 224 x 3],對應(yīng)于[Height x Width x Channels],將此3D陣列轉(zhuǎn)換為1D向量將得到大小為150528的向量!對于如此小的圖像,這是一個巨大的向量!在整個數(shù)據(jù)集上生成此向量時,我的計算機崩潰了好幾次。最后我只在一個較小的子集(1K行)上運行它來說明這個方法。

具有大量白色的稀疏向量:在視覺上檢查時裝數(shù)據(jù)集中的圖像時,我們會注意到圖片中有很大的白色區(qū)域。因此,這個150528元素向量的許多元素是值255(對于白色),并且沒有添加任何與圖像中的對象相關(guān)的信息。換句話說,這種“嵌入”方案不能有效地對圖像對象進行編碼,而是包含大量無用的空白。

缺乏局部結(jié)構(gòu):最后,直接展平圖像會丟失圖片的所有局部結(jié)構(gòu)。例如,我們通過眼睛、耳朵、鼻子和嘴巴的相對位置來識別人臉圖像。這些是各種各樣的“特征”級別的信息,如果我們一次只看一行像素,就會完全忽略這些信息。這種損失的影響是,一張倒置的臉與一張右側(cè)朝上的臉有著非常不同的嵌入,即使這兩張臉都是同一張人臉的照片!

隨著基于卷積神經(jīng)網(wǎng)絡(luò)CNN和Transformer結(jié)構(gòu)的新型神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)的出現(xiàn),我們基本上克服了這些問題。這篇文章的其余部分將深入探討如何使用這些神經(jīng)網(wǎng)絡(luò)將我們的圖像轉(zhuǎn)換為嵌入。

基于分類目標的卷積神經(jīng)網(wǎng)絡(luò)預(yù)訓練

也許最著名的計算機視覺任務(wù)之一就是將圖像分為不同的類別。通常,對于這項任務(wù),我們將使用CNN模型(如ResNet)作為編碼器,將圖像轉(zhuǎn)換為向量,然后將該向量通過多層感知器(MLP)模型來確定圖像的類別,如下圖所示。

研究人員將使用交叉熵損失對CNN+MLP模型進行訓練,以準確分類圖像類別。

8eb4b1b6-0e7a-11ed-ba43-dac502259ad0.png

這種方法提供了最先進的精確度,甚至超過了大多數(shù)人的能力。在訓練這樣一個模型后,我們可以去掉MLP層,直接將CNN編碼器的輸出作為每個輸入圖像的嵌入向量。

事實上,我們不需要為許多現(xiàn)實世界的問題從頭開始訓練我們自己的CNN模型。相反,我們直接下載并使用已經(jīng)訓練過的模型來識別日常對象,例如ImageNet數(shù)據(jù)集中的類別。

Towhee是一個python庫,它可以使用這些預(yù)訓練好的模型快速生成嵌入。讓我們看看如何做到這一點。

Towhee管道

Towhee是一個python庫,提供了非常易于使用的嵌入生成管道。我們可以使用towhee將圖像轉(zhuǎn)換為嵌入,代碼不到五行!首先,讓我們在終端窗口中使用pip安裝towhee。


#Activatethecondaenvironmentifnotalreadydoneso #condaactivatesemantic_similarity pipinstalltowheetorchtorchvision

接下來,在Jupyter筆記本單元中,讓我們導入庫并實例化一個管道對象。


fromtowheeimportpipeline embedding_pipeline=pipeline('image-embedding')

接下來,讓我們在一行代碼中使用管道將圖像轉(zhuǎn)換為嵌入!嵌入管道的輸出有一些額外的維度,我們可以使用np.squeeze去除這些維度。


image_df['towhee_img_embedding']=image_df['img_path'].progress_apply(lambdax:np.squeeze(embedding_pipeline(x))) image_df.head()

8ec1da6c-0e7a-11ed-ba43-dac502259ad0.png

在繼續(xù)之前,讓我們創(chuàng)建一個helper函數(shù),該函數(shù)接受嵌入列的名稱、用作查詢圖像的數(shù)據(jù)幀索引以及要搜索的類似圖像的k個數(shù)。

該函數(shù)計算查詢圖像的嵌入與數(shù)據(jù)幀中所有其他圖像的嵌入之間的余弦相似度,以找到前k個最相似的圖像并顯示它們。


defplot_similar(df,embedding_col,query_index,k_neighbors=5): '''Helperfunctiontotakeadataframeindexasinputqueryanddisplaytheknearestneighbors ''' #Calculatepairwisecosinesimilaritiesbetweenqueryandallrows similarities=cosine_similarity([df[embedding_col][query_index]],df[embedding_col].values.tolist())[0] #Findnearestneighborindices k=k_neighbors+1 nearest_indices=np.argpartition(similarities,-k)[-k:] nearest_indices=nearest_indices[nearest_indices!=query_index] #Plotinputimage img=Image.open(df['img_path'][query_index]).convert('RGB') plt.imshow(img) plt.title(f'QueryProduct. Index:{query_index}') #Plotnearestneighborsimages fig=plt.figure(figsize=(20,4)) plt.suptitle('SimilarProducts') foridx,neighborinenumerate(nearest_indices): plt.subplot(1,len(nearest_indices),idx+1) img=Image.open(df['img_path'][neighbor]).convert('RGB') plt.imshow(img) plt.title(f'CosineSim:{similarities[neighbor]:.3f}') plt.tight_layout()

我們現(xiàn)在可以通過查詢數(shù)據(jù)幀中的隨機圖像并使用上述輔助函數(shù)顯示k個最相似的圖像來測試towhee嵌入的質(zhì)量。

如下圖所示,towhee嵌入非常準確,我們每次查詢都會從包含多個不同產(chǎn)品(如連衣裙、手表、包和配件)的整套圖像中找到類似的圖片!

考慮到我們僅用三行代碼就生成了這些嵌入,這更令人印象深刻!


plot_similar(df=image_df, embedding_col='towhee_img_embedding', query_index=randint(0,len(image_df)),#Queryarandomimage k_neighbors=5)

8ecf5e3a-0e7a-11ed-ba43-dac502259ad0.png

從結(jié)果中,我們可以得出結(jié)論,towhee是快速生成相似性搜索應(yīng)用程序嵌入的良好起點。

然而,我們沒有明確地訓練這些模型,以確保相似的圖像具有彼此相同的嵌入。因此,在相似性搜索的上下文中,來自此類模型的嵌入對于所有用例可能都不是最準確的。

你現(xiàn)在可能會問的一個自然問題是,“是否有一種方法可以訓練模型,使相似的圖像具有彼此相似的嵌入?”謝天謝地,有!

基于度量學習目標的卷積神經(jīng)網(wǎng)絡(luò)預(yù)訓練

進入度量學習,這是生成嵌入的最有希望的方法之一,特別是對于相似性搜索應(yīng)用程序。在度量學習的最基本層面上,

我們使用神經(jīng)網(wǎng)絡(luò)(如CNN或Transformer網(wǎng)絡(luò))將圖像轉(zhuǎn)換為嵌入。

我們構(gòu)造這些嵌入,以便語義相似的圖像彼此靠近,而不同的圖像則相距更遠。

8edfe192-0e7a-11ed-ba43-dac502259ad0.png

訓練度量學習模型需要在數(shù)據(jù)處理方式和模型訓練方式方面進行創(chuàng)新。

數(shù)據(jù):在度量學習中,對于每個稱為“錨點”圖像的源圖像,我們需要至少一個稱為“正樣本”的類似圖像我們還需要第三個圖像,稱為“負樣本”,以改進嵌入表示。在最近針對每個源圖像的度量學習方法中,我們使用各種數(shù)據(jù)增強綜合生成“錨點”和“正樣本”圖像,如下圖所示。

模型:度量學習模型大多具有暹羅網(wǎng)絡(luò)體系結(jié)構(gòu)。錨點圖像、正圖像和負圖像依次通過相同的模型生成嵌入,然后使用特殊的損失函數(shù)進行比較。其中一個損失函數(shù)稱為對比損失,該模型的目標是將錨點圖像和正面圖像的嵌入移動得更近,使它們之間的距離接近0。相反,該模型旨在將錨點和負樣本移動得更遠,以便它們之間的距離更大。

8ef2db9e-0e7a-11ed-ba43-dac502259ad0.png

在用這種方法訓練模型后,我們可以通過數(shù)學計算嵌入向量之間的距離來發(fā)現(xiàn)任意兩幅圖像之間的相似性,這些距離可以使用余弦距離等度量。正如這篇中型博客文章所示,存在幾種距離度量,余弦距離常用于比較嵌入。

SimCLR:簡單對比學習

SimCLR代表視覺表征對比學習的簡單框架。它是使用一種稱為對比學習的度量學習方法生成圖像嵌入的常用方法之一。在對比學習中,對比損失函數(shù)比較兩個嵌入是相似的(0)還是不同的(1)。

SimCLR的優(yōu)點在于它是一種簡單的自監(jiān)督算法(圖像類不需要任何標簽?。┻@實現(xiàn)了與一些受監(jiān)督方法相當?shù)男阅?,如下圖所示!

8f03d0e8-0e7a-11ed-ba43-dac502259ad0.png8f18872c-0e7a-11ed-ba43-dac502259ad0.png

SimCLR的基本思想如下。

給定一個圖像,創(chuàng)建同一圖像的兩個增強版本。這些增強可以是裁剪和調(diào)整大小、顏色失真、旋轉(zhuǎn)、添加噪聲等。上圖顯示了一些增強的示例。

批處理中所有圖像的增強版本通過CNN編碼器,該編碼器將圖像轉(zhuǎn)換為嵌入。然后,這些CNN嵌入通過一個簡單的多層感知器(MLP)將其轉(zhuǎn)換為另一個空間,該感知器只有一個隱藏層。

最后,使用余弦距離比較MLP輸出處的嵌入。該模型期望來自同一圖像的增強的余弦距離為0,而來自不同圖像的增強的余弦距離為1。然后,損失函數(shù)更新CNN和MLP的參數(shù),以便嵌入更接近我們的期望。

一旦訓練完成,我們就不再需要MLP,直接使用CNN編碼器的輸出作為嵌入。

下圖從概念上解釋了整個過程。有關(guān)更多詳細信息,請查看這篇谷歌博客文章。

https://ai.googleblog.com/2020/04/advancing-self-supervised-and-semi.html

8f2b96dc-0e7a-11ed-ba43-dac502259ad0.png

作者進行了幾次實驗,確定隨機裁剪和顏色失真是增強的最佳組合,如下所示。

8f3c57c4-0e7a-11ed-ba43-dac502259ad0.png

與towhee一樣,我們使用其他研究人員在ImageNet上預(yù)先訓練的模型直接提取SimCLR嵌入。然而,在撰寫本文時,為了獲得SimCLR預(yù)訓練過的嵌入,我們需要使用Pytorch Lightning Bolts庫編寫幾行代碼。我從官方lightning文檔中改編了以下內(nèi)容。首先,在終端窗口中使用pip安裝必要的庫。


#Activatethecondaenvironmentifnotalreadydoneso #condaactivatesemantic_similarity pipinstalllightning-bolts

接下來,在Jupyter筆記本單元中,我們導入必要的庫,并根據(jù)你的計算機是否有GPU將設(shè)備設(shè)置為cuda或cpu。


frompl_bolts.models.self_supervisedimportSimCLR importtorch fromtorch.utils.dataimportDataset,DataLoader fromtorchvisionimportio,transforms #UseGPUifitisavailable device=torch.device('cuda'iftorch.cuda.is_available()else'cpu')

接下來,讓我們加載在ImageNet上預(yù)先訓練的SimCLR模型,并將其設(shè)置為評估模式,因為我們只想從模型中獲得嵌入,而不想再訓練它。


#loadresnet50pre-trainedusingSimCLRonimagenet weight_path='https://pl-bolts-weights.s3.us-east-2.amazonaws.com/simclr/bolts_simclr_imagenet/simclr_imagenet.ckpt' simclr=SimCLR.load_from_checkpoint(weight_path,strict=False,batch_size=32) #SendtheSimCLRencodertothedeviceandsetittoeval simclr_resnet50=simclr.encoder.to(device) simclr_resnet50.eval();

以下兩個步驟針對Pytorch;用于實現(xiàn)模型的基礎(chǔ)庫。我們首先創(chuàng)建一個數(shù)據(jù)集,該數(shù)據(jù)集可以接受我們的數(shù)據(jù)幀作為輸入,從img_path列讀取圖像,應(yīng)用一些轉(zhuǎn)換,最后創(chuàng)建一批圖像,我們可以將其輸入到模型中。


#CreateadatasetforPytorch classFashionImageDataset(Dataset): def__init__(self,df,transform=None): self.df=df self.transform=transform def__len__(self): returnlen(self.df) def__getitem__(self,idx): #LoadtheImage img_path=self.df.loc[idx,'img_path'] image=io.read_image(img_path,mode=io.image.ImageReadMode.RGB)/255. #ApplyTransformations ifself.transform: image=self.transform(image) returnimage #Transforms ##NormalizetransformtoensuretheimageshavesimilarintensitydistributionsasImageNet ##Resizetransformtoensureallimagesinabatchhavethesamesize transformations=transforms.Compose([ transforms.Normalize((0.485,0.456,0.406),(0.229,0.224,0.225)), transforms.Resize(size=(64,64)) ]) #CreatetheDataLoadertoloadimagesinbatches emb_dataset=FashionImageDataset(df=image_df,transform=transformations) emb_dataloader=DataLoader(emb_dataset,batch_size=32)

最后,我們可以在dataloader中迭代批處理,為所有圖像生成嵌入,并將它們作為列存儲回dataframe中。


#Createembeddings embeddings=[] forbatchintqdm(emb_dataloader): batch=batch.to(device) embeddings+=simclr_resnet50(batch)[0].tolist() #Assignembeddingstoacolumninthedataframe image_df['simclr_img_embeddings']=embeddings image_df.head()

8f4d7d2e-0e7a-11ed-ba43-dac502259ad0.png

現(xiàn)在是有趣的部分!我們可以使用相同的helper函數(shù)測試SimCLR嵌入的質(zhì)量。

我們從數(shù)據(jù)幀中查詢隨機圖像,并顯示k個最相似的圖像。如下所示,SimCLR嵌入也非常適合為我們運行的每個查詢找到類似的圖像!


plot_similar(df=image_df, embedding_col='simclr_img_embeddings', query_index=randint(0,len(image_df)), k_neighbors=5)

8f5fe874-0e7a-11ed-ba43-dac502259ad0.png

用度量學習目標預(yù)訓練的圖像-文本多模態(tài)神經(jīng)網(wǎng)絡(luò)

最后,將圖像和文本嵌入到統(tǒng)一嵌入空間的模型有了巨大的改進,這開辟了幾個優(yōu)秀的應(yīng)用程序,如 Image-To-Text 和 Text-To - 圖像相似度搜索。這種范式中最流行的模型之一是CLIP(對比語言圖像預(yù)訓練)。

CLIP是一種基于度量學習框架的神經(jīng)網(wǎng)絡(luò)。CLIP使用圖像作為錨點,相應(yīng)的文本描述作為正樣本來構(gòu)建圖像-文本對。我們可以在多個應(yīng)用程序中使用CLIP,包括文本到圖像、圖像到文本、圖像到圖像和文本到文本的相似性搜索。

圖像通過ResNet或ViT編碼器生成圖像嵌入。文本描述通過基于Transformer的編碼器提供,以生成文本嵌入。CLIP聯(lián)合訓練圖像和文本編碼器,以便在一批N個圖像-文本對中,第i個圖像的嵌入與第i個文本的嵌入具有最高的點積,如下圖所示。

8f6c8714-0e7a-11ed-ba43-dac502259ad0.png

訓練完成后,我們可以通過將兩者轉(zhuǎn)換為各自的嵌入并使用點積或余弦距離進行比較,找到與查詢圖像最相似的文本行,如下圖所示。

相反,我們也可以以相同的方式搜索給定查詢文本的最相似圖像。讓我們看看如何在示例問題上實現(xiàn)這一點。

8f7b4448-0e7a-11ed-ba43-dac502259ad0.png

Sentence Transformers

使用優(yōu)秀的句子Transformer庫,在我們的數(shù)據(jù)上生成CLIP嵌入非常簡單。然而,由于操作系統(tǒng)對一次可以打開的文件數(shù)量的限制,在處理成千上萬的圖像時,我們需要編寫幾行樣板代碼。首先,在終端窗口中使用pip安裝必要的庫。


#Activatethecondaenvironmentifnotalreadydoneso #condaactivatesemantic_similarity pipinstallsentence_transformersftfy

接下來,在Jupyter筆記本單元中,讓我們導入庫并實例化片段模型。


fromsentence_transformersimportSentenceTransformer model=SentenceTransformer('clip-ViT-B-32')

接下來,我們需要迭代10K個圖像,以繞過操作系統(tǒng)對一次可以打開的文件數(shù)量的限制。我們在每次迭代期間加載所有圖像并生成CLIP嵌入。


#Initializeanemptylisttocollectembeddings clip_embeddings=[] #Generateembeddingsfor10_000imagesoneachiteration step=10_000 foridxinrange(0,len(image_df),step): #Loadthe`step`numberofimages images=[ Image.open(img_path).convert('RGB') forimg_pathinimage_df['img_path'].iloc[idx:idx+step] ] #GenerateCLIPembeddingsfortheloadedimages clip_embeddings.extend(model.encode(images,show_progress_bar=True).tolist()) #Assigntheembeddingsbacktothedataframe image_df['clip_img_embedding']=clip_embeddings image_df.head()

8f8d779e-0e7a-11ed-ba43-dac502259ad0.png

現(xiàn)在我們有了所有圖像的CLIP嵌入,我們可以使用相同的輔助函數(shù)來測試嵌入的質(zhì)量。

我們從數(shù)據(jù)幀中查詢隨機圖像,并顯示k個最相似的圖像。如下圖所示,CLIP嵌入也非常準確,可以為我們運行的每個查詢找到相似的圖像!


plot_similar(df=image_df, embedding_col='clip_img_embedding', query_index=randint(0,len(image_df)), k_neighbors=5)

8f9ff2c0-0e7a-11ed-ba43-dac502259ad0.png

雖然我們必須編寫一些額外的代碼來生成CLIP嵌入,但它提供的一個顯著優(yōu)勢是文本到圖像搜索。換句話說,我們可以搜索與給定文本描述匹配的所有圖像。讓我們看看下面的內(nèi)容。

由于我們已經(jīng)將圖像轉(zhuǎn)換為CLIP嵌入,現(xiàn)在只需要將文本查詢轉(zhuǎn)換為CLIP嵌入。然后,我們可以利用文本嵌入和數(shù)據(jù)幀中所有圖像嵌入之間的余弦相似度來搜索相似的產(chǎn)品。我們將編寫一個簡單的助手函數(shù)來為我們完成這一切,如下所示。最后,我們將繪制所有類似的k個產(chǎn)品圖像。


deftext_image_search(text_query,df,img_emb_col,k=5): '''Helperfunctiontotakeatextqueryasinputanddisplaytheknearestneighborimages ''' #Calculatethetextembeddings text_emb=model.encode(text_query).tolist() #Calculatethepairwisecosinesimilaritiesbetweentextqueryandimagesfromallrows similarities=cosine_similarity([text_emb],df[img_emb_col].values.tolist())[0] #Findnearestneighbors nearest_indices=np.argpartition(similarities,-k)[-k:] #PrintQueryText print(f'QueryText:{text_query}') #Plotnearestneighborsimages fig=plt.figure(figsize=(20,4)) plt.suptitle('SimilarProducts') foridx,neighborinenumerate(nearest_indices): plt.subplot(1,len(nearest_indices),idx+1) img=Image.open(df['img_path'][neighbor]).convert('RGB') plt.imshow(img) plt.title(f'CosineSim:{similarities[neighbor]:.3f}') plt.tight_layout()

現(xiàn)在,我們可以使用helper函數(shù)測試示例文本查詢。如下圖所示,如果我們的測試查詢是“一件女裝的照片”,那么最相似的產(chǎn)品都是女裝!盡管每個產(chǎn)品的標題沒有明確指定“連衣裙”一詞,但CLIP模型能夠僅從文本和圖像嵌入推斷出這些圖像與查詢“一張女裝照片”最相關(guān)。

繼續(xù)嘗試其他查詢!


text_query="aphotoofawomen'sdress" text_image_search(text_query, df=image_df, img_emb_col='clip_img_embedding', k=5)

8fab3202-0e7a-11ed-ba43-dac502259ad0.png

結(jié)論

深度學習研究和開源代碼庫的最新技術(shù)為從圖像和文本數(shù)據(jù)生成高質(zhì)量嵌入提供了許多簡單的方法。這些現(xiàn)成的嵌入是為許多實際問題構(gòu)建原型的絕佳起點!下面的流程圖有助于選擇要使用的初始嵌入。但是,在將任何單個查詢部署到生產(chǎn)環(huán)境之前,請不斷評估一些復雜示例查詢上嵌入模型的準確性!

說到生產(chǎn),我們在這里使用的數(shù)據(jù)集是一個只有6K個圖像的玩具數(shù)據(jù)集。在現(xiàn)實世界的應(yīng)用程序中,例如電子商務(wù)商店,你將有數(shù)億個產(chǎn)品圖像需要在幾秒鐘內(nèi)嵌入、存儲和執(zhí)行近鄰搜索!問題的規(guī)模需要使用強大的向量搜索數(shù)據(jù)庫,如Milvus!

8fd34440-0e7a-11ed-ba43-dac502259ad0.png

審核編輯:彭靜

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5087

    文章

    19153

    瀏覽量

    306428
  • 神經(jīng)網(wǎng)絡(luò)

    關(guān)注

    42

    文章

    4776

    瀏覽量

    100952
  • 計算機
    +關(guān)注

    關(guān)注

    19

    文章

    7523

    瀏覽量

    88315
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1507

    瀏覽量

    62217

原文標題:計算機視覺中的語義相似性搜索

文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    【PYNQ-Z2申請】基于PYNQ的卷積神經(jīng)網(wǎng)絡(luò)加速

    項目名稱:基于PYNQ的卷積神經(jīng)網(wǎng)絡(luò)加速試用計劃:申請理由:本人研究生在讀,想要利用PYNQ深入探索卷積神經(jīng)網(wǎng)絡(luò)的硬件加速,在PYNQ上實現(xiàn)圖像的快速處理項目計劃:1、在PC端實現(xiàn)Ln
    發(fā)表于 12-19 11:37

    卷積神經(jīng)網(wǎng)絡(luò)如何使用

    卷積神經(jīng)網(wǎng)絡(luò)(CNN)究竟是什么,鑒于神經(jīng)網(wǎng)絡(luò)在工程上經(jīng)歷了曲折的歷史,您為什么還會在意它呢? 對于這些非常中肯的問題,我們似乎可以給出相對簡明的答案。
    發(fā)表于 07-17 07:21

    卷積神經(jīng)網(wǎng)絡(luò)模型發(fā)展及應(yīng)用

    神經(jīng)網(wǎng)絡(luò)已經(jīng)廣泛應(yīng)用于圖像分類、目標檢測、語義分割以及自然語言處理等領(lǐng)域。首先分析了典型卷積神經(jīng)網(wǎng)絡(luò)模型為提高其性能增加
    發(fā)表于 08-02 10:39

    卷積神經(jīng)網(wǎng)絡(luò)簡介:什么是機器學習?

    大量的二維矩陣。為了實現(xiàn)我們的實際分類目標,我們將二維數(shù)據(jù)轉(zhuǎn)換為長一維向量。轉(zhuǎn)換是在所謂的扁平層中完成的,然后是一個或兩個完全連接的層。最后兩層類型的神經(jīng)元類似于圖2所示的結(jié)構(gòu)。神經(jīng)網(wǎng)絡(luò)的最后一層
    發(fā)表于 02-23 20:11

    python卷積神經(jīng)網(wǎng)絡(luò)cnn的訓練算法

    python卷積神經(jīng)網(wǎng)絡(luò)cnn的訓練算法? 卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network,CNN)一直是深度學習領(lǐng)
    的頭像 發(fā)表于 08-21 16:41 ?1717次閱讀

    卷積神經(jīng)網(wǎng)絡(luò)模型訓練步驟

    模型訓練是將模型結(jié)構(gòu)和模型參數(shù)相結(jié)合,通過樣本數(shù)據(jù)的學習訓練模型,使得模型可以對新的樣本數(shù)據(jù)進行準確的預(yù)測和分類。本文將詳細介紹 CNN 模型訓練的步驟。 CNN 模型結(jié)構(gòu)
    的頭像 發(fā)表于 08-21 16:42 ?1782次閱讀

    卷積神經(jīng)網(wǎng)絡(luò)如何識別圖像

    多層卷積層、池化層和全連接層。CNN模型通過訓練識別并學習高度復雜的圖像模式,對于識別物體和進行圖像分類等任務(wù)有著非常優(yōu)越的表現(xiàn)。本文將會詳細介紹卷積
    的頭像 發(fā)表于 08-21 16:49 ?1957次閱讀

    卷積神經(jīng)網(wǎng)絡(luò)層級結(jié)構(gòu) 卷積神經(jīng)網(wǎng)絡(luò)卷積層講解

    分類目標檢測、人臉識別等。卷積神經(jīng)網(wǎng)絡(luò)的核心是卷積層和池化層,它們構(gòu)成了網(wǎng)絡(luò)的主干,實現(xiàn)了對
    的頭像 發(fā)表于 08-21 16:49 ?8985次閱讀

    卷積神經(jīng)網(wǎng)絡(luò)的介紹 什么是卷積神經(jīng)網(wǎng)絡(luò)算法

    卷積神經(jīng)網(wǎng)絡(luò)的介紹 什么是卷積神經(jīng)網(wǎng)絡(luò)算法 卷積神經(jīng)網(wǎng)絡(luò)涉及的關(guān)鍵技術(shù)
    的頭像 發(fā)表于 08-21 16:49 ?1912次閱讀

    卷積神經(jīng)網(wǎng)絡(luò)算法流程 卷積神經(jīng)網(wǎng)絡(luò)模型工作流程

    卷積神經(jīng)網(wǎng)絡(luò)算法流程 卷積神經(jīng)網(wǎng)絡(luò)模型工作流程? 卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Ne
    的頭像 發(fā)表于 08-21 16:50 ?2928次閱讀

    什么是卷積神經(jīng)網(wǎng)絡(luò)?為什么需要卷積神經(jīng)網(wǎng)絡(luò)

    卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network,CNN)是一種用于處理具有類似網(wǎng)格結(jié)構(gòu)的數(shù)據(jù)的神經(jīng)網(wǎng)絡(luò)。它廣泛用于圖像和視頻識別、文本分類等領(lǐng)域。CNN可以自動
    發(fā)表于 08-22 18:20 ?2661次閱讀

    利用卷積神經(jīng)網(wǎng)絡(luò)實現(xiàn)SAR目標分類的研究

    卷積神經(jīng)網(wǎng)絡(luò)(CNN)是一種在圖像處理和計算機視覺領(lǐng)域廣泛應(yīng)用的深度學習模型,因其能夠自動學習圖像的層次化特征表示而成為SAR目標分類的理想選擇。
    發(fā)表于 04-08 09:39 ?483次閱讀
    利用<b class='flag-5'>卷積</b><b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>實現(xiàn)SAR<b class='flag-5'>目標</b><b class='flag-5'>分類</b>的研究

    卷積神經(jīng)網(wǎng)絡(luò)訓練的是什么

    、訓練過程以及應(yīng)用場景。 1. 卷積神經(jīng)網(wǎng)絡(luò)的基本概念 1.1 卷積神經(jīng)網(wǎng)絡(luò)的定義 卷積
    的頭像 發(fā)表于 07-03 09:15 ?457次閱讀

    cnn卷積神經(jīng)網(wǎng)絡(luò)分類有哪些

    卷積神經(jīng)網(wǎng)絡(luò)(CNN)是一種深度學習模型,廣泛應(yīng)用于圖像分類、目標檢測、語義分割等領(lǐng)域。本文將詳細介紹CNN在分類任務(wù)中的應(yīng)用,包括基本結(jié)構(gòu)
    的頭像 發(fā)表于 07-03 09:28 ?670次閱讀

    卷積神經(jīng)網(wǎng)絡(luò)分類方法有哪些

    卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Networks,CNN)是一種深度學習模型,廣泛應(yīng)用于圖像分類目標檢測、語義分割等計算機視覺任務(wù)。本文將詳細介紹
    的頭像 發(fā)表于 07-03 09:40 ?511次閱讀