{
 "nbformat": 4,
 "nbformat_minor": 5,
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  },
  "accelerator": "GPU",
  "colab": {
   "provenance": []
  }
 },
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# PyTorch ile Derin Öğrenme · Dataset ve DataLoader\n",
    "\n",
    "Macademia · Büyükler için"
   ],
   "id": "c00"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **Colab'da çalıştırma:** Bu dosyayı [colab.research.google.com](https://colab.research.google.com) adresinde **Dosya → Not defteri yükle** ile aç. GPU için **Çalışma zamanı → Çalışma zamanı türünü değiştir → T4 GPU** seç. Hücreleri yukarıdan aşağı sırayla çalıştır (Shift + Enter). PyTorch Colab'da kuruludur; bilgisayarında çalıştırmak istersen `pip install torch torchvision`."
   ],
   "id": "c01"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch, random, numpy as np\n",
    "torch.manual_seed(0); random.seed(0); np.random.seed(0)          # tekrarlanabilirlik\n",
    "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
    "print('PyTorch', torch.__version__, '| device:', device)"
   ],
   "id": "c02"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Kendi Dataset sınıfın"
   ],
   "id": "c03"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch.utils.data import Dataset, DataLoader, random_split\n",
    "class SensorVerisi(Dataset):\n",
    "    def __init__(self, n=1000):\n",
    "        g = torch.Generator().manual_seed(0)\n",
    "        self.X = torch.randn(n, 3, generator=g); self.y = (self.X.sum(1) > 0).long()\n",
    "    def __len__(self):\n",
    "        return len(self.X)\n",
    "    def __getitem__(self, i):\n",
    "        return self.X[i], self.y[i]\n",
    "ds = SensorVerisi()\n",
    "print(len(ds), ds[0])"
   ],
   "id": "c04"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Ayrım ve yığınlar"
   ],
   "id": "c05"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tr, va = random_split(ds, [800, 200], generator=torch.Generator().manual_seed(42))\n",
    "for bs, drop in [(64, False), (64, True), (100, False)]:\n",
    "    dl = DataLoader(tr, batch_size=bs, shuffle=True, drop_last=drop)\n",
    "    sizes = [len(xb) for xb, _ in dl]\n",
    "    print(f'bs={bs} drop_last={drop}: len={len(dl)} last={sizes[-1]}')                # son yığın boyu"
   ],
   "id": "c06"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Karıştırma tekrarlanabilir mi?"
   ],
   "id": "c07"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def first_batch(seed):\n",
    "    dl = DataLoader(range(20), batch_size=5, shuffle=True, generator=torch.Generator().manual_seed(seed))\n",
    "    return next(iter(dl)).tolist()\n",
    "print(first_batch(1), first_batch(1), first_batch(2))"
   ],
   "id": "c08"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Bir eğitim döngüsünde kullanmak"
   ],
   "id": "c09"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch import nn\n",
    "model = nn.Sequential(nn.Linear(3, 16), nn.ReLU(), nn.Linear(16, 2)).to(device)\n",
    "opt = torch.optim.Adam(model.parameters(), lr=0.01)\n",
    "tr_dl = DataLoader(tr, batch_size=64, shuffle=True); va_dl = DataLoader(va, batch_size=256)\n",
    "for epoch in range(5):\n",
    "    model.train()\n",
    "    for xb, yb in tr_dl:\n",
    "        xb, yb = xb.to(device), yb.to(device)\n",
    "        opt.zero_grad(); nn.functional.cross_entropy(model(xb), yb).backward(); opt.step()\n",
    "    model.eval(); ok = 0\n",
    "    with torch.no_grad():\n",
    "        for xb, yb in va_dl:\n",
    "            ok += (model(xb.to(device)).argmax(1).cpu() == yb).sum().item()\n",
    "    print(epoch, ok / len(va))"
   ],
   "id": "c10"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Alıştırmalar\n",
    "1. Bir CSV dosyasını okuyan bir Dataset yaz.\n",
    "2. `num_workers=2` dene ve süreyi ölç.\n",
    "3. Sınıfa göre sıralı veride `shuffle=False` ile eğit; sonucu karşılaştır."
   ],
   "id": "c11"
  }
 ]
}