{
"cells": [
{
"cell_type": "markdown",
"id": "589a68f2",
"metadata": {
"papermill": {
"duration": 0.004049,
"end_time": "2026-06-03T14:03:17.294782+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:17.290733+00:00",
"status": "completed"
},
"tags": []
},
"source": [
"# Convolution Tutorial Series — Part 3: Stride"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "36944e5e",
"metadata": {
"_kg_hide-input": true,
"execution": {
"iopub.execute_input": "2026-06-03T14:03:17.303408Z",
"iopub.status.busy": "2026-06-03T14:03:17.302856Z",
"iopub.status.idle": "2026-06-03T14:03:17.356423Z",
"shell.execute_reply": "2026-06-03T14:03:17.355275Z"
},
"jupyter": {
"source_hidden": true
},
"papermill": {
"duration": 0.065354,
"end_time": "2026-06-03T14:03:17.363675+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:17.298321+00:00",
"status": "completed"
},
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
""
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.display import Video\n",
"\n",
"video_path = '/kaggle/input/datasets/massimilianoghiotto/neurogolf-convseries-part3-supportvideo/ConvTask149.mp4'\n",
"\n",
"Video(video_path, width=750, height=450, embed=True)"
]
},
{
"cell_type": "markdown",
"id": "4f543be9",
"metadata": {
"papermill": {
"duration": 0.007325,
"end_time": "2026-06-03T14:03:17.379587+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:17.372262+00:00",
"status": "completed"
},
"tags": []
},
"source": [
"**Goal:** Understand the **stride** attribute in the convolution. This is the third episode in our series covering the ONNX Conv function. We will explain these concepts simply using ARC tasks as examples. The previous episodes covered [Kernel Size & Bias](https://www.kaggle.com/code/massimilianoghiotto/convolution-series-part-1) and [Padding](https://www.kaggle.com/code/massimilianoghiotto/convolution-series-part-2).\n",
"\n",
"**Task (ARC 149):**\n",
"1. **Grid Analysis:** The input is an 11x11 grid divided by gray (8) lines into a 3x3 arrangement of 3x3 blocks.\n",
"2. **The Rule:** For each 3x3 block, count the number of pink (6) pixels.\n",
"3. **The Output:** If a block contains 2 or more pink pixels, the corresponding output pixel is blue (1). Otherwise, it is black (0).\n",
"\n",
"**Our approach:** Use a single Conv layer with **stride 4** to jump directly from one 3x3 block to the next, skipping the separator lines.\n",
"\n",
"**Score formula:** `Points = max(1.0, 25.0 - log(Mem_bytes + Params))`\n",
"\n",
"**Our result:** Mem=340, Params=97, **18.920 points**\n",
"\n",
"---"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "d17c823b",
"metadata": {
"execution": {
"iopub.execute_input": "2026-06-03T14:03:17.396671Z",
"iopub.status.busy": "2026-06-03T14:03:17.395668Z",
"iopub.status.idle": "2026-06-03T14:03:43.520523Z",
"shell.execute_reply": "2026-06-03T14:03:43.519254Z"
},
"papermill": {
"duration": 26.136169,
"end_time": "2026-06-03T14:03:43.522980+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:17.386811+00:00",
"status": "completed"
},
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m16.6/16.6 MB\u001b[0m \u001b[31m55.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\r\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m17.2/17.2 MB\u001b[0m \u001b[31m52.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\r\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m56.2/56.2 kB\u001b[0m \u001b[31m751.9 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\r\n",
"\u001b[?25h"
]
}
],
"source": [
"!pip install -q numpy==2.4.4 2>/dev/null\n",
"!pip install -q onnx==1.21.0 2>/dev/null\n",
"!pip install -q onnxruntime==1.24.4 2>/dev/null\n",
"!pip install -q onnx-tool==1.0.1 2>/dev/null"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "ca82556b",
"metadata": {
"_kg_hide-input": true,
"execution": {
"iopub.execute_input": "2026-06-03T14:03:43.544109Z",
"iopub.status.busy": "2026-06-03T14:03:43.543578Z",
"iopub.status.idle": "2026-06-03T14:03:44.045290Z",
"shell.execute_reply": "2026-06-03T14:03:44.044128Z"
},
"jupyter": {
"source_hidden": true
},
"papermill": {
"duration": 0.514202,
"end_time": "2026-06-03T14:03:44.047588+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:43.533386+00:00",
"status": "completed"
},
"tags": []
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAv8AAAGCCAYAAAB3r6ygAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAASdAAAEnQB3mYfeAAAII5JREFUeJzt3X+QXXV9N/DPhs3NT3c3P7nZEPYGlB8VYqIReSYJiWlrSxgaf1Qr1jZGIBUex9GHGWI6E0iQ0kjASCli9SGATy3lZ4OopFhN45Y6ghaUUlTQLE1c1oRdsoEEs0Tu80fc212yyf5IuF/I9/Wa2ZnLveee9/ecs7nnzTlnz60pl8vlAAAAjnrDUg8AAACoDuUfAAAyofwDAEAmlH8AAMiE8g8AAJlQ/gEAIBPKPwAAZEL5BwCATCj/AACQCeUfAAAyofwDAEAmlH9e1x5++OGoqamJmpqaePDBB1MPp2p2794d48aNi5qamli7dm3q4QDwW+VyOU4//fSoqamJCy+8MPVwDvDVr341ampqYuTIkbFt27bUwyEB5f8otmrVqkox/shHPpJ6OAd1yy23xKpVq2LVqlWxc+fOQb135cqVERHx9re/PebMmVN5/kc/+lFcfPHFMXPmzKitra2sh1tuuaXP+Vx77bVx7rnnxsSJEyvTlkqlIS7R/7j33nvjwx/+cJxwwgmV+dbU1ERLS8sB03Z0dMSKFSti/vz5MXr06ENuuzFjxlR2KmvXro0XXnjhsMcKMBSlUqnX59uhfv71X/819XAH5NFHH63slwY75ttvvz3+8z//MyIiPvnJT1ae37ZtW5x//vkxY8aMmDBhQtTW1sa4ceNizpw5ccMNN8RvfvObIY93zZo1sWDBgmhsbIwRI0bEqFGj4uSTT46Pf/zjBxT8D3zgA9HY2Bh79+6Nv/qrvxpyJq9jZY5al19+eTkiyhFRXrJkSerhHNT8+fMr49yyZcuA3/fYY49V3vfFL36x12vr1q2rvNbz5+abb+5zXvX19QdM29TUNPSF+q3Fixf3OY6+lvORRx7pc9qDbbuf/vSnlWmuv/76wx4rwFA0NTX1+dnV18+mTZtSD3dAbr755sqYL7/88kG9921ve1s5Ispnnnlmr+ebm5sPuW6WLVs25PGeeOKJB53vlClTys8++2yv6VesWFGOiHKhUCi3t7cPOZfXJ0f+ed26+eabIyJi2LBh8Z73vKfXaw0NDXHuuefGVVdd1euMwMHMnDkzLrroorjqqquO6BiPP/74+NM//dO44YYboqGh4ZDTFgqFOOuss+LTn/50fPSjH+133ieddFK8+c1vjog46BkNgFfbXXfdFc3NzZWfYrFYee1v/uZver02a9asw87bvXv3Yc/j1fLYY4/FD3/4w4iIeN/73tfrtTFjxsSHP/zhuOmmm+Kf//mf4957741zzjmn8vr69euHvGxz586Nq6++OjZs2BDf+ta34sorr4zhw4dHRMQzzzwTd911V6/p3/ve90ZERFdXV/zDP/zDkDJ5HUv9fx+8eg525L/n8+vXry+vW7eufOKJJ5YLhUJ5xowZ5W9/+9u95tPzyPyPf/zj8sUXX1yeOHFiefTo0eVzzjmn/NRTT/WavnvaVx45f+UR/k2bNh3yKEh/ZwGmT59ejojyrFmzDjndn/zJn/R75L/bE088ccgj/6tXr668fskll1Sev/322yvP/8Ef/EGf8z722GMHvGw33njjgM7afPKTn6xM99///d+HnCdANfQ8E9DzSP+2bdvKS5cuLc+YMaM8YcKEcm1tbXncuHHld77zneV/+qd/6jWPnvuHJUuWlO++++7yW97ylnKhUKgcif/Nb35TXr16dXnq1KnlUaNGlRcsWFB+5JFHDnk2ecOGDeXf/d3fLTc0NJQLhUL5pJNOKq9ataq8Z8+ePsf/yp/+zgL03Ef86Ec/6nddPffcc73mv2PHjgPmM9h9TbeeZ57Xrl17wOvjxo0rR0R54cKF/Y6To4vyfxQbSPk/4YQTDvhwe8Mb3lDu6OioTN/zg/Tkk08+YPqpU6f2OqVYjfLf2tpame78888/5Ho4kuX/pZdeKs+aNascEeXa2tryo48+Wu7o6KgU+/r6+vLWrVv7nPerUf6/8pWvVKa77bbbDjlPgGo4WPn/3ve+d8jP/FtvvbUybc/9w/Tp08s1NTUHFPBPfOITB8yjvr6+XCqV+vysXbly5UGz582bV967d+8B4x9s+X/Xu95VjojyyJEjyy+99NJBp3v55ZfLO3bs6FXyTzvttMrrh7Ov2bNnT3nTpk3lSZMmVeb9gx/84IDpFi5cWI6I8pgxY8r79u075HJxdHHZT+Z+8YtfxPLly+NrX/tavOUtb4mIiOeff/6gpwHb29vj5ptvjjvvvDNOOOGEiIj45S9/OaTLZWbNmhXNzc0xc+bMynN33nln5fTwlClTDvreJ554ovL4jW9846Czh6q2tjZuueWWKBQKsW/fvli2bFlccskl8atf/SoiIq677ro47rjjqjaensv+X//1X1XLBRisYrEYa9asibvvvjv+5V/+JTZt2hS33nprTJo0KSIirrzyyj7ft2XLlpg9e3bceeedsWHDhpg3b1789Kc/jeuvvz4i9l/6edlll8V9990XZ5xxRp83VHj44YfjM5/5TERETJkyJW666abYuHFj5bKb5ubmWLduXUTsv4zpL//yLyvvXbp0aWW/1N8lmd37pqampqitre1zmg9+8IMxbNiwmDRpUlx++eURsf+ynXvuuacyzVD2NRs3boyampoYPXp0vPOd74wdO3ZEsViM9evXx9ve9rYDxtG9/9i9e3c8/fTTh1wuji59/2aSjcWLF8eaNWsiImLPnj3xwQ9+MCIinnrqqT6n/+u//uvK3WcaGhri93//9yMiYsOGDXHttdcOKru+vj7mzp0b9fX1ledmz549oLvsPPvss5XH48aNG1Tu4ZoxY0asXLkyVq5cGQ899FA89NBDERFx7rnnxpIlS6o6lp7L3nOdALzWlEqlKBaL8fnPfz4ee+yx6OzsjHK5XHn9ySefjF27dkVdXV2v940dOzY2btwY48ePrzx39dVXV977nve8J1avXh0REXPmzImpU6fGiy++2GseX/3qVyuPly5dGieddFJERHzsYx+Lb3zjGxER8fd///exfPnymD17duVuPRH7/3Zr7ty5A1rG7s/hwe6Xhg8ffsDdfo7Evmb48OHx8ssv9/naK/cf3Qf0OPo58p+5+fPnVx5PmDCh8vhgt9x8xzveUXl8xhlnVB63tLT0+hCvphS5n/70p3udsaivr48vfelLVR9HqnUOMFjr1q2Lj3zkI9Hc3Bw7d+7s8/Orr33PnDlzehX/iP1nrbv13C+NGzcuTjnllAPm8bOf/azy+Kqrrop58+bFvHnz4txzz608/5Of/GRQy3Moh/psXr16dWzevDnuuOOOWLRoUUREbNq0KX7v934vfv3rX/eadjD7mjPPPDOam5vjG9/4Rlx22WUxYsSI2Lp1a1xwwQXx9a9/fVBj5Oim/Geu5//59zxFOZAPhZqamkO+/sqjGEfyyPTEiRMrj5977rkjNt+B6uzsjGeeeaby388//3yfp5pfbT2Xvec6AXit6b5MJyLi0ksvjW9/+9vR3Nwcp59+euX5vo5SH3vssYecb3/7ooHat29f7N2797Dm0f05fKj90sknnxxnnXVWvP/974/77rsvpk+fHhH7L6H97ne/22vawexrGhoaYu7cubFo0aJYvXp1LF++vPJaX5fy2n/kS/lnULpPO0ZEfP/736887v6Sl4ioXMbT3t4eL730UkTsPzNwsKMqw4b9z6/hwU5PvtKpp55aeXywS5ReTR//+Mcr114ec8wx8fLLL8fSpUsPOGrzauu57L/zO79T1WyAwfjlL38ZEfvPMn/2s5+NhQsXxqxZsyrPH0xf5f7EE0+sPH744Ycrj5977rk+9zXdl/lE7L9NdHn/DU96/ezevTtGjBgREUPbL0X8z77p6aefjn379vV67ZWXIvXllWc+BrKvOdh8e663vs6odO8/xowZE01NTf2OjaOHa/4ZlBUrVkRtbW2MGTMmVqxYUXl+8eLFlcdvfOMb44c//GG8+OKL8aEPfSjOOuus+MIXvnDQby/sefbhy1/+cixatChGjRoVs2fPPug4pkyZEtOnT48tW7bEf/zHfxzw+tNPP13ZIfT8dsMf/OAHMXbs2IiIWLRoUYwePToiIu6///7YvXt3tLa2Vqbds2dP5d7IpVKpMp577rkn/vEf/zEi9t/HeebMmbFy5cr4yU9+EitXroy1a9f2yus+StPziNL9998fkyZNijFjxsTZZ59dyfvmN78ZERGPPPJIr2XpHsfb3/72Xh/SPacbyPcZAKTS1NQUTz75ZLS3t8eaNWtixowZcd1110VHR8eg57V48eJYvnx5lMvluPvuu+Mzn/lMvPWtb43rrruuzzL8oQ99KK677rqIiPjUpz4VHR0dMWPGjNi5c2f8/Oc/jwceeCCamppi/fr1EdF7v7Rx48Y466yzYuTIkXH66af3+ju1V5ozZ0488MADsXfv3nj88ccrN9LoHnP338qVSqXYtWtX3HrrrbFly5aI2F/We34PwkD3Nbfffnt8/vOfj/POOy9OOeWUGDlyZHz/+9+Pz372s5V5vfWtbz1grI8++mhE7L9s6phjjjn0CufokuAOQ1TJQG712fPWl6+8r3K3nrfonDFjxgG3PpsyZUp5+/btlen/7u/+7oBpxo4dWz7uuOP6vP3a9ddf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\n",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import json, warnings, os, sys\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib.patches as patches\n",
"import onnx\n",
"from onnx import helper, TensorProto, numpy_helper\n",
"import onnxruntime as ort\n",
"\n",
"warnings.filterwarnings('ignore')\n",
"plt.rcParams['figure.dpi'] = 120\n",
"\n",
"arc_colors = [\n",
" '#000000', '#0074D9', '#FF4136', '#2ECC40', '#FFDC00', \n",
" '#AAAAAA', '#F012BE', '#FF851B', '#7FDBCA', '#870C25'\n",
"]\n",
"\n",
"def plot_arc_grid(grid, ax, title=''):\n",
" H, W = len(grid), len(grid[0])\n",
" img = np.zeros((H, W, 3), dtype=np.uint8)\n",
" for r in range(H):\n",
" for c in range(W):\n",
" hex_c = arc_colors[grid[r][c]].lstrip('#')\n",
" img[r,c] = [int(hex_c[i:i+2], 16) for i in (0, 2, 4)]\n",
" ax.imshow(img, interpolation='nearest')\n",
" ax.set_xticks([]); ax.set_yticks([])\n",
" if title: ax.set_title(title, fontsize=10, fontweight='bold')\n",
" for r in range(H+1): ax.axhline(r-0.5, color='gray', lw=0.5, alpha=0.3)\n",
" for c in range(W+1): ax.axvline(c-0.5, color='gray', lw=0.5, alpha=0.3)\n",
"\n",
"with open('/kaggle/input/competitions/neurogolf-2026/task149.json') as f:\n",
" task = json.load(f)\n",
"\n",
"fig, axes = plt.subplots(1, 2, figsize=(8, 4))\n",
"plot_arc_grid(task['train'][0]['input'], axes[0], 'Input (11x11)')\n",
"plot_arc_grid(task['train'][0]['output'], axes[1], 'Target (3x3)')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "5055e255",
"metadata": {
"papermill": {
"duration": 0.008842,
"end_time": "2026-06-03T14:03:44.065647+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:44.056805+00:00",
"status": "completed"
},
"tags": []
},
"source": [
"# 1. What is the Stride?\n",
"\n",
"Stride determines how many pixels the kernel moves after each computation. \n",
"- **Stride 1 (Default):** The kernel moves 1 pixel at a time. Every possible window is checked.\n",
"- **Stride > 1:** The kernel \"skips\" pixels. This reduces the output resolution.\n",
"\n",
"In Task 149, we have 3x3 blocks separated by a single line of gray pixels. \n",
"- Block 1 starts at `(0,0)` and ends at `(2,2)`.\n",
"- The next block starts at `(0,4)`.\n",
"- To jump from the start of Block 1 to the start of Block 2, we need a **stride of 4**.\n",
"- The same regularity holds vertically.\n",
"\n",
"By setting `strides=[4, 4]`, our 3x3 kernel will land exactly on the 9 relevant blocks and ignore the separator lines entirely!"
]
},
{
"cell_type": "markdown",
"id": "7e5e7b70",
"metadata": {
"papermill": {
"duration": 0.008598,
"end_time": "2026-06-03T14:03:44.083001+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:44.074403+00:00",
"status": "completed"
},
"tags": []
},
"source": [
"# 2. The Model Design\n",
"\n",
"### Step 1: Count Pink Pixels\n",
"We use a `Conv` layer with:\n",
"- **Kernel 3x3:** To match the block size.\n",
"- **Stride 4x4:** To jump over the gray lines.\n",
"- **Weights:** A single channel that sums pink (channel 6) pixels, so W is of dimensions [1, 10, 3, 3] with $W[0, 6, i, j] = 1.0$ for every i, j = 0, 1, 2 and zero otherwise.\n",
"- **Bias:** Set to `-1.5`. \n",
" - If count = 0 or 1, `count - 1.5` is **negative**.\n",
" - If count $\\ge$ 2, `count - 1.5` is **positive**.\n",
"\n",
"This creates a 3x3 \"score map\" where positive values mean \"At least 2 pink pixels found\".\n",
"\n",
"### Step 2: Channel Expansion and Padding\n",
"The competition expects a 10-channel 30x30 grid as input and output. We use four nodes to explain how this is assembled:\n",
"1. **Slice:**: Since the input is 30x30 we compute some extra zero values (see Section 3) that we eliminate with a single slice.\n",
"2. **Neg:** Creates the negative of our score map (for channel 0, the black background).\n",
"3. **Concat:** Combines the negative map (ch0) and the original map (ch1) into a 2-channel 3x3 tensor.\n",
"4. **Pad:** We pad the 2-channel 3x3 tensor on both the **channel dimension** (adding 8 empty channels to reach 10) and the **spatial dimensions** (adding 27 pixels to reach 30x30)."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "2ab1ea38",
"metadata": {
"_kg_hide-input": true,
"execution": {
"iopub.execute_input": "2026-06-03T14:03:44.102672Z",
"iopub.status.busy": "2026-06-03T14:03:44.102136Z",
"iopub.status.idle": "2026-06-03T14:03:44.116873Z",
"shell.execute_reply": "2026-06-03T14:03:44.115937Z"
},
"jupyter": {
"source_hidden": true
},
"papermill": {
"duration": 0.032331,
"end_time": "2026-06-03T14:03:44.124058+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:44.091727+00:00",
"status": "completed"
},
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"video_path = '/kaggle/input/datasets/massimilianoghiotto/neurogolf-convseries-part3-supportvideo/ConvTask149.mp4'\n",
"\n",
"Video(video_path, width=750, height=450, embed=True)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "266ba1f1",
"metadata": {
"execution": {
"iopub.execute_input": "2026-06-03T14:03:44.155913Z",
"iopub.status.busy": "2026-06-03T14:03:44.155411Z",
"iopub.status.idle": "2026-06-03T14:03:44.167056Z",
"shell.execute_reply": "2026-06-03T14:03:44.166193Z"
},
"papermill": {
"duration": 0.029947,
"end_time": "2026-06-03T14:03:44.168959+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:44.139012+00:00",
"status": "completed"
},
"tags": []
},
"outputs": [],
"source": [
"def create_task149_model():\n",
" # Setup Input/Output infos\n",
" X = helper.make_tensor_value_info(\"input\", TensorProto.FLOAT, [1, 10, 30, 30])\n",
" Y = helper.make_tensor_value_info(\"output\", TensorProto.FLOAT, [1, 10, 30, 30])\n",
"\n",
" # Weights: Sum pink (ch6) over 3x3 windows\n",
" w_conv = np.zeros((1, 10, 3, 3), dtype=np.float32)\n",
" w_conv[0, 6, :, :] = 1.0\n",
" b_conv = np.array([-1.5], dtype=np.float32)\n",
" \n",
" # Parameters for the slice\n",
" starts = np.array([0, 0], dtype=np.int64)\n",
" ends = np.array([3, 3], dtype=np.int64)\n",
" axes = np.array([2, 3], dtype=np.int64)\n",
"\n",
" nodes = [\n",
" # The Stride Magic: Jump every 4 pixels\n",
" helper.make_node(\"Conv\", [\"input\", \"w_conv\", \"b_conv\"], [\"counts\"],\n",
" kernel_shape=[3, 3], strides=[4, 4], pads=[0, 0, 0, 0]),\n",
"\n",
" # Slice to the active input\n",
" helper.make_node(\"Slice\", [\"counts\", \"starts\", \"ends\", \"axes\"], [\"r3\"]),\n",
" \n",
" # Logical Negation for Channel 0 (Background)\n",
" helper.make_node(\"Neg\", [\"r3\"], [\"neg_counts\"]),\n",
" \n",
" # Assemble active channels (0=Black, 1=Blue)\n",
" helper.make_node(\"Concat\", [\"neg_counts\", \"r3\"], [\"r2\"], axis=1),\n",
" \n",
" # Pad to 10 channels AND 30x30 spatial size in one go!\n",
" # pads format: [n_begin, c_begin, h_begin, w_begin, n_end, c_end, h_end, w_end]\n",
" helper.make_node(\"Pad\", [\"r2\"], [\"output\"], mode=\"constant\", value=0.0,\n",
" pads=[0, 0, 0, 0, 0, 8, 27, 27])\n",
" ]\n",
"\n",
" graph = helper.make_graph(nodes, \"stride_demo\", [X], [Y], initializer=[\n",
" numpy_helper.from_array(w_conv, name=\"w_conv\"),\n",
" numpy_helper.from_array(b_conv, name=\"b_conv\"),\n",
" numpy_helper.from_array(starts, name=\"starts\"),\n",
" numpy_helper.from_array(ends, name=\"ends\"),\n",
" numpy_helper.from_array(axes, name=\"axes\"),\n",
" ])\n",
" \n",
" model = helper.make_model(graph, opset_imports=[helper.make_operatorsetid(\"\", 10)])\n",
" return model\n",
"\n",
"model = create_task149_model()\n",
"onnx.save(model, \"stride_tutorial.onnx\")"
]
},
{
"cell_type": "markdown",
"id": "3aeb399e",
"metadata": {
"papermill": {
"duration": 0.013448,
"end_time": "2026-06-03T14:03:44.195678+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:44.182230+00:00",
"status": "completed"
},
"tags": []
},
"source": [
"# 3. The Output Shape Formula\n",
"\n",
"When using stride, the output size is calculated as:\n",
"\n",
"$$Output = \\left\\lfloor \\frac{Input + 2 \\cdot Padding - Kernel}{Stride} \\right\\rfloor + 1$$\n",
"\n",
"For Task 149:\n",
"- Input = 30\n",
"- Padding = 0\n",
"- Kernel = 3\n",
"- Stride = 4\n",
"\n",
"$$Output = \\left\\lfloor \\frac{30 + 0 - 3}{4} \\right\\rfloor + 1 = \\left\\lfloor \\frac{27}{4} \\right\\rfloor + 1 = 6 + 1 = 7$$\n",
"\n",
"The output is a 7x7 grid, with extra zero values outside the top-left 3x3 square."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "cd490bc0",
"metadata": {
"_kg_hide-input": true,
"execution": {
"iopub.execute_input": "2026-06-03T14:03:44.226627Z",
"iopub.status.busy": "2026-06-03T14:03:44.226238Z",
"iopub.status.idle": "2026-06-03T14:03:44.560311Z",
"shell.execute_reply": "2026-06-03T14:03:44.559409Z"
},
"jupyter": {
"source_hidden": true
},
"papermill": {
"duration": 0.352922,
"end_time": "2026-06-03T14:03:44.562321+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:44.209399+00:00",
"status": "completed"
},
"tags": []
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABHQAAAF4CAYAAAA19q5qAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAASdAAAEnQB3mYfeAAALSZJREFUeJzt3XuYVXW9P/DP4DAzIHdGnFBgvKB5jqF4g3PA8GhKikcsPZq3kLwcb8dKK8MeFbWUbt46WlmgaKUmJmSSqR1SzkklPWnUk2nGeNBx5CaYIYzI+v3Bb3YzzIWZcdyLL/N6Pc88z569116f79pr7+937/dee31LsizLAgAAAIBk9Mi7AQAAAAB0jEAHAAAAIDECHQAAAIDECHQAAAAAEiPQAQAAAEiMQAcAAAAgMQIdAAAAgMQIdAAAAAASI9ABAAAASIxABwAAACAxAh0AAACAxAh0AAAiIsuy+NCHPhQlJSVx1lln5d2cZn74wx9GSUlJVFRUxCuvvJJ3c4Ct2Omnnx4lJSVRUlISv/rVrwrXN1xXXV3d5TWnT59eWP/tt9/e5evvjEmTJkVJSUkcfvjheTel3bpqHz388MMxZsyY6Nu3b2Gdq1ev7pI25iXLsthzzz2jpKQkzj///Lybs1UQ6PC+a9y5n3766Xk3p0W33357TJ8+PaZPn558RwfQXtXV1YX+eUt/jT8QbM2effbZQn/e0Tbfc8898fvf/z4iIj7zmc8Urn/llVfijDPOiFGjRsXgwYOjtLQ0Bg4cGOPGjYubb7453n333U63d8aMGXHIIYfE0KFDo7y8PHr16hV77rlnXHDBBc1CmxNOOCGGDh0a69evj6985Sudrgl0ncbvcxv/9e/fP8aNGxczZ86MLMvybmaXWL16daF/3VoCm7Y8+eSTMX/+/Ij4e5/eOOja0t/06dPza/x7VFNTE5MnT45FixbFW2+91eS2zo6T3//+92PixIkxbNiw6NWrV1RUVMQuu+wSp59+ejz//POdbuvixYvj1FNPjb322isGDBgQPXv2jMrKyjjssMPiRz/6UZNlS0pK4tOf/nShPUuXLu103W1GBu+zK664IouILCKyKVOm5N2cFk2YMKHQxiVLluTdHICiGDFiRKHv29LfggUL8m5uu9x2222FNl9xxRUduu/++++fRUQ2duzYJtcvXLiwzcfm7LPP7nR7d9ttt1bX+4EPfCBbsWJFk+WnTZuWRURWVlaWrVy5stN1ga7R+H1ua39Tp04terumTJnSYv+9cOHCbOHChdlvfvObDq9zyZIlhXVOmDCh2e0vv/xyYf2vv/76e2h91zjuuOOyiMiGDh2abdy4Mcuypo/Llv46OoZ0lYb6I0aM6PQ6vve97xXWc+yxx2a/+tWvsoULF2YbNmzo9Dh52GGHtfpY9enTJ/vTn/7Uqbbeeeedbe6Ha665psnyb775ZlZeXp5FRHbxxRd3qua2xBE6ANBNzZkzJxYuXFj4q6qqKtx20003Nblt9OjR77ne3/72t/e8jvfL4sWL45lnnomIiOOOO67Jbdtvv32ceuqpMXPmzPjFL34R8+bNi0mTJhVunzVrVqe3bfz48fG1r30t5s6dG4888kh8+ctfjp49e0ZExGuvvRZz5sxpsvzHP/7xiIior69v9s0lkK8jjzwyFi5cGI888kiceeaZhetvu+22ePrpp9u878aNG2PdunXvdxNj/PjxMX78+DjggAO6fN3Dhw8vrH/IkCFdvv6OWLlyZTzwwAMREfGxj30sSkpKIiLiS1/6UpOx7cgjjyzcZ+rUqU1u+9SnPpVL27tCbW1t4fIxxxwTEyZMiPHjx8d2223X6XXus88+cdVVV8V9990Xjz76aNx4443Rr1+/iIh466234rbbbuvUegcNGhRnnXVW3HnnnfHoo4/Gj3/84/inf/qnwu033XRTk+X79u0bH/nIRyJi00+RN2zY0Mkt2kbknSix7WvpCJ3G182aNSu7/vrrs9122y0rKyvLRo0alf3yl79sso7GR9D87ne/y84777yssrIy6927dzZp0qTsz3/+c5Plo5Vke/MjcRYsWNBmIuxoHaA7aXzETuNvdF955ZVs6tSp2ahRo7LBgwdnpaWl2cCBA7N/+Zd/ye6///4m62jcr06ZMiW77777sn322ScrKysrfBP47rvvZldeeWW20047Zb169coOOeSQ7Le//W2bR0vOnTs3O+yww7IBAwZkZWVl2R577JFNnz49W7t2bYvt3/xvS99CXnnllYVln3vuuS0+Vm+88UaT9S9fvrzZehp/c3jPPfcUrp84cWKb6548eXJh2a9//evNbh84cGAWEdmhhx66xXYC76/WjkTfuHFjtssuuxRuu+6665otP3PmzOzqq6/Ohg8fnvXo0aPQ727cuDGbNWtW9s///M9Z3759s4qKimzUqFHZDTfckL377rvN2vCtb30r23XXXbOKiorswAMPzH75y1+2eoROa++RN2zYkN18883Z2LFjs379+mUVFRXZ7rvvXjgCsa0jWxqO1mm8bbfddluT9T/zzDPZ8ccfn+24445Zz549sx133DE77rjjsqeffrrJcpsfPXLnnXdm//iP/5iVlZVlI0eOzO6555527ZfZs2cX1jNv3rxWl2u8XZuPExs3bsy++93vZmPGjMn69OmTlZeXZ3vuuWc2bdq0bPXq1U2W7ehnlba0to/q6+uzb37zm9l+++2X9e7dO+vdu3d20EEHZXfeeWeL99/8b8SIEe9pnGzJpz/96cL9zz///CzLsmz58uXZkCFDsojI+vXrl7366qtZlmXZO++8k40aNSqLiKxHjx7ZwoULW13vb3/728J6t99++2a333DDDYXbH3/88Q63e1si0OF9t6VAZ9ddd23WofTt2zdbtWpVYR2NO8k999yz2fI77bRTk8PSBToAHddaoPPEE0+02VfOnj27sGzjfnWXXXbJSkpKmr1ZvPDCC5uto3///ll1dXWL/e9ll13Wau2DDz44W79+fbP2d/SN6hFHHJFFRFZRUZG98847rS63cePGbPny5U2Cm7333rtw+zvvvJONHj06i4istLQ0e/bZZ7NVq1ZlO+64Y2E7ly5d2uK6165dmy1YsCDbYYcdCuve/MNOlmXZoYceWniTu2HDhja3C3h/tXVqgX322adw24wZM5otv/l74IZ+95Of/GSrfdmJJ57YpMbXv/71Zsv07Nkz22uvvdod6NTX12cTJ05stWaWvbdAZ968eVnPnj1bvG/Pnj2bBC6NA52WPiP06NEje/7557e4X84+++zCfVrrczffrsbjxMaNG7NPfOITrW7zBz/4wff0WaUtre2jtn7y9IUvfKHZ/Tf/68pAZ926ddnTTz+djRw5snD/OXPmFG6fM2dO4frjjjsuy7Isu+aaawrXtfZTqXfffTd79dVXs3POOaew7NFHH91succff7xw+7XXXtvudm+LBDq877YU6EREdskll2Q//elPmwx8//mf/1lYR+NOsrKyMrvtttuye++9t0lHf9FFFxWWb6kj3Hw9S5YsyVavXp0tXLgw23fffQvX33vvvYXf/65bt64YDxHAVqG1QGfJkiXZjBkzsvvuuy979NFHswULFmSzZ88uBA8jR44sLLt5UH7ggQdm9957bzZ37tzs0UcfzZ5//vlCyNOjR4/s8ssvzx544IHs8MMPb3K/hkBn0aJFhes+8IEPZDNnzsweeuihbNKkSc0+KP3mN7/JLr300sL1U6dOLfTnL7/8cpvbPmzYsMIb8daceOKJzd4Ajx8/PnvhhReaLPfcc89lZWVlWURkBx10UDZ16tTC8rfffnuz9f785z9vtt6qqqps1qxZLbaj8QeVl156qc3tAt5fLb3PXbduXXbHHXc0CbQffPDBZstHRHbKKadkDz74YHbHHXdkL7zwQnbvvfc2CQbuuuuu7IEHHsjGjh1buP7uu+/OsizLVq1alfXq1atw/X/8x39kDz74YHbqqac2qbGlQOcb3/hG4frevXtnV199dfbQQw9l3/ve97IDDzwwy7KsWdv23XffQv/6u9/9rtm2NQQ6b731VlZZWVm4/txzz83mz5+fnXfeeU3e27/11ltZljUNdCIiO+OMM7Kf/exnTcKMz33uc1vcLwcffHAWEVl5eXmby7UW6Nx9992F6wcOHJjdeuut2f333184wiQisnPOOaewfEc/q7SlpX3UOLgbO3Zsdv/992dz5sxpEh49+eSTWZZtOk9S43Hn0ksvLZw36b2Mk1mWZX/84x+bjVcDBgxoMVRpPGZef/31WUVFRRaxKQx7++23my0/ZsyYJustKSnJjj766BbPx1RbW1tY7rTTTmvX47qtKg3I2eTJk2PGjBkREbF27dr4xCc+ERERf/7zn1tc/tprry3MljVgwIDCNIRz586Nb37zmx2q3b9//xg/fnz079+/cN0BBxzwvkzlCJCq6urqqKqqihtuuCEWL14ca9asaTJry4svvhhvvvlm4bf0Dfr06RMPPfRQDBo0qHDd1772tcJ9P/axj8WVV14ZERHjxo2LnXbaKd5+++0m6/jhD39YuDx16tTYY489IiLinHPOiQcffDAiIn7wgx/EJZdcEgcccEBhlqqIv5/PoT1WrFgREREDBw5s1/INevbs2WyWq1GjRsVll10Wl112WSxatCgWLVoUERH/+q//GlOmTGn3ejdu3NjibY3buGLFith111071Gbg/TF79uyYPXt2s+sPOOCAmDhxYrPrx40bFz/4wQ+aXPf5z3++cPn888+PnXfeOSIizjjjjHjyyScjYlOfd+KJJ8YjjzxS6DMPPPDAwrlGJk6cGI8//nj83//9X7vafeeddxYuX3/99XH22WcX/m84F9DIkSML5/eK+Pt76C15+OGHC/3r/vvvH7fccktEbDrf0FNPPRXPPPNMrFixIh555JE49thjm9x3n332ie9///sREVFZWRm//OUvI6L1zwiNdbZPb9D4HGVXXXVVnHXWWRERsfvuu8eHPvShiNg0M+Itt9xSOD9Pgy19Vlm2bFm88MILTe7Tv3//wnpb0vh5ctFFF0VlZWVERJxyyilx+eWXF5YZM2ZMjB8/Ph599NHC8iNHjmyyrzo7TramtLS0xZncbr755vjVr34Vr7/+enz2s5+NiIjtttsuZs+eHRUVFVtcb48ePaK0tLTFsXDzcbA7E+iQuwkTJhQuDx48uHC5tenDx4wZU7h80EEHFS7X1NRElmXNOlUA3pvrr78+LrroojaXWb16dbNAZ9y4cU3CnIiIv/zlL4XLjfvzgQMHxgc/+MH47W9/22T5xm96r7nmmrjmmmua1X4v06VurqU3pQ2uvPLKOO+88+L111+P22+/PebPnx8LFiyIj3zkI/HnP/+5yRvUL37xi3HffffFs88+GxGb3qzfeuutLa537NixsXDhwnjzzTfjqaeeiq9+9auxdOnSOPPMM2PHHXeMo48+ut1tBLYeZWVlccIJJ8QNN9zQ4sloN39tRzTt8y688MIW1/vHP/4xIpr2pwceeGDh8nbbbRf7779/uwOdxjVbatN70Xjdjfv8iE3v4xtORr95wBHR8c8ILelsf9lau/fee+/o3bt3rF27Nt54441Yvnx5sxNAb+mzyvz582Pq1KlN7jNhwoQ2pxBv3J4TTjihxWUanhfvpxEjRsTChQtj7dq18eyzz8aMGTNixYoVcemll0bfvn3jggsuKCw7ePDguPnmm+P4448vXHfxxRc3eUwau/XWW+ONN96IpUuXxre//e349a9/HXPnzo1XXnklfvOb3zRZ1jj4dwIdctc4YS0t/ftTsj0v1C2FN5t/a9rdE1yAzvjWt75VuPyFL3whJk6cGGVlZXHeeefF4sWLIyJa/AZtxx13bHO9XRXAb9iwIdavXx/l5eWdXkdlZWUsXbo03njjjVaX2XPPPWPPPfeMiE0zYe2+++6xZMmSePXVV+Pxxx+PI444orDsmjVr4rXXXiv8/9e//jVqamqazCTWYMCAAYVvSI866qiI2PSNcMSmb4k3/4DVuI0N39IC+TvyyCPj0ksvjZKSkujbt2+MHDkyevXq1eryW+ojW9OeWfVS+IJzS218L58RGvrGtvr0YijmfijGTJK9evUqjFdHHHFE7LDDDoXZwH70ox81CXQimodMjY8O2tyoUaMKlz/+8Y/H4MGDY926dfH000/HCy+8UDhCN8I42Jhpy0lOw6HrERFPPfVU4XJ1dXWh02z4CdXKlSvjnXfeiYhNqXhr3+L26PH3l0Jrh7gDdFevvvpqRGz6tu2rX/1qHHrooTF69OjC9a1p6Y3sbrvtVrjc+Bu3N954o8U+uvEbuNtuuy2yTef/a/L3t7/9rRDmdLY/32uvvSIi4uWXX242BermPwNryebfGF9wwQXx+uuvR8Smb8s3btwYU6dObTItcWvrbfy4tfRNdMPPDbbffvsYMWLEFtsGFMeQIUNi/PjxMW7cuBg1alSbYU5Ey31k4z5vwYIFLfZ5L730UkREk59bNp4W/d13393iNOmt1Wz4KWtLOtO/Nl534/fwm//feLmu0NCn19fXx9KlSzt8/9ba/fvf/z7Wrl0bEZsCpx122KHZfbf0WeX0009vtk/bOjpn8/b85S9/afF50fCTtC3pzH5cv359i0FaW+PV4sWL4+qrr46IKByhNn/+/Lj99tubLNeZsbDxz+7+4R/+YYvt35Y5QofkTJs2LUpLS2P77bePadOmFa6fPHly4fLuu+8ezzzzTLz99ttx8sknx4c//OG45ZZbmh2x06DxNwDf+9734qijjopevXrFAQcc8P5tCEAiRowYES+++GKsXLkyZsyYEaNGjYobb7wxVq1a1eF1TZ48OS655JLIsizuu+++uPrqq2O//faLG2+8scU3dSeffHLceOONERHx2c9+NlatWhWjRo2K1atXx0svvRQPP/xwjBgxImbNmhURTfvzhx56KD784Q9HRUVFfOhDH2pyvrTNjRs3Lh5++OFYv359/OEPf4h99tmnSZsbzoNQXV0db775ZsyePTuWLFkSEZvedI4ePbqw/E9+8pO4++67I2LTkTz77rtvXHbZZfH888/HZZddFl//+tcjYtP5F2644YY46aST4oMf/GBUVFQUfnLVYL/99mvW1oafcY0ZM6bFn3EA6TrllFNi3rx5ERFx2mmnxZe+9KUYOXJkLF++PF588cV48MEH48gjj4wrrrgiDj/88KioqIh169bFokWL4jOf+UxMnDgx7r777nb/3Coi4tRTT43nnnsuIjb1s8uWLYsDDzwwXn311bj11lvjiSeeiIim/evixYtj7ty5UVlZGcOHD4/hw4e3uO4jjjgiBg8eHCtXroynn346Lrjggpg0aVLMnz+/EDpVVlYWzjPTVcaNG1f4mev//u//xrBhwzp0/5NPPjl++tOfRkTE5ZdfHuXl5VFZWVk471tExIknnthiKNeezyoddcoppxT20dFHHx1f+MIXYuedd47XXnstnn/++Zg3b15cfPHFhXP3tKUz4+QTTzwRZ555Zpx22mmx9957R79+/WLx4sXxla98pbBM4/Fqw4YNMWXKlKivr4/S0tJ46KGH4uSTT45ly5bFZz/72Tj88MNjp512iohN55gaO3ZsjB8/PoYPHx7Lli2LW265pfCeoFevXoWArkHjn2ePGzdui9u8TXv/z7tMd7elWa4aT2vYeHaUxlM/Nj5zfOOzyzf8feADH8iWLVtWWP673/1us2X69OmT7bzzzoX/G0+J+61vfavZ8pvPkAWwrWttlquWpsWtrKxsMrtGQ5/aWj/eWEvTlvfr169J/fZOW755neXLl2fl5eXNlmm8PS1ZvHhxYdlvfOMbTW5rPAa19Nd4utjly5dnQ4YMKcz88dprr2X19fWFsatHjx7Zr3/96yzLms/msvnf5tPiZtmmmbwabm88GySQj7amLd/S8o3fAzfW1rTlsdlsTDNmzGh2e48ePZrMrtSeacs/8pGPtFqvsf3337/V9rS2bXPnzu3UtOWNt3PJkiWF6xumSW/LypUrC7MNXnDBBa0u19a05S3NbNha/9zRzyptaWkfrV+/vs1pyzd/zNt6nnVmnNx8BsvN/6qqqprMujh9+vTCbZdcckmWZVl2zz33FK476qijCsu2NZV6RGQ333xzs/Y0zHRZVVWVbdiwoV2P67bKT65Izl133RUXXnhh7LDDDtGrV6848sgj4/HHH29yyOOZZ54Z06ZNiyFDhkSvXr3i0EMPjYULFzY51L+xf//3f49LLrkkhg8f3uQwRAA2fWP75S9/OUaMGBG9e/eOQw45JP7rv/6rxfPBtMd1110X06dPj6FDh0ZFRUUcfPDBsWDBgibfGvbu3btw+aqrroqf/exn8dGPfjQGDx4cPXv2jJ122inGjx8fM2bMaPKNaWVlZcydOzdGjx69xZ87NLb33nsXjsr8yU9+0uS2s88+O4455pgYMWJE9OrVq1B/8uTJ8dOf/rTJETXnnXdeLFu2LCI2zehVVVUVPXv2jFmzZjX56dXbb78dY8eOjbPPPjv23nvvGDhwYGy33XYxYMCAGDNmTFxzzTWxaNGiZjO0NLStvLw8TjrppHZvH5CO2bNnxx133BETJkyI/v37R1lZWQwfPjwOO+ywuOmmm+K8884rLHvJJZfEjTfeGNXV1VFeXh777rtvzJs3Lw4++OB21+vZs2f8/Oc/j5tuuikOOuig6NOnT1RUVMTuu+9emN2pwV133RUf/ehHOzR71OTJk+OJJ56I448/PoYMGRKlpaWxww47xMc//vH49a9/Hcccc0y719VegwYNKqz3/vvv7/BJdEtKSuJHP/pRfOc734mDDjoott9++ygvL4899tgjvvjFL8aTTz7Z6mPQns8qHVVWVhYPPfRQYR/17ds3KioqYpdddolJkybFzJkz42Mf+1i71tWZcXKPPfaICy+8MPbbb7+orKyM7bbbLvr27RujR4+OadOmxe9+97vCTwCfe+65wpE7u+22W1xxxRURselkzg0zmc2fP79wZO3nPve5OOKII2LnnXeO8vLyKCsri+rq6jjppJPi8ccfb/J8j9h0TrqGWbxOPfXUbn+kaknW0Wc35OCQQw6Jxx57LCIilixZYlpxgIRlLcxIuHLlyhg+fHisXbs2BgwYECtXrix6wH7PPffEJz7xiYiI+MMf/rDV/S7/nXfeierq6qitrY1zzz23MP0vAM099dRTMXbs2IjYFCAceeSR71stn1WK55Zbbonzzz8/ysvL48UXX+zwz+m2NQ5FAACK6hvf+EZMmzYt/ud//ieWLl0a//3f/x3HH3984UST//Zv/5bL0ZInnHBC7L333hGxaar2rc2Pf/zjqK2tjfLy8rj00kvzbg7AVm3MmDGFmQOvu+66nFtDV8iyrHBevTPPPLPbhzkRTooMABTZ3/72t5gxY0bMmDGj2W177bVXXHvttTm0atMh9g3TsG+NTjnllDjllFPybgZAMtqatYv0lJSUxJ/+9Ke8m7FVcYQOAFBUhxxySEyaNCl22mmnKCsriz59+sTo0aPjqquuikWLFsXgwYPz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\n",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Results on ARC-AGI examples: 5 pass, 0 fail\n",
"Results on ARC-GEN examples: 262 pass, 0 fail\n",
"\n",
"Your network IS READY for submission!\n",
"\n",
"Performance stats (memory values reported here are approximate):\n",
"Name Type Forward_MACs FPercent Memory MPercent Params PPercent InShape OutShape\n",
"------ ------ -------------- ---------- -------- ---------- -------- ---------- ---------- ----------\n",
"Conv_0 Conv 4,459 99.80% 560 93.96% 91 100.00% 1x10x30x30 1x1x7x7\n",
"Neg_2 Neg 9 0.20% 36 6.04% 0 0.00% 1x1x3x3 1x1x3x3\n",
"Total _ 4,468 100% 596 100% 91 100% _ _\n",
"\n",
"It appears to require 340 bytes + 97 params, yielding 18.920 points.\n",
"\n",
"Next steps:\n",
" * Click the link below to download task149.onnx onto your local machine.\n",
" * Create a zip file containing that network along with all others.\n",
" * Submit that zip file to the Kaggle competition so that it can be officially scored.\n",
"\n"
]
},
{
"data": {
"text/html": [
"task149.onnx
"
],
"text/plain": [
"/kaggle/working/task149.onnx"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"def run_inference(grid, model_path):\n",
" oh = np.zeros((1, 10, 30, 30), dtype=np.float32)\n",
" for r in range(len(grid)):\n",
" for c in range(len(grid[0])):\n",
" oh[0, grid[r][c], r, c] = 1.0\n",
" sess = ort.InferenceSession(model_path)\n",
" out = sess.run(None, {'input': oh})[0]\n",
" return (out[0] > 0.0).astype(int)\n",
"\n",
"example_idx = 0\n",
"inp = task['train'][example_idx]['input']\n",
"target = task['train'][example_idx]['output']\n",
"pred_raw = run_inference(inp, \"stride_tutorial.onnx\")\n",
"pred = np.argmax(pred_raw, axis=0)\n",
"\n",
"fig, axes = plt.subplots(1, 3, figsize=(12, 4))\n",
"plot_arc_grid(inp, axes[0], 'Input')\n",
"plot_arc_grid(target, axes[1], 'Target (3x3)')\n",
"plot_arc_grid(pred[:3, :3], axes[2], 'Prediction (Top-left 3x3)')\n",
"plt.show()\n",
"\n",
"# Verify with official checker\n",
"import sys\n",
"sys.path.append(\"/kaggle/input/competitions/neurogolf-2026/neurogolf_utils\")\n",
"from neurogolf_utils import *\n",
"passed = verify_network(model, 149, task)"
]
},
{
"cell_type": "markdown",
"id": "312a1784",
"metadata": {
"papermill": {
"duration": 0.014976,
"end_time": "2026-06-03T14:03:44.591723+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:44.576747+00:00",
"status": "completed"
},
"tags": []
},
"source": [
"# Summary\n",
"- **Stride** is used to skip pixels and reduce resolution.\n",
"- **Jump Frequency:** Stride 4 jumps every 4 pixels, perfect for 3x3 blocks with 1-pixel separators.\n",
"- **Formula:** Use the shape formula to ensure your stride lands exactly where you want it.\n",
"- **Assembly:** Using `Neg`, `Concat`, and `Pad` makes it easy to visualize how the model builds the 10-channel output from a single score map."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "57d8a1c7",
"metadata": {
"execution": {
"iopub.execute_input": "2026-06-03T14:03:44.631616Z",
"iopub.status.busy": "2026-06-03T14:03:44.631204Z",
"iopub.status.idle": "2026-06-03T14:03:46.835318Z",
"shell.execute_reply": "2026-06-03T14:03:46.834426Z"
},
"papermill": {
"duration": 2.224621,
"end_time": "2026-06-03T14:03:46.837646+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:44.613025+00:00",
"status": "completed"
},
"tags": []
},
"outputs": [],
"source": [
"import shutil\n",
"import os\n",
"import zipfile\n",
"\n",
"# --- CONFIGURATION ---\n",
"SOURCE_FOLDER = '/kaggle/input/datasets/massimilianoghiotto/neurogolf2026-6254/submission'\n",
"OUTPUT_ZIP = '/kaggle/working/submission.zip'\n",
"\n",
"# Package the ZIP (Ensuring files are at the root)\n",
"with zipfile.ZipFile(OUTPUT_ZIP, 'w', zipfile.ZIP_DEFLATED) as zipf:\n",
" for root, dirs, files in os.walk(SOURCE_FOLDER):\n",
" for file in files:\n",
" if file.endswith('.onnx'):\n",
" file_path = os.path.join(root, file)\n",
" zipf.write(file_path, os.path.relpath(file_path, SOURCE_FOLDER))"
]
},
{
"cell_type": "markdown",
"id": "53e074c9",
"metadata": {
"papermill": {
"duration": 0.015585,
"end_time": "2026-06-03T14:03:46.869316+00:00",
"exception": false,
"start_time": "2026-06-03T14:03:46.853731+00:00",
"status": "completed"
},
"tags": []
},
"source": [
"### **This is the best that we are able to do for the moment, if anyone has any suggestion, please write it in the comments, we are happy to have some brainstorning between people.**"
]
}
],
"metadata": {
"kaggle": {
"accelerator": "none",
"dataSources": [
{
"databundleVersionId": 17255611,
"sourceId": 116438,
"sourceType": "competition"
},
{
"databundleVersionId": 17567559,
"datasetId": 10603997,
"sourceId": 16560807,
"sourceType": "datasetVersion"
}
],
"dockerImageVersionId": 31400,
"isGpuEnabled": false,
"isInternetEnabled": true,
"language": "python",
"sourceType": "notebook"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.13"
},
"papermill": {
"default_parameters": {},
"duration": 33.260352,
"end_time": "2026-06-03T14:03:47.405479+00:00",
"environment_variables": {},
"exception": null,
"input_path": "__notebook__.ipynb",
"output_path": "__notebook__.ipynb",
"parameters": {},
"start_time": "2026-06-03T14:03:14.145127+00:00",
"version": "2.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}