CoolFace
Modelpublic

emilyxuan/accesscontrol

sourceHugging Faceupdated 4mo agoView on Hugging Face
0likes
plot_trigger_pca.py111 linesDownload Raw Back to root
1import random2import numpy as np3import torch4import matplotlib.pyplot as plt5from sklearn.decomposition import PCA6 7from trigger_encoder import TriggerEncoder8 9 10def build_unseen_trigger(img_size, num_points=2, grid_size=8, seed=999, square_size=3):11    assert square_size >= 1 and square_size % 2 == 112 13    margin = max(2, img_size // 8)14    xs = torch.linspace(margin, img_size - margin - 1, steps=grid_size).long()15    ys = torch.linspace(margin, img_size - margin - 1, steps=grid_size).long()16    candidate_positions = [(int(y), int(x)) for y in ys for x in xs]17 18    trig = torch.full((3, img_size, img_size), -1.0, dtype=torch.float32)19    rng = random.Random(int(seed))20    selected = rng.sample(candidate_positions, num_points)21 22    half = square_size // 223    for (y, x) in selected:24        y1 = max(0, y - half)25        y2 = min(img_size, y + half + 1)26        x1 = max(0, x - half)27        x2 = min(img_size, x + half + 1)28        trig[:, y1:y2, x1:x2] = 1.029 30    return trig31 32 33def main():34    ckpt_path = "./logs/cifar10_cond_acsctrl/cond128_neg0.25_0.25_seed42/cond128_neg0.5_seed42_20260426_003254/checkpoints/global_ckpt_round240.pt"35    device = "cuda" if torch.cuda.is_available() else "cpu"36 37    ckpt = torch.load(ckpt_path, map_location="cpu")38    cfg = ckpt["config"]39 40    img_size = cfg["img_size"]41    cond_dim = cfg["cond_dim"]42    trigger_base_ch = cfg["trigger_base_ch"]43 44    encoder = TriggerEncoder(45        in_ch=3,46        base_ch=trigger_base_ch,47        cond_dim=cond_dim,48        img_size=img_size,49        grid_size=8,50        hidden_dim=256,51        use_coord_feat=True,52    ).to(device)53    encoder.load_state_dict(ckpt["trigger_encoder"], strict=True)54    encoder.eval()55 56    client_triggers = [t.clone() for t in ckpt["client_triggers"]]57 58    xs = []59    labels = []60 61    with torch.no_grad():62        # trained triggers63        for i, trig in enumerate(client_triggers):64            emb = encoder(trig.unsqueeze(0).to(device)).squeeze(0).cpu().numpy()65            xs.append(emb)66            labels.append(f"trained_{i}")67 68        # fixed unseen triggers69        for s in [999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019]:70            trig = build_unseen_trigger(71                img_size=img_size,72                num_points=cfg.get("unseen_num_points", 2),73                grid_size=cfg.get("unseen_grid_size", 8),74                seed=s,75                square_size=cfg.get("unseen_square_size", 3),76            )77            emb = encoder(trig.unsqueeze(0).to(device)).squeeze(0).cpu().numpy()78            xs.append(emb)79            labels.append(f"unseen_{s}")80 81        # none82        none_emb = np.zeros(cond_dim, dtype=np.float32)83        xs.append(none_emb)84        labels.append("none")85 86    X = np.stack(xs, axis=0)87    pca = PCA(n_components=2)88    X2 = pca.fit_transform(X)89 90    plt.figure(figsize=(8, 6))91    for i, name in enumerate(labels):92        if name.startswith("trained_"):93            marker = "o"94        elif name.startswith("unseen_"):95            marker = "^"96        else:97            marker = "x"98 99        plt.scatter(X2[i, 0], X2[i, 1], marker=marker)100        plt.text(X2[i, 0] + 0.02, X2[i, 1] + 0.02, name, fontsize=8)101 102    plt.xlabel(f"PC1 ({pca.explained_variance_ratio_[0] * 100:.1f}%)")103    plt.ylabel(f"PC2 ({pca.explained_variance_ratio_[1] * 100:.1f}%)")104    plt.title("Trigger Embedding PCA")105    plt.tight_layout()106    plt.savefig("trigger_pca240.png", dpi=200)107    print("saved: trigger_pca220.png")108 109 110if __name__ == "__main__":111    main()