訂閱
糾錯(cuò)
加入自媒體

使用遷移學(xué)習(xí)加強(qiáng)你的圖像搜索

圖像相似度

正如你可能知道的,反向圖像搜索的問題是尋找相似的圖像。

但是如何定義圖像相似性呢?給出兩個(gè)樣本圖像,從視覺上我們可以很容易地確定它們是否相似。我們?nèi)绾瓮ㄟ^編程來做到這一點(diǎn)?

一種非常簡(jiǎn)單的方法將基于與圖像關(guān)聯(lián)的元數(shù)據(jù)。換句話說,我們可以將圖像大小、RGB值、類別標(biāo)簽等元數(shù)據(jù)信息與每張圖像關(guān)聯(lián)起來。

許多web應(yīng)用程序仍然利用這種方法進(jìn)行反向圖像搜索。此類應(yīng)用程序通常將此類元數(shù)據(jù)存儲(chǔ)在ElasticSearch?或Solr?等優(yōu)化文本搜索平臺(tái)中。這種方法很簡(jiǎn)單,但存在許多缺陷。最明顯的一個(gè)是需要大量的手工工作來標(biāo)記每個(gè)圖像。

一種更復(fù)雜的、基于計(jì)算機(jī)視覺的技術(shù)是從圖像本身提取不同的特征。傳統(tǒng)的計(jì)算機(jī)視覺算法,如SIFT和SURF,在提取特征時(shí)具有很強(qiáng)的魯棒性,可以通過比較特征來識(shí)別相似的圖像。

SIFT、SURF和其他一些傳統(tǒng)方法都擅長(zhǎng)從輸入圖像中提取關(guān)鍵特征。圖1描述了如何利用基于SIFT的特征來查找類似的圖像。

圖1:基于SIFT特征的圖像相似性。它非常適用于堅(jiān)硬或不變的物體。這個(gè)例子展示了兩張從不同角度拍攝的自由女神像的照片。使用彩色線條顯示了兩個(gè)圖像之間的前50個(gè)匹配特征。

這個(gè)是一個(gè)快速和強(qiáng)大的方法,在我們有堅(jiān)硬對(duì)象的場(chǎng)景中非常有用。

例如,用矩形盒子如包裝盒或圓形圓盤如表盤等識(shí)別圖像,用這種方法是非常有效的。另一方面,不那么堅(jiān)硬的物體很難匹配。例如,兩個(gè)不同的人體模型以不同的姿勢(shì)展示同一件襯衫/裙子,這可能會(huì)讓傳統(tǒng)技術(shù)難以處理。

你可能知道,可以嘗試使用基于元數(shù)據(jù)的方法或甚至使用傳統(tǒng)的基于計(jì)算機(jī)視覺的技術(shù)來識(shí)別類似的圖像。兩者都有各自的優(yōu)點(diǎn)和缺點(diǎn),F(xiàn)在讓我們從深度學(xué)習(xí)的角度來探索圖像的相似性。

圖像特征與遷移學(xué)習(xí)

遷移學(xué)習(xí)可以用于特征提取、微調(diào)和預(yù)訓(xùn)練設(shè)置。

回顧cnn的特征提取,我們知道預(yù)訓(xùn)練的模型中的初始層可以理解圖像。

在遷移學(xué)習(xí)的幫助下,我們可以訓(xùn)練由預(yù)訓(xùn)練好的網(wǎng)絡(luò)作為特征提取器,然后再訓(xùn)練幾個(gè)淺層。

反向圖像搜索用例巧妙地利用了預(yù)訓(xùn)練模型的特征提取特征(遷移學(xué)習(xí))。

讓我們利用預(yù)訓(xùn)練好的ResNet-50將圖像轉(zhuǎn)化為特征。這些特征通常是密集的一維向量。將輸入轉(zhuǎn)換為向量的過程也稱為向量化。

我們首先需要準(zhǔn)備一個(gè)預(yù)訓(xùn)練ResNet-50模型的實(shí)例。接下來,我們需要一個(gè)實(shí)用函數(shù)來預(yù)處理輸入圖像并得到向量輸出。代碼清單1給出了實(shí)現(xiàn)。

代碼清單1:使用預(yù)訓(xùn)練的ResNet-50將圖像轉(zhuǎn)換為特征向量

# 獲取預(yù)訓(xùn)練模型的工具函數(shù)

def get_pretrained_model(name):

  if (name == 'resnet'):

      # keras API輕松使用預(yù)訓(xùn)練模型

      model = ResNet50(weights='imagenet',
                        include_top=False,
                        input_shape=(224, 224, 3),
                    pooling='max')

  else:

      print("Specified model not available")

  return model

# 將圖像轉(zhuǎn)換為矢量的實(shí)用函數(shù)

def extract_features(img_path, model):

   input_shape = (224, 224, 3)

   img = image.load_img(img_path,

                       target_size=(input_shape[0], input_shape[1]))

  img_array = image.img_to_array(img)

  expanded_img_array = np.expand_dims(img_array, axis=0)

  preprocessed_img = preprocess_input(expanded_img_array)

  features = model.predict(preprocessed_img)

  flattened_features = features.flatten()

  normalized_features = flattened_features / norm(flattened_features)

  return normalized_features

# 獲取一個(gè)隨機(jī)圖像的特征向量

features = extract_features('101_ObjectCategories/Faces/image_0003.jpg',
                           model)

如果我們仔細(xì)看一下清單1中的代碼,keras API使得準(zhǔn)備預(yù)訓(xùn)練模型的實(shí)例和使用它來進(jìn)行我們預(yù)期的特征提取非常容易。

如圖所示,該函數(shù)將圖像輸入轉(zhuǎn)換為2048維密集向量輸出。2048維向量是從ResNet模型的平均池化層中獲得的,該模型在沒有分類層的情況下實(shí)例化。

注意:我們利用ResNet-50來獲得圖像向量,但我們可以自由使用任何其他預(yù)訓(xùn)練模型。我們只需要記住一些方面,例如預(yù)訓(xùn)練網(wǎng)絡(luò)的領(lǐng)域和我們的反向圖像搜索數(shù)據(jù)集以及輸出向量的維數(shù)。

例如,如果我們用vgg -16來代替ResNet-50,特征向量就會(huì)減少到512維。我們將進(jìn)一步討論這些選擇的影響。

在我們開始實(shí)際的反向圖像搜索任務(wù)之前,我們需要一個(gè)數(shù)據(jù)集開始。為了說明目的,我們將使用加州理工學(xué)院101?數(shù)據(jù)集。這個(gè)數(shù)據(jù)集是由李飛飛和他的團(tuán)隊(duì)在2003年收集的,包含了大約40到800張圖像,分別屬于101個(gè)不同的對(duì)象類別。

該數(shù)據(jù)集具有相當(dāng)高質(zhì)量的圖像,非常適合我們的理解目的。

我們已經(jīng)準(zhǔn)備了一個(gè)將圖像轉(zhuǎn)換為向量的工具,讓我們利用相同的函數(shù)來獲得參考數(shù)據(jù)集中圖像的向量表示。這也有助于可視化這些向量,以更好地理解他們。

這個(gè)想法是,相似的物體/圖像應(yīng)該有附近的向量。但我們?nèi)绾慰梢暬粋(gè)2048維空間呢?為此,我們將采用一種降維技術(shù),稱為t-SNE。不用講太多細(xì)節(jié),把t-SNE看作是將高維向量轉(zhuǎn)換為低維空間的方法,同時(shí)保持重要的特征。

有一個(gè)非常簡(jiǎn)化的例子,目前有一個(gè)非常長(zhǎng)的雜貨清單。將清單上的單個(gè)項(xiàng)目分類為蔬菜、水果、乳制品等少數(shù)類別,可以看作是向低維空間的轉(zhuǎn)變,同時(shí)仍然保留重要特征。

在我們目前的情況下,我們將使用t-SNE將2048維向量轉(zhuǎn)換為2維或3維。通過降低維度,我們可以很容易地可視化。

代碼清單2展示了將我們的參考數(shù)據(jù)集轉(zhuǎn)換為向量,然后為了可視化目的降低它們的維數(shù)。代碼清單2:向量化Caltech-101數(shù)據(jù)集和基于t-SNE的降維

batch_size = 64

root_dir = '101_ObjectCategories/'

datagen = tensorflow.keras.preprocessing.

    image.ImageDataGenerator(preprocessing_function=preprocess_input)

#  ImageDataGenerator對(duì)象可以根據(jù)需要從磁盤讀取

#  而不用占用大量?jī)?nèi)存

generator = datagen.flow_from_directory(root_dir,
                                       target_size=(224, 224),
                                       batch_size=batch_size,
                                       class_mode=None,
                                       shuffle=False)

num_images = len(generator.filenames)

num_epochs = int(math.ceil(num_images / batch_size))

start_time = time.time()

feature_list = []

# 模型預(yù)測(cè)是特征向量,因?yàn)樽罱K的分類層被移除

feature_list = model.predict(generator, num_epochs)

end_time = time.time()

# 功能被規(guī)范化以避免縮放問題。

# 限制一個(gè)特征可能采用的值的范圍,以確保一個(gè)或幾個(gè)維度不會(huì)主導(dǎo)整個(gè)特征空間。

for i, features in tqdm(enumerate(feature_list)):

  feature_list[i] = features / norm(features)

print("Num images   = ", len(generator.classes))

print("Shape of feature_list = ", feature_list.shape)

print("Time taken in sec = ", end_time - start_time)

# output

Num images   =  9144

Shape of feature_list =  (9144, 2048)

Time taken in sec =  30.623387098312378

我們已經(jīng)完成了一半,準(zhǔn)備了一個(gè)反向圖像搜索的解決方案。下一步使用這些特征來識(shí)別類似的圖像。

ANNOY:超快的鄰居搜索ANNOY是一個(gè)高度優(yōu)化的超快的最近鄰居搜索方法。ANNOY由Spotify開發(fā),旨在為用戶提供音樂推薦。由于每天有數(shù)百萬用戶在他們的手機(jī)和網(wǎng)絡(luò)上使用它,實(shí)現(xiàn)的重點(diǎn)是速度和準(zhǔn)確性。

ANNOY是用C++開發(fā)的,并且提供Python包裝器,ANNOY是一個(gè)基于樹的向量相似度搜索方法,它有效地利用了內(nèi)存和并行處理。它提供了許多距離度量選項(xiàng),如歐幾里得、余弦、漢明等。

讓我們?cè)诖a清單3中查看使用ANNOY來進(jìn)行反向圖像搜索的快速實(shí)現(xiàn)。

代碼清單3 (a):基于ANNOY的反向圖像搜索

from annoy import AnnoyIndex

annoy_index = AnnoyIndex(2048,'angular')  

# 添加特征到annoy_index

for i in range(num_images):

  feature = feature_list[i]

  # 為每個(gè)annoy_index添加特征向量

  annoy_index.a(chǎn)dd_item(i, feature)

# 構(gòu)建40個(gè)搜索樹

annoy_index.build(40)

annoy_index.save('annoy_caltech101index.a(chǎn)nn')

# 測(cè)試搜索性能

%timeit annoy_index.get_nns_by_vector(feature_list[random_image_index],
                                     5,
                                     include_distances=True)

# 輸出

1000 loops, best of 3: 770 ?s per loop

代碼清單3 (b):測(cè)試基于ANNOY的反向圖像搜索性能

# 測(cè)試一個(gè)更大的樣本

def calculate_annoy_time():

  for i in range(0, 100):

    random_image_index = random.randint(0, num_images)
     

    # 這個(gè)函數(shù)返回類似于查詢的vector

    indexes = annoy_index.get_nns_by_vector(feature_list[random_image_index],
                                             5,
                                             include_distances=True)

%time calculate_annoy_time()

# output

CPU times: user 139 ms, sys: 0 ns, total: 139 ms

Wall time: 142 ms

如清單3所示,使用ANNOY非常簡(jiǎn)單。它是高效的,搜索時(shí)間驚人的快。搜索結(jié)果也非常令人印象深刻,如圖2所示。

圖2:基于ANNOY的反向圖像搜索。每一行表示一個(gè)搜索查詢。最左邊的列代表查詢圖像,最右邊代表搜索結(jié)果。每個(gè)匹配結(jié)果都標(biāo)有其與查詢圖像的歐氏距離。

在很大程度上,ANNOY克服了與搜索速度和內(nèi)存需求相關(guān)的限制。

它還提供了一些額外的選項(xiàng)來進(jìn)行調(diào)整,以進(jìn)一步提高性能。其中一個(gè)與特征向量的大小有關(guān)。這也是很明顯的。如果我們減少向量的大小,它將直接減少尋找鄰居所需的內(nèi)存大小。我們利用ResNet-50輸出2048維向量。如果我們使用像VGG-16, VGG-19甚至是MobileNet這樣的模型,VGG模型的特征向量將減少到512個(gè),而MobileNet的特征向量將減少到1024個(gè)(幾乎減少了50%的大。。

除此之外,我們甚至可以利用典型的降維技術(shù),如主成分分析(PCA)或甚至t-SNE,這是一些最廣泛使用的技術(shù)。這樣的技術(shù)可以幫助我們大幅減少特征向量的大小,從而減少總體的計(jì)算和內(nèi)存需求(盡管這將與搜索性能進(jìn)行權(quán)衡)。

優(yōu)化近鄰搜索方法的需求是如此之大,許多可擴(kuò)展的解決方案已經(jīng)開發(fā)了多年。

在不深入細(xì)節(jié)的情況下,諸如雅虎的LOPQ5,NGT6已經(jīng)在商業(yè)應(yīng)用程序應(yīng)用。在同一直線上,F(xiàn)acebook AI相似性搜索或FAISS為GPU優(yōu)化實(shí)現(xiàn)。

本節(jié)討論的反向圖像搜索的不同方法和實(shí)現(xiàn)是基于首先將圖像轉(zhuǎn)換為特征向量,然后是相似度搜索算法的核心思想。優(yōu)化后的實(shí)現(xiàn)進(jìn)一步關(guān)注內(nèi)存的利用,同時(shí)返回結(jié)果的速度仍然非?。

從這一節(jié)可以明顯看出,反向圖像搜索是一個(gè)活躍的研究領(lǐng)域,通過這些技術(shù),研究人員正在不斷地突破邊界。這些方法的成功開辟了越來越多的用例,其中反向圖像搜索是一個(gè)重要的方面。

現(xiàn)在我們對(duì)反向圖片搜索有了一個(gè)很好的理解,我們可以使用這些知識(shí)從電子商務(wù)網(wǎng)站輕松地找到類似的產(chǎn)品,甚至從一組照片中刪除重復(fù)。

同樣,反向圖片搜索也被Flickr等服務(wù)廣泛使用,用于推薦類似圖片、谷歌購物、Pinterest的“相似”功能、亞馬遜的產(chǎn)品掃描儀,識(shí)別剽竊作品。

不同的場(chǎng)景需要不同的技術(shù),表1簡(jiǎn)要介紹了本節(jié)中討論的每種方法,以供快速參考。

表1:各種鄰域搜索方法的總結(jié)

參考文獻(xiàn)

image.png

       原文標(biāo)題 : 使用遷移學(xué)習(xí)加強(qiáng)你的圖像搜索

聲明: 本文由入駐維科號(hào)的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場(chǎng)。如有侵權(quán)或其他問題,請(qǐng)聯(lián)系舉報(bào)。

發(fā)表評(píng)論

0條評(píng)論,0人參與

請(qǐng)輸入評(píng)論內(nèi)容...

請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字

您提交的評(píng)論過于頻繁,請(qǐng)輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無評(píng)論

暫無評(píng)論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號(hào)
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯(cuò)
x
*文字標(biāo)題:
*糾錯(cuò)內(nèi)容:
聯(lián)系郵箱:
*驗(yàn) 證 碼:

粵公網(wǎng)安備 44030502002758號(hào)