- 기초 그래프 컨볼루션 네트워크 (GCN)
1.1 주요 변수 정의 무방향 그래프 ( G = (V, E) ) 에 대해:
- ( V ): 노드 수 ( N )
- ( E ): 간선 집합
- 인접 행렬 ( A \in \mathbb{R}^{N \times N} )
- 차수 행렬 ( D \in \mathbb{R}^{N \times N} ), ( D_{ii} = \sum_j A_{ij} )
- 특성 행렬 ( X \in \mathbb{R}^{N \times C} )
1.2 이웃 특성의 조합 방식 기존의 ( AX ) 연산은 중심 노드 자체 정보를 누락함. 이를 보완하기 위해 ( \tilde{A} = A + \lambda I_N ) 를 사용하여 자기 자신과의 연결을 포함.
또한, 단순 합산은 차수에 따라 출력 크기가 달라져서 정규화가 필요. 표준화 전략으로는 ( \tilde{D}^{-1/2} \tilde{A} \tilde{D}^{-1/2} X ) 가 사용되며, 이는 각 이웃에 대한 가중 평균을 제공.
이 방법은 고차원 노드에 더 큰 영향을 부여하고, 저차원 노드에는 낮은 가중치를 할당함으로써 균형 잡힌 표현을 가능하게 함.
1.3 다층 그래프 컨볼루션 공식 다층 구조에서 각 층은 다음과 같이 정의됨: [ H^{(l+1)} = \sigma\left( \tilde{D}^{-1/2} \tilde{A} \tilde{D}^{-1/2} H^{(l)} W^{(l)} \right) ] 여기서 ( \sigma ) 는 비선형 활성화 함수, ( W^{(l)} ) 는 가중치 매개변수.
- ST-GCN: 시공간 그래프 컨볼루션 네트워크
2.1 주요 기여
- 시간 축까지 확장된 그래프 컨볼루션을 통해 동작의 시계열적 특성을 효과적으로 포착.
- 관절 간 연결의 중요도를 학습 가능한 가중치로 모델링.
- 공간적 및 시간적 이웃 정보를 동시에 처리하는 구조 설계.
2.2 입력 데이터 구성
- OpenPose 기반 18개 관절 추출
- 그래프 구성:
- ( E_S ): 프레임 내 관절 연결 (정적 구조)
- ( E_T ): 연속 프레임 간 동일 관절 연결 (시간적 흐름)
입력 형식: ( \mathcal{X} \in \mathbb{R}^{C \times T \times V} )
- ( C=3 ): (x,y,신뢰도) 좌표
- ( T=300 ): 프레임 수
- ( V=18 ): 관절 수
2.3 공간 컨볼루션 설계
- 샘플링 함수: 거리 기준으로 이웃 범위 제한 (예: 1차 이웃만 포함)
- 가중치 함수: 각 이웃 그룹에 대해 독립적인 가중치 설정
- 그룹화 전략:
- 단일 라벨링: 모든 이웃을 하나의 그룹으로 통합
- 거리 기반 분할: 중심 노드와 다른 이웃을 구분
- 공간 구조 기반 분할 (본 논문 사용):
- 루트 (자신)
- 중심에 가까운 이웃 (centripetal)
- 중심에서 멀리 떨어진 이웃 (centrifugal)
각 그룹은 별도의 가중치 행렬 ( A_k ) 로 표현되며, 전체 ( A ) 는 이들 부분 행렬의 집합으로 구성됨.
2.4 시공간 컨볼루션 공식 [ \mathbf{X}^{(l+1)} = \sum_{k=1}^K \mathbf{A}_k \mathbf{X}^{(l)} \mathbf{W}_k ] 여기서 ( \mathbf{A}_k ) 는 k번째 그룹에 해당하는 정규화된 인접 행렬.
또한, 학습 가능한 엣지 중요도 ( M ) 도 도입되어, 특정 관절 간 상호작용 강도를 자동으로 학습.
[ \mathbf{A} \rightarrow \mathbf{A} \odot M ]
2.5 모델 아키텍처
- 9층 스택된
ST-GCN블록 - 채널 수: 64 → 128 → 256
- 각 층마다 리스크 감소를 위한
Dropout(0.5)적용 - 중간 4층과 7층에서
stride=2의MaxPooling - 최종 출력:
Global Average Pooling→Fully Connected Layer
2.6 핵심 코드 구조
graph.py: 그래프 구조 생성 및 분할 전략 정의tgcn.py: 공간 그래프 컨볼루션 (ConvTemporalGraphical)st-gcn.py: 전체 모델 구조 및 전방전파
# graph.py 예시: 공간 구조 기반 분할
def get_adjacency(self, strategy):
if strategy == 'spatial':
A = []
for hop in valid_hop:
a_root = np.zeros((self.num_node, self.num_node))
a_close = np.zeros((self.num_node, self.num_node))
a_further = np.zeros((self.num_node, self.num_node))
for i in range(self.num_node):
for j in range(self.num_node):
if self.hop_dis[j, i] == hop:
if self.hop_dis[j, self.center] == self.hop_dis[i, self.center]:
a_root[j, i] = norm_adj[j, i]
elif self.hop_dis[j, self.center] > self.hop_dis[i, self.center]:
a_close[j, i] = norm_adj[j, i]
else:
a_further[j, i] = norm_adj[j, i]
if hop == 0:
A.append(a_root)
else:
A.append(a_root + a_close)
A.append(a_further)
return np.stack(A)
# tgcn.py: 그래프 컨볼루션 계산
class ConvTemporalGraphical(nn.Module):
def forward(self, x, A):
x = self.conv(x) # [N, C*kernel_size, T, V]
n, kc, t, v = x.size()
x = x.view(n, self.kernel_size, kc // self.kernel_size, t, v)
return torch.einsum('nkctv,kvw->nctw', (x, A)), A
- AS-GCN: 액션 기반 그래프 컨볼루션 네트워크
3.1 문제점
- ST-GCN은 고차원 관절 간의 실제 물리적 거리에 국한됨.
- 그러나 많은 동작(예: 걷기, 손 흔들기)은 멀리 떨어진 관절 간의 유기적 협동이 필수적.
3.2 해결책: 두 가지 링크 구조 도입
- S-links (Structure links): 기존의 생물학적 구조 기반 연결
- A-links (Action links): 동작 패턴에 따라 자동 추론되는 비물리적 연결
이 두 링크를 결합하여 동작 구조 그래프를 구성.
3.3 A-link 추론 모듈 (AIM)
- 인코더: 다중 반복 메시지 전달을 통해 연결 가능성 추론
- 각 관절 특성 ( p_i^{(0)} = \text{vec}(X_{i,:,:}) )
- 반복적으로 노드 ↔ 링크 간 정보 전달: [ f_e(\mathbf{p}_i, \mathbf{p}_j) = \text{MLP}([\mathbf{p}_i \oplus \mathbf{p}_j]) ] [ f_v(\mathbf{p}_i) = \text{MLP}(\text{Agg}({\mathbf{f}e}{j \sim i}) \oplus \mathbf{p}_i) ]
- 디코더: 과거 관절 위치와 ( A )-link 확률을 입력으로 다음 프레임 예측
- 목적: 자기주도적 학습을 통한 동작 패턴 강화
- 추가 모델 개요
- 2S-AGCN: 2-stage 액션 그래프 네트워크, 초기 링크 추론 후 재조정
- MS-G3D: 다중 스케일 3D 그래프 컨볼루션, 다양한 거리 범위의 특징 동시 추출
- CTR-GCN: 컨텍스트 기반 그래프 컨볼루션, 주변 환경 정보 포함
모든 모델은 인간 행동 이해를 위한 고차원 관계 모델링, 시간적 일관성 유지, 자기주도적 학습을 목표로 함.