大家經(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)了