Fix edge-index scene mixing; add relative residual cap; guard LED sigma NaN
Browse filesAll new behaviour is behind environment toggles that default to OFF, so the previous behaviour is reproduced bit-for-bit when they are unset.
MoFlow/models/graph_interaction_nba.py
SRA_EDGE_FIX=1 fixes _make_batched_edge_index: [S,2,E0].reshape(2,-1) packed
scene blocks into the src/dst rows, so 0% of edges stayed inside a scene and
half the nodes had no incoming edge. permute(1,0,2) first keeps the rows intact.
MoFlow/models/graph_interaction_nba_v6.py
SRA_RES_CAP_REL=r caps the graph residual relative to the host embedding
(||res|| <= r*||orig||). This is what makes MoFlow stable
after the edge fix; absolute caps only delay divergence.
SRA_RES_CAP=c absolute cap (kept for comparison; inferior on MoFlow).
SRA_GATE_SCALE, SRA_SOFT_START, SRA_GATE_BIAS additional damping knobs.
Caps use torch.where, not rn.clamp(max=c)/(rn+eps): the latter has zero
gradient at res=0 and silently shrinks sub-cap values.
LED/trainer/train_led_graph.py
LED_SIGMA_CLAMP / LED_SIGMA_DETACH / LED_STD_EPS guard the NaN path that
killed LED full-SRA (sigma ON) at epoch 4; plus logvar logging.
docs/RELCAP.md, docs/MOFLOW_EDGEFIX.md write-ups of both fixes.
- LED/trainer/train_led_graph.py +32 -1
- MoFlow/fm_nba_graph_v6_nosigma.py +4 -1
- MoFlow/fm_sdd.py +4 -1
- MoFlow/fm_sdd_graph.py +4 -1
- MoFlow/models/graph_interaction_nba.py +21 -2
- MoFlow/models/graph_interaction_nba_v6.py +64 -1
- docs/MOFLOW_EDGEFIX.md +204 -0
- docs/RELCAP.md +181 -0
|
@@ -276,12 +276,26 @@ class Trainer:
|
|
| 276 |
batch_size, traj_mask, past_traj, fut_traj = self.data_preprocess(data)
|
| 277 |
|
| 278 |
sample_prediction, mean_estimation, variance_estimation = self.model_initializer(past_traj, traj_mask)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 279 |
sample_prediction = (torch.exp(variance_estimation / 2)[..., None, None]
|
| 280 |
* sample_prediction
|
| 281 |
-
/ sample_prediction.std(dim=1).mean(dim=(1, 2))[:, None, None, None]
|
|
|
|
| 282 |
loc = sample_prediction + mean_estimation[:, None]
|
| 283 |
|
| 284 |
sigma_input = variance_estimation if self.use_sigma else None
|
|
|
|
|
|
|
|
|
|
| 285 |
generated_y = self.p_sample_loop_accelerate(past_traj, traj_mask, loc, sigma=sigma_input)
|
| 286 |
|
| 287 |
loss_dist = ((generated_y - fut_traj.unsqueeze(dim=1)).norm(p=2, dim=-1)
|
|
@@ -290,6 +304,17 @@ class Trainer:
|
|
| 290 |
* (generated_y - fut_traj.unsqueeze(dim=1)).norm(p=2, dim=-1).mean(dim=(1, 2))
|
| 291 |
+ variance_estimation).mean()
|
| 292 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 293 |
loss = loss_dist * 50 + self.uncertainty_weight * loss_uncertainty
|
| 294 |
loss_total += loss.item()
|
| 295 |
loss_dt += loss_dist.item() * 50
|
|
@@ -334,6 +359,9 @@ class Trainer:
|
|
| 334 |
batch_size, traj_mask, past_traj, fut_traj = self.data_preprocess(data)
|
| 335 |
|
| 336 |
sample_prediction, mean_estimation, variance_estimation = self.model_initializer(past_traj, traj_mask)
|
|
|
|
|
|
|
|
|
|
| 337 |
sample_prediction = (torch.exp(variance_estimation / 2)[..., None, None]
|
| 338 |
* sample_prediction
|
| 339 |
/ sample_prediction.std(dim=1).mean(dim=(1, 2))[:, None, None, None])
|
|
@@ -381,6 +409,9 @@ class Trainer:
|
|
| 381 |
batch_size, traj_mask, past_traj, fut_traj = self.data_preprocess(data)
|
| 382 |
|
| 383 |
sample_prediction, mean_estimation, variance_estimation = self.model_initializer(past_traj, traj_mask)
|
|
|
|
|
|
|
|
|
|
| 384 |
sample_prediction = (torch.exp(variance_estimation / 2)[..., None, None]
|
| 385 |
* sample_prediction
|
| 386 |
/ sample_prediction.std(dim=1).mean(dim=(1, 2))[:, None, None, None])
|
|
|
|
| 276 |
batch_size, traj_mask, past_traj, fut_traj = self.data_preprocess(data)
|
| 277 |
|
| 278 |
sample_prediction, mean_estimation, variance_estimation = self.model_initializer(past_traj, traj_mask)
|
| 279 |
+
|
| 280 |
+
# --- ฯ ์์ ํ ๊ฐ๋ (๊ธฐ๋ณธ ์ ๋ถ off => ์๋ณธ๊ณผ ๋นํธ ๋จ์๋ก ๋์ผ) --------------
|
| 281 |
+
# ๋ฐฐ๊ฒฝ: --use_sigma ๋ก logvar ๋ฅผ ๊ทธ๋ํ์ ๋ฃ์ผ๋ฉด NLL ์ด์ธ์ gradient ๊ฒฝ๋ก๊ฐ
|
| 282 |
+
# ํ๋ ๋ ์๊ธด๋ค. logvar ๊ฐ ์์๋ก ๋ฐ๋ฆฌ๋ฉด exp(-logvar) ๊ฐ ํญ์ฃผํ๊ณ
|
| 283 |
+
# exp(logvar/2)*x / std(x) ์ ๋ถ๋ชจ๋ 0 ์ผ๋ก ๊ฐ์ NaN ์ด ๋๋ค.
|
| 284 |
+
# (์ค์ ๋ก LED full SRA ฯ ON ์ด epoch 4 ์์ ์ด๋ ๊ฒ ์ฃฝ์๋ค)
|
| 285 |
+
_clamp = float(os.environ.get('LED_SIGMA_CLAMP', 0.0) or 0.0)
|
| 286 |
+
if _clamp > 0:
|
| 287 |
+
variance_estimation = variance_estimation.clamp(-_clamp, _clamp)
|
| 288 |
+
|
| 289 |
sample_prediction = (torch.exp(variance_estimation / 2)[..., None, None]
|
| 290 |
* sample_prediction
|
| 291 |
+
/ sample_prediction.std(dim=1).mean(dim=(1, 2))[:, None, None, None]
|
| 292 |
+
.clamp_min(float(os.environ.get('LED_STD_EPS', 0.0) or 0.0)))
|
| 293 |
loc = sample_prediction + mean_estimation[:, None]
|
| 294 |
|
| 295 |
sigma_input = variance_estimation if self.use_sigma else None
|
| 296 |
+
# ฯ ๋ฅผ '๊ฒ์ดํธ ์ ํธ'๋ก๋ง ์ฐ๊ณ ๋ถ์ฐ ํค๋๋ก ์ญ์ ํํ์ง ์๋ ์ต์
|
| 297 |
+
if sigma_input is not None and os.environ.get('LED_SIGMA_DETACH', '') not in ('', '0', 'false', 'False'):
|
| 298 |
+
sigma_input = sigma_input.detach()
|
| 299 |
generated_y = self.p_sample_loop_accelerate(past_traj, traj_mask, loc, sigma=sigma_input)
|
| 300 |
|
| 301 |
loss_dist = ((generated_y - fut_traj.unsqueeze(dim=1)).norm(p=2, dim=-1)
|
|
|
|
| 304 |
* (generated_y - fut_traj.unsqueeze(dim=1)).norm(p=2, dim=-1).mean(dim=(1, 2))
|
| 305 |
+ variance_estimation).mean()
|
| 306 |
|
| 307 |
+
# logvar ์ถ์ด๋ฅผ ๋จ๊ธด๋ค (NaN ์ด ๋๋ฉด ์์ธ์ ์ฌํ์ ์ ์ ์๊ฒ)
|
| 308 |
+
if count % 200 == 0:
|
| 309 |
+
with torch.no_grad():
|
| 310 |
+
_v = variance_estimation.detach()
|
| 311 |
+
self.tb.add_scalar('sigma/logvar_min', float(_v.min()), self.global_step)
|
| 312 |
+
self.tb.add_scalar('sigma/logvar_max', float(_v.max()), self.global_step)
|
| 313 |
+
self.tb.add_scalar('sigma/logvar_mean', float(_v.mean()), self.global_step)
|
| 314 |
+
self.tb.add_scalar('sigma/pred_std_min',
|
| 315 |
+
float(sample_prediction.std(dim=1).mean(dim=(1, 2)).min()),
|
| 316 |
+
self.global_step)
|
| 317 |
+
|
| 318 |
loss = loss_dist * 50 + self.uncertainty_weight * loss_uncertainty
|
| 319 |
loss_total += loss.item()
|
| 320 |
loss_dt += loss_dist.item() * 50
|
|
|
|
| 359 |
batch_size, traj_mask, past_traj, fut_traj = self.data_preprocess(data)
|
| 360 |
|
| 361 |
sample_prediction, mean_estimation, variance_estimation = self.model_initializer(past_traj, traj_mask)
|
| 362 |
+
_c = float(os.environ.get('LED_SIGMA_CLAMP', 0.0) or 0.0)
|
| 363 |
+
if _c > 0:
|
| 364 |
+
variance_estimation = variance_estimation.clamp(-_c, _c)
|
| 365 |
sample_prediction = (torch.exp(variance_estimation / 2)[..., None, None]
|
| 366 |
* sample_prediction
|
| 367 |
/ sample_prediction.std(dim=1).mean(dim=(1, 2))[:, None, None, None])
|
|
|
|
| 409 |
batch_size, traj_mask, past_traj, fut_traj = self.data_preprocess(data)
|
| 410 |
|
| 411 |
sample_prediction, mean_estimation, variance_estimation = self.model_initializer(past_traj, traj_mask)
|
| 412 |
+
_c = float(os.environ.get('LED_SIGMA_CLAMP', 0.0) or 0.0)
|
| 413 |
+
if _c > 0:
|
| 414 |
+
variance_estimation = variance_estimation.clamp(-_c, _c)
|
| 415 |
sample_prediction = (torch.exp(variance_estimation / 2)[..., None, None]
|
| 416 |
* sample_prediction
|
| 417 |
/ sample_prediction.std(dim=1).mean(dim=(1, 2))[:, None, None, None])
|
|
@@ -18,7 +18,10 @@ import copy
|
|
| 18 |
import torch
|
| 19 |
import argparse
|
| 20 |
from torch.utils.data import DataLoader
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
from data.dataloader_nba_graph import NBADatasetMinMax, seq_collate_nba_graph
|
| 24 |
|
|
|
|
| 18 |
import torch
|
| 19 |
import argparse
|
| 20 |
from torch.utils.data import DataLoader
|
| 21 |
+
try: # tensorboardX needs a protobuf build
|
| 22 |
+
from tensorboardX import SummaryWriter # that is not present in this env
|
| 23 |
+
except ImportError:
|
| 24 |
+
from torch.utils.tensorboard import SummaryWriter
|
| 25 |
|
| 26 |
from data.dataloader_nba_graph import NBADatasetMinMax, seq_collate_nba_graph
|
| 27 |
|
|
@@ -3,7 +3,10 @@ import torch
|
|
| 3 |
import argparse
|
| 4 |
import copy
|
| 5 |
from torch.utils.data import DataLoader, random_split
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
from data.dataloader_sdd_moflow import SDDDatasetMinMax as NBADatasetMinMax
|
| 9 |
from data.dataloader_sdd_moflow import seq_collate_sdd as seq_collate_nba
|
|
|
|
| 3 |
import argparse
|
| 4 |
import copy
|
| 5 |
from torch.utils.data import DataLoader, random_split
|
| 6 |
+
try:
|
| 7 |
+
from tensorboardX import SummaryWriter
|
| 8 |
+
except ImportError:
|
| 9 |
+
from torch.utils.tensorboard import SummaryWriter
|
| 10 |
|
| 11 |
from data.dataloader_sdd_moflow import SDDDatasetMinMax as NBADatasetMinMax
|
| 12 |
from data.dataloader_sdd_moflow import seq_collate_sdd as seq_collate_nba
|
|
@@ -28,7 +28,10 @@ import copy
|
|
| 28 |
import torch
|
| 29 |
import argparse
|
| 30 |
from torch.utils.data import DataLoader
|
| 31 |
-
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
from data.dataloader_sdd_moflow_graph import SDDDatasetMinMax as NBADatasetMinMax, seq_collate_sdd_graph as seq_collate_nba_graph
|
| 34 |
from data.dataloader_sdd_moflow import SortedByASampler
|
|
|
|
| 28 |
import torch
|
| 29 |
import argparse
|
| 30 |
from torch.utils.data import DataLoader
|
| 31 |
+
try:
|
| 32 |
+
from tensorboardX import SummaryWriter
|
| 33 |
+
except ImportError:
|
| 34 |
+
from torch.utils.tensorboard import SummaryWriter
|
| 35 |
|
| 36 |
from data.dataloader_sdd_moflow_graph import SDDDatasetMinMax as NBADatasetMinMax, seq_collate_sdd_graph as seq_collate_nba_graph
|
| 37 |
from data.dataloader_sdd_moflow import SortedByASampler
|
|
@@ -20,6 +20,7 @@ Memory-efficient design for MoFlow's [B=250, K=20, A=11] NBA setting:
|
|
| 20 |
the A6000's 48 GB).
|
| 21 |
"""
|
| 22 |
|
|
|
|
| 23 |
import torch
|
| 24 |
import torch.nn as nn
|
| 25 |
from torch_geometric.nn.conv import MessagePassing
|
|
@@ -200,14 +201,32 @@ class FutureInteractionGraph(nn.Module):
|
|
| 200 |
return torch.tensor([src, dst], dtype=torch.long)
|
| 201 |
|
| 202 |
def _make_batched_edge_index(self, num_scenes: int) -> torch.Tensor:
|
| 203 |
-
"""Stack num_scenes copies of the A-node graph with correct offsets.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
single = self._single_edge_index # [2, E0]
|
| 205 |
A = self.num_agents
|
| 206 |
offsets = torch.arange(num_scenes, device=single.device) * A # [S]
|
| 207 |
batched = (single.unsqueeze(0)
|
| 208 |
.expand(num_scenes, -1, -1) # [S, 2, E0]
|
| 209 |
+ offsets.view(-1, 1, 1))
|
| 210 |
-
|
|
|
|
|
|
|
|
|
|
| 211 |
|
| 212 |
# ------------------------------------------------------------------
|
| 213 |
# Forward
|
|
|
|
| 20 |
the A6000's 48 GB).
|
| 21 |
"""
|
| 22 |
|
| 23 |
+
import os
|
| 24 |
import torch
|
| 25 |
import torch.nn as nn
|
| 26 |
from torch_geometric.nn.conv import MessagePassing
|
|
|
|
| 201 |
return torch.tensor([src, dst], dtype=torch.long)
|
| 202 |
|
| 203 |
def _make_batched_edge_index(self, num_scenes: int) -> torch.Tensor:
|
| 204 |
+
"""Stack num_scenes copies of the A-node graph with correct offsets.
|
| 205 |
+
|
| 206 |
+
NOTE (edge-index scene-mixing bug):
|
| 207 |
+
`batched` is [S, 2, E0]; its contiguous layout is
|
| 208 |
+
s0_src, s0_dst, s1_src, s1_dst, ... A direct `.reshape(2, -1)` therefore
|
| 209 |
+
packs *scene blocks* into each row instead of the src/dst rows, so row 0
|
| 210 |
+
ends up holding s0_src followed by s0_dst, etc. Consequences (measured,
|
| 211 |
+
A=11): 0% of edges stay inside a scene, exactly half the nodes receive no
|
| 212 |
+
incoming edge at all, and the other half receive 2x the intended degree.
|
| 213 |
+
The correct behaviour is to move the src/dst axis first via permute.
|
| 214 |
+
|
| 215 |
+
SRA_EDGE_FIX=1 selects the correct per-scene graph. The default keeps the
|
| 216 |
+
original (buggy) behaviour so that previously trained checkpoints and any
|
| 217 |
+
in-flight runs remain reproducible. See models/graph_interaction_nba_v6.py
|
| 218 |
+
(line ~171), which is the call site used by MID / LED / MoFlow.
|
| 219 |
+
"""
|
| 220 |
single = self._single_edge_index # [2, E0]
|
| 221 |
A = self.num_agents
|
| 222 |
offsets = torch.arange(num_scenes, device=single.device) * A # [S]
|
| 223 |
batched = (single.unsqueeze(0)
|
| 224 |
.expand(num_scenes, -1, -1) # [S, 2, E0]
|
| 225 |
+ offsets.view(-1, 1, 1))
|
| 226 |
+
if os.environ.get('SRA_EDGE_FIX', '') not in ('', '0', 'false', 'False'):
|
| 227 |
+
# [S, 2, E0] -> [2, S, E0] -> [2, S*E0]: keeps src/dst rows intact
|
| 228 |
+
return batched.permute(1, 0, 2).reshape(2, -1)
|
| 229 |
+
return batched.reshape(2, -1) # [2, S*E0] (legacy, scene-mixing)
|
| 230 |
|
| 231 |
# ------------------------------------------------------------------
|
| 232 |
# Forward
|
|
@@ -28,6 +28,7 @@ Document content (unchanged from V5):
|
|
| 28 |
โ GNN message passing on sparse graph.
|
| 29 |
"""
|
| 30 |
|
|
|
|
| 31 |
import torch
|
| 32 |
import torch.nn as nn
|
| 33 |
from models.graph_interaction_nba_v4 import FutureInteractionGraphV4
|
|
@@ -106,6 +107,29 @@ class FutureInteractionGraphV6(FutureInteractionGraphV4):
|
|
| 106 |
in_channels = in_ch,
|
| 107 |
)
|
| 108 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
# ------------------------------------------------------------------
|
| 110 |
# Forward
|
| 111 |
# ------------------------------------------------------------------
|
|
@@ -280,6 +304,45 @@ class FutureInteractionGraphV6(FutureInteractionGraphV4):
|
|
| 280 |
# ---- Gated residual ---------------------------------------------
|
| 281 |
orig = y_emb.reshape(B * K * A, D)
|
| 282 |
gate = self.gate_proj(torch.cat([orig, nodes], dim=-1))
|
| 283 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 284 |
|
| 285 |
return out.view(B, K, A, D)
|
|
|
|
| 28 |
โ GNN message passing on sparse graph.
|
| 29 |
"""
|
| 30 |
|
| 31 |
+
import os
|
| 32 |
import torch
|
| 33 |
import torch.nn as nn
|
| 34 |
from models.graph_interaction_nba_v4 import FutureInteractionGraphV4
|
|
|
|
| 107 |
in_channels = in_ch,
|
| 108 |
)
|
| 109 |
|
| 110 |
+
# ---- SRA_SOFT_START: identity-at-init for the graph branch ----------
|
| 111 |
+
# By default V6 inherits a randomly-initialised out_proj and a sigmoid
|
| 112 |
+
# gate that starts around 0.5, so a randomly-initialised graph output is
|
| 113 |
+
# injected into the host from the very first step. With SRA_EDGE_FIX=1
|
| 114 |
+
# every node now receives its full neighbour set (previously half the
|
| 115 |
+
# nodes were orphans), which makes that initial shock large enough to
|
| 116 |
+
# destabilise one-step flow matching (MoFlow).
|
| 117 |
+
#
|
| 118 |
+
# MID does not suffer from this because it zero-inits its own
|
| 119 |
+
# graph_out_proj and opens a learnable, clamped gate over a warmup
|
| 120 |
+
# schedule. SRA_SOFT_START ports that recipe to V6:
|
| 121 |
+
# * out_proj zero-init -> graph contributes exactly 0 at step 0
|
| 122 |
+
# * gate bias -> large negative, so sigmoid(gate) starts near 0
|
| 123 |
+
# Both stay LEARNABLE, so unlike a fixed SRA_GATE_SCALE the graph can
|
| 124 |
+
# still grow to full strength during training.
|
| 125 |
+
if os.environ.get('SRA_SOFT_START', '') not in ('', '0', 'false', 'False'):
|
| 126 |
+
nn.init.zeros_(self.out_proj.weight)
|
| 127 |
+
nn.init.zeros_(self.out_proj.bias)
|
| 128 |
+
_gb = float(os.environ.get('SRA_GATE_BIAS', -4.0) or -4.0)
|
| 129 |
+
for _m in self.gate_proj.modules():
|
| 130 |
+
if isinstance(_m, nn.Linear):
|
| 131 |
+
nn.init.constant_(_m.bias, _gb) # sigmoid(-4) ~ 0.018
|
| 132 |
+
|
| 133 |
# ------------------------------------------------------------------
|
| 134 |
# Forward
|
| 135 |
# ------------------------------------------------------------------
|
|
|
|
| 304 |
# ---- Gated residual ---------------------------------------------
|
| 305 |
orig = y_emb.reshape(B * K * A, D)
|
| 306 |
gate = self.gate_proj(torch.cat([orig, nodes], dim=-1))
|
| 307 |
+
# SRA_GATE_SCALE: global damping on the graph residual (default 1.0 = off).
|
| 308 |
+
_gs = float(os.environ.get('SRA_GATE_SCALE', 1.0) or 1.0)
|
| 309 |
+
res = _gs * gate * self.out_proj(nodes) # [N, D] graph perturbation
|
| 310 |
+
|
| 311 |
+
# SRA_RES_CAP: per-node residual-norm cap (default 0 = off). With
|
| 312 |
+
# SRA_EDGE_FIX=1 training is healthy (loss decreases monotonically) but
|
| 313 |
+
# *sampling* diverges: the graph is applied at every one of MoFlow's flow
|
| 314 |
+
# steps and its output feeds the next step, so any oversized per-node
|
| 315 |
+
# perturbation compounds geometrically over the integration. The old
|
| 316 |
+
# scene-mixing bug hid this by leaving half the nodes orphaned (weaker
|
| 317 |
+
# perturbation, less compounding). Capping each node's residual NORM
|
| 318 |
+
# bounds the per-step perturbation that drives the blow-up, while leaving
|
| 319 |
+
# the (majority) small perturbations untouched โ unlike a global scale it
|
| 320 |
+
# only clips the outliers, so the graph keeps its normal expressive range.
|
| 321 |
+
# ์ฃผ์: ์์ ๊ตฌํ `res * (rn.clamp(max=cap) / (rn + 1e-6))` ์ ๋ ๊ฐ์ง๊ฐ ํ๋ ธ๋ค.
|
| 322 |
+
# (1) res ๊ฐ ์ ํํ 0 ์ด๋ฉด ์ค์ผ์ผ์ด 0/1e-6 = 0 ์ด ๋์ด **gradient ๋ 0** ์ด๋ค.
|
| 323 |
+
# SRA_SOFT_START(out_proj zero-init) ์ ๊ฐ์ด ์ผ๋ฉด out_proj ๊ฐ 0 ์ ์๊ตฌํ
|
| 324 |
+
# ๊ฐํ ๊ทธ๋ํ๊ฐ ํ์ต๋์ง ์๋๋ค(=์ฌ์ค์ host ๋จ๋
). ์ค์ ๋ก ๊ทธ ์กฐํฉ์ผ๋ก
|
| 325 |
+
# ๋๋ฆฐ ์คํ๋ค์ out_proj ๋ 58 epoch ๋ค์๋ ์ ํํ 0 ์ด์๋ค.
|
| 326 |
+
# (2) cap ๋ฏธ๋ง์ธ๋ฐ๋ rn/(rn+1e-6) ๋งํผ ์ถ์๋๋ค (rn=1e-5 ์ด๋ฉด 0.909 ๋ฐฐ).
|
| 327 |
+
# torch.where ๋ก ๋ฐ๊พธ๋ฉด cap ์ดํ๋ ์ ํํ ๋ฌด์ฐ์ฐ(์ค์ผ์ผ 1)์ด๊ณ res=0 ์์๋
|
| 328 |
+
# gradient ๊ฐ ํ๋ฅธ๋ค. clamp_min ์ ๋ฏธ์ ํ ๋ถ๊ธฐ์ Inf ๋ฅผ ๋ง๋๋ค.
|
| 329 |
+
_cap = float(os.environ.get('SRA_RES_CAP', 0.0) or 0.0)
|
| 330 |
+
if _cap > 0:
|
| 331 |
+
rn = res.norm(dim=-1, keepdim=True) # [N, 1]
|
| 332 |
+
res = res * torch.where(rn > _cap, _cap / rn.clamp_min(1e-6),
|
| 333 |
+
torch.ones_like(rn))
|
| 334 |
+
|
| 335 |
+
# SRA_RES_CAP_REL: ๋
ธ๋๋ณ ์ํ์ **ํธ์คํธ ์๋ฒ ๋ฉ norm ์ ๋น๋ก**ํด ์ ํ๋ค.
|
| 336 |
+
# ์ ๋ cap ์ ์๋ฒ ๋ฉ ์ค์ผ์ผ์ ์์กดํด ํธ์คํธ๋ง๋ค ์๋ฏธ๊ฐ ๋ฌ๋ผ์ง๋ค(MoFlow ์์
|
| 337 |
+
# ํ๋ํ 3.0 ์ด MID ์์๋ ์ฌ์ค์ ๋ฌด์ฐ์ฐ์ผ ์ ์๋ค). ์ํ๋ง ๋ฐ์ฐ์ ๊ฒฐ๊ตญ
|
| 338 |
+
# "์คํ
๋น ์๋ ์ญ๋"์ด ๋์ ๋๋ ๋ฌธ์ ์ด๋ฏ๋ก, โresโ โค ratioยทโorigโ ๋ก ๋๋ฉด
|
| 339 |
+
# ์ค์ผ์ผ ๋ฌด๊ดํ๊ฒ ๋์ ๋ฅ ์ ์ง์ ์ ํํ๋ค. ์ธก์ ๊ฐ ๊ธฐ์ค ๋ฌด์ ํ ์ ๋น์จ์ ~0.39.
|
| 340 |
+
_rel = float(os.environ.get('SRA_RES_CAP_REL', 0.0) or 0.0)
|
| 341 |
+
if _rel > 0:
|
| 342 |
+
lim = _rel * orig.norm(dim=-1, keepdim=True) # [N, 1] ๋
ธ๋๋ณ ์ํ
|
| 343 |
+
rn = res.norm(dim=-1, keepdim=True)
|
| 344 |
+
res = res * torch.where(rn > lim, lim / rn.clamp_min(1e-6),
|
| 345 |
+
torch.ones_like(rn))
|
| 346 |
+
out = orig + res
|
| 347 |
|
| 348 |
return out.view(B, K, A, D)
|
|
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MoFlow โ edge-index ๋ฒ๊ทธ ์์ ๊ณผ ์ํ๋ง ๋ฐ์ฐ ํด๊ฒฐ
|
| 2 |
+
|
| 3 |
+
**ํ ์ค ์์ฝ**
|
| 4 |
+
edge-index reshape ๋ฒ๊ทธ๋ก ๊ทธ๋ํ๊ฐ ์ฌ์ ๋ค์๊ณ ์์๋ค(`permute` ๋ก ์์ ). ๊ทธ๋ฐ๋ฐ
|
| 5 |
+
**์ ์ ๊ทธ๋ํ๋ฅผ ๋ฃ์ MoFlow ๋ง ๋ฐ์ฐ**ํ๋ค โ ํ์ต์ด ์๋๋ผ **์ํ๋ง**์์. ๋
ธ๋๋ณ
|
| 6 |
+
**residual-norm cap** ์ผ๋ก ์คํ
๋น ์ญ๋์ ์ ํํด ํด๊ฒฐํ๋ค.
|
| 7 |
+
|
| 8 |
+
์์ ๋์: `models/graph_interaction_nba.py`(`_make_batched_edge_index`),
|
| 9 |
+
`models/graph_interaction_nba_v6.py`(SRA ๊ทธ๋ํ ์ถ๋ ฅ๋ถ).
|
| 10 |
+
๋ชจ๋ ๋ณ๊ฒฝ์ **ํ๊ฒฝ๋ณ์ ํ ๊ธ์ด๊ณ ๊ธฐ๋ณธ๊ฐ off** โ ์ผ์ง ์์ผ๋ฉด ์๋ณธ๊ณผ ๋์ผํ๊ฒ ๋์ํด
|
| 11 |
+
๊ธฐ์กด ์ฒดํฌํฌ์ธํธยท๊ธฐ์กด(๋ฒ๊ทธ) ๊ฒฐ๊ณผ์ ์ฌํ์ฑ์ด ๋ณด์กด๋๋ค.
|
| 12 |
+
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
## 1. ๋ฒ๊ทธ: edge-index ๊ฐ ์ฌ์ ๋ค์์
|
| 16 |
+
|
| 17 |
+
```python
|
| 18 |
+
batched = single.unsqueeze(0).expand(S, -1, -1) + offsets.view(-1, 1, 1) # [S, 2, E0]
|
| 19 |
+
return batched.reshape(2, -1) # โ ๋ฒ๊ทธ
|
| 20 |
+
```
|
| 21 |
+
|
| 22 |
+
`[S, 2, E0]` ์ ๋ฉ๋ชจ๋ฆฌ ์์๋ `s0_src, s0_dst, s1_src, s1_dst, โฆ` ์ด๋ค.
|
| 23 |
+
`reshape(2,-1)` ์ ์ด ๋ฒํผ๋ฅผ **์/๋ค ์ ๋ฐ**์ผ๋ก ์๋ฅด๋ฏ๋ก row0 ์ ์ฌ0 ๋ธ๋ก,
|
| 24 |
+
row1 ์ ์ฌ1 ๋ธ๋ก์ด ๋ค์ด๊ฐ๋ค โ src/dst ๊ฐ ์๋๋ผ **์ฌ์ผ๋ก ๋๋๋ค**.
|
| 25 |
+
|
| 26 |
+
์ค์ธก (A=11, S=4):
|
| 27 |
+
|
| 28 |
+
| | ๊ฐ์-์ฌ edge | ์ด์ 0์ธ ๊ณ ์ ๋
ธ๋ | ๋
ธ๋ degree |
|
| 29 |
+
|---|---|---|---|
|
| 30 |
+
| ๋ฒ๊ทธ | **0 %** | **50 %** | 0 ๋๋ 20 (์ ์ 10) |
|
| 31 |
+
| ์์ | **100 %** | 0 % | ์ ๋ถ 10 |
|
| 32 |
+
|
| 33 |
+
`scores.view(B*K*A, A-1)` ์ top-N ์ด์ ๊ทธ๋ฃนํ๋ ๋ฒ๊ทธ์์ **33 %** ๋ง ์ค์ ํ๊ฒ๊ณผ
|
| 34 |
+
์ผ์นํ๊ณ , ์์ ํ **100 %** ๊ฐ ๋๋ค. ์ฆ ์ด์ ์ ํ ์์ฒด๋ ๋ง๊ฐ์ ธ ์์๋ค.
|
| 35 |
+
|
| 36 |
+
์ธ๋ฑ์ค ๋ฒ์๋ ์ ์(0~43)์ด๋ผ PyG ๊ฐ ์๋ฌ๋ฅผ ๋ด์ง ์๋๋ค โ **ํฌ๋์ ์์ด ์กฐ์ฉํ ํ๋ฆฐ
|
| 37 |
+
๊ทธ๋ํ**๋ฅผ ์ฐ๊ณ ์์๊ณ , ๊ทธ๋์ ์ค๋ ๋ฐ๊ฒฌ๋์ง ์์๋ค.
|
| 38 |
+
|
| 39 |
+
### ์์ (`SRA_EDGE_FIX=1`)
|
| 40 |
+
|
| 41 |
+
```python
|
| 42 |
+
if os.environ.get('SRA_EDGE_FIX', ...):
|
| 43 |
+
return batched.permute(1, 0, 2).reshape(2, -1) # src/dst ์ถ์ ๋จผ์ โ ์ฌ ๋ด๋ถ ๊ทธ๋ํ
|
| 44 |
+
return batched.reshape(2, -1) # ๊ธฐ๋ณธ: ์๋(๋ฒ๊ทธ) ๋์
|
| 45 |
+
```
|
| 46 |
+
|
| 47 |
+
**baseline ์ ๊ทธ๋ํ๋ฅผ ์ธ์คํด์คํํ์ง ์์ผ๋ฏ๋ก ์ด ๋ฒ๊ทธ์ ๋ฌด๊ดํ๋ค** โ ๋น๊ต์ ํ์ชฝ
|
| 48 |
+
์ถ์ ์จ์ ํ๋ค. ์ํฅ์ ๋ฐ์ ๊ฒ์ SRA/ablation ์ชฝ๋ฟ์ด๋ค.
|
| 49 |
+
|
| 50 |
+
---
|
| 51 |
+
|
| 52 |
+
## 2. ์ฆ์: ํ์ต์ ์ ์, ์ํ๋ง๋ง ๋ฐ์ฐ
|
| 53 |
+
|
| 54 |
+
edge ๋ฅผ ๊ณ ์น์ MoFlow-NBA ์ eval ADE ๊ฐ ํญ๋ฐํ๋ค. ๊ฒ์ดํธยท์ด๊ธฐํ ์ฒ๋ฐฉ์ด ์ฐ๋ฌ์
|
| 55 |
+
์คํจํ ๋ค, train loss ์ eval ์ **์๊ฐ ์ ๋ ฌ**ํด์ ์์ธ์ ํน์ ํ๋ค:
|
| 56 |
+
|
| 57 |
+
```
|
| 58 |
+
train loss : 96.5 โ 35.6 โ 20.1 โ 18.0 โ 16.6 ๋จ์กฐ ๊ฐ์ (์์ ์ ์)
|
| 59 |
+
eval ADE : 1.13 โ 1.07 โ 1.52 โ 1.85 โ 3.49 ๋ฐ์ฐ
|
| 60 |
+
```
|
| 61 |
+
|
| 62 |
+
train loss ๊ฐ ๋งค๋๋ฝ๊ฒ ๋ด๋ ค๊ฐ๋ **๋ฐ๋ก ๊ทธ ์๊ฐ** eval ์ด ํฐ์ง๋ค. ์ด ๊ด์ฐฐ์ด ์ฒ๋ฐฉ์
|
| 63 |
+
๋ฐฉํฅ์ ๋ฐ๊ฟจ๋ค โ ๋ฌธ์ ๋ ํ์ต์ด ์๋๋ผ **์ํ๋ง**์ด๋ค.
|
| 64 |
+
|
| 65 |
+
---
|
| 66 |
+
|
| 67 |
+
## 3. ์์ธ: train/sample mismatch (MoFlow ๊ณ ์ )
|
| 68 |
+
|
| 69 |
+
- **ํ์ต**: ๋๋ค timestep ํ๋์์ ๊ทธ๋ํ๊ฐ **ํ ๋ฒ** ์ ์ฉ๋๋ค โ ์ญ๋์ด ๋์ ๋ ๊ฒฝ๋ก๊ฐ ์๋ค.
|
| 70 |
+
- **์ํ๋ง**: MoFlow ์ flow ์ ๋ถ์ 10 ์คํ
. ๊ทธ๋ํ๊ฐ **๋งค ์คํ
** ์ ์ฉ๋๊ณ ๊ทธ ์ถ๋ ฅ์ด
|
| 71 |
+
๋ค์ ์คํ
์ ์
๋ ฅ(`y_abs`)์ผ๋ก ๋๋จน์๋๋ค โ ์ญ๋์ด **๊ธฐํ๊ธ์์ ์ผ๋ก ๋์ **๋๋ค.
|
| 72 |
+
|
| 73 |
+
๋ฒ๊ทธํ์ด ์ ํฐ์ง ์ด์ ๋ ์ด๊ฑธ๋ก ์ค๋ช
๋๋ค: ๋
ธ๋ ์ ๋ฐ์ด ๊ณ ์์ฌ์ ๊ทธ๋ํ ์ญ๋์ด ์ฌ์ค์
|
| 74 |
+
์ ๋ฐ๋ง ํ๋ ๊ณ , ๊ทธ๋งํผ ์ํ๋ง ๋์ ์ด ์ฝํ๋ค. **๋ฒ๊ทธ๊ฐ ์ฐ์ฐํ ์ ๊ทํ ์ญํ **์ ํ๊ณ ์์๋ค.
|
| 75 |
+
|
| 76 |
+
MIDยทLED ๋ iterative denoiser ๋ผ ๊ทธ๋ํ๋ฅผ ๋ฐ๋ณต ์ ์ ๊ณผ์ ์ ์ผ๋ถ๋ก ํก์ํ๋ค โ
|
| 77 |
+
๊ทธ๋์ ๊ฐ์ V6 ๋ฅผ ์จ๋ ๋ฐ์ฐํ์ง ์๋๋ค. (์ด์ ์ ๊ด์ฐฐํ "MoFlow ๋ plug-in ๋ชจ๋์
|
| 78 |
+
์ ๋
๋ฏผ๊ฐํ๊ณ faithful GameFormer/C2F ๋ ์ ๋ถ ๋ฐ์ฐ"๊ณผ ์ ํํ ๊ฐ์ ํจํด.)
|
| 79 |
+
|
| 80 |
+
์ธก์ : ๊ทธ๋ํ residual ๋
ธ๋ norm โ **6.3** vs ํธ์คํธ ์๋ฒ ๋ฉ ๋
ธ๋ norm โ **16**
|
| 81 |
+
โ ์ญ๋์ด ์๋ฒ ๋ฉ์ **์ฝ 40 %**. ํ์ต์ด ์งํ๋๋ฉด ์ด ๋ถํฌ์ ๊ผฌ๋ฆฌ(outlier)๊ฐ ์ปค์ง๊ณ ,
|
| 82 |
+
๊ทธ outlier ๊ฐ ์ํ๋ง ๋์ ์ ์ด๋ฐํ๋ค.
|
| 83 |
+
|
| 84 |
+
---
|
| 85 |
+
|
| 86 |
+
## 4. ์คํจํ ์ฒ๋ฐฉ๋ค๊ณผ ๊ทธ ์ด์
|
| 87 |
+
|
| 88 |
+
| ์ฒ๋ฐฉ | ๊ฑด๋๋ฆฐ ๋์ | ๊ฒฐ๊ณผ |
|
| 89 |
+
|---|---|---|
|
| 90 |
+
| `SRA_GATE_SCALE=0.1` (๊ฒ์ดํธ ์ ์ญ ์ถ์) | ํ์ต | eval 5ํ์ฐจ๋ถํฐ ๋จ์กฐ ์
ํ |
|
| 91 |
+
| `SRA_SOFT_START` (out_proj zero-init + gate bias โ4) | ํ์ต ์ด๊ธฐ๊ฐ | eval **3ํ์ฐจ** ๋ฐ์ฐ (์คํ๋ ค ๋ ๋น ๋ฆ) |
|
| 92 |
+
| ๊ฒ์ดํธ ๊ธฐ๋ณธ๊ฐ ์ ์ง | โ | eval 4ํ์ฐจ ๋ฐ์ฐ |
|
| 93 |
+
|
| 94 |
+
์
๋ค **ํ์ต**์ ์กฐ์ ํ๋ค. ๊ทธ๋ฐ๋ฐ ํ์ต์ ์๋ ๋ฉ์ฉกํ์ผ๋ฏ๋ก ํจ๊ณผ๊ฐ ์์๋ค.
|
| 95 |
+
`SRA_SOFT_START` ๋ ์ด๊ธฐ ์ถ๋ ฅ์ ์์ identity(โฮโ=0)๋ก ๋ง๋ค์๋๋ฐ๋, ํ์ต ๋ช ์คํ
|
| 96 |
+
๋ง์ `out_proj` ๊ฐ ์๋ผ์ ๋๊ฐ์ด ํฐ์ก๋ค โ **์ด๊ธฐ ์ถฉ๊ฒฉ ๊ฐ์ค์ด ๋ฐ์ฆ๋** ์
์ด๋ค.
|
| 97 |
+
|
| 98 |
+
---
|
| 99 |
+
|
| 100 |
+
## 5. ํด๋ฒ: ๋
ธ๋๋ณ residual-norm cap (`SRA_RES_CAP`)
|
| 101 |
+
|
| 102 |
+
์ํ๋ง ์ **์คํ
๋น ๋
ธ๋ ์ญ๋์ ํฌ๊ธฐ**๋ฅผ ์ง์ ์ ํํ๋ค. ์ ์ญ ์ถ์(gate scale)์ ๋ฌ๋ฆฌ
|
| 103 |
+
์ ์ ํฌ๊ธฐ์ ์ญ๋์ ๊ทธ๋๋ก ๋๊ณ **๋์ ์ ์ ๋ฐํ๋ ํฐ outlier ๋ง** ์๋ผ๋ธ๋ค.
|
| 104 |
+
|
| 105 |
+
```python
|
| 106 |
+
res = _gs * gate * self.out_proj(nodes) # [N, D] ๊ทธ๋ํ ์ญ๋
|
| 107 |
+
_cap = float(os.environ.get('SRA_RES_CAP', 0.0)) # 0 = ๋(๊ธฐ๋ณธ)
|
| 108 |
+
if _cap > 0:
|
| 109 |
+
rn = res.norm(dim=-1, keepdim=True) # [N, 1] ๋
ธ๋๋ณ norm
|
| 110 |
+
res = res * (rn.clamp(max=_cap) / (rn + 1e-6)) # norm ์ํ
|
| 111 |
+
out = orig + res
|
| 112 |
+
```
|
| 113 |
+
|
| 114 |
+
๊ฒ์ฆ: `SRA_RES_CAP=3.0` ์์ ๋
ธ๋ norm ์ด ์ ํํ `โค3.0` ์ผ๋ก ์๋ฆฌ๊ณ , gradient ๋
|
| 115 |
+
์ ์ง๋๋ฉฐ(ํ์ต ๊ณ์ ๊ฐ๋ฅ), ๊ฐ๋ณ A(SDD) ๋ ํต๊ณผ.
|
| 116 |
+
|
| 117 |
+
**gate scale ๊ณผ์ ๊ฒฐ์ ์ ์ฐจ์ด**: gate scale ์ ์ ํธ๋ฅผ ์๊ตฌํ ์ค์ฌ ๊ทธ๋ํ ํจ๊ณผ๊น์ง
|
| 118 |
+
๊ฐ์ด ์ฃฝ์ธ๋ค. cap ์ ๋ถํฌ์ ๊ผฌ๋ฆฌ๋ง ์๋ฅด๋ฏ๋ก ๊ทธ๋ํ์ ํํ๋ ฅ์ ๋๋ถ๋ถ ๋ณด์กดํ๋ค.
|
| 119 |
+
|
| 120 |
+
---
|
| 121 |
+
|
| 122 |
+
## 6. ๊ฒฐ๊ณผ
|
| 123 |
+
|
| 124 |
+
### ๋ฐ์ฐ ์ง์ (eval 3~5) ํต๊ณผ ์ฌ๋ถ
|
| 125 |
+
|
| 126 |
+
| eval # | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
| 127 |
+
|---|---|---|---|---|---|---|---|---|
|
| 128 |
+
| ๊ฒ์ดํธ ๊ธฐ๋ณธ | 1.141 | 1.052 | 1.048 | **1.828** | 1.429 | 1.716 | 1.821 | โ |
|
| 129 |
+
| soft-start | 1.134 | 1.075 | **1.516** | 1.852 | 1.697 | 1.862 | 1.765 | โ |
|
| 130 |
+
| gate 0.1 | 1.143 | 1.104 | 1.118 | 1.107 | **1.355** | 1.468 | 1.521 | 1.622 |
|
| 131 |
+
| **cap 3.0** | 1.145 | 1.053 | 1.007 | 0.969 | 0.942 | 0.988 | 0.927 | **0.894** |
|
| 132 |
+
| **cap 6.0** | 1.138 | 1.018 | 0.999 | 0.976 | 0.950 | 0.947 | 0.962 | 0.895 |
|
| 133 |
+
| *baseline(์ฐธ๊ณ )* | 1.163 | 1.021 | 0.961 | 0.964 | 0.952 | 0.955 | 0.953 | 0.895 |
|
| 134 |
+
|
| 135 |
+
cap ๋ ๊ฐ ๋ชจ๋ ๋ฐ์ฐ ์ง์ ์ ํต๊ณผํ๊ณ **baseline ๊ถค์ ์ ๊ทธ๋๋ก ๋ฐ๋ผ๊ฐ๋ค**.
|
| 136 |
+
|
| 137 |
+
### ์ฅ๊ธฐ ์๋ ด (2026-07-28 ๊ธฐ์ค, 58ํ ํ๊ฐ ยท 10029/25500 = 39 %)
|
| 138 |
+
|
| 139 |
+
| ์ค์ | ํ์ฌ best ADE/FDE | ๋น๊ณ |
|
| 140 |
+
|---|---|---|
|
| 141 |
+
| **cap 6.0** | **0.7373 / 0.9080** | ๋ฐ์ฐ ์์ด 58ํ |
|
| 142 |
+
| **cap 3.0** | **0.7399 / 0.9300** | ๋ฐ์ฐ ์์ด 58ํ |
|
| 143 |
+
| *๊ธฐ์กด(๋ฒ๊ทธํ) SRA* | *0.695* | ์์ฃผ๊ฐ |
|
| 144 |
+
| *baseline* | *0.703* | ์์ฃผ๊ฐ |
|
| 145 |
+
|
| 146 |
+
cap 3.0 ๊ณผ 6.0 ์ ์ฐจ์ด๊ฐ **0.0026** ์ ๋ถ๊ณผํ๋ค โ ์ด ์ฒ๋ฐฉ์ cap ๊ฐ์ ๋ฏผ๊ฐํ์ง ์๋ค
|
| 147 |
+
(ํ์ดํผํ๋ผ๋ฏธํฐ ํ๋์ ์์กดํ๋ ์์๋ฐฉํธ์ด ์๋๋ผ๋ ๊ทผ๊ฑฐ).
|
| 148 |
+
|
| 149 |
+
### ๋ค๋ฅธ ์ค์ ์์์ ์ฌํ
|
| 150 |
+
|
| 151 |
+
๊ฐ์ ์ฒ๋ฐฉ(`EDGE_FIX + SOFT_START + RES_CAP=3.0`)์ผ๋ก ๋๋ฆฐ MoFlow-NBA ablation 2๊ฑด๋
|
| 152 |
+
๋ฐ์ฐ ์์ด ํ๊ฐ ์ค โ cap ์ ํจ๊ณผ๊ฐ full SRA ํ ์ค์ ์๋ง ๊ตญํ๋์ง ์๋๋ค.
|
| 153 |
+
|
| 154 |
+
| ์คํ | ํ๊ฐ ์ | ํ์ฌ best |
|
| 155 |
+
|---|---|---|
|
| 156 |
+
| sparse selection (no ฯ) | 16 | 0.8034 |
|
| 157 |
+
| encoding (all nbrs, no ฯ) | 9 | 0.8648 |
|
| 158 |
+
|
| 159 |
+
---
|
| 160 |
+
|
| 161 |
+
## 7. ํ๊ณ์ ๋ฏธํ์ (์ ์งํ๊ฒ)
|
| 162 |
+
|
| 163 |
+
**โ SOFT_START ๊ฐ ๊ต๋ ๋ณ์๋ค.** cap ์คํ 4๊ฑด ๋ชจ๋ `SRA_SOFT_START=1` ์ ํจ๊ป ์ผฐ๋ค.
|
| 164 |
+
๋ฐ๋ผ์ "cap ๋จ๋
์ผ๋ก ์ถฉ๋ถํ๊ฐ"๋ **์์ง ๊ฒ์ฆ๋์ง ์์๋ค**. soft-start ๋ ๋จ๋
์ผ๋ก๋
|
| 165 |
+
์คํจํ์ผ๋ฏ๋ก cap ์ด ํต์ฌ์ธ ๊ฒ์ ๋ถ๋ช
ํ์ง๋ง, ๋์ ๊ธฐ์ฌ๋ฅผ ๋ถ๋ฆฌํ๋ ค๋ฉด
|
| 166 |
+
`RES_CAP` ๋ง ์ผ ๋์กฐ ์คํ์ด ํ์ํ๋ค.
|
| 167 |
+
|
| 168 |
+
**โก ์ต์ข
์๋ ด๊ฐ ๋ฏธํ์ .** 39 % ์ง์ ์์ 0.737 ์ด๊ณ , ๊ธฐ์กด(๋ฒ๊ทธํ) 0.695 / baseline
|
| 169 |
+
0.703 ๋ณด๋ค ์์ง ์๋ค. ๋จ์ 61 % ์ cosine LR ๊ฐ์ ์์ ๋ ๋ด๋ ค๊ฐ ์ฌ์ง๋ ์์ผ๋,
|
| 170 |
+
**0.695 ๋ฅผ ์ฌํํ์ง ๋ชปํ ๊ฐ๋ฅ์ฑ๋ ์ด๋ ค ์๋ค.**
|
| 171 |
+
|
| 172 |
+
**โข ๊ทธ ๊ฒฝ์ฐ์ ๊ฒฐ๋ก ๋ ๋ณด๊ณ ํ ๊ฐ์น๊ฐ ์๋ค.** "์ ์ ์ฌ-๋ด๋ถ ๊ทธ๋ํ๋ ์์ ์ ์ผ๋ก ํ์ต๋๋
|
| 173 |
+
MoFlow ์ one-step flow matching ์์๋ ์ด๋์ด ์ ํ์ "์ด๋ผ๋ ๊ฒ ์์ฒด๊ฐ, ๋ฒ๊ทธํ์
|
| 174 |
+
0.695 ๊ฐ **์๋ํ ๋ฉ์ปค๋์ฆ์ด ์๋๋ผ ์ฐ์ฐํ ์ ๊ทํ ํจ๊ณผ**์์ ์ ์์์ ์์ฌํ๋
|
| 175 |
+
๋ฐ๊ฒฌ์ด๋ค.
|
| 176 |
+
|
| 177 |
+
**โฃ MID / LED ๋ ๋ค๋ฅธ ์ฒ๋ฐฉ์ ์ด๋ค.** RES_CAP ์ MoFlow ์ ์ฉ์ด๋ค. MID ๋
|
| 178 |
+
`graph_gate_init` 0.01โ0.001 + warmup 100โ200 ์ผ๋ก ๋ถ๊ดด๋ฅผ ๋ง์๊ณ , LED ๋ ๋ณ๋
|
| 179 |
+
์ฒ๋ฐฉ ์์ด ํ๋ณต ์ค์ด๋ค(LED sparse no-ฯ ๋ ์ด๋ฏธ ๊ธฐ์กด๊ฐ 0.886 โ **0.800** ์ผ๋ก ์์ฌ).
|
| 180 |
+
|
| 181 |
+
---
|
| 182 |
+
|
| 183 |
+
## 8. ์ฌํ
|
| 184 |
+
|
| 185 |
+
```bash
|
| 186 |
+
# MoFlow-NBA full SRA (ํ์ฌ ์คํ ์ค์ )
|
| 187 |
+
SRA_EDGE_FIX=1 SRA_SOFT_START=1 SRA_RES_CAP=3.0 \
|
| 188 |
+
CUDA_VISIBLE_DEVICES=0 python fm_nba_graph_v6.py \
|
| 189 |
+
--cfg cfg/nba/cor_fm.yml --exp edgefix_cap3 \
|
| 190 |
+
--batch_size 192 --epochs 150 --fm_in_scaling --tied_noise \
|
| 191 |
+
--top_n_neighbors 5 --uncertainty_weight 0.01 --data_dir ./data/nba
|
| 192 |
+
|
| 193 |
+
# no-ฯ ablation ์ ์ ์ฉ ์คํฌ๋ฆฝํธ ์ฌ์ฉ (use_sigma_gating=False ํ๋์ฝ๋ฉ)
|
| 194 |
+
SRA_EDGE_FIX=1 SRA_SOFT_START=1 SRA_RES_CAP=3.0 \
|
| 195 |
+
python fm_nba_graph_v6_nosigma.py --cfg cfg/nba/cor_fm.yml --exp ef_sparse_nosig \
|
| 196 |
+
--batch_size 192 --epochs 150 --fm_in_scaling --tied_noise --top_n_neighbors 5
|
| 197 |
+
```
|
| 198 |
+
|
| 199 |
+
| ํ ๊ธ | ๊ธฐ๋ณธ | ์ญํ |
|
| 200 |
+
|---|---|---|
|
| 201 |
+
| `SRA_EDGE_FIX` | off | edge-index ์ฌ ํผํฉ ๋ฒ๊ทธ ์์ (**ํต์ฌ**) |
|
| 202 |
+
| `SRA_RES_CAP` | 0 (off) | ๋
ธ๋๋ณ residual norm ์ํ โ MoFlow ์ํ๋ง ์์ ํ (**ํต์ฌ**) |
|
| 203 |
+
| `SRA_SOFT_START` | off | out_proj zero-init + gate bias โ4 (๋ณด์กฐ, ๋จ๋
์ผ๋ก๋ ์คํจ) |
|
| 204 |
+
| `SRA_GATE_SCALE` | 1.0 | ๊ฒ์ดํธ ์ ์ญ ์ถ์ (์คํจํ ์ฒ๋ฐฉ, ์ฝ๋๋ง ์์กด) |
|
|
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# `SRA_RES_CAP_REL` โ ์๋ residual cap
|
| 2 |
+
|
| 3 |
+
**ํ ์ค ์์ฝ**
|
| 4 |
+
edge ๋ฒ๊ทธ๋ฅผ ๊ณ ์น์ MoFlow ์ํ๋ง์ด ๋ฐ์ฐํ๋ค. ์ ๋ cap(`SRA_RES_CAP`)์ ๊ฐ์ ๋ฎ์ถฐ๋
|
| 5 |
+
๋ฐ์ฐ ์์ ์ ๋ฏธ๋ฃฐ ๋ฟ์ด์๋ค. ์ํ์ **ํธ์คํธ ์๋ฒ ๋ฉ norm ์ ๋น๋ก**ํ๋๋ก ๋ฐ๊พธ์
|
| 6 |
+
(`โresโ โค ratioยทโorigโ`) 13ํ ํ๊ฐ๊น์ง ์์ ์ ์ผ๋ก ํ๊ฐํ๋ฉฐ baseline ์ ์์ฐ๋ค.
|
| 7 |
+
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
## 1. ์ ์ ๋ cap ์ผ๋ก๋ ๋ถ์กฑํ๊ฐ
|
| 11 |
+
|
| 12 |
+
๋ฐ์ฐ์ ์์ธ์ MoFlow ์ **train/sample mismatch** ๋ค. ํ์ต์ ๋๋ค timestep ํ๋์์
|
| 13 |
+
๊ทธ๋ํ๋ฅผ ํ ๋ฒ๋ง ์ ์ฉํ์ง๋ง, ์ํ๋ง์ 10 ์คํ
flow ์ ๋ถ์์ ๋งค ์คํ
์ ์ฉํ๊ณ ๊ทธ
|
| 14 |
+
์ถ๋ ฅ์ด ๋ค์ ์คํ
์
๋ ฅ์ผ๋ก ๋๋จน์๋๋ค โ ์ญ๋์ด ๋์ ๋๋ค.
|
| 15 |
+
|
| 16 |
+
์ ๋ cap ์ `โresโ โค c` ๋ก **๊ณ ์ ํฌ๊ธฐ**๋ฅผ ๊ฐ์ ํ๋ค. ๋ฌธ์ ๋ ๋ ๊ฐ์ง๋ค.
|
| 17 |
+
|
| 18 |
+
1. **ํธ์คํธ ์ค์ผ์ผ ์์กด.** residual norm ์ ๊ทธ ํธ์คํธ ์๋ฒ ๋ฉ์ด ์ฐ๋ ์ค์ผ์ผ ์์
|
| 19 |
+
์๋ค. ์ธก์ ๊ฐ: MoFlow ์์ ๊ทธ๋ํ residual โ **6.3**, ํธ์คํธ ์๋ฒ ๋ฉ โ **16**.
|
| 20 |
+
MoFlow ์์ ํ๋ํ `c = 3.0` ์ด ์๋ฒ ๋ฉ ์ค์ผ์ผ์ด ๋ค๋ฅธ MID/LED ์์๋ ์ฌ์ค์
|
| 21 |
+
๋ฌด์ฐ์ฐ์ด๊ฑฐ๋ ๋ฐ๋๋ก ๊ณผ๋ํ ์ ์ฝ์ด ๋๋ค.
|
| 22 |
+
2. **๋์ ์ ๊ฒฐ์ ํ๋ ๊ฒ์ ์ ๋ ํฌ๊ธฐ๊ฐ ์๋๋ผ ๋น์จ.** ์คํ
๋น ์ํ๊ฐ
|
| 23 |
+
`x โ x + res` ๋ก ๊ฐฑ์ ๋ ๋ ๋ฐ์ฐ ์ฌ๋ถ๋ฅผ ์ง๋ฐฐํ๋ ๊ฒ์ `โresโ/โxโ` ๋ค. ์ ๋ cap ์
|
| 24 |
+
์ด ๋น์จ์ ์ง์ ํต์ ํ์ง ๋ชปํ๋ค.
|
| 25 |
+
|
| 26 |
+
์ค์ ๋ก ์ ๋ cap ์ ๊ฐ์ ๋ฎ์ถ์๋ก **๋ฐ์ฐ์ด ๋ฏธ๋ค์ง ๋ฟ ์ฌ๋ผ์ง์ง ์์๋ค**:
|
| 27 |
+
|
| 28 |
+
| ์ ๋ cap | ๋ฐ์ฐ ์์ |
|
| 29 |
+
|---|---|
|
| 30 |
+
| 6.0 | eval 4 |
|
| 31 |
+
| 3.0 | eval 5 |
|
| 32 |
+
| 1.0 | eval 9 (์ดํ 1.15~1.61 ์ง๋) |
|
| 33 |
+
| 0.5 | 12ํ์ฐจ๋ถํฐ ๋ฐ๋ฑ (0.873 โ 0.922 โ 0.958) |
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
## 2. ๊ตฌํ
|
| 38 |
+
|
| 39 |
+
```python
|
| 40 |
+
# SRA_RES_CAP_REL: ๋
ธ๋๋ณ ์ํ์ ํธ์คํธ ์๋ฒ ๋ฉ norm ์ ๋น๋กํด ์ ํ๋ค.
|
| 41 |
+
_rel = float(os.environ.get('SRA_RES_CAP_REL', 0.0) or 0.0)
|
| 42 |
+
if _rel > 0:
|
| 43 |
+
lim = _rel * orig.norm(dim=-1, keepdim=True) # [N, 1] ๋
ธ๋๋ณ ์ํ
|
| 44 |
+
rn = res.norm(dim=-1, keepdim=True)
|
| 45 |
+
res = res * torch.where(rn > lim, lim / rn.clamp_min(1e-6),
|
| 46 |
+
torch.ones_like(rn))
|
| 47 |
+
out = orig + res
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
- `orig` = ํธ์คํธ ์๋ฒ ๋ฉ, `res` = ๊ทธ๋ํ ์ญ๋. ์ํ์ด **๋
ธ๋๋ง๋ค** ์๊ธฐ ์๋ฒ ๋ฉ ํฌ๊ธฐ์
|
| 51 |
+
๋น๋กํด ์ ํด์ง๋ฏ๋ก ์ค์ผ์ผ ๋ฌด๊ดํ๋ค.
|
| 52 |
+
- `torch.where` ๋ฅผ ์ฐ๋ ์ด์ ๋ ยง4 ์ฐธ์กฐ (์ด์ ๊ตฌํ์ ์น๋ช
์ ๋ฒ๊ทธ).
|
| 53 |
+
- ๊ธฐ๋ณธ๊ฐ `0` = ๊บผ์ง. ์ผ์ง ์์ผ๋ฉด ์๋ณธ๊ณผ ๋์ผํ๊ฒ ๋์ํ๋ค.
|
| 54 |
+
|
| 55 |
+
๊ฒ์ฆ (A=11, K=4):
|
| 56 |
+
|
| 57 |
+
| ์ค์ | out_proj grad | โresโmax | โresโ/โorigโ max |
|
| 58 |
+
|---|---|---|---|
|
| 59 |
+
| ๋ฌด์ ํ | 1,716,997 | 9.009 | **0.557** |
|
| 60 |
+
| ์ ๋ cap 1.0 | 255,169 | 1.000 | 0.071 |
|
| 61 |
+
| relcap 0.10 | 408,742 | 1.765 | **0.100** โ |
|
| 62 |
+
| relcap 0.03 | 122,623 | 0.529 | **0.030** โ |
|
| 63 |
+
|
| 64 |
+
๋น์จ์ด ์ง์ ๊ฐ์ผ๋ก ์ ํํ ์ ํ๋๊ณ gradient ๋ ์ ์์ด๋ค.
|
| 65 |
+
|
| 66 |
+
---
|
| 67 |
+
|
| 68 |
+
## 3. ๊ฒฐ๊ณผ (MoFlow-NBA, full SRA, `SRA_EDGE_FIX=1`)
|
| 69 |
+
|
| 70 |
+
eval ๋ณ min-ADEโโ @4.0s:
|
| 71 |
+
|
| 72 |
+
| eval | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
|
| 73 |
+
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| 74 |
+
| **relcap 0.03** | 1.190 | 1.010 | 0.979 | 1.019 | 0.971 | 0.941 | 0.912 | 0.894 | 0.894 | 0.857 | 0.863 | 0.863 | **0.840** |
|
| 75 |
+
| **relcap 0.10** | 1.128 | 1.017 | 0.988 | 0.954 | 0.950 | 0.944 | 0.958 | 0.936 | 0.880 | 0.889 | 0.857 | 0.862 | 0.876 |
|
| 76 |
+
| cap 0.5 (์ ๋) | 1.155 | 1.032 | 1.018 | 0.990 | 0.978 | 0.907 | 0.937 | 0.901 | 0.931 | 0.873 | 0.875 | 0.922 | 0.958 |
|
| 77 |
+
| cap 1.0 (์ ๋) | 1.146 | 1.013 | 0.985 | 1.020 | 0.978 | 1.006 | 1.170 | 0.966 | **1.309** | 1.378 | 1.150 | 1.344 | 1.370 |
|
| 78 |
+
| *baseline(์ฐธ๊ณ )* | 1.163 | 1.021 | 0.961 | 0.964 | 0.952 | 0.955 | 0.953 | 0.895 | โ | โ | โ | โ | โ |
|
| 79 |
+
|
| 80 |
+
ํ์ฌ best (ADE/FDE ๋ **๊ฐ์ ํ๊ฐ ์์ **์์ ์ง์ง์):
|
| 81 |
+
|
| 82 |
+
| ์ค์ | best ADE / FDE | @eval | ์งํ |
|
| 83 |
+
|---|---|---|---|
|
| 84 |
+
| **relcap 0.03** | **0.8399 / 1.0025** | 13 | 2368/25500 (9 %) |
|
| 85 |
+
| relcap 0.10 | 0.8568 / 1.0441 | 11 | 2349/25500 |
|
| 86 |
+
| cap 0.5 | 0.8732 / 1.0531 | 10 | 2379/25500 |
|
| 87 |
+
| cap 1.0 | 0.9662 / 1.2508 | 8 | 3390/25500 โ ๋ฐ์ฐ |
|
| 88 |
+
|
| 89 |
+
๊ด์ฐฐ:
|
| 90 |
+
|
| 91 |
+
- **์๋ ๋ฐ์ฐ ์ง์ (eval 4~5)์ ์๋ cap 2์ข
๋ชจ๋ ํต๊ณผ**ํ๋ค. ์ ๋ cap 1.0 ๋ 8ํ์ฐจ๊น์ง๋
|
| 92 |
+
๋ฉ์ฉกํด ๋ณด์์ผ๋ฏ๋ก 4~5ํ ํต๊ณผ๋ง์ผ๋ก๋ ๋ถ์กฑํ๋ฐ, 13ํ๊น์ง ์ ์ง๋ ๊ฒ์ ๋ค๋ฅธ ์์ค์ ๊ทผ๊ฑฐ๋ค.
|
| 93 |
+
- **baseline(0.895) ์ ์์ฐ๋ค.** relcap 0.03 ์ด 0.840 ์ผ๋ก โ0.055.
|
| 94 |
+
- ์ ๋ cap 0.5 ๋ 10ํ์ฐจ 0.873 ์ดํ **0.922 โ 0.958 ๋ก 3ํ ์ฐ์ ์์น** โ ์๋ cap ๊ณผ
|
| 95 |
+
๋ฌ๋ฆฌ ๋ถ์์ ์กฐ์ง์ด ๋ณด์ธ๋ค.
|
| 96 |
+
- ๋น์จ์ 0.10 โ 0.03 ์ผ๋ก ๋ ์กฐ์ฌ๋ ์ฑ๋ฅ์ด ๋๋น ์ง์ง ์์๋ค. ์ฆ **๋ฌด์ ํ ์ํ์ ๋น์จ
|
| 97 |
+
0.557 ์ ํ์ ์ด์์ผ๋ก ํฌ๊ณ , ๊ทธ ๊ผฌ๋ฆฌ๊ฐ ๋ฐ์ฐ์ ์ ๋ฐ**ํ๋ค๋ ํด์๊ณผ ์ผ์นํ๋ค.
|
| 98 |
+
|
| 99 |
+
---
|
| 100 |
+
|
| 101 |
+
## 4. โ ๏ธ ๊ฐ์ด ๊ณ ์น ๊ฒ โ ์ด์ cap ๊ตฌํ์ ์น๋ช
์ ๋ฒ๊ทธ
|
| 102 |
+
|
| 103 |
+
์ฒ์ ์์ฑํ cap ์ ์ด๋ฌ๋ค:
|
| 104 |
+
|
| 105 |
+
```python
|
| 106 |
+
res = res * (rn.clamp(max=cap) / (rn + 1e-6)) # ์๋ชป๋จ
|
| 107 |
+
```
|
| 108 |
+
|
| 109 |
+
๋ ๊ฐ์ง๊ฐ ํ๋ ธ๋ค.
|
| 110 |
+
|
| 111 |
+
**(1) `res = 0` ์์ gradient ๊ฐ ์ ํํ 0 ์ด ๋๋ค.** ์ค์ผ์ผ์ด `0 / 1e-6 = 0` ์ด ๋๊ณ
|
| 112 |
+
Jacobian ๋ 0 ์ด๋ค. `SRA_SOFT_START`(out_proj zero-init) ์ ํจ๊ป ์ผ๋ฉด `out_proj` ๊ฐ
|
| 113 |
+
0 ์ ์๊ตฌํ ๊ฐํ **๊ทธ๋ํ๊ฐ ์ ํ ํ์ต๋์ง ์๋๋ค**. NaN ์ด ์๋๋ผ ์กฐ์ฉํ ์ฃฝ๋๋ค.
|
| 114 |
+
|
| 115 |
+
์ค์ธก (out_proj gradient ํฉ):
|
| 116 |
+
|
| 117 |
+
| ์ค์ | grad |
|
| 118 |
+
|---|---|
|
| 119 |
+
| SOFT_START ๋ง | 78,751 |
|
| 120 |
+
| RES_CAP ๋ง | 765,506 |
|
| 121 |
+
| **SOFT_START + RES_CAP** | **0.00** โ ํ์ต ๋ถ๊ฐ |
|
| 122 |
+
|
| 123 |
+
์ด ์กฐํฉ์ผ๋ก ๋๋ฆฐ ์คํ๋ค์ ์ฒดํฌํฌ์ธํธ๋ฅผ ์ด์ด๋ณด๋ **58 epoch ๋ค์๋
|
| 124 |
+
`future_graph.out_proj` ๊ฐ ์ ํํ `0.000e+00`** ์ด์๋ค. ์ฆ ๊ทธ ์คํ๋ค์ host ๋จ๋
|
| 125 |
+
(=baseline) ์ ์ธก์ ํ ๊ฒ์ด๊ณ , "cap ์ด ๋ฐ์ฐ์ ํด๊ฒฐํ๋ค"๋ ๊ฒฐ๋ก ์ **๊ทธ๋ํ๊ฐ ๊บผ์ ธ ์์ด
|
| 126 |
+
๋ฐ์ฐํ ๊ฒ์ด ์์์ ๋ฟ**์ด์๋ค. ํด๋น ๊ฒฐ๊ณผ 4๊ฑด์ ํ๊ธฐํ๋ค.
|
| 127 |
+
|
| 128 |
+
**(2) cap ๋ฏธ๋ง ๊ฐ๋ ๋ถ๋นํ๊ฒ ์ถ์๋๋ค.** `rn/(rn+1e-6)` ์ `rn` ์ด ์์์๋ก 1 ์์
|
| 129 |
+
๋ฉ์ด์ง๋ค โ `โresโ=1e-5` ์์ **0.909 ๋ฐฐ**.
|
| 130 |
+
|
| 131 |
+
`torch.where` ๋ก ๋ฐ๊พธ๋ฉด ๋ ๋ค ํด๊ฒฐ๋๋ค:
|
| 132 |
+
|
| 133 |
+
| ๊ฒ์ฆ | old | new |
|
| 134 |
+
|---|---|---|
|
| 135 |
+
| `res=0` ์์ gradient | 0.0000 | **31.30** |
|
| 136 |
+
| โresโ=1e-5 ์ผ ๋ ์ค์ผ์ผ | 0.909 | **1.000** |
|
| 137 |
+
| cap ์ด๊ณผ ์ ์ํ | 3.0 | 3.0 (๋์ผ) |
|
| 138 |
+
| ์ ์ ๊ตฌ๊ฐ gradient ์ฐจ์ด | โ | ์๋์ฐจ 6e-7 |
|
| 139 |
+
|
| 140 |
+
---
|
| 141 |
+
|
| 142 |
+
## 5. ์ฌ์ฉ๋ฒ
|
| 143 |
+
|
| 144 |
+
```bash
|
| 145 |
+
# ๊ถ์ฅ ์ค์ (MoFlow-NBA)
|
| 146 |
+
SRA_EDGE_FIX=1 SRA_RES_CAP_REL=0.03 \
|
| 147 |
+
CUDA_VISIBLE_DEVICES=0 python fm_nba_graph_v6.py \
|
| 148 |
+
--cfg cfg/nba/cor_fm.yml --exp v3_rel003 \
|
| 149 |
+
--batch_size 192 --epochs 150 --fm_in_scaling --tied_noise \
|
| 150 |
+
--top_n_neighbors 5 --uncertainty_weight 0.01 --data_dir ./data/nba
|
| 151 |
+
```
|
| 152 |
+
|
| 153 |
+
| ํ ๊ธ | ๊ธฐ๋ณธ | ์ญํ |
|
| 154 |
+
|---|---|---|
|
| 155 |
+
| `SRA_EDGE_FIX` | off | edge-index ์ฌ ํผํฉ ๋ฒ๊ทธ ์์ (**ํ์**) |
|
| 156 |
+
| `SRA_RES_CAP_REL` | 0 (off) | **๋น์จ ์ํ** `โresโ โค rยทโorigโ` โ ๊ถ์ฅ |
|
| 157 |
+
| `SRA_RES_CAP` | 0 (off) | ์ ๋ ์ํ โ MoFlow ์์ ์ด๋ฑํจ์ด ํ์ธ๋จ |
|
| 158 |
+
| `SRA_SOFT_START` | off | **RES_CAP ๊ณผ ํจ๊ป ์ฐ์ง ๋ง ๊ฒ** (ยง4). ๋จ๋
์ผ๋ก๋ ๋ฐ์ฐ ๋ชป ๋ง์ |
|
| 159 |
+
| `SRA_GATE_SCALE` | 1.0 | ์ ์ญ ์ถ์ โ ๊ฐ์ฅ ๋นจ๋ฆฌ ๋ฐ์ฐ(3ํ์ฐจ), ํ๊ธฐ |
|
| 160 |
+
|
| 161 |
+
---
|
| 162 |
+
|
| 163 |
+
## 6. ๋ฏธํ์ / ํ๊ณ
|
| 164 |
+
|
| 165 |
+
**โ ์ต์ข
์๋ ด๊ฐ์ ์์ง ๋ชจ๋ฅธ๋ค.** ํ์ฌ 9 %(2368/25500) ์์ 0.840 ์ด๋ค.
|
| 166 |
+
๊ธฐ์กด(๋ฒ๊ทธํ) SRA = **0.695**, baseline = **0.703**. ๋จ์ 91 % ์ cosine LR ๊ฐ์ ์์
|
| 167 |
+
๋ ๋ด๋ ค๊ฐ์ผ ํ๋ฉฐ, **0.695 ์ ๋๋ฌํ์ง ๋ชปํ ๊ฐ๋ฅ์ฑ์ ์ฌ์ ํ ์ด๋ ค ์๋ค.**
|
| 168 |
+
|
| 169 |
+
**โก ๋น์จ๊ฐ ํ๋์ด ๋๋์ง ์์๋ค.** 0.03 ๊ณผ 0.10 ์ด ๋น์ทํ๊ณ 0.03 ์ด ๊ทผ์ ์ฐ์๋ค.
|
| 170 |
+
๋ ์กฐ์ธ ๊ฐ(0.01)์ด ๋์์ง, ์๋๋ฉด 0.03 ์ด ์ด๋ฏธ ๊ณผ๋ํ ์ ์ฝ์ธ์ง๋ ๋ฏธ๊ฒ์ฆ์ด๋ค.
|
| 171 |
+
cap ์ ์กฐ์ผ์๋ก ๋ฐ์ฐ์ ๋งํ์ง๋ง ๊ทธ๋ํ ๊ธฐ์ฌ๋ ์ค์ด๋๋ฏ๋ก, **"๋ฐ์ฐ ์ ํ๋ฉด์
|
| 172 |
+
baseline ๋ณด๋ค ๋์" ๊ตฌ๊ฐ์ด ์ค์ ๋ก ์กด์ฌํ๋์ง**๊ฐ ์ต์ข
์ง๋ฌธ์ด๋ค. ํ์ฌ 0.840 vs
|
| 173 |
+
baseline 0.895 ๋ ๊ทธ ๊ตฌ๊ฐ์ด ์กด์ฌํ๋ค๋ ์ฒซ ์ฆ๊ฑฐ๋ค.
|
| 174 |
+
|
| 175 |
+
**โข MoFlow ์ ์ฉ ์ฒ๋ฐฉ์ด๋ค.** MIDยทLED ๋ iterative denoiser ๋ผ ์ด ๋ฐ์ฐ์ด ์๊ณ ,
|
| 176 |
+
`RES_CAP*` ์ ์ฐ์ง ์๋๋ค (MID ๋ gate_init/warmup, LED ๋ ์ฒ๋ฐฉ ์์).
|
| 177 |
+
๋ค๋ฅธ ํธ์คํธ์ ์ ์ฉํ๋ ค๋ฉด ๊ทธ ํธ์คํธ์ residual/embedding ๋น์จ์ ๋จผ์ ์ธก์ ํด์ผ ํ๋ค.
|
| 178 |
+
|
| 179 |
+
**โฃ ์ ๋ cap ์ด ํญ์ ๋์๋ค๊ณ ๋จ์ ํ ์๋ ์๋ค.** cap 0.5 ๋ ์์ง ๋ฐ์ฐํ์ง ์์๊ณ
|
| 180 |
+
๋ฐ๋ฑ ์กฐ์ง๋ง ๋ณด์ธ๋ค. ์๋ cap ์ ์ฐ์๋ ํ์ฌ 13ํ ํ๊ฐ ๊ธฐ์ค์ ๊ด์ฐฐ์ด๋ฉฐ, ์์ฃผ๊น์ง
|
| 181 |
+
๊ฐ์ผ ํ์ ๋๋ค.
|