一、ST-GCN
该模型建立在一系列骨架图之上,其中每个节点对应于人体的一个关节。符合节点自然连通性的空间边(图1中淡蓝色线条)和跨越连续时间步长连接相同节点的时间边(淡绿色线条)。在此基础上构建了多层时空图卷积,实现了信息沿图维和时间维的整合。
1.骨架图构建
在具有N个关节和T个框架的骨架序列上构造了无向时空图G = (V, E)。
节点设置为 𝑉={𝑣𝑡𝑖|𝑡=1,...,𝑇;𝑖=1,...,𝑁} ,包括骨架序列中的所有关节。
边用 𝐸 来表示,上面我们说到边有两种,分别是在时间上和空间上,因此用如下表示:为第一个子集描述了每帧的骨架内连接 𝐸𝑠={𝑣𝑡𝑖𝑣𝑡𝑗|(𝑖,𝑗)∈𝐻} ,其中H为自然连接的人体关节集合;第二个子集包含帧间边,它们连接连续帧中的相同节点 𝐸𝐹={𝑣𝑡𝑖𝑣(𝑡+1)𝑖} ,对于一个特定的关节 𝑖 , 𝐸𝐹 中的所有边都将表示它随时间的轨迹。
2.空间图卷积神经网络
首先是传统的卷积神经网络
其中,p为采样函数,采样x像素点周围(h,w)范围内的相邻像素点做卷积运算;W为权重函数,提供用于与输入采样特征进行内积运算的权重矩阵。
2.1 采样函数
在ST-GCN中,节点node等同于传统卷积的图像像素点,采样函数就是负责指定对每个节点进行图卷积操作时,所涉及到的相邻节点范围,在本文中D = 1, 即一阶相邻节点(直接相连的节点)。
公式如下
,对于D= 1 ,
2.2 权重函数
传统神经网络因为有固定的顺序,所示可以直接索引一个(c×K×K)的张量。但在graph中却没有默认的空间排列。
ST- GCN的具体做法是将节点node换分成多个子集,比如向心、离心、根节点。对每个子集分配不同的权重。 子集的映射关系
因此 权重函数 为
or
2.3 空间图卷积
更新后的卷积公式:
其中 用于平衡不同子集的贡献程度
最后更新为
2.4 时空卷积
将空间图扩展到时空域中。具体定义公式:
从上式可以看出,相邻节点的定义是“在空间距离上小于K,在帧距离上前后小于Γ/2”,即在空间邻域的定义上加入了时间约束。
上文介绍的采样函数、权重函数是针对空间graph的,时间上的图卷积也需要一套采样函数、权重函数。
3 分区策略
(a) 输入骨骼序列的示意图,红色节点为本次卷积计算的中心节点,红色虚线内蓝色节点为其采样的相邻节点。
(b) 单一划分:把节点的邻域节点全划为一个子集(包括自身),缺点:邻域节点与同一个权重进行内积,无法计算局部微分属性。
(c)基于距离划分:中心节点为一类,相邻节点(不包括自身)为另一类
(d) 空间配置划分(也是本文真正采用的方法,这么分配或许更能表征人体关键点的向心运动与离心运动):按照关节点的向心离心关系定义,r表示节点到骨骼图重心的平均距离。此时对于一个节点的卷积运算,其权重矩阵包括三种权重向量。
4、模型实现
采用单一划分策略:
采用多个子集的划分策略:
代码中具体的卷积方法确实这样的:
def _normalize_digraph(self, A): #矩阵归一化,即每个矩阵值÷对应列的节点数 Dl = np.sum(A, 0) # 按列求和,每个节点相连的个数 num_node = A.shape[0] #假设 A.shape的值是 (3, 3),而 A.shape[0] 的值就是 3,表示矩阵 A 有 3 行。 Dn = np.zeros((num_node, num_node)) for i in range(num_node): if Dl[i] > 0: Dn[i, i] = Dl[i] ** (-1) # 给对角线赋值,值为当前节点连接节点数的倒数 AD = np.dot(A, Dn) # 修改邻接矩阵。A*Dn return AD