{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a799e7e4",
   "metadata": {},
   "source": [
    "# Day 1 — Meet the Machines 🤖\n",
    "\n",
    "> **Mission briefing:** You passed the entrance exam, so here's your reward: a walk through the Lab's equipment room. Four finished AI machines are humming on the benches — one that **sees**, one that **reads moods**, one that **writes stories**, and a **sorting hat** that files text into any categories you invent. Today you just get to *play* with them. There's a catch, though: by Demo Day you will have **rebuilt every single one yourself**.\n",
    "\n",
    "**Previously in the Lab:** you were the Data Detective — you can read data. Now meet the machines that devour it.\n",
    "\n",
    "**Today you will:**\n",
    "- See the **map of AI** — how machine learning, deep learning, and the \"superpowers\" fit together\n",
    "- Run four **pretrained** models: image recognition, sentiment, text generation, zero-shot sorting\n",
    "- Try to **fool** them, bend them, and break them (that's how you learn what they can't do)\n",
    "- Meet the **AI Studio** — the app you'll assemble one tab per day\n",
    "\n",
    "*These models were trained on giant datasets using enormous computers. You won't train them today — you'll borrow them, the way real researchers stand on each other's shoulders.*\n",
    "\n",
    "<details data-resource-precision=\"1\"><summary>A precise reading</summary><p>This course focuses on learning from data. AI also includes rule-based and search systems. Tables are a useful starting point, but images, audio and text need representations suited to their structure.</p></details>\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c35de5c7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:27.659739Z",
     "iopub.status.busy": "2026-08-17T12:57:27.659547Z",
     "iopub.status.idle": "2026-08-17T12:57:27.768636Z",
     "shell.execute_reply": "2026-08-17T12:57:27.767614Z"
    }
   },
   "outputs": [],
   "source": [
    "# ╔═══════════════════════════════════════════════════════════════════╗\n",
    "# ║ SETUP — run me first! (identical in every Lab notebook)           ║\n",
    "# ╚═══════════════════════════════════════════════════════════════════╝\n",
    "import os, sys, pathlib\n",
    "\n",
    "IN_COLAB = \"google.colab\" in sys.modules\n",
    "SMOKE = os.environ.get(\"SMOKE_TEST\", \"0\") == \"1\"   # tiny fast run for automated tests\n",
    "\n",
    "REPO_URL = \"https://github.com/A-Halimi/ai-studio-internship.git\"  # instructor: set once\n",
    "\n",
    "if IN_COLAB:\n",
    "    if not pathlib.Path(\"/content/ai-studio-internship\").exists():\n",
    "        !git clone -q {REPO_URL} /content/ai-studio-internship\n",
    "    %cd /content/ai-studio-internship/notebooks/day01\n",
    "    %pip -q install transformers==5.13.0\n",
    "\n",
    "HERE = pathlib.Path.cwd()\n",
    "REPO = HERE.parents[1]                       # .../notebooks/dayNN -> repo root\n",
    "DATA_DIR = pathlib.Path(os.environ.get(\"COURSE_DATA_DIR\", REPO / \"data\"))\n",
    "SAMPLES_DIR = REPO / \"data_samples\"          # small datasets shipped with the repo\n",
    "MODELS_DIR = REPO / \"ai_studio\" / \"models\"   # where your Studio modules unlock\n",
    "for p in (REPO / \"data\", MODELS_DIR):\n",
    "    p.mkdir(parents=True, exist_ok=True)\n",
    "\n",
    "import random\n",
    "import numpy as np\n",
    "SEED = 42\n",
    "random.seed(SEED); np.random.seed(SEED)\n",
    "print(f\"✅ Setup done | Colab: {IN_COLAB} | Smoke test: {SMOKE}\")\n",
    "print(f\"   data: {DATA_DIR}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "73d011c6",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:27.770417Z",
     "iopub.status.busy": "2026-08-17T12:57:27.770224Z",
     "iopub.status.idle": "2026-08-17T12:57:29.046964Z",
     "shell.execute_reply": "2026-08-17T12:57:29.045840Z"
    }
   },
   "outputs": [],
   "source": [
    "import torch\n",
    "torch.manual_seed(SEED)\n",
    "DEVICE = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "if DEVICE.type == \"cuda\":\n",
    "    print(f\"⚡ Running on GPU: {torch.cuda.get_device_name(0)}\")\n",
    "else:\n",
    "    print(\"🐢 No GPU found — running on CPU. Everything still works, just slower.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb3ce425",
   "metadata": {},
   "source": [
    "## 🗺️ The map of AI\n",
    "\n",
    "People throw around \"AI\", \"machine learning\", and \"deep learning\" as if they mean the same thing. They don't — they **nest**, like Russian dolls:\n",
    "\n",
    "- **Artificial Intelligence** — any program that does something we'd call \"smart.\"\n",
    "- **Machine Learning** — a *kind* of AI that isn't hand-coded with rules; it **learns patterns from data**. (Yesterday you saw the patterns; ML is teaching a machine to find them.)\n",
    "- **Deep Learning** — machine learning with **neural networks** stacked many layers deep. It powers almost every jaw-dropping AI you've heard of.\n",
    "\n",
    "And there are **three ways** a machine can learn:\n",
    "\n",
    "- **Supervised** — learn from *labeled* examples (\"this penguin is a Gentoo\"). ← Day 2\n",
    "- **Unsupervised** — find structure with *no* labels (\"these things clump together\"). ← Day 3\n",
    "- **Reinforcement** — learn by *trial, reward, and error*, like training a dog. ← Day 9\n",
    "\n",
    "Run the next cell for the map."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "20a8c861",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:29.048767Z",
     "iopub.status.busy": "2026-08-17T12:57:29.048553Z",
     "iopub.status.idle": "2026-08-17T12:57:29.458476Z",
     "shell.execute_reply": "2026-08-17T12:57:29.457443Z"
    }
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "from matplotlib.patches import FancyBboxPatch\n",
    "\n",
    "fig, (axL, axR) = plt.subplots(1, 2, figsize=(11, 5))\n",
    "\n",
    "# Left: AI contains ML contains Deep Learning (nested boxes)\n",
    "axL.set_xlim(0, 10); axL.set_ylim(0, 10); axL.axis(\"off\")\n",
    "for x, y, w, h, label, color, fs in [\n",
    "    (0.5, 0.5, 9.0, 9.0, \"Artificial Intelligence\", \"#e8f0fe\", 13),\n",
    "    (1.6, 1.6, 6.8, 6.3, \"Machine Learning\", \"#c6dafc\", 12),\n",
    "    (2.8, 2.6, 4.4, 3.9, \"Deep Learning\", \"#8ab4f8\", 12),\n",
    "]:\n",
    "    axL.add_patch(FancyBboxPatch((x, y), w, h, boxstyle=\"round,pad=0.02\",\n",
    "                                 fc=color, ec=\"#222\", lw=1.5))\n",
    "    axL.text(x + w / 2, y + h - 0.5, label, ha=\"center\", va=\"top\",\n",
    "             fontsize=fs, fontweight=\"bold\")\n",
    "axL.text(5.0, 3.9, \"neural networks\\nwith many layers\", ha=\"center\", va=\"center\",\n",
    "         fontsize=10, style=\"italic\")\n",
    "axL.set_title(\"AI  ⊃  Machine Learning  ⊃  Deep Learning\", fontweight=\"bold\")\n",
    "\n",
    "# Right: the three ways to learn + two superpowers\n",
    "axR.set_xlim(0, 10); axR.set_ylim(0, 10); axR.axis(\"off\")\n",
    "axR.set_title(\"How machines learn\", fontweight=\"bold\")\n",
    "for i, (name, desc, color) in enumerate([\n",
    "    (\"Supervised\", \"learn from labeled examples\", \"#a5d6a7\"),\n",
    "    (\"Unsupervised\", \"find structure, no labels\", \"#fff59d\"),\n",
    "    (\"Reinforcement\", \"learn by trial and reward\", \"#ef9a9a\"),\n",
    "]):\n",
    "    y = 8.2 - i * 2.3\n",
    "    axR.add_patch(FancyBboxPatch((0.5, y - 0.9), 9.0, 1.6, boxstyle=\"round,pad=0.02\",\n",
    "                                 fc=color, ec=\"#222\"))\n",
    "    axR.text(5.0, y + 0.15, name, ha=\"center\", fontsize=12, fontweight=\"bold\")\n",
    "    axR.text(5.0, y - 0.5, desc, ha=\"center\", fontsize=9)\n",
    "axR.text(5.0, 0.6, \"Two superpowers you'll build:   Vision (images)  +  Language (text)\",\n",
    "         ha=\"center\", fontsize=10, fontweight=\"bold\")\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d529be71",
   "metadata": {},
   "source": [
    "## 👁️ Superpower 1 — Vision\n",
    "\n",
    "First up: a machine that **looks at a photo and names what's in it**. Ours is **ResNet-18**, a neural network trained on **ImageNet** — 1.2 million photos across 1000 categories (dogs, castles, teapots, you name it).\n",
    "\n",
    "We don't have to train it — we just **download the finished brain** and use it. Two details matter:\n",
    "\n",
    "- `.eval()` puts the network in \"just answer, don't learn\" mode.\n",
    "- `weights.transforms()` is the exact **preprocessing** (resize, crop, normalize) the model expects. Feed it anything else and it gets confused — models are picky eaters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1e950c16",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:29.460203Z",
     "iopub.status.busy": "2026-08-17T12:57:29.460003Z",
     "iopub.status.idle": "2026-08-17T12:57:33.899411Z",
     "shell.execute_reply": "2026-08-17T12:57:33.898273Z"
    }
   },
   "outputs": [],
   "source": [
    "from torchvision.models import resnet18, ResNet18_Weights\n",
    "from sklearn.datasets import load_sample_image\n",
    "from PIL import Image\n",
    "\n",
    "weights = ResNet18_Weights.DEFAULT\n",
    "model = resnet18(weights=weights).eval().to(DEVICE)\n",
    "preprocess = weights.transforms()          # the model's required input pipeline\n",
    "categories = weights.meta[\"categories\"]    # the 1000 label names\n",
    "print(f\"ResNet-18 ready — it knows {len(categories)} categories.\")\n",
    "\n",
    "\n",
    "def classify_top5(img_array):\n",
    "    \"\"\"Return the model's 5 most confident labels for one image (a NumPy array).\"\"\"\n",
    "    img = Image.fromarray(img_array)\n",
    "    batch = preprocess(img).unsqueeze(0).to(DEVICE)   # 1 image -> a batch of 1\n",
    "    with torch.no_grad():\n",
    "        logits = model(batch)\n",
    "    probs = torch.softmax(logits, dim=1)[0]           # turn scores into probabilities\n",
    "    top_p, top_i = probs.topk(5)\n",
    "    return [(categories[i], p.item()) for i, p in zip(top_i, top_p)]\n",
    "\n",
    "\n",
    "def show_top5(img_array, title):\n",
    "    preds = classify_top5(img_array)\n",
    "    labels = [name for name, _ in preds][::-1]\n",
    "    scores = [p for _, p in preds][::-1]\n",
    "    fig, (ax_img, ax_bar) = plt.subplots(1, 2, figsize=(10, 4))\n",
    "    ax_img.imshow(img_array); ax_img.axis(\"off\"); ax_img.set_title(title)\n",
    "    ax_bar.barh(labels, scores)\n",
    "    ax_bar.set_xlim(0, 1)\n",
    "    ax_bar.set_xlabel(\"Confidence\")\n",
    "    ax_bar.set_title(\"Top-5 guesses\")\n",
    "    plt.tight_layout(); plt.show()\n",
    "    return preds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7fb049df",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:33.901661Z",
     "iopub.status.busy": "2026-08-17T12:57:33.901352Z",
     "iopub.status.idle": "2026-08-17T12:57:34.482535Z",
     "shell.execute_reply": "2026-08-17T12:57:34.481386Z"
    }
   },
   "outputs": [],
   "source": [
    "china = load_sample_image(\"china.jpg\")     # a photo that ships with scikit-learn\n",
    "_ = show_top5(china, \"china.jpg\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8d24c421",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:34.484664Z",
     "iopub.status.busy": "2026-08-17T12:57:34.484434Z",
     "iopub.status.idle": "2026-08-17T12:57:34.571197Z",
     "shell.execute_reply": "2026-08-17T12:57:34.570182Z"
    }
   },
   "outputs": [],
   "source": [
    "flower = load_sample_image(\"flower.jpg\")\n",
    "_ = show_top5(flower, \"flower.jpg\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c8fa4311",
   "metadata": {},
   "source": [
    "### 🔬 Your turn (mini-task)\n",
    "\n",
    "Look at the two bar charts. **In a sentence or two, jot down what the model got right and what it got wrong.** Was it confidently correct? Confidently *wrong*? Notice that it never says \"I don't know\" — it always spreads its bet across the labels it was trained on, even for a photo that matches none of them well. Keeping models honest about their own uncertainty is a real research problem."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b8a7f2bc",
   "metadata": {},
   "source": [
    "## 💬 Superpower 2 — Reading the mood\n",
    "\n",
    "Next machine: **sentiment analysis**. It reads a sentence and decides whether the feeling behind it is **positive** or **negative**, with a confidence score.\n",
    "\n",
    "The `transformers` library gives us a one-liner called a **pipeline**: name the task, name the model, and it downloads and wires everything up. Ours is a **DistilBERT** model fine-tuned on movie reviews."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d038c90f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:34.573468Z",
     "iopub.status.busy": "2026-08-17T12:57:34.573320Z",
     "iopub.status.idle": "2026-08-17T12:57:38.494008Z",
     "shell.execute_reply": "2026-08-17T12:57:38.492840Z"
    }
   },
   "outputs": [],
   "source": [
    "from transformers import pipeline\n",
    "\n",
    "mood = pipeline(\"text-classification\",\n",
    "                model=\"distilbert-base-uncased-finetuned-sst-2-english\",\n",
    "                device=0 if DEVICE.type == \"cuda\" else -1)\n",
    "\n",
    "sentences = [\n",
    "    \"I absolutely loved this movie, what a ride!\",\n",
    "    \"This is the worst day I have ever had.\",\n",
    "    \"The food was okay, nothing special.\",\n",
    "]\n",
    "for s in sentences:\n",
    "    r = mood(s)[0]\n",
    "    print(f\"{r['label']:8} ({r['score']:.2f})   {s}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81fe51d9",
   "metadata": {},
   "source": [
    "### 🧪 Exercise 1 — Fool the mood reader\n",
    "\n",
    "These models learn from patterns of words, so they struggle with things humans read instantly — like **sarcasm**.\n",
    "\n",
    "- Write a sentence that *sounds* positive word-for-word but really means the opposite, and store it in `sarcastic`.\n",
    "- **Goal:** get the model to answer **POSITIVE** for something you clearly meant as a complaint."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d49c47ec",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:38.496085Z",
     "iopub.status.busy": "2026-08-17T12:57:38.495783Z",
     "iopub.status.idle": "2026-08-17T12:57:38.504865Z",
     "shell.execute_reply": "2026-08-17T12:57:38.503895Z"
    }
   },
   "outputs": [],
   "source": [
    "# ==================== YOUR CODE HERE ====================\n",
    "### HINT: pile on happy words for an unhappy situation\n",
    "### HINT: e.g. \"Oh great, my flight got cancelled again. I just LOVE airports.\"\n",
    "...\n",
    "result = mood(sarcastic)[0]\n",
    "print(f\"{result['label']} ({result['score']:.2f})   {sarcastic}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ff3c081",
   "metadata": {},
   "source": [
    "## ✍️ Superpower 3 — The story writer\n",
    "\n",
    "This machine **generates text**. Give **GPT-2** the start of a sentence and it keeps going, one word at a time, each word guessed from everything before it. (Yes — it's a distant, much smaller ancestor of the models you talk to today.)\n",
    "\n",
    "A couple of dials:\n",
    "\n",
    "- `max_new_tokens` — how many words to add.\n",
    "- `temperature` — the \"creativity\" knob. Low = safe and repetitive, high = wild. We use `0.9` for some spice."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5334de6a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:38.506265Z",
     "iopub.status.busy": "2026-08-17T12:57:38.506132Z",
     "iopub.status.idle": "2026-08-17T12:57:41.245698Z",
     "shell.execute_reply": "2026-08-17T12:57:41.244653Z"
    }
   },
   "outputs": [],
   "source": [
    "storyteller = pipeline(\"text-generation\", model=\"gpt2\",\n",
    "                       device=0 if DEVICE.type == \"cuda\" else -1)\n",
    "\n",
    "MAX_NEW = 20 if SMOKE else 40\n",
    "prompt = \"In the year 3000, the last robot on Earth discovered\"\n",
    "torch.manual_seed(SEED)          # reproducible demo\n",
    "out = storyteller(prompt, max_new_tokens=MAX_NEW, do_sample=True,\n",
    "                  temperature=0.9, pad_token_id=50256)\n",
    "print(out[0][\"generated_text\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9912811",
   "metadata": {},
   "source": [
    "### 🧪 Exercise 2 — Be the author\n",
    "\n",
    "Swap in **your own** prompt and see what the machine dreams up.\n",
    "\n",
    "- Set `my_prompt` to any opening you like — a fairy tale, a news headline, a recipe.\n",
    "- Run it a few times: because `do_sample=True`, you get a different story every time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ec73cea9",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:41.247466Z",
     "iopub.status.busy": "2026-08-17T12:57:41.247313Z",
     "iopub.status.idle": "2026-08-17T12:57:41.618800Z",
     "shell.execute_reply": "2026-08-17T12:57:41.617667Z"
    }
   },
   "outputs": [],
   "source": [
    "# ==================== YOUR CODE HERE ====================\n",
    "### HINT: anything goes — the funnier the opener, the funnier the result\n",
    "...\n",
    "torch.manual_seed(SEED)          # reproducible demo\n",
    "out = storyteller(my_prompt, max_new_tokens=MAX_NEW, do_sample=True,\n",
    "                  temperature=0.9, pad_token_id=50256)\n",
    "print(out[0][\"generated_text\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9ed7e19",
   "metadata": {},
   "source": [
    "## 🎩 Superpower 4 — The sorting hat\n",
    "\n",
    "The last machine is the cleverest trick. **Zero-shot classification** sorts text into categories **it was never trained on**. You invent the labels on the spot, and it figures out which one fits best.\n",
    "\n",
    "\"Zero-shot\" means zero training examples for your specific categories — it reasons about the *meaning* of the words instead."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "21a987e9",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:41.620589Z",
     "iopub.status.busy": "2026-08-17T12:57:41.620445Z",
     "iopub.status.idle": "2026-08-17T12:57:42.974349Z",
     "shell.execute_reply": "2026-08-17T12:57:42.973259Z"
    }
   },
   "outputs": [],
   "source": [
    "sorter = pipeline(\"zero-shot-classification\",\n",
    "                  model=\"typeform/distilbert-base-uncased-mnli\",\n",
    "                  device=0 if DEVICE.type == \"cuda\" else -1)\n",
    "\n",
    "text = \"I spent all weekend building a robot that sorts my socks by color.\"\n",
    "labels = [\"technology\", \"sports\", \"cooking\", \"art\"]\n",
    "res = sorter(text, candidate_labels=labels)\n",
    "for lbl, score in zip(res[\"labels\"], res[\"scores\"]):\n",
    "    print(f\"{lbl:12} {score:.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aa7a3fb9",
   "metadata": {},
   "source": [
    "### 🧪 Exercise 3 — Invent the categories\n",
    "\n",
    "Give the sorting hat your own text and your own labels.\n",
    "\n",
    "- Set `my_text` to any sentence, and `my_labels` to 3–5 categories it might fall into.\n",
    "- **Try to trip it up:** a sentence that could belong to two categories at once is the interesting case."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f50de769",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-17T12:57:42.975976Z",
     "iopub.status.busy": "2026-08-17T12:57:42.975837Z",
     "iopub.status.idle": "2026-08-17T12:57:42.998482Z",
     "shell.execute_reply": "2026-08-17T12:57:42.997190Z"
    }
   },
   "outputs": [],
   "source": [
    "my_text = \"The championship match went to overtime and the crowd went wild.\"\n",
    "# ==================== YOUR CODE HERE ====================\n",
    "### HINT: pick categories the text might plausibly belong to\n",
    "...\n",
    "res = sorter(my_text, candidate_labels=my_labels)\n",
    "print(f\"Text: {my_text}\\n\")\n",
    "for lbl, score in zip(res[\"labels\"], res[\"scores\"]):\n",
    "    print(f\"{lbl:12} {score:.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07903df6",
   "metadata": {},
   "source": [
    "## 🧪 This is the mission: your AI Studio\n",
    "\n",
    "Everything you just played with was built by *other* people. Over the next two weeks you'll build your **own** versions — and they'll live inside one app: the **AI Studio**.\n",
    "\n",
    "The Studio has one tab per capability. Each starts **🔒 locked**, and you unlock it by finishing that day's notebook (which trains and saves the model the tab needs):\n",
    "\n",
    "| Day | Tab | What you'll build |\n",
    "|----|-----|-------------------|\n",
    "| 2 | 🐧 Prediction Machine | classify penguins from measurements |\n",
    "| 3 | 🎨 Pattern Finder | discover groups in data with *no* labels |\n",
    "| 5 | ✍️ Digit Reader | recognize handwritten digits |\n",
    "| 6 | 🕵️ Photo Detective | recognize objects in photos |\n",
    "| 7 | 🪨📄✂️ RPS Arena | play rock–paper–scissors through the camera |\n",
    "| 8 | 💬 Language Lab | understand and generate text |\n",
    "| 9 | 🎮 Game Master | an agent that learns to win a game |\n",
    "\n",
    "Want a peek? From the repo root run:\n",
    "\n",
    "```\n",
    "python ai_studio/app.py\n",
    "```\n",
    "\n",
    "Today **every tab shows 🔒** — you haven't built anything yet. That padlock wall *is* the mission. By **Demo Day (Day 10)** you'll open the app and every lock will be gone. 🔓"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c65e2d5",
   "metadata": {},
   "source": [
    "> **📦 A note on the first run.** Outside the course's Docker container, the very first time you load these models your computer downloads roughly **1.5 GB** of weights from the internet, so give it a minute. Inside the Lab's container everything is **pre-baked** — no download, no waiting. Either way, you only pay this cost once."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "931682e0",
   "metadata": {},
   "source": [
    "## 🏁 Checkpoint\n",
    "\n",
    "You've met the machines. In a single afternoon you:\n",
    "\n",
    "- ✅ Placed AI, machine learning, and deep learning on the same map\n",
    "- ✅ Ran a **vision** model that names objects in photos\n",
    "- ✅ Ran a **sentiment** model — and fooled it with sarcasm\n",
    "- ✅ Made a **language** model write, and a **zero-shot** model sort\n",
    "- ✅ Saw the **AI Studio** you're about to fill, one locked tab at a time\n",
    "\n",
    "The big secret: none of these are magic. Each is a pattern-finder trained on data — the same idea you'll master step by step.\n",
    "\n",
    "> **Tomorrow (Day 2):** you stop borrowing and start **building**. You'll train your own classifier on yesterday's penguins and unlock the first tab of your Studio — **🐧 Prediction Machine**. 🔓"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2099d0d",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "<div align=\"center\" style=\"background:#14161E;border-radius:12px;padding:18px 12px 14px;margin-top:6px\">\n",
    "  <a href=\"https://ahalimi.com\" target=\"_blank\">\n",
    "    <img src=\"data:image/webp;base64,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\" alt=\"Dr. Abdelghafour HALIMI\" width=\"260\"/>\n",
    "  </a>\n",
    "</div>\n",
    "\n",
    "<div align=\"center\" style=\"text-align:center;margin-top:8px\"><sub>The Lab · AI Studio — Intro to AI · © 2026 <b>Dr. Abdelghafour HALIMI</b> · <a href=\"https://ahalimi.com\">ahalimi.com</a> · All rights reserved.</sub></div>"
   ]
  }
 ],
 "metadata": {
  "authors": [
   {
    "name": "Dr. Abdelghafour HALIMI"
   }
  ],
  "copyright": "© 2026 Dr. Abdelghafour HALIMI · ahalimi.com · All rights reserved",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
