코딩 및 기타
YNet 코드
정지홍
2025. 10. 17. 15:36
https://jihong.tistory.com/731
[Trajectory] Y-net
From Goals, Waypoints & Paths To Long Term Human Trajectory Forecasting[2012.01526] From Goals, Waypoints & Paths To Long Term Human Trajectory Forecasting From Goals, Waypoints & Paths To Long Term Human Trajectory ForecastingHuman trajectory forecasting
jihong.tistory.com
[배치, 높이, 폭, 채널]




1. YNetTorch 클래스
if segmentation_model_fp와 else문
- 해당되는 내용은 3가지 경우의 수로 나눌수있다.
- 경우 1 ==> segmentation_model_fp가 준비되어 있다면, raw이미지에 segmentatin을 수행하겠다.
- 경우 1-1 ==> use_features_only=False는 클래스 확률맵을 사용하겠다. (Class*Height*Width)의 3차원 벡터
- 만약, [도로, 보도, 잔디, 계단, 벽]라고 하면 5개의 채널이 존재한다면, semantic_classes=5이다.
- 경우 1-2 ==> use_features_only=True 는 segmetation의 head를 끄고, 직전 특징맵을 사용하겠다는 의미. (F_dim*Height*Width)의 3차원 벡터
- F_dim은 세그멘테이션 백본의 “마지막 1×1 Conv(클래스 분류기)” 바로 직전 특징 채널 수" 이다.
- 경우 1-1 ==> use_features_only=False는 클래스 확률맵을 사용하겠다. (Class*Height*Width)의 3차원 벡터
- 경우 2 ==> else에서 segmetation된 image를 주겠다.
- 경우 3 ==> else에서 segmetation된 image를 안주겠다.
- nn.Identify()는 입력을 그대로 반환하는 모듈이다.
- line 129 : encoder를 생성
- line 131 : goal_decoder를 생성
- line 132 : traject_decoder를 생성


2. YNetEncoder클래스
- 우선 RGB Image가 semantic_classes이다. 혹은 클래스의 갯수.
- line 20 : 이는 nn.Module의 __init()을 호출하는것.
- 클래스는 nn.Module을 상속하는것이니 사실상 위 부모의 __init__()을 호출하는것.
- line 21 : pythorch의 모듈컨테이너이다.
- 여러개의 nn.Module( ex. Conv2d , Linear , Sequential 등 )을 python의 list처럼 담아두는것.
- 이렇게 해야, 모델의 하위 모델로 등록시켜줌.
- line 23 : 첫번째 stage
- Conv2d( in_channels , channels[0] , kernel_size=(3,3) , stride=(1,1) , padding=(1,1) , nn.ReLu )
- u-net의 첫번째 레이어.
- channels는 전달 받은거... channels[0]은 64일것.
- line 28 : 나머지 stage들을 반복적으로 구성
- len(channels)-1만큼 반복...
- u-net기반이니, "max pool 2x2" , "conv 3x3 ReLU" , "conv 3x3 ReLU"가 들어갈것.
- line 36 : decoder에 넘기기 전에 한번 더 다운 샘플링 수행
- line 38 : 순전파.


3. YNet-Decoder 클래스
- line 46 : 클래스 정의... 인코더의 skip feature들을 받아서 upsaming+결합하여 heatmap을 예측하는 디코더
- line 47 : 초기 traj=False로 설정
- line 48 : super(YNetDecoder , self ).__init__()으로 nn.Module을 초기화.
- line 50 : 만약 True라면, 이는 trajectory decoder를 의미.
- line 51 : [ channel + traj for channel in encoder_channels ]
- goal_decoder는 "segmetation + past trajectory"를 사용하고,
goal_decoder이후의 trajectory_decoder는 "segmetation + past trajectory + goal/waypoint heatmap"을 사용
- goal_decoder는 "segmetation + past trajectory"를 사용하고,
- line 51 : [ channel + traj for channel in encoder_channels ]
- line 52 : encoder_channels를 역순으로 바꾼다.
- [ N , C , H , W ]이다.
- [ 배치 , 채널 , 높이 , 폭 ]
- 모든 과정에서 배치는 변하지 않음. H와 W는 padding과 stride에 따라 달라짐
- line 53 : encoder_channels는 한번 역순으로 바꾸었으니, 가장 작은 해상도의 skip feature의 채널수이다.
- line 57 : 센터에서 채널 폭을 키워서 표현력을 늘림.
- self.center = nn.Sequential( nn.Conv2d , nn.ReLU , nn.Conv2d , nn.ReLU )
- 입력은 [N, center_channels, H, W]
출력은 [N, center_channels*2, H, W]- stride=1 , padding=1 , kernel=3이니...
- ===> 즉, line 57에서 "첫번째 Conv2d + ReLU"는 통과가 된다면 채널이 2배가 된다... "두번째 Conv2d + ReLU"는 채널은 유지된다. 하지만 2번째의 역할은 특징을 더 정제하는것.
- 입력은 [N, center_channels, H, W]
- self.center = nn.Sequential( nn.Conv2d , nn.ReLU , nn.Conv2d , nn.ReLU )