用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/majiayu000/claude-skill-registry --skill federated-learning命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
LLM token logprobs and calibration. Per-decision confidence, ECE, Brier, reliability diagrams, low-confidence triage.
Analyze LLM token logprobs and calibration. Use for per-decision confidence, ECE, Brier scores, reliability diagrams, and low-confidence triage.
回顾最近 N 天的 Claude Code 使用记录——扫描原始会话数据,按主题分组汇总"我都做了什么",并从个人操作系统视角输出模式、风险与增删建议。当用户说 /recap、"看看我这几天做了什么"、"回顾一下我最近的会话"、"这两天我用 claude 干了啥"、"活动回顾" 时使用。
基于 SOC 职业分类
正在显示 SKILL.md
| name | federated-learning |
| description | Train models across distributed clients with privacy-preserving federated algorithms |
| Strategy | Privacy | Scale | Non-IID Tolerance | Best For |
|---|---|---|---|---|
| FedAvg | Low | Cross-silo | Low | Homogeneous data, fast prototyping |
| FedProx | Low | Cross-silo | Medium | Heterogeneous clients, stragglers |
| FedAvg + DP | High | Either | Low | Regulatory compliance |
| FedSGD + SecAgg | Very High | Cross-silo | Low | Finance, healthcare |
| Compressed FedAvg | Low | Cross-device | Low | Mobile/IoT, bandwidth-constrained |
| Scaffold | Low | Cross-silo | High | Highly non-IID data |
| Dimension | Cross-Device | Cross-Silo |
|---|---|---|
| Clients | Millions of phones/IoT | 2-100 organizations |
| Data per client | Small (KB-MB) | Large (GB-TB) |
| Participation | 0.1-1% per round | 100% per round |
| Trust model | Untrusted | Semi-trusted partners |
import torch
import torch.nn as nn
from copy import deepcopy
from typing import List, Dict, Tuple
class FedAvgServer:
"""Central server for federated averaging."""
def __init__(self, global_model: nn.Module):
self.global_model = global_model
def aggregate(self, client_updates: List[Tuple[Dict, int]]):
"""Weighted average of client models by dataset size."""
total_samples = sum(n for _, n in client_updates)
state = self.global_model.state_dict()
for key in state:
state[key] = sum(
s[key].float() * (n / total_samples) for s, n in client_updates)
self.global_model.load_state_dict(state)
def run_round(self, clients: List["FedClient"]):
global_state = deepcopy(self.global_model.state_dict())
updates = [c.train(global_state) for c in clients]
self.aggregate(updates)
class :
():
.model = model_fn()
.train_loader = train_loader
.lr, .local_epochs = lr, local_epochs
() -> [, ]:
.model.load_state_dict(global_state)
.model.train()
optimizer = torch.optim.SGD(.model.parameters(), lr=.lr)
criterion = nn.CrossEntropyLoss()
num_samples =
_ (.local_epochs):
x, y .train_loader:
optimizer.zero_grad()
criterion(.model(x), y).backward()
optimizer.step()
num_samples += (x)
.model.state_dict(), num_samples // .local_epochs
class FedProxClient(FedClient):
"""Adds L2 penalty toward global model to limit client drift."""
def __init__(self, model_fn, train_loader, lr=0.01, local_epochs=5, mu=0.01):
super().__init__(model_fn, train_loader, lr, local_epochs)
self.mu = mu
def train(self, global_state: Dict) -> Tuple[Dict, int]:
self.model.load_state_dict(global_state)
self.model.train()
global_params = {k: v.clone().detach() for k, v in self.model.named_parameters()}
optimizer = torch.optim.SGD(self.model.parameters(), lr=self.lr)
num_samples = 0
for _ in range(self.local_epochs):
for x, y in self.train_loader:
optimizer.zero_grad()
loss = nn.CrossEntropyLoss()(self.model(x), y)
# Proximal term: (mu/2) * ||w - w_global||^2
for name, param in self.model.named_parameters():
loss += (self.mu / 2) * ((param - global_params[name]) ** 2).sum()
loss.backward()
optimizer.step()
num_samples += (x)
.model.state_dict(), num_samples // .local_epochs
class DPFedAvgClient(FedClient):
"""Per-sample gradient clipping + Gaussian noise for (epsilon, delta)-DP."""
def __init__(self, model_fn, loader, lr=0.01, local_epochs=5,
max_grad_norm=1.0, noise_multiplier=1.1):
super().__init__(model_fn, loader, lr, local_epochs)
self.max_grad_norm = max_grad_norm
self.noise_multiplier = noise_multiplier
def clip_and_noise(self, batch_size: int):
"""Clip gradients, then add calibrated Gaussian noise."""
total_norm = torch.sqrt(sum(
p.grad.norm(2) ** 2 for p in self.model.parameters() if p.grad is not None))
clip_coef = min(1.0, self.max_grad_norm / (total_norm + 1e-6))
for p in self.model.parameters():
if p.grad is not None:
p.grad.mul_(clip_coef)
p.grad.add_(torch.randn_like(p.grad) * (
self.noise_multiplier * self.max_grad_norm / batch_size))
def train() -> [, ]:
.model.load_state_dict(global_state)
.model.train()
optimizer = torch.optim.SGD(.model.parameters(), lr=.lr)
num_samples =
_ (.local_epochs):
x, y .train_loader:
optimizer.zero_grad()
nn.CrossEntropyLoss()(.model(x), y).backward()
.clip_and_noise((x))
optimizer.step()
num_samples += (x)
.model.state_dict(), num_samples // .local_epochs
class TopKCompressor:
"""Keep only top-k% of gradient values; accumulate residuals."""
def __init__(self, compress_ratio=0.01):
self.compress_ratio = compress_ratio
self.residuals = {} # error feedback per parameter
def compress(self, model: nn.Module) -> Dict:
compressed = {}
for name, param in model.named_parameters():
if param.grad is None:
continue
grad = param.grad.data
if name in self.residuals:
grad = grad + self.residuals[name] # error feedback
flat = grad.view(-1)
k = max(1, int(len(flat) * self.compress_ratio))
_, indices = torch.topk(flat.abs(), k)
values = flat[indices]
residual = flat.clone()
residual[indices] = 0
self.residuals[name] = residual.view_as(grad)
compressed[name] = (values, indices)
return compressed
def quantize_updates(state_dict, num_bits=8):
"""Uniform quantization of model deltas to reduce bandwidth."""
q = {}
for key, tensor in state_dict.items():
t_min, t_max = tensor.min(), tensor.max()
scale = (t_max - t_min) / (2 ** num_bits - 1)
q[key] = {"data": ((tensor - t_min) / (scale + 1e-8)).round().byte(),
"min": t_min, "scale": scale}
return q
def dequantize_updates(q):
return {k: v["data"].float() * v["scale"] + v["min"] for k, v in q.items()}
class SecureAggregator:
"""Masking-based secure aggregation (conceptual)."""
def generate_masks(self, client_ids: list, param_shape):
"""Each client pair shares a seed; masks cancel on sum."""
masks = {cid: torch.zeros(param_shape) for cid in client_ids}
for i, c1 in enumerate(client_ids):
for c2 in client_ids[i + 1:]:
g = torch.Generator().manual_seed(hash((c1, c2)) % (2 ** 32))
mask = torch.randn(param_shape, generator=g)
masks[c1] += mask; masks[c2] -= mask # cancels on sum
return masks
import flwr as fl
class FlowerClient(fl.client.NumPyClient):
def __init__(self, model, train_loader, val_loader, lr=0.01):
self.model, self.train_loader, self.val_loader, self.lr = (
model, train_loader, val_loader, lr)
def get_parameters(self, config):
return [v.cpu().numpy() for v in self.model.state_dict().values()]
def set_parameters(self, params):
sd = dict(zip(self.model.state_dict().keys(), [torch.tensor(v) for v in params]))
self.model.load_state_dict(sd)
def fit(self, parameters, config):
self.set_parameters(parameters)
opt = torch.optim.SGD(self.model.parameters(), lr=self.lr)
self.model.train()
for x, y in self.train_loader:
opt.zero_grad(); nn.CrossEntropyLoss()(self.model(x), y).backward(); opt.step()
return self.get_parameters(config), len(self.train_loader.dataset), {}
():
.set_parameters(parameters)
.model.()
correct, total = ,
torch.no_grad():
x, y .val_loader:
correct += (.model(x).argmax() == y).().item()
total += (y)
( - correct / total), total, {: correct / total}