聚类学习笔记
0、聚类的分类
根据sklearn的算法选择路径,聚类算法分为
- KMeans、MiniBatchKmeans
- GMM(高斯混合模型)、VBGMM
- MeanShift(均值漂移)
- AffinityPropagation(AP聚类)
- AgglomerativeClustering(层次聚类)
- DBSCAN(基于密度的扫描聚类)
- LVQ(学习向量量化)
1、基于scikit-learn的K-Means算法
1.0、KMeans()类的参数:
- n_clusters:聚类中心的数量,默认8
- max_iter:最大迭代次数,默认300
- tol:容忍的最小误差,小于即退出迭代,默认1e-4
- n_init:整个算法随机运行10次,选最好的一次,默认10
- init:聚类中心选择方案,三个选择‘k-means++’、‘random’、ndarray。默认k-means++
- k-means++:随机选一个点作为聚类中心,对每个点计算与最近已选聚类中心的距离D(x)。然后选择D(x)最大的点作为新的聚类中心,循环,直到选出n_clusters个聚类中心
- random:随机选k个作为聚类中心
- ndarray:若传入的为矩阵(ndarray),则选取矩阵的第一行作为聚类中心
- algorithm:k-means距离计算方法,三个选择:“auto”、“full”、“elkan”,默认auto
- full:传统的距离计算方式
- elkan:使用三角不等式,效率更高,但是不支持稀疏矩阵
- auto:当为稀疏矩阵时,采用full,否则elkan
- precompute_distance:是否将数据全部放入内存
- n_jobs:同时进行计算的核数(并发数),-1为所有CPU,1为不并行。因为sklearn不支持GPU,所以为了速度,建议设置为-1
- verbose:是否输出详细信息,默认为0不输出
- random_state:用于随机产生中心的随机序列
1.1、KMeans实例对象的方法
kmeans = KMeans()
- fit(feature):对feature进行聚类
- predict():对新数据类别进行预测
- cluster_centers_:获取聚类中心
- labels_:获取训练数据所属的类别
- inertia_:获取每个点到聚类中心的距离和
- fit_predict(feature):先fit再predict
- transform(feature):将feature转换为k列矩阵,其中每行为一个实例,每个实例含k个数值,每个数代表到聚类中心的距离
- fit_transform(feature):先fit再transform
2. K-Means 核心代码,以PUL模型为例,使用Keras实现**
参考论文:Unsupervised Person Re-identification: Clustering and Fine-tuning
Github:https://github.com/hehefan/Unsupervised-Person-Re-identification-Clustering-and-Fine-tuning
"""
流程:提取特征-实例化kmeans对象(确定聚类中心选择方案、距离计算方法 )-得到中心点-计算距离矩阵-计算相似度矩阵-选择相似图-微调
"""
from sklearn.cluster import KMeans
# extract features
features = []
for img in unlabeled_images:
feature = net.predict(img) # 提取特征
features.append(np.squeeze(feature))
features = np.array(features)
# clustering
NUM_CLUSTER = 700 # 已知分类数为700,默认为8
kmeans = KMeans(n_clusters=NUM_CLUSTER).fit(features) # 创建实例并训练
# select centers 选择聚类中心
distances = kmeans.transform(features) # num images * NUM_CLUSTER
# distance为n行700列的矩阵,数值为距聚类中心的距离
center_idx = np.argmin(distances, axis=0) # 输出每一列的最小值(0)的下标,为聚类中心
centers = [features[i] for i in center_idx] #
# calculate similarity matrix 计算相似矩阵,计算每个feature和center的相似度,是700行的矩阵
similarities = sess.run(similarity, {center_t: centers, other_t: features}) # NUM_CLUSTER * num images
# select reliable images 选择相似图片
reliable_image_idx = np.unique(np.argwhere(similarities > LAMBDA)[:, 1]) # 选择相似度大于阈值的img
print('ckpt %d: # reliable images %d' % (ckpt, len(reliable_image_idx)))
sys.stdout.flush()
images = np.array([unlabeled_images[i][0] for i in reliable_image_idx])
labels = to_categorical([kmeans.labels_[i] for i in reliable_image_idx])
# retrain: fine tune 使用相似图片进行微调,进行训练
init_model = load_model('checkpoint/0.ckpt') # 载入在其他REID数据集上训练的模型
x = init_model.get_layer('avg_pool').output
x = Flatten(name='flatten')(x)
x = Dropout(0.5)(x)
x = Dense(NUM_CLUSTER, activation='softmax', name='fc8', kernel_initializer=RandomNormal(mean=0.0, stddev=0.001))(x)
net = Model(input=init_model.input, output=x)
for layer in net.layers:
layer.trainable = True
net.compile(optimizer=SGD(lr=0.001, momentum=0.9), loss='categorical_crossentropy')
net.fit_generator(datagen.flow(images, labels, batch_size=BATCH_SIZE), steps_per_epoch=len(images) / BATCH_SIZE + 1,
epochs=NUM_EPOCH)
net.save('checkpoint/%d.ckpt' % ckpt)
print("Finish retrain: fine tune")