关注公众号,发现CV技术之美
▊ 写在前面
群体活动识别是一个关键而又具有挑战性的问题,其核心在于充分探索个体之间的时空交互,产生合理的群体表征 。然而,以前的方法要么分别建模空间和时间信息,要么直接聚合个体特征形成群体特征。
为了解决这些问题,作者提出了一种新的群体活动识别网络,称为GroupFormer 。它联合建模 时空上下文信息,通过聚类 时空Transformer,有效地增强个体和群体的表征。具体来说,GroupFormer有三个的优点:
1)聚类时空Transformer(Clustered Spatial-Temporal Transformer)能够增强个体表征和群体的表征 ;
2)GroupFormer对时空依赖关系进行综合建模 ,并利用解码器建立时空信息之间的联系。
3)利用聚类注意机制动态地将个体划分为多个聚类 ,以更高效地学习具有活动感知能力的语义表征。
此外,实验结果表明,该框架在Volleyball数据集和 Collective Activity数据集上优于SOTA的方法。
▊ 0. K-Means聚类算法
本文在算法实现的时候用到k-means算法,因此,在介绍这篇文章之前,先和大家一起来复习k-means算法吧!
首先我们来看K-Means的名字,K和means分别是什么?K是指类的数量 (是一个超参数),means是指均值 (指的是算法的特性)。
K-means算法主要有步骤可以分为四步:
第一步:初始化聚类中心,这一步就是根据K的数量,来随机初始化K个聚类中心;
第二步:给聚类中心分配样本;
第三步:移动聚类中心;
第四步:判断是否达到终止条件,决定是否停止移动。
聚类之后的效果如下(K=4):
完整代码:
import numpy as np
def distance(p1,p2):
return np.sqrt((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)
def kmeans(nums,k,tolerance=1e-4,max_iter=100):
centers={} #聚类中心
#初始化中心点
for i in range(k):
centers[i]=np.random.randint(low=0,high=500,size=2)
for iter in range(max_iter):
print('this is',iter,'epoch')
clusters={} #每个类包含那些点
#初始化每个类的点
for i in range(k):
clusters[i]=[]
#计算所有点所属的类
for item in nums:
all_dis=[]
for i in range(k):
all_dis.append(distance(item,centers[i]))
clusters[np.argmin(all_dis)].append(item)
#计算新的聚类中心
pre_centers=centers.copy()
for i in range(k):
centers[i]=np.mean(clusters[i],axis=0)
#判断是否还需要继续更新
ok=True
for i in range(k):
if(abs(np.sum((centers[i]-pre_centers[i])**2))>tolerance):
ok=False
break
if(ok==True):
break
return centers,clusters
input=np.random.randint(low=0,high=500,size=(5