如何實(shí)現(xiàn)圖像聚類(lèi)

大家經(jīng)常見(jiàn)的是文章聚類(lèi)、商品聚類(lèi),即根據(jù)文章中的關(guān)鍵詞以及商品自身屬性,然后從機(jī)器學(xué)習(xí)算法中選擇一種常見(jiàn)的聚類(lèi)算法去實(shí)現(xiàn);那么關(guān)于如何進(jìn)行圖像聚類(lèi)如何實(shí)現(xiàn)呢

背景

業(yè)務(wù)當(dāng)中需要給圖片風(fēng)格進(jìn)行標(biāo)簽化,關(guān)于圖片格化處理,這里想的是根據(jù)圖像分類(lèi)的算法來(lái)做,因?yàn)榉诸?lèi)屬于有監(jiān)督學(xué)習(xí),需要整理相關(guān)的訓(xùn)練樣本,如果上來(lái)就通過(guò)人工的方式去整理,成本太高,再加上前期大家認(rèn)知的不同意,樣本質(zhì)量也難得到保障;所以需要先對(duì)已有商品進(jìn)行聚類(lèi)分析,在聚類(lèi)的結(jié)果集上進(jìn)行相關(guān)樣本的整理。


實(shí)現(xiàn)流程

整個(gè)流程并不復(fù)雜,首先采用深度學(xué)習(xí)模型進(jìn)行圖片特征抽取,然后采用K-means對(duì)特征進(jìn)行聚類(lèi)。

特征抽取

  • CNN模型是圖片特征提取常用網(wǎng)絡(luò),這里將使用經(jīng)典圖像分類(lèi)模型Vgg16的卷積網(wǎng)絡(luò)進(jìn)行相關(guān)圖像處理
from keras.applications.vgg16 import VGG16
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input
 
import numpy as np
import pylab
import io
from PIL import Image
from numpy import linalg as LA

base_model = VGG16(weights='imagenet', pooling='max',include_top=False)  #這里也可以使用自己的數(shù)據(jù)集進(jìn)行訓(xùn)練
    
def get_image_feature(path):
    
    model = base_model
#     print(model.summary())
     
    img = Image.open(path)
    img = img.convert('RGB')
    img = img.resize((224,224), Image.NEAREST)
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    features = model.predict(x)
    return features[0]
 
features = get_image_feature()

vec = features/LA.norm(features)
 
print(vec.shape, vec.tolist())

圖片聚類(lèi)

采用k-means對(duì)圖片特征進(jìn)行聚類(lèi)分析,特征長(zhǎng)度512

from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
import pandas as pd
import numpy as np


features = [
    [],
    [] 
]
names = ['', '']

 
df = pd.DataFrame( features )
name_df = pd.DataFrame( names )
samples=df.values

#未進(jìn)行標(biāo)準(zhǔn)化
kmeans=KMeans(n_clusters=3)
kmeans.fit(samples)#訓(xùn)練模型
labels=kmeans.predict(samples)#預(yù)測(cè)
name_df[labels==1]

完整代碼

網(wǎng)上整理了凱旋門(mén)和埃菲爾鐵塔的圖片,簡(jiǎn)單測(cè)試下效果

from keras.applications.vgg16 import VGG16
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input
import os 
import numpy as np
import pylab
import io
from PIL import Image
from numpy import linalg as LA
from sklearn.cluster import KMeans

base_model = VGG16(weights='imagenet', pooling='max',include_top=False)  #這里也可以使用自己的數(shù)據(jù)集進(jìn)行訓(xùn)練
    
def get_image_feature(path):
    
    model = base_model
#     print(model.summary())
     
    img = Image.open(path)
    img = img.convert('RGB')
    img = img.resize((224,224), Image.NEAREST)
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    features = model.predict(x)
    return features[0]


feature_ls = []
names = []
for name in os.listdir("d:/tmp/天池/jd"):
    
    features = get_image_feature(os.path.join("d:/tmp/天池/jd", name))
    #特征標(biāo)準(zhǔn)化
    vec = features/LA.norm(features)

    #print(name,"==", vec.tolist())
    names.append(name)
    feature_ls.append(vec.tolist())
    

df = pd.DataFrame(feature_ls)
names_df = pd.DataFrame(names)
samples=df.values 
kmeans=KMeans(n_clusters=3)
kmeans.fit(samples)#訓(xùn)練模型
labels=kmeans.predict(samples)#預(yù)測(cè)
print(labels, names_df[labels==0] ) 

效果

  • 結(jié)果打印
 # 將標(biāo)簽值為0的數(shù)據(jù)進(jìn)行輸出
[1 1 1 1 1 0 0 0 0 0 0 0]             0
5    test.jpg
6     tt1.jpg
7     tt2.jpg
8     tt3.jpg
9     tt4.jpg
10    tt5.jpg
11  ttkxm.jpg

可以看出所有的鐵塔被劃分到一個(gè)類(lèi)了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容