[refactor] move rbm.stack* + rbm.rnn_helper → stack/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+17
-17
@@ -18,7 +18,7 @@
|
||||
"source": [
|
||||
"import numpy as np_cpu\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from rbm.stack_rnn import StackRnn\n",
|
||||
"from stack.rnn import StackRnn\n",
|
||||
"from rbm.matrix import np, convert\n",
|
||||
"from rbm.entity import EntityParams, TrainingParams\n",
|
||||
"from rbm.status import CheckpointStatus"
|
||||
@@ -42,7 +42,7 @@
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# ── Configuration ─────────────────────────────────────────────────────────\n",
|
||||
"# \u2500\u2500 Configuration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
|
||||
"TEMPORAL_DEPTH = 16 # characters per training sequence (= number of RBMs)\n",
|
||||
"NUM_SEQ = 200 # training sequences (covers first 200k chars)\n",
|
||||
"CONTEXT_SIZE = 128 # recurrent hidden / context state size\n",
|
||||
@@ -73,12 +73,12 @@
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# ── Load text and build character vocabulary ───────────────────────────────\n",
|
||||
"# \u2500\u2500 Load text and build character vocabulary \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
|
||||
"with open(\"data/moby.txt\", \"r\", encoding=\"utf-8\") as f:\n",
|
||||
" raw = f.read()\n",
|
||||
"\n",
|
||||
"# Reduce vocabulary: uppercase letters, digits, and separating punctuation.\n",
|
||||
"# Lowercase → uppercase; everything else → space; collapse runs of spaces.\n",
|
||||
"# Lowercase \u2192 uppercase; everything else \u2192 space; collapse runs of spaces.\n",
|
||||
"import re\n",
|
||||
"ALLOWED = set(' .!?ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')\n",
|
||||
"text = raw.upper()\n",
|
||||
@@ -131,7 +131,7 @@
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# ── Encode text as one-hot sequences ──────────────────────────────────────\n",
|
||||
"# \u2500\u2500 Encode text as one-hot sequences \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
|
||||
"# Each training sequence is TEMPORAL_DEPTH consecutive characters encoded as\n",
|
||||
"# one-hot vectors. Non-overlapping; constants defined in Configuration.\n",
|
||||
"encoded = np_cpu.array([char_to_idx[c] for c in text], dtype=np_cpu.int32)\n",
|
||||
@@ -143,7 +143,7 @@
|
||||
"\n",
|
||||
"print(f\"sequences shape : {sequences.shape}\")\n",
|
||||
"print(f\"memory : {sequences.nbytes / 1e6:.1f} MB\")\n",
|
||||
"print(f\"covers chars : 0 – {NUM_SEQ * TEMPORAL_DEPTH - 1:,}\")"
|
||||
"print(f\"covers chars : 0 \u2013 {NUM_SEQ * TEMPORAL_DEPTH - 1:,}\")"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
@@ -152,7 +152,7 @@
|
||||
"text": [
|
||||
"sequences shape : (200, 16, 40)\n",
|
||||
"memory : 1.0 MB\n",
|
||||
"covers chars : 0 – 3,199\n"
|
||||
"covers chars : 0 \u2013 3,199\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -174,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# ── Build model ────────────────────────────────────────────────────────────\n",
|
||||
"# \u2500\u2500 Build model \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
|
||||
"# Unrolled mode: TEMPORAL_DEPTH separate RBMs, one per position in the sequence.\n",
|
||||
"# Each RBM_t has its own W_t, b_v_t, b_h_t.\n",
|
||||
"# visible_t = [context_{t-1} (CONTEXT_SIZE) | x_t (vocab_size)]\n",
|
||||
@@ -234,7 +234,7 @@
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# ── Train ──────────────────────────────────────────────────────────────────\n",
|
||||
"# \u2500\u2500 Train \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
|
||||
"# CheckpointStatus saves weights at every progress report.\n",
|
||||
"# Re-run this cell to continue training from the last checkpoint.\n",
|
||||
"status = CheckpointStatus(rnn.state_save, update_interval=5)\n",
|
||||
@@ -352,7 +352,7 @@
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# ── Generation helpers ─────────────────────────────────────────────────────\n",
|
||||
"# \u2500\u2500 Generation helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
|
||||
"\n",
|
||||
"def predict_next(rnn, context, n_gibbs=10, temperature=1.0):\n",
|
||||
" \"\"\"Return a character probability distribution conditioned on context.\n",
|
||||
@@ -435,7 +435,7 @@
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# ── Reconstruction accuracy (teacher-forced) ───────────────────────────────\n",
|
||||
"# \u2500\u2500 Reconstruction accuracy (teacher-forced) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
|
||||
"# At each step the model sees the true x_t, updates h_t, then reconstructs\n",
|
||||
"# x_t from h_t. This measures how well h_t retains the input, not prediction.\n",
|
||||
"EVAL_START = NUM_SEQ * TEMPORAL_DEPTH\n",
|
||||
@@ -482,7 +482,7 @@
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# ── Next-step prediction accuracy ─────────────────────────────────────────\n",
|
||||
"# \u2500\u2500 Next-step prediction accuracy \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
|
||||
"# Given context (= h_{t-1}), predict x_t before observing it.\n",
|
||||
"rnn.reset(batch_size=1)\n",
|
||||
"h = np.zeros((1, CONTEXT_SIZE))\n",
|
||||
@@ -534,7 +534,7 @@
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# ── Free text generation ───────────────────────────────────────────────────\n",
|
||||
"# \u2500\u2500 Free text generation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
|
||||
"for temp in [0.5, 1.0, 1.5]:\n",
|
||||
" print(f\"\\n{'='*60}\")\n",
|
||||
" print(f\"Temperature = {temp}\")\n",
|
||||
@@ -582,7 +582,7 @@
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# ── Hidden state trace ─────────────────────────────────────────────────────\n",
|
||||
"# \u2500\u2500 Hidden state trace \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
|
||||
"# Plot the hidden unit activations over one sequence to see what the RNN\n",
|
||||
"# has learned to track.\n",
|
||||
"rnn.reset(batch_size=1)\n",
|
||||
@@ -605,7 +605,7 @@
|
||||
"plt.colorbar(label='h activation')\n",
|
||||
"plt.xlabel('Time step (character)')\n",
|
||||
"plt.ylabel('Hidden unit (first 64)')\n",
|
||||
"plt.title(f'Hidden state trace — \"{seq_str[:50]}…\"')\n",
|
||||
"plt.title(f'Hidden state trace \u2014 \"{seq_str[:50]}\u2026\"')\n",
|
||||
"tick_pos = range(0, TEMPORAL_DEPTH, 5)\n",
|
||||
"plt.xticks(tick_pos, [seq_str[i] for i in tick_pos], fontsize=8)\n",
|
||||
"plt.tight_layout()\n",
|
||||
@@ -655,7 +655,7 @@
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# ── Character frequency: data vs model predictions ─────────────────────────\n",
|
||||
"# \u2500\u2500 Character frequency: data vs model predictions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
|
||||
"# Compare the character distribution in the training data to the distribution\n",
|
||||
"# the model assigns when conditioning on a fixed context.\n",
|
||||
"true_counts = np_cpu.bincount(eval_enc[:500].astype(int), minlength=vocab_size).astype(float)\n",
|
||||
@@ -730,4 +730,4 @@
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user