Match figure styling and labels to the submitted manuscript
Enlarge the in-canvas fonts and line weights of the result figures so that they stay legible at the printed column width, split the Fig. 5 convergence curve into a pre-meta adaptation entry and the proposed MAML entry, and rename the autoencoder legend to match the table row. Add the analytic complexity replot behind Fig. 4, which was missing from the repository, and correct the table numbering in the README.
This commit is contained in:
@@ -2,3 +2,4 @@ data_mnist/
|
|||||||
results_bert/bert_feats.pt
|
results_bert/bert_feats.pt
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
fig/
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ fixed random seeds.
|
|||||||
| `c18_mnist_doppler.py` | Doppler sweep behind Fig. 7, with task-conditional decoder-side adaptation at every operating point. |
|
| `c18_mnist_doppler.py` | Doppler sweep behind Fig. 7, with task-conditional decoder-side adaptation at every operating point. |
|
||||||
| `c19_mnist_epoch.py` | Convergence study behind Fig. 5, recording the task-adapted SER at every training checkpoint. |
|
| `c19_mnist_epoch.py` | Convergence study behind Fig. 5, recording the task-adapted SER at every training checkpoint. |
|
||||||
| `c22_maml_epoch.py` | Budget-matched meta-training trajectory that forms the right-hand segment of Fig. 5. |
|
| `c22_maml_epoch.py` | Budget-matched meta-training trajectory that forms the right-hand segment of Fig. 5. |
|
||||||
| `c21_mnist_flat.py` | Flat Rayleigh study behind Table III, including the decoder-side first-order MAML variant. |
|
| `c21_mnist_flat.py` | Flat Rayleigh study behind Table II, including the decoder-side first-order MAML variant. |
|
||||||
| `c20_bert.py` | Concluding BERT/AG News text study behind Fig. 8, from feature caching to training and evaluation. |
|
| `c20_bert.py` | Concluding BERT/AG News text study behind Fig. 8, from feature caching to training and evaluation. |
|
||||||
|
| `fig_replot_complexity.py` | Analytic complexity comparison behind Fig. 4, for the softmax and the signed realizations. |
|
||||||
|
|
||||||
## Reproducing the figures
|
## Reproducing the figures
|
||||||
|
|
||||||
@@ -28,14 +29,21 @@ Each figure regenerates from the stored CSV results without
|
|||||||
retraining.
|
retraining.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
python3 fig_replot_complexity.py # Fig. 4
|
||||||
python3 c19_mnist_epoch.py --mode fig # Fig. 5
|
python3 c19_mnist_epoch.py --mode fig # Fig. 5
|
||||||
python3 c13_mnist.py --mode fig # Fig. 6
|
python3 c13_mnist.py --mode fig # Fig. 6
|
||||||
python3 c18_mnist_doppler.py --mode fig # Fig. 7
|
python3 c18_mnist_doppler.py --mode fig # Fig. 7
|
||||||
python3 c20_bert.py --mode fig # Fig. 8
|
python3 c20_bert.py --mode fig # Fig. 8
|
||||||
```
|
```
|
||||||
|
|
||||||
Table III values are stored in `results_mnist/mnist_flat.csv`, and
|
Fig. 4 is analytic and needs no stored results. In Fig. 5 the green
|
||||||
Table IV values come from `results_mnist/mnist_results.csv` and
|
curve is split into two legend entries: left of the dotted line the
|
||||||
|
five-step adaptation starts from the jointly trained model and no
|
||||||
|
meta-training has taken place, and right of it the receiver
|
||||||
|
meta-trains within the same total step budget.
|
||||||
|
|
||||||
|
Table II values are stored in `results_mnist/mnist_flat.csv`, and
|
||||||
|
Table III values come from `results_mnist/mnist_results.csv` and
|
||||||
`results_mnist/mnist_doppler.csv`.
|
`results_mnist/mnist_doppler.csv`.
|
||||||
|
|
||||||
## Rerunning the experiments
|
## Rerunning the experiments
|
||||||
|
|||||||
+11
-4
@@ -502,7 +502,7 @@ def make_fig(args):
|
|||||||
LAB = {"digital_genie": "Digital chain genie CSI",
|
LAB = {"digital_genie": "Digital chain genie CSI",
|
||||||
"digital_pilot": "Digital chain pilot CSI",
|
"digital_pilot": "Digital chain pilot CSI",
|
||||||
"semantic_tf": "Transformer SE separation",
|
"semantic_tf": "Transformer SE separation",
|
||||||
"semantic_ae": "Per-user AE multiple access",
|
"semantic_ae": "Per-user AE",
|
||||||
"semantic": "Proposed signed joint",
|
"semantic": "Proposed signed joint",
|
||||||
"semantic_maml": "Proposed signed MAML"}
|
"semantic_maml": "Proposed signed MAML"}
|
||||||
STY = {"digital_genie": dict(color="gray", marker="^", ls="--"),
|
STY = {"digital_genie": dict(color="gray", marker="^", ls="--"),
|
||||||
@@ -511,8 +511,14 @@ def make_fig(args):
|
|||||||
"semantic_ae": dict(color="tab:brown", marker="X", ls="-"),
|
"semantic_ae": dict(color="tab:brown", marker="X", ls="-"),
|
||||||
"semantic": dict(color="tab:red", marker="o", ls="-"),
|
"semantic": dict(color="tab:red", marker="o", ls="-"),
|
||||||
"semantic_maml": dict(color="tab:green", marker="D", ls="--")}
|
"semantic_maml": dict(color="tab:green", marker="D", ls="--")}
|
||||||
|
plt.rcParams.update({"font.size": 13, "axes.labelsize": 13,
|
||||||
|
"xtick.labelsize": 12, "ytick.labelsize": 12,
|
||||||
|
"axes.linewidth": 1.1, "grid.linewidth": 0.8,
|
||||||
|
"xtick.major.width": 1.1, "ytick.major.width": 1.1,
|
||||||
|
"xtick.minor.width": 0.8, "ytick.minor.width": 0.8,
|
||||||
|
"xtick.major.size": 4.5, "ytick.major.size": 4.5})
|
||||||
fig = plt.figure(figsize=(5.2, 3.9))
|
fig = plt.figure(figsize=(5.2, 3.9))
|
||||||
ax = fig.add_axes([0.14, 0.125, 0.835, 0.845])
|
ax = fig.add_axes([0.155, 0.145, 0.82, 0.82])
|
||||||
for mkey in LAB:
|
for mkey in LAB:
|
||||||
pts = sorted([(float(r["snr_db"]), float(r["ser"]))
|
pts = sorted([(float(r["snr_db"]), float(r["ser"]))
|
||||||
for r in rows if r["method"] == mkey])
|
for r in rows if r["method"] == mkey])
|
||||||
@@ -520,11 +526,12 @@ def make_fig(args):
|
|||||||
continue
|
continue
|
||||||
xs, ys = zip(*pts)
|
xs, ys = zip(*pts)
|
||||||
ys = [max(v, 1e-5) for v in ys]
|
ys = [max(v, 1e-5) for v in ys]
|
||||||
ax.semilogy(xs, ys, label=LAB[mkey], ms=4, lw=1.3, **STY[mkey])
|
ax.semilogy(xs, ys, label=LAB[mkey], ms=5, lw=1.8, **STY[mkey])
|
||||||
ax.set_xlabel("SNR (dB)")
|
ax.set_xlabel("SNR (dB)")
|
||||||
ax.set_ylabel("SER")
|
ax.set_ylabel("SER")
|
||||||
ax.grid(True, which="both", alpha=0.35)
|
ax.grid(True, which="both", alpha=0.35)
|
||||||
ax.legend(fontsize=7.5, loc="center right", bbox_to_anchor=(0.985, 0.66))
|
ax.legend(fontsize=9, framealpha=1.0, labelspacing=0.3,
|
||||||
|
handlelength=1.8, loc="center right", bbox_to_anchor=(0.985, 0.66))
|
||||||
out = os.path.join(args.fig_dir, f"mnist_ser_vs_snr_fd{args.eval_fd}.pdf")
|
out = os.path.join(args.fig_dir, f"mnist_ser_vs_snr_fd{args.eval_fd}.pdf")
|
||||||
fig.savefig(out)
|
fig.savefig(out)
|
||||||
print("saved", out)
|
print("saved", out)
|
||||||
|
|||||||
+11
-4
@@ -114,7 +114,7 @@ def make_fig(args):
|
|||||||
LAB = {"digital_genie": "Digital chain genie CSI",
|
LAB = {"digital_genie": "Digital chain genie CSI",
|
||||||
"digital_pilot": "Digital chain pilot CSI",
|
"digital_pilot": "Digital chain pilot CSI",
|
||||||
"semantic_tf": "Transformer SE separation",
|
"semantic_tf": "Transformer SE separation",
|
||||||
"semantic_ae": "Per-user AE multiple access",
|
"semantic_ae": "Per-user AE",
|
||||||
"semantic": "Proposed signed joint",
|
"semantic": "Proposed signed joint",
|
||||||
"semantic_maml": "Proposed signed MAML"}
|
"semantic_maml": "Proposed signed MAML"}
|
||||||
STY = {"digital_genie": dict(color="gray", marker="^", ls="--"),
|
STY = {"digital_genie": dict(color="gray", marker="^", ls="--"),
|
||||||
@@ -123,8 +123,14 @@ def make_fig(args):
|
|||||||
"semantic_ae": dict(color="tab:brown", marker="X", ls="-"),
|
"semantic_ae": dict(color="tab:brown", marker="X", ls="-"),
|
||||||
"semantic": dict(color="tab:red", marker="o", ls="-"),
|
"semantic": dict(color="tab:red", marker="o", ls="-"),
|
||||||
"semantic_maml": dict(color="tab:green", marker="D", ls="--")}
|
"semantic_maml": dict(color="tab:green", marker="D", ls="--")}
|
||||||
|
plt.rcParams.update({"font.size": 13, "axes.labelsize": 13,
|
||||||
|
"xtick.labelsize": 12, "ytick.labelsize": 12,
|
||||||
|
"axes.linewidth": 1.1, "grid.linewidth": 0.8,
|
||||||
|
"xtick.major.width": 1.1, "ytick.major.width": 1.1,
|
||||||
|
"xtick.minor.width": 0.8, "ytick.minor.width": 0.8,
|
||||||
|
"xtick.major.size": 4.5, "ytick.major.size": 4.5})
|
||||||
fig = plt.figure(figsize=(5.2, 3.9))
|
fig = plt.figure(figsize=(5.2, 3.9))
|
||||||
ax = fig.add_axes([0.14, 0.125, 0.835, 0.845])
|
ax = fig.add_axes([0.155, 0.145, 0.82, 0.82])
|
||||||
for mkey in LAB:
|
for mkey in LAB:
|
||||||
pts = sorted([(float(r["fd_norm"]), float(r["ser"]))
|
pts = sorted([(float(r["fd_norm"]), float(r["ser"]))
|
||||||
for r in rows if r["method"] == mkey])
|
for r in rows if r["method"] == mkey])
|
||||||
@@ -132,11 +138,12 @@ def make_fig(args):
|
|||||||
if not pts:
|
if not pts:
|
||||||
continue
|
continue
|
||||||
xs, ys = zip(*pts)
|
xs, ys = zip(*pts)
|
||||||
ax.semilogy(xs, ys, label=LAB[mkey], ms=4, lw=1.3, **STY[mkey])
|
ax.semilogy(xs, ys, label=LAB[mkey], ms=5, lw=1.8, **STY[mkey])
|
||||||
ax.set_xlabel(r"Normalized Doppler $f_D T_{\mathrm{sym}}$")
|
ax.set_xlabel(r"Normalized Doppler $f_D T_{\mathrm{sym}}$")
|
||||||
ax.set_ylabel("SER")
|
ax.set_ylabel("SER")
|
||||||
ax.grid(True, which="both", alpha=0.35)
|
ax.grid(True, which="both", alpha=0.35)
|
||||||
ax.legend(fontsize=7.5, loc="center right", bbox_to_anchor=(0.985, 0.72))
|
ax.legend(fontsize=9, framealpha=1.0, labelspacing=0.3,
|
||||||
|
handlelength=1.8, loc="center right", bbox_to_anchor=(0.985, 0.72))
|
||||||
out = os.path.join(args.fig_dir,
|
out = os.path.join(args.fig_dir,
|
||||||
f"mnist_ser_vs_doppler_snr{int(args.eval_snr)}.pdf")
|
f"mnist_ser_vs_doppler_snr{int(args.eval_snr)}.pdf")
|
||||||
fig.savefig(out)
|
fig.savefig(out)
|
||||||
|
|||||||
+29
-11
@@ -22,7 +22,7 @@ import c13_mnist as m13
|
|||||||
MODELS = {
|
MODELS = {
|
||||||
"semantic": (m13.MnistSemanticMA, "Proposed signed joint"),
|
"semantic": (m13.MnistSemanticMA, "Proposed signed joint"),
|
||||||
"semantic_tf": (m13.MnistTransformerMA, "Transformer SE separation"),
|
"semantic_tf": (m13.MnistTransformerMA, "Transformer SE separation"),
|
||||||
"semantic_ae": (m13.MnistPerUserAE, "Per-user AE multiple access"),
|
"semantic_ae": (m13.MnistPerUserAE, "Per-user AE"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -202,24 +202,30 @@ def main():
|
|||||||
STY = {"semantic": dict(color="tab:red", marker="o", ls="-"),
|
STY = {"semantic": dict(color="tab:red", marker="o", ls="-"),
|
||||||
"semantic_tf": dict(color="tab:purple", marker="P", ls="-"),
|
"semantic_tf": dict(color="tab:purple", marker="P", ls="-"),
|
||||||
"semantic_ae": dict(color="tab:brown", marker="X", ls="-")}
|
"semantic_ae": dict(color="tab:brown", marker="X", ls="-")}
|
||||||
|
plt.rcParams.update({"font.size": 13, "axes.labelsize": 13,
|
||||||
|
"xtick.labelsize": 12, "ytick.labelsize": 12,
|
||||||
|
"axes.linewidth": 1.1, "grid.linewidth": 0.8,
|
||||||
|
"xtick.major.width": 1.1, "ytick.major.width": 1.1,
|
||||||
|
"xtick.minor.width": 0.8, "ytick.minor.width": 0.8,
|
||||||
|
"xtick.major.size": 4.5, "ytick.major.size": 4.5})
|
||||||
fig = plt.figure(figsize=(5.2, 3.9))
|
fig = plt.figure(figsize=(5.2, 3.9))
|
||||||
ax = fig.add_axes([0.14, 0.125, 0.835, 0.845])
|
ax = fig.add_axes([0.155, 0.145, 0.82, 0.82])
|
||||||
xgrid = sorted({int(r["step"]) for r in rows
|
xgrid = sorted({int(r["step"]) for r in rows
|
||||||
if r["method"] == "semantic"})
|
if r["method"] == "semantic"})
|
||||||
if "digital_genie" in floors:
|
if "digital_genie" in floors:
|
||||||
ax.semilogy(xgrid, [floors["digital_genie"]] * len(xgrid),
|
ax.semilogy(xgrid, [floors["digital_genie"]] * len(xgrid),
|
||||||
label="Digital chain genie CSI", ms=3.5, lw=1.2,
|
label="Digital chain genie CSI", ms=5, lw=1.7,
|
||||||
color="gray", marker="^", ls="--")
|
color="gray", marker="^", ls="--")
|
||||||
if "digital_pilot" in floors:
|
if "digital_pilot" in floors:
|
||||||
ax.semilogy(xgrid, [floors["digital_pilot"]] * len(xgrid),
|
ax.semilogy(xgrid, [floors["digital_pilot"]] * len(xgrid),
|
||||||
label="Digital chain pilot CSI", ms=3.5, lw=1.2,
|
label="Digital chain pilot CSI", ms=5, lw=1.7,
|
||||||
color="k", marker="v", ls="-")
|
color="k", marker="v", ls="-")
|
||||||
for key in ["semantic_tf", "semantic_ae", "semantic"]:
|
for key in ["semantic_tf", "semantic_ae", "semantic"]:
|
||||||
label = MODELS[key][1]
|
label = MODELS[key][1]
|
||||||
pts = sorted([(int(r["step"]), float(r["ser"])) for r in rows
|
pts = sorted([(int(r["step"]), float(r["ser"])) for r in rows
|
||||||
if r["method"] == key])
|
if r["method"] == key])
|
||||||
xs, ys = zip(*pts)
|
xs, ys = zip(*pts)
|
||||||
ax.semilogy(xs, ys, label=label, ms=3.5, lw=1.3, **STY[key])
|
ax.semilogy(xs, ys, label=label, ms=5, lw=1.8, **STY[key])
|
||||||
# signed MAML: the deployed receiver applies the five-step
|
# signed MAML: the deployed receiver applies the five-step
|
||||||
# task-conditional adaptation at every checkpoint. During the
|
# task-conditional adaptation at every checkpoint. During the
|
||||||
# warm-start phase the adapted SER of the evolving joint model is
|
# warm-start phase the adapted SER of the evolving joint model is
|
||||||
@@ -239,17 +245,29 @@ def main():
|
|||||||
pre_pts = sorted([(int(r["step"]), float(r["ser"]))
|
pre_pts = sorted([(int(r["step"]), float(r["ser"]))
|
||||||
for r in rows if r["method"] == "semantic"
|
for r in rows if r["method"] == "semantic"
|
||||||
and int(r["step"]) < warm_end])
|
and int(r["step"]) < warm_end])
|
||||||
pts = pre_pts + meta_pts
|
# Left of the dotted line no meta-training has happened yet, so
|
||||||
xs, ys = zip(*pts)
|
# the curve is the joint model with the same five-step
|
||||||
ax.semilogy(xs, ys, label="Proposed signed MAML", ms=3.5, lw=1.3,
|
# adaptation applied. It is drawn dashed with open markers and
|
||||||
color="tab:green", marker="D", ls="--")
|
# carries its own legend entry, since it is the control
|
||||||
ax.axvline(warm_end, color="gray", ls=":", lw=1.0)
|
# condition rather than the proposed MAML receiver.
|
||||||
|
pre_seg = pre_pts + meta_pts[:1]
|
||||||
|
xs, ys = zip(*pre_seg)
|
||||||
|
ax.semilogy(xs, ys, label="Adaptation from joint model", ms=5,
|
||||||
|
lw=1.8, color="tab:green", marker="D", ls="--",
|
||||||
|
markerfacecolor="none")
|
||||||
|
xs, ys = zip(*meta_pts)
|
||||||
|
ax.semilogy(xs, ys, label="Proposed signed MAML", ms=5, lw=1.8,
|
||||||
|
color="tab:green", marker="D", ls="-")
|
||||||
|
ax.axvline(warm_end, color="gray", ls=":", lw=1.4)
|
||||||
ax.set_xlabel("Training step")
|
ax.set_xlabel("Training step")
|
||||||
ax.set_ylabel("SER")
|
ax.set_ylabel("SER")
|
||||||
if "digital_genie" in floors:
|
if "digital_genie" in floors:
|
||||||
|
# extra headroom below the genie floor so that the seven-entry
|
||||||
|
# legend sits in free space instead of over the curves
|
||||||
ax.set_ylim(bottom=floors["digital_genie"] * 0.5)
|
ax.set_ylim(bottom=floors["digital_genie"] * 0.5)
|
||||||
ax.grid(True, which="both", alpha=0.35)
|
ax.grid(True, which="both", alpha=0.35)
|
||||||
ax.legend(fontsize=7.5, loc="center left", bbox_to_anchor=(0.02, 0.32))
|
ax.legend(fontsize=9, loc="center left", bbox_to_anchor=(0.02, 0.34),
|
||||||
|
framealpha=1.0, labelspacing=0.3, handlelength=1.8)
|
||||||
out = os.path.join(args.fig_dir, "mnist_epoch_convergence.pdf")
|
out = os.path.join(args.fig_dir, "mnist_epoch_convergence.pdf")
|
||||||
fig.savefig(out)
|
fig.savefig(out)
|
||||||
print("saved", out)
|
print("saved", out)
|
||||||
|
|||||||
+11
-4
@@ -441,7 +441,7 @@ def make_fig(args):
|
|||||||
LAB = {"digital_genie": "Digital chain genie CSI",
|
LAB = {"digital_genie": "Digital chain genie CSI",
|
||||||
"digital_pilot": "Digital chain pilot CSI",
|
"digital_pilot": "Digital chain pilot CSI",
|
||||||
"semantic_tf": "Transformer SE separation",
|
"semantic_tf": "Transformer SE separation",
|
||||||
"semantic_ae": "Per-user AE multiple access",
|
"semantic_ae": "Per-user AE",
|
||||||
"semantic": "Proposed signed joint",
|
"semantic": "Proposed signed joint",
|
||||||
"semantic_maml": "Proposed signed MAML"}
|
"semantic_maml": "Proposed signed MAML"}
|
||||||
STY = {"digital_genie": dict(color="gray", marker="^", ls="--"),
|
STY = {"digital_genie": dict(color="gray", marker="^", ls="--"),
|
||||||
@@ -450,8 +450,14 @@ def make_fig(args):
|
|||||||
"semantic_ae": dict(color="tab:brown", marker="X", ls="-"),
|
"semantic_ae": dict(color="tab:brown", marker="X", ls="-"),
|
||||||
"semantic": dict(color="tab:red", marker="o", ls="-"),
|
"semantic": dict(color="tab:red", marker="o", ls="-"),
|
||||||
"semantic_maml": dict(color="tab:green", marker="D", ls="--")}
|
"semantic_maml": dict(color="tab:green", marker="D", ls="--")}
|
||||||
|
plt.rcParams.update({"font.size": 13, "axes.labelsize": 13,
|
||||||
|
"xtick.labelsize": 12, "ytick.labelsize": 12,
|
||||||
|
"axes.linewidth": 1.1, "grid.linewidth": 0.8,
|
||||||
|
"xtick.major.width": 1.1, "ytick.major.width": 1.1,
|
||||||
|
"xtick.minor.width": 0.8, "ytick.minor.width": 0.8,
|
||||||
|
"xtick.major.size": 4.5, "ytick.major.size": 4.5})
|
||||||
fig = plt.figure(figsize=(5.2, 3.9))
|
fig = plt.figure(figsize=(5.2, 3.9))
|
||||||
ax = fig.add_axes([0.14, 0.125, 0.835, 0.845])
|
ax = fig.add_axes([0.155, 0.145, 0.82, 0.82])
|
||||||
for mkey in LAB:
|
for mkey in LAB:
|
||||||
pts = sorted([(float(r["snr_db"]), float(r["ser"]))
|
pts = sorted([(float(r["snr_db"]), float(r["ser"]))
|
||||||
for r in rows if r["method"] == mkey])
|
for r in rows if r["method"] == mkey])
|
||||||
@@ -459,11 +465,12 @@ def make_fig(args):
|
|||||||
if not pts:
|
if not pts:
|
||||||
continue
|
continue
|
||||||
xs, ys = zip(*pts)
|
xs, ys = zip(*pts)
|
||||||
ax.semilogy(xs, ys, label=LAB[mkey], ms=4, lw=1.3, **STY[mkey])
|
ax.semilogy(xs, ys, label=LAB[mkey], ms=5, lw=1.8, **STY[mkey])
|
||||||
ax.set_xlabel("SNR (dB)")
|
ax.set_xlabel("SNR (dB)")
|
||||||
ax.set_ylabel("SER")
|
ax.set_ylabel("SER")
|
||||||
ax.grid(True, which="both", alpha=0.35)
|
ax.grid(True, which="both", alpha=0.35)
|
||||||
ax.legend(fontsize=7.5, loc="center right", bbox_to_anchor=(0.985, 0.66))
|
ax.legend(fontsize=9, framealpha=1.0, labelspacing=0.3,
|
||||||
|
handlelength=1.8, loc="center right", bbox_to_anchor=(0.985, 0.66))
|
||||||
out = os.path.join(args.fig_dir,
|
out = os.path.join(args.fig_dir,
|
||||||
f"bert_ser_vs_snr_fd{args.eval_fd}.pdf")
|
f"bert_ser_vs_snr_fd{args.eval_fd}.pdf")
|
||||||
fig.savefig(out)
|
fig.savefig(out)
|
||||||
|
|||||||
Executable
+41
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Replot Fig. 4: demultiplexing-stage complexity ratio vs U/T,
|
||||||
|
# now including the signed user-wise attention variant.
|
||||||
|
#
|
||||||
|
# O_transformer = L * T * d * dff (FFN-dominated, L = 12 layers)
|
||||||
|
# O_softmax = U * d^2 + U^2 * d (key/value projections + scores)
|
||||||
|
# O_signed = U^2 * d + U^2 * 2h + h^2 (Gram + score network, h = 64)
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib
|
||||||
|
matplotlib.use("Agg")
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
T, L, d, h = 32, 12, 128, 64
|
||||||
|
U = np.arange(16, 65)
|
||||||
|
x = U / T
|
||||||
|
|
||||||
|
plt.rcParams.update({"font.size": 13, "axes.labelsize": 13,
|
||||||
|
"xtick.labelsize": 12, "ytick.labelsize": 12,
|
||||||
|
"axes.linewidth": 1.1, "grid.linewidth": 0.8,
|
||||||
|
"xtick.major.width": 1.1, "ytick.major.width": 1.1,
|
||||||
|
"xtick.minor.width": 0.8, "ytick.minor.width": 0.8,
|
||||||
|
"xtick.major.size": 4.5, "ytick.major.size": 4.5})
|
||||||
|
fig = plt.figure(figsize=(5.2, 3.9))
|
||||||
|
ax = fig.add_axes([0.155, 0.145, 0.82, 0.82])
|
||||||
|
colors = {1.0: "tab:blue", 0.5: "tab:orange", 0.25: "tab:green"}
|
||||||
|
for r in [1.0, 0.5, 0.25]: # r = d / dff
|
||||||
|
dff = d / r
|
||||||
|
o_tf = L * T * d * dff
|
||||||
|
o_soft = U * d ** 2 + U ** 2 * d
|
||||||
|
o_sgn = U ** 2 * d + U ** 2 * 2 * h + h ** 2
|
||||||
|
ax.plot(x, o_soft / o_tf, color=colors[r], ls="-", lw=1.9,
|
||||||
|
label=f"Softmax, $d/d_{{\\mathrm{{ff}}}}$={r:g}")
|
||||||
|
ax.plot(x, o_sgn / o_tf, color=colors[r], ls="--", lw=1.9,
|
||||||
|
label=f"Signed, $d/d_{{\\mathrm{{ff}}}}$={r:g}")
|
||||||
|
ax.set_yscale("log")
|
||||||
|
ax.set_xlabel(r"User-to-token ratio $U/T$")
|
||||||
|
ax.set_ylabel(r"$\mathcal{O}_{\mathrm{Attention}}/\mathcal{O}_{\mathrm{Transformer}}$")
|
||||||
|
ax.grid(True, which="both", alpha=0.35)
|
||||||
|
ax.legend(fontsize=9, ncol=2, loc="lower right")
|
||||||
|
fig.savefig("fig/complexity_ratio_vs_UT_dff.pdf")
|
||||||
|
print("saved fig/complexity_ratio_vs_UT_dff.pdf")
|
||||||
Reference in New Issue
Block a user