[refactor] move rbm.stack* + rbm.rnn_helper → stack/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 08:10:03 +02:00
co-authored by Claude Sonnet 4.6
parent b0d370a56b
commit 2da2262368
12 changed files with 56 additions and 58 deletions
+16 -16
View File
@@ -25,7 +25,7 @@
"\n", "\n",
"import numpy as np_cpu\n", "import numpy as np_cpu\n",
"import matplotlib.pyplot as plt\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.matrix import np, convert\n",
"from rbm.entity import EntityParams, TrainingParams\n", "from rbm.entity import EntityParams, TrainingParams\n",
"from rbm.status import CheckpointStatus" "from rbm.status import CheckpointStatus"
@@ -49,7 +49,7 @@
} }
}, },
"source": [ "source": [
"# ── Config ─────────────────────────────────────────────────────────────────\n", "# \u2500\u2500 Config \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",
"SENSORY_SIZE = 40 # numVisibleX * numVisibleY = 1 * 40\n", "SENSORY_SIZE = 40 # numVisibleX * numVisibleY = 1 * 40\n",
"CONTEXT_SIZE = 256 # numContext = numHidden\n", "CONTEXT_SIZE = 256 # numContext = numHidden\n",
"UNROLL_DEPTH = 1 # number of time-step entities (1 = shared weights)\n", "UNROLL_DEPTH = 1 # number of time-step entities (1 = shared weights)\n",
@@ -88,7 +88,7 @@
} }
}, },
"source": [ "source": [
"# ── Training sentence ──────────────────────────────────────────────────────\n", "# \u2500\u2500 Training sentence \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",
"SENTENCE = (\n", "SENTENCE = (\n",
" \"Call me Ishmael. Some years ago, never mind how long precisely, \"\n", " \"Call me Ishmael. Some years ago, never mind how long precisely, \"\n",
" \"having little money in my pocket and nothing particular to interest \"\n", " \"having little money in my pocket and nothing particular to interest \"\n",
@@ -135,7 +135,7 @@
} }
}, },
"source": [ "source": [
"# ── Visualise one-hot encoding ─────────────────────────────────────────────\n", "# \u2500\u2500 Visualise one-hot encoding \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",
"step = max(1, N_SAMPLES // 40) # show at most 40 tick labels\n", "step = max(1, N_SAMPLES // 40) # show at most 40 tick labels\n",
"tick_pos = range(0, N_SAMPLES, step)\n", "tick_pos = range(0, N_SAMPLES, step)\n",
"\n", "\n",
@@ -182,19 +182,19 @@
} }
}, },
"source": [ "source": [
"# ── Prepare sequences for StackRnn ─────────────────────────────────────────\n", "# \u2500\u2500 Prepare sequences for StackRnn \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",
"# Tile the single sentence N_REPEAT times to form a real batch so GPU/CPU\n", "# Tile the single sentence N_REPEAT times to form a real batch so GPU/CPU\n",
"# matrix ops are (N_REPEAT, 168) instead of (1, 168).\n", "# matrix ops are (N_REPEAT, 168) instead of (1, 168).\n",
"N_REPEAT = 500\n", "N_REPEAT = 500\n",
"sequences = np_cpu.tile(sensory_np[np_cpu.newaxis, :, :], (N_REPEAT, 1, 1))\n", "sequences = np_cpu.tile(sensory_np[np_cpu.newaxis, :, :], (N_REPEAT, 1, 1))\n",
"print(f\"sequences shape : {sequences.shape} {N_REPEAT} × {N_SAMPLES} chars\")" "print(f\"sequences shape : {sequences.shape} \u2192 {N_REPEAT} \u00d7 {N_SAMPLES} chars\")"
], ],
"outputs": [ "outputs": [
{ {
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"sequences shape : (500, 180, 40) → 500 × 180 chars\n" "sequences shape : (500, 180, 40) \u2192 500 \u00d7 180 chars\n"
] ]
} }
], ],
@@ -216,7 +216,7 @@
} }
}, },
"source": [ "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",
"rnn = StackRnn(PRJ_NAME, WORK_DIR)\n", "rnn = StackRnn(PRJ_NAME, WORK_DIR)\n",
"for layer in StackRnn.make_unrolled(\n", "for layer in StackRnn.make_unrolled(\n",
" UNROLL_DEPTH,\n", " UNROLL_DEPTH,\n",
@@ -247,7 +247,7 @@
"print(f\"Layers : {rnn.num_layers()} (alternating t % {rnn.num_layers()})\")\n", "print(f\"Layers : {rnn.num_layers()} (alternating t % {rnn.num_layers()})\")\n",
"print(f\"Visible : {rnn.h_size()} (context) + {rnn.sensory_size()} (sensory) = {e.shape[0]}\")\n", "print(f\"Visible : {rnn.h_size()} (context) + {rnn.sensory_size()} (sensory) = {e.shape[0]}\")\n",
"print(f\"Hidden : {rnn.h_size()}\")\n", "print(f\"Hidden : {rnn.h_size()}\")\n",
"print(f\"Parameters : {e.shape[0] * e.shape[1] * rnn.num_layers():,} ({rnn.num_layers()} × {e.shape[0] * e.shape[1]:,})\")" "print(f\"Parameters : {e.shape[0] * e.shape[1] * rnn.num_layers():,} ({rnn.num_layers()} \u00d7 {e.shape[0] * e.shape[1]:,})\")"
], ],
"outputs": [ "outputs": [
{ {
@@ -258,7 +258,7 @@
"Layers : 1 (alternating t % 1)\n", "Layers : 1 (alternating t % 1)\n",
"Visible : 256 (context) + 40 (sensory) = 296\n", "Visible : 256 (context) + 40 (sensory) = 296\n",
"Hidden : 256\n", "Hidden : 256\n",
"Parameters : 75,776 (1 × 75,776)\n" "Parameters : 75,776 (1 \u00d7 75,776)\n"
] ]
} }
], ],
@@ -279,10 +279,10 @@
} }
}, },
"source": [ "source": [
"# ── Train: predict next character from current context ─────────────────────\n", "# \u2500\u2500 Train: predict next character from current context \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
"# Unrolled layers alternate: layer[t % num_layers] owns each time-step position.\n", "# Unrolled layers alternate: layer[t % num_layers] owns each time-step position.\n",
"# Step 1 advance context: h_t = layer[t%D].forward([h_{t-1} | x_t])\n", "# Step 1 \u2014 advance context: h_t = layer[t%D].forward([h_{t-1} | x_t])\n",
"# Step 2 CD on [h_t | x_{t+1}] using the same layer[t%D]\n", "# Step 2 \u2014 CD on [h_t | x_{t+1}] using the same layer[t%D]\n",
"from rbm.train import cd_binary_binary, _to_gpu\n", "from rbm.train import cd_binary_binary, _to_gpu\n",
"from rbm.matrix import rms_error_accu\n", "from rbm.matrix import rms_error_accu\n",
"\n", "\n",
@@ -354,7 +354,7 @@
} }
}, },
"source": [ "source": [
"# ── Reconstruction: teacher-forced ─────────────────────────────────────────\n", "# \u2500\u2500 Reconstruction: 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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n",
"# Step through each sample, reconstruct, compare to input.\n", "# Step through each sample, reconstruct, compare to input.\n",
"rnn.reset(batch_size=1)\n", "rnn.reset(batch_size=1)\n",
"recons = []\n", "recons = []\n",
@@ -388,7 +388,7 @@
} }
}, },
"source": [ "source": [
"# ── Visualise reconstruction ───────────────────────────────────────────────\n", "# \u2500\u2500 Visualise reconstruction \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",
"step = max(1, N_SAMPLES // 40)\n", "step = max(1, N_SAMPLES // 40)\n",
"tick_pos = range(0, N_SAMPLES, step)\n", "tick_pos = range(0, N_SAMPLES, step)\n",
"\n", "\n",
@@ -430,7 +430,7 @@
} }
}, },
"source": [ "source": [
"# ── Next-step prediction ───────────────────────────────────────────────────\n", "# \u2500\u2500 Next-step prediction \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",
"# Given h_t (context after seeing x_t), predict x_{t+1} via clamped Gibbs.\n", "# Given h_t (context after seeing x_t), predict x_{t+1} via clamped Gibbs.\n",
"def predict_next(rnn, context, n_gibbs=NUM_GIBBS, temperature=1.0):\n", "def predict_next(rnn, context, n_gibbs=NUM_GIBBS, temperature=1.0):\n",
" entity = rnn.next_entity()\n", " entity = rnn.next_entity()\n",
+16 -16
View File
@@ -18,7 +18,7 @@
"source": [ "source": [
"import numpy as np_cpu\n", "import numpy as np_cpu\n",
"import matplotlib.pyplot as plt\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.matrix import np, convert\n",
"from rbm.entity import EntityParams, TrainingParams\n", "from rbm.entity import EntityParams, TrainingParams\n",
"from rbm.status import CheckpointStatus" "from rbm.status import CheckpointStatus"
@@ -42,7 +42,7 @@
} }
}, },
"source": [ "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", "TEMPORAL_DEPTH = 16 # characters per training sequence (= number of RBMs)\n",
"NUM_SEQ = 200 # training sequences (covers first 200k chars)\n", "NUM_SEQ = 200 # training sequences (covers first 200k chars)\n",
"CONTEXT_SIZE = 128 # recurrent hidden / context state size\n", "CONTEXT_SIZE = 128 # recurrent hidden / context state size\n",
@@ -73,12 +73,12 @@
} }
}, },
"source": [ "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", "with open(\"data/moby.txt\", \"r\", encoding=\"utf-8\") as f:\n",
" raw = f.read()\n", " raw = f.read()\n",
"\n", "\n",
"# Reduce vocabulary: uppercase letters, digits, and separating punctuation.\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", "import re\n",
"ALLOWED = set(' .!?ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')\n", "ALLOWED = set(' .!?ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')\n",
"text = raw.upper()\n", "text = raw.upper()\n",
@@ -131,7 +131,7 @@
} }
}, },
"source": [ "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", "# Each training sequence is TEMPORAL_DEPTH consecutive characters encoded as\n",
"# one-hot vectors. Non-overlapping; constants defined in Configuration.\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", "encoded = np_cpu.array([char_to_idx[c] for c in text], dtype=np_cpu.int32)\n",
@@ -143,7 +143,7 @@
"\n", "\n",
"print(f\"sequences shape : {sequences.shape}\")\n", "print(f\"sequences shape : {sequences.shape}\")\n",
"print(f\"memory : {sequences.nbytes / 1e6:.1f} MB\")\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": [ "outputs": [
{ {
@@ -152,7 +152,7 @@
"text": [ "text": [
"sequences shape : (200, 16, 40)\n", "sequences shape : (200, 16, 40)\n",
"memory : 1.0 MB\n", "memory : 1.0 MB\n",
"covers chars : 0 3,199\n" "covers chars : 0 \u2013 3,199\n"
] ]
} }
], ],
@@ -174,7 +174,7 @@
} }
}, },
"source": [ "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", "# 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", "# 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", "# visible_t = [context_{t-1} (CONTEXT_SIZE) | x_t (vocab_size)]\n",
@@ -234,7 +234,7 @@
} }
}, },
"source": [ "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", "# CheckpointStatus saves weights at every progress report.\n",
"# Re-run this cell to continue training from the last checkpoint.\n", "# Re-run this cell to continue training from the last checkpoint.\n",
"status = CheckpointStatus(rnn.state_save, update_interval=5)\n", "status = CheckpointStatus(rnn.state_save, update_interval=5)\n",
@@ -352,7 +352,7 @@
} }
}, },
"source": [ "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", "\n",
"def predict_next(rnn, context, n_gibbs=10, temperature=1.0):\n", "def predict_next(rnn, context, n_gibbs=10, temperature=1.0):\n",
" \"\"\"Return a character probability distribution conditioned on context.\n", " \"\"\"Return a character probability distribution conditioned on context.\n",
@@ -435,7 +435,7 @@
} }
}, },
"source": [ "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", "# 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", "# x_t from h_t. This measures how well h_t retains the input, not prediction.\n",
"EVAL_START = NUM_SEQ * TEMPORAL_DEPTH\n", "EVAL_START = NUM_SEQ * TEMPORAL_DEPTH\n",
@@ -482,7 +482,7 @@
} }
}, },
"source": [ "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", "# Given context (= h_{t-1}), predict x_t before observing it.\n",
"rnn.reset(batch_size=1)\n", "rnn.reset(batch_size=1)\n",
"h = np.zeros((1, CONTEXT_SIZE))\n", "h = np.zeros((1, CONTEXT_SIZE))\n",
@@ -534,7 +534,7 @@
} }
}, },
"source": [ "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", "for temp in [0.5, 1.0, 1.5]:\n",
" print(f\"\\n{'='*60}\")\n", " print(f\"\\n{'='*60}\")\n",
" print(f\"Temperature = {temp}\")\n", " print(f\"Temperature = {temp}\")\n",
@@ -582,7 +582,7 @@
} }
}, },
"source": [ "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", "# Plot the hidden unit activations over one sequence to see what the RNN\n",
"# has learned to track.\n", "# has learned to track.\n",
"rnn.reset(batch_size=1)\n", "rnn.reset(batch_size=1)\n",
@@ -605,7 +605,7 @@
"plt.colorbar(label='h activation')\n", "plt.colorbar(label='h activation')\n",
"plt.xlabel('Time step (character)')\n", "plt.xlabel('Time step (character)')\n",
"plt.ylabel('Hidden unit (first 64)')\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", "tick_pos = range(0, TEMPORAL_DEPTH, 5)\n",
"plt.xticks(tick_pos, [seq_str[i] for i in tick_pos], fontsize=8)\n", "plt.xticks(tick_pos, [seq_str[i] for i in tick_pos], fontsize=8)\n",
"plt.tight_layout()\n", "plt.tight_layout()\n",
@@ -655,7 +655,7 @@
} }
}, },
"source": [ "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", "# Compare the character distribution in the training data to the distribution\n",
"# the model assigns when conditioning on a fixed context.\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", "true_counts = np_cpu.bincount(eval_enc[:500].astype(int), minlength=vocab_size).astype(float)\n",
+1 -1
View File
@@ -21,4 +21,4 @@ readme = "README.md"
[tool.setuptools] [tool.setuptools]
package-dir = {"" = "src"} package-dir = {"" = "src"}
packages = ["rbm", "image"] packages = ["rbm", "image", "stack"]
View File
+4 -4
View File
@@ -1,7 +1,7 @@
from .status import Status from rbm.status import Status
from .train import train from rbm.train import train
from .stack import Stack, StackType from stack.stack import Stack, StackType
from .matrix import Mat, np from rbm.matrix import Mat, np
class StackDeep(Stack): class StackDeep(Stack):
def __init__(self, name: str, work_dir: str = '.'): def __init__(self, name: str, work_dir: str = '.'):
@@ -1,9 +1,9 @@
import json import json
from .stack import StackType from stack.stack import StackType
from .layer import Layer from rbm.layer import Layer
from .entity import EntityParams, TrainingParams from rbm.entity import EntityParams, TrainingParams
from .stack_deep import StackDeep from stack.deep import StackDeep
from .stack_rnn import StackRnn from stack.rnn import StackRnn
class StackFactory: class StackFactory:
@classmethod @classmethod
+6 -7
View File
@@ -1,11 +1,10 @@
import numpy as _np_cpu import numpy as _np_cpu
from .status import Status from rbm.status import Status
from .train import _to_gpu, cd_binary_binary, cd_gaussian_binary, cd_gaussian_gaussian, cd_binary_gaussian from rbm.train import _to_gpu, cd_binary_binary, cd_gaussian_binary, cd_gaussian_gaussian, cd_binary_gaussian
from .stack import Stack, StackType from stack.stack import Stack, StackType
from .matrix import Mat, np, rms_error_accu, convert from rbm.matrix import Mat, np, rms_error_accu, convert
from .entity import Entity from rbm.entity import Entity, EntityParams, TrainingParams
from .layer import Layer from rbm.layer import Layer
from .entity import EntityParams, TrainingParams
_CD_FUNC = { _CD_FUNC = {
Entity.Type.BB_RBM: cd_binary_binary, Entity.Type.BB_RBM: cd_binary_binary,
@@ -38,4 +38,3 @@ def clamp_one_hot(src_dst: np.ndarray) -> np.ndarray:
class Rnn: class Rnn:
def __init__(self): def __init__(self):
pass pass
+1 -1
View File
@@ -1,6 +1,6 @@
import os import os
from enum import Enum from enum import Enum
from .layer import Layer from rbm.layer import Layer
class StackType(Enum): class StackType(Enum):
Deep = "Deep", Deep = "Deep",
+2 -2
View File
@@ -1,9 +1,9 @@
import os.path import os.path
import cv2 as cv import cv2 as cv
from argparse import ArgumentParser from argparse import ArgumentParser
from rbm.stack_factory import StackFactory from stack.factory import StackFactory
from rbm.status import Status from rbm.status import Status
from rbm.stack_deep import StackDeep from stack.deep import StackDeep
from rbm.matrix import Mat, np, convert, read_armadillo from rbm.matrix import Mat, np, convert, read_armadillo
from rbm.entity import Entity from rbm.entity import Entity
+1 -1
View File
@@ -1,6 +1,6 @@
"""Tests for StackRnn — shared-weights and unrolled (own-weights) modes.""" """Tests for StackRnn — shared-weights and unrolled (own-weights) modes."""
import numpy as _np_cpu import numpy as _np_cpu
from rbm.stack_rnn import StackRnn from stack.rnn import StackRnn
from rbm.matrix import np, convert from rbm.matrix import np, convert
from rbm.entity import EntityParams, TrainingParams from rbm.entity import EntityParams, TrainingParams
from rbm.status import Status from rbm.status import Status
+1 -1
View File
@@ -1,6 +1,6 @@
import numpy as np import numpy as np
import pytest import pytest
from rbm.rnn_helper import shift_right, shift_left, shift_up, shift_down, ch2idx, idx2ch, VOCAB from stack.rnn_helper import shift_right, shift_left, shift_up, shift_down, ch2idx, idx2ch, VOCAB
M = np.array([ M = np.array([
[1, 2, 3], [1, 2, 3],