Metadata-Version: 2.2
Name: newton-vision
Version: 1.1.5
Summary: High-Performance Computer Vision & Deep Learning Framework in C++ & CUDA with PyTorch Parity
Keywords: deep-learning,computer-vision,cuda,autograd,cnn,resnet,mobilenet,cpp
Author-Email: newton-vision Core Team <info@newton-vision.org>
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Image Processing
Project-URL: Homepage, https://github.com/onur/newton-vision
Project-URL: Documentation, https://github.com/onur/newton-vision/tree/master/docs
Project-URL: Repository, https://github.com/onur/newton-vision.git
Requires-Python: >=3.9
Requires-Dist: numpy>=1.20.0
Description-Content-Type: text/markdown

# 🌌 newton-vision

> **C++17 ve CUDA çekirdekli, PyTorch ekosistemiyle uyumlu, eğitim ve araştırma odaklı hafif derin öğrenme framework'ü.**

[![PyPI Version](https://img.shields.io/pypi/v/newton-vision.svg?color=blue)](https://pypi.org/project/newton-vision/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/)

---

## İçindekiler

1. [Proje Nedir?](#-proje-nedir)
2. [Kurulum](#-kurulum)
3. [Modül Haritası](#-modül-haritası--api-referansı)
4. [Hızlı Başlangıç — 3 Senaryo](#-hızlı-başlangıç--3-temel-senaryo)
5. [Model Zoo — Hazır Mimariler](#-model-zoo--hazır-mimariler)
6. [Katman Referansı — Tüm Layer API](#-katman-referansı--tüm-layer-api)
7. [Tensor & Autograd Motoru](#-tensor--autograd-motoru-fluxion)
8. [Kayıp Fonksiyonları & Optimizatörler](#-kayıp-fonksiyonları--optimizatörler-gravity)
9. [INT8 Kuantizasyon Motoru](#-int8-kuantizasyon-motoru)
10. [JIT & Serileştirme Motoru](#-jit--serileştirme-motoru)
11. [PyTorch Ağırlık Aktarımı](#-pytorch-ağırlık-aktarımı)
12. [Cihaz Yönetimi — CPU & CUDA](#-cihaz-yönetimi--cpu--cuda)
13. [C++ Backend Mimarisi](#-c-backend-mimarisi)
14. [Benchmark Sonuçları](#-benchmark-sonuçları)
15. [Transformer & LLM Yetkinliği](#-transformer--llm-yetkinliği)
16. [Örnek Projeler & Öğreticiler](#-örnek-projeler--öğreticiler)
17. [Test Kapsamı](#-test-kapsamı)
18. [Katkıda Bulunma](#-katkıda-bulunma)
19. [Güvenlik Politikası](#-güvenlik-politikası)
20. [Sürüm Geçmişi](#-sürüm-geçmişi)
21. [Lisans](#-lisans)

---

## ❓ Proje Nedir?

### Bu Framework Ne Yapar?

`newton-vision` aşağıdaki yetenekleri **sıfırdan** C++17, CUDA ve Python ile gerçekleştirir:

| Yetenek | Açıklama |
|---|---|
| **Reverse-Mode Autograd** | Topolojik sıralama ile otomatik türev hesaplama (backward pass) |
| **CNN Katmanları** | Conv2d, MaxPool2d, AvgPool2d, BatchNorm2d (C++ im2col + GEMM ile) |
| **Transformer Katmanları** | MultiHeadAttention, LayerNorm, GELU, PatchEmbedding |
| **Model Zoo** | ResNet-18, MobileNetV2, ViT-Tiny, ViT-Base |
| **Eğitim Döngüsü** | CrossEntropyLoss, MSELoss, Adam, SGD (momentum destekli) |
| **INT8 Kuantizasyon** | Per-Channel ve Global INT8 kuantizasyon, QuantizedLinear |
| **PyTorch Uyumluluğu** | `state_dict` birebir yükleme desteği |
| **JIT / Serileştirme** | `.nv` (sıkıştırılmış), `.nv.bin` (saf C++ ikili), ONNX export |
| **InferenceEngine** | FPS ve gecikme takipli canlı çıkarım motoru |
| **Cihaz Yönetimi** | CPU/CUDA geçişi, AVX2 SIMD otomatik tespiti |

### Neden Var?

Derin öğrenme algoritmalarının arkasındaki matematiksel ve donanımsal mantığı (L1/L2 Cache Locality, SIMD AVX2, Topolojik Autograd Sıralaması) **şeffaf** bir şekilde göstermek, deneyler yapmak ve C++ ortamında bağımsız hızlı çıkarım çalıştırmak için geliştirilmiştir.

### Kim Kullanmalı?

- Derin öğrenme motorlarının **iç çalışma mekanizmasını** öğrenmek isteyen araştırmacılar ve öğrenciler
- PyTorch'ta eğittiği modelleri **Python bağımlılığı olmadan** C++ ortamında çalıştırmak isteyen mühendisler
- INT8 kuantizasyon ile **bellek optimizasyonu** yapmak isteyen geliştiriciler

### Kim Kullanmamalı?

- Petabaytlarca veri üzerinde binlerce GPU ile devasa LLM eğitimi yapacak büyük endüstriyel dağıtık sistem ekipleri (PyTorch / JAX kullanmaya devam etmelidirler)

### PyTorch İle İlişkisi Ne?

`newton-vision`, PyTorch'un rakibi veya "katili" **değildir**. PyTorch `.pth` `state_dict` ağırlıklarını birebir yükleyebilen, PyTorch ekosistemiyle **uyumlu çalışan bir kardeş altyapıdır**.

---

## 🚀 Kurulum

```bash
pip install newton-vision
```

**Gereksinimler:**
- Python 3.9+
- NumPy >= 1.20.0
- C++17 uyumlu derleyici (build için: MSVC, GCC, Clang)
- CUDA Toolkit (opsiyonel, GPU ivmelendirme için)

---

## 🗺️ Modül Haritası & API Referansı

`newton-vision` Newton fiziği temalı bir isimlendirme sistemine sahiptir:

```
newton_vision
├── optics         → Görsel Katmanlar (Conv2d, Linear, BatchNorm2d, LayerNorm, GELU, MultiHeadAttention...)
├── fluxion        → Autograd Türev Motoru (Tensor, backward, .cuda(), .cpu(), .to(device))
├── gravity        → Kayıp & Optimizatörler (MSELoss, CrossEntropyLoss, SGD, Adam)
├── principia      → Cihaz Yönetimi (is_cuda_available, get_device, set_device)
├── models         → Model Zoo (ResNet18, MobileNetV2, VisionTransformer, vit_tiny, vit_base)
├── quantization   → INT8 Kuantizasyon (quantize_model, quantize_tensor, QuantizedLinear)
├── weights        → PyTorch Ağırlık Aktarıcı (load_state_dict)
└── jit            → Serileştirme & Çıkarım (InferenceEngine, save/load_model, export_onnx)
```

Her modüle `import newton_vision as nv` ile erişilir:

```python
import newton_vision as nv

# Katmanlar (optics aracılığıyla veya doğrudan):
nv.Conv2d, nv.Linear, nv.ReLU, nv.GELU, nv.BatchNorm2d, nv.LayerNorm, nv.MultiHeadAttention

# Modeller:
nv.models.resnet18(), nv.models.mobilenet_v2(), nv.models.vit_tiny(), nv.models.vit_base()

# Eğitim:
nv.gravity.CrossEntropyLoss(), nv.gravity.Adam(), nv.gravity.SGD()

# Kuantizasyon:
nv.quantize_model(), nv.quantize_tensor(), nv.QuantizedLinear()

# JIT / Serileştirme:
nv.save_model(), nv.load_model(), nv.export_onnx(), nv.InferenceEngine()

# Cihaz:
nv.principia.is_cuda_available(), nv.principia.set_device("cuda")
```

---

## ⚡ Hızlı Başlangıç — 3 Temel Senaryo

### Senaryo 1: Sıfırdan Model Eğitimi (Sadece newton-vision)

Hiçbir harici framework'e ihtiyaç duymadan, saf Autograd türev grafı ile model eğitimi:

```python
import newton_vision as nv
import numpy as np

# ── 1. Sentetik Veri Seti ──────────────────────────────────────────
np.random.seed(42)  # Tekrarlanabilirlik
X_train = np.random.randn(80, 16).astype(np.float32)
y_train = np.random.randint(0, 3, size=(80,)).astype(np.int64)

# ── 2. Model Mimarisi (2 Katmanlı MLP) ────────────────────────────
fc1 = nv.Linear(16, 32)
relu = nv.ReLU()
fc2 = nv.Linear(32, 3)

# ── 3. Optimizatör & Kayıp ────────────────────────────────────────
all_params = fc1.parameters() + fc2.parameters()
optimizer = nv.gravity.Adam(all_params, lr=0.02)
loss_fn = nv.gravity.CrossEntropyLoss()

# ── 4. Eğitim Döngüsü (30 Epoch) ─────────────────────────────────
for epoch in range(1, 31):
    x = nv.Tensor(X_train, requires_grad=True)

    # Forward Pass
    logits = fc2(relu(fc1(x)))
    loss = loss_fn(logits, y_train)

    # Backward Pass (Otomatik Türev)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 10 == 0:
        pred = np.argmax(logits.data, axis=1)
        acc = np.mean(pred == y_train) * 100
        print(f"Epoch {epoch:02d}/30 | Loss: {float(loss.data):.4f} | Acc: {acc:.1f}%")

# Beklenen Çıktı:
# Epoch 10/30 | Loss: 0.8234 | Acc: 68.8%
# Epoch 20/30 | Loss: 0.4512 | Acc: 87.5%
# Epoch 30/30 | Loss: 0.2103 | Acc: 96.2%
```

**Bu Kod Ne Yapıyor:**
1. 80 örnekli 3 sınıflı sentetik veri oluşturur
2. `Linear(16→32) → ReLU → Linear(32→3)` mimarisinde bir MLP tanımlar
3. Adam optimizatörü ile CrossEntropy kaybını minimize eder
4. Her epoch'ta `loss.backward()` çağrısı ile topolojik sıralamaya göre tüm parametrelerin gradyanlarını otomatik hesaplar

---

### Senaryo 2: ViT-Tiny ile Çıkarım (Inference)

```python
import newton_vision as nv
import numpy as np

# ── 1. Görüntü Tensörü (Batch=1, C=3, H=224, W=224) ──────────────
x = nv.Tensor(np.random.randn(1, 3, 224, 224).astype(np.float32))

# ── 2. Vision Transformer Modeli ──────────────────────────────────
model = nv.models.vit_tiny(num_classes=1000)

# ── 3. İleri Geçiş ───────────────────────────────────────────────
logits = model(x)
print(f"Çıktı boyutu: {logits.data.shape}")  # (1, 1000)

# ── 4. Tahmin ─────────────────────────────────────────────────────
predicted_class = np.argmax(logits.data, axis=1)
print(f"Tahmin edilen sınıf: {predicted_class[0]}")
```

**ViT-Tiny Mimarisi:**
- Embed Dim: 192, Depth: 12 Transformer blok, Heads: 3
- Patch Size: 16×16, Image Size: 224×224
- Parametre sayısı: ~5.7M
- Toplam katman akışı: `PatchEmbedding → [CLS Token + Positional Embedding] → 12x TransformerBlock → LayerNorm → Linear Head`

---

### Senaryo 3: PyTorch Ağırlık Aktarımı & INT8 Kuantizasyon

```python
import newton_vision as nv
import numpy as np

# ── PyTorch'ta eğitilmiş ağırlıkları yükle ────────────────────────
# (PyTorch kurulu değilse bile .npy dosyasından yüklenebilir)
try:
    import torch
    torch_model = torch.nn.Linear(10, 5)
    w_np = torch_model.weight.detach().numpy().T  # PyTorch: (out, in) → newton: (in, out)
    b_np = torch_model.bias.detach().numpy()
except ImportError:
    # PyTorch yoksa rastgele ağırlık
    w_np = np.random.randn(10, 5).astype(np.float32) * 0.1
    b_np = np.zeros(5, dtype=np.float32)

# ── INT8 Kuantize Katman Oluştur ──────────────────────────────────
q_layer = nv.QuantizedLinear(in_features=10, out_features=5)
q_layer.load_fp32_weights(w_np, b_np)

# ── 4x Küçük Bellekle Çıkarım ────────────────────────────────────
test_input = np.random.randn(4, 10).astype(np.float32)
output = q_layer(test_input)
print(f"INT8 çıktı boyutu: {output.data.shape}")  # (4, 5)

# ── Bellek Tasarrufu Hesaplama ────────────────────────────────────
fp32_size = 10 * 5 * 4  # 200 byte
int8_size = 10 * 5 * 1 + 4  # 54 byte (ağırlıklar + scale)
print(f"Bellek tasarrufu: {(1 - int8_size/fp32_size)*100:.1f}%")  # ~73%
```

---

## 🏗️ Model Zoo — Hazır Mimariler

### ResNet-18

```python
model = nv.models.resnet18(num_classes=10)
x = nv.Tensor(np.random.randn(1, 3, 224, 224).astype(np.float32))
logits = model(x)  # (1, 10)
```

**Mimari:** `Conv2d(7×7) → BN → ReLU → MaxPool → 4×[ResidualBlock(3×3)] → AvgPool → Linear`

ResidualBlock skip-connection ile gradient vanishing sorununu çözer:
```
input ──→ Conv → BN → ReLU → Conv → BN ──→ (+) → ReLU → output
  │                                          ↑
  └──────────── identity shortcut ───────────┘
```

### MobileNetV2

```python
model = nv.models.mobilenet_v2(num_classes=10)
x = nv.Tensor(np.random.randn(1, 3, 224, 224).astype(np.float32))
logits = model(x)  # (1, 10)
```

**Mimari:** Inverted Residual Block yapısı — depthwise separable convolution ile parametre verimliliği:
```
input → 1×1 Conv(expand) → BN → ReLU → 3×3 DWConv → BN → ReLU → 1×1 Conv(project) → BN → (+) → output
```

### Vision Transformer (ViT)

```python
# ViT-Tiny (5.7M parametre)
model_tiny = nv.models.vit_tiny(num_classes=1000)

# ViT-Base (86M parametre)
model_base = nv.models.vit_base(num_classes=1000)

# Özel yapılandırma
from newton_vision.models.vit import VisionTransformer
custom_vit = VisionTransformer(
    img_size=224,
    patch_size=16,
    in_channels=3,
    num_classes=100,
    embed_dim=384,
    depth=6,
    num_heads=6,
    mlp_ratio=4.0
)
```

**ViT Çalışma Prensibi (adım adım):**

```
1. PatchEmbedding: 224×224 görüntüyü 16×16 patch'lere böl → 196 patch
2. Her patch'i Conv2d(16×16, stride=16) ile embed_dim boyutuna projekte et
3. [CLS] token'ı dizinin başına ekle → 197 token
4. Positional Embedding ekle (öğrenilebilir)
5. 12× TransformerBlock:
   ├── LayerNorm → MultiHeadAttention → Residual Connection
   └── LayerNorm → MLP(Linear→GELU→Linear) → Residual Connection
6. Son LayerNorm
7. [CLS] token çıktısını al → Linear Head → sınıf logits
```

**ViT Yapılandırma Karşılaştırması:**

| Yapılandırma | Embed Dim | Depth | Heads | MLP Ratio | Parametre |
|---|---|---|---|---|---|
| ViT-Tiny | 192 | 12 | 3 | 4.0 | ~5.7M |
| ViT-Base | 768 | 12 | 12 | 4.0 | ~86M |

---

## 🧱 Katman Referansı — Tüm Layer API

### Conv2d — 2D Evrişim Katmanı

```python
conv = nv.Conv2d(
    in_channels=3,       # Giriş kanal sayısı
    out_channels=64,     # Çıkış kanal sayısı (filtre sayısı)
    kernel_size=3,       # Filtre boyutu (3×3)
    stride=1,            # Kayma adımı
    padding=1,           # Kenar dolgusu
    dilation=1,          # Dilated convolution genişlemesi
    groups=1,            # Grouped convolution (depthwise için groups=in_channels)
    bias=True,           # Bias vektörü kullanılsın mı
    device="cpu"         # "cpu" veya "cuda"
)

# İleri geçiş
x = nv.Tensor(np.random.randn(1, 3, 32, 32).astype(np.float32), requires_grad=True)
y = conv(x)  # (1, 64, 32, 32) — padding=1 ile boyut korunur

# Autograd destekli — backward() otomatik çalışır
y.sum().backward()
print(x.grad.shape)  # (1, 3, 32, 32)
```

**C++ Backend'de `im2col + GEMM` ile çalışır.** 2D görüntüyü sütun matrisine dönüştürerek BLAS-tarzı matris çarpımı yapar. Bu yöntem iç içe döngülü naif evrişime göre **~10x hızlanma** sağlar.

### Linear — Tam Bağlantılı Katman

```python
fc = nv.Linear(in_features=512, out_features=10, bias=True, device="cpu")
x = nv.Tensor(np.random.randn(4, 512).astype(np.float32), requires_grad=True)
y = fc(x)  # (4, 10)
```

Matematik: `y = x @ W + b` (Kaiming He başlatma ile)

### Aktivasyon Fonksiyonları

```python
relu = nv.ReLU()          # max(0, x)
leaky = nv.LeakyReLU(0.01)  # x if x > 0 else 0.01*x
sigmoid = nv.Sigmoid()     # 1 / (1 + exp(-x))
tanh = nv.Tanh()           # (exp(x) - exp(-x)) / (exp(x) + exp(-x))
gelu = nv.GELU()           # x * Φ(x) — Transformer'ların standart aktivasyonu
```

Tüm aktivasyonlar C++ backend ile hızlandırılmıştır. GELU ve ReLU autograd backward desteğine sahiptir.

### BatchNorm2d — Batch Normalizasyonu

```python
bn = nv.BatchNorm2d(num_features=64, eps=1e-5, device="cpu")
x = nv.Tensor(np.random.randn(8, 64, 16, 16).astype(np.float32))
y = bn(x)  # (8, 64, 16, 16) — normalize + scale + shift
```

Running mean ve running variance takibi ile eğitim sırasında istatistik toplama.

### LayerNorm — Katman Normalizasyonu

```python
ln = nv.LayerNorm(normalized_shape=192, eps=1e-5, device="cpu")
x = nv.Tensor(np.random.randn(4, 197, 192).astype(np.float32))
y = ln(x)  # (4, 197, 192) — son boyut üzerinden normalize
```

Transformer mimarilerinde her bloktan önce kullanılır.

### MultiHeadAttention — Çok Başlı Öz-Dikkat

```python
mha = nv.MultiHeadAttention(embed_dim=192, num_heads=3, bias=True, device="cpu")
x = nv.Tensor(np.random.randn(2, 197, 192).astype(np.float32))
y = mha(x)  # (2, 197, 192)
```

**İç Çalışma Mekanizması:**
1. Girişi Q, K, V projeksiyonlarına ayırır (3 ayrı Linear katman)
2. Her başlık (head) için `head_dim = embed_dim / num_heads` boyutunda bağımsız attention hesaplar
3. `Attention(Q,K,V) = softmax(Q·Kᵀ / √d_k) · V`
4. Tüm başlıkları birleştirip çıkış projeksiyonu uygular

### MaxPool2d & AvgPool2d — Havuzlama Katmanları

```python
maxpool = nv.MaxPool2d(kernel_size=2, stride=2)
avgpool = nv.AvgPool2d(kernel_size=7, stride=1)

x = nv.Tensor(np.random.randn(1, 64, 32, 32).astype(np.float32), requires_grad=True)
y_max = maxpool(x)  # (1, 64, 16, 16) — boyutu yarıya indirir
y_avg = avgpool(x)  # (1, 64, 26, 26)
```

MaxPool2d autograd backward desteğine sahiptir.

---

## 🔬 Tensor & Autograd Motoru (Fluxion)

### Tensor Oluşturma

```python
import newton_vision as nv
import numpy as np

# NumPy dizisinden
x = nv.Tensor(np.array([1.0, 2.0, 3.0]), requires_grad=True)

# Çok boyutlu
x = nv.Tensor(np.random.randn(2, 3, 224, 224).astype(np.float32), requires_grad=True)

# Cihaz belirtme
x = nv.Tensor(np.zeros((4, 10)), device="cuda")
```

### Temel Özellikler

```python
x = nv.Tensor(np.random.randn(2, 3, 4).astype(np.float32), requires_grad=True)

print(x.shape)     # (2, 3, 4)
print(x.ndim)      # 3
print(x.strides)   # (48, 16, 4) — byte cinsinden
print(x.device)    # "cpu"
print(x.data)      # NumPy ndarray'e doğrudan erişim
print(x.grad)      # Gradyan (backward sonrası dolar)
```

### Desteklenen Operasyonlar (Autograd Destekli)

```python
a = nv.Tensor(np.array([2.0, 3.0]), requires_grad=True)
b = nv.Tensor(np.array([4.0, 5.0]), requires_grad=True)

c = a + b        # Toplama (backward destekli)
d = a * b        # Çarpma (backward destekli)
e = a - b        # Çıkarma (backward destekli)
f = a.sum()      # Toplam skaler (backward destekli)
g = a.mean()     # Ortalama skaler (backward destekli)
h = a[0]         # İndeksleme / dilimleme (backward destekli)
```

### Backward — Otomatik Türev Hesaplama

```python
x = nv.Tensor(np.array([2.0, 3.0]), requires_grad=True)
w = nv.Tensor(np.array([0.5, -1.0]), requires_grad=True)

# Forward
y = (x * w).sum()

# Backward — tüm requires_grad=True tensörlerin gradyanlarını hesaplar
y.backward()

print(x.grad)  # [0.5, -1.0] — ∂y/∂x = w
print(w.grad)  # [2.0,  3.0] — ∂y/∂w = x
```

**Autograd Mekanizması:**
1. Her operasyon bir çocuk düğümü (`_children`) ve bir `_backward` fonksiyonu kaydeder
2. `backward()` çağrıldığında topolojik sıralama (topological sort) ile tüm graf tersine gezilir
3. Zincir kuralı (chain rule) ile her düğümün gradyanı hesaplanır

### Cihaz Transferi

```python
x = nv.Tensor(np.zeros((2, 3)), device="cpu")

# CPU → CUDA
x_gpu = x.cuda()       # veya x.to("cuda")

# CUDA → CPU
x_cpu = x_gpu.cpu()     # veya x_gpu.to("cpu")
```

---

## 📉 Kayıp Fonksiyonları & Optimizatörler (Gravity)

### CrossEntropyLoss — Çapraz Entropi Kaybı

```python
loss_fn = nv.gravity.CrossEntropyLoss()

logits = nv.Tensor(np.random.randn(4, 10).astype(np.float32), requires_grad=True)
labels = np.array([3, 7, 1, 0])  # Hedef sınıf indeksleri

loss = loss_fn(logits, labels)
loss.backward()  # Gradyanlar otomatik hesaplanır
```

Dahili olarak numerik kararlı softmax uygular: `exp(x - max(x))`

### MSELoss — Ortalama Kare Hata

```python
loss_fn = nv.gravity.MSELoss()

pred = nv.Tensor(np.array([1.0, 2.0, 3.0]), requires_grad=True)
target = nv.Tensor(np.array([1.5, 2.5, 3.5]))

loss = loss_fn(pred, target)
loss.backward()
```

### Adam Optimizatörü

```python
optimizer = nv.gravity.Adam(
    params=model.parameters(),  # Eğitilebilir parametre listesi
    lr=0.001,                   # Öğrenme oranı
    beta1=0.9,                  # 1. moment üstel azalma faktörü
    beta2=0.999,                # 2. moment üstel azalma faktörü
    eps=1e-8                    # Sayısal kararlılık epsilon değeri
)

# Eğitim adımı
optimizer.zero_grad()   # Gradyanları sıfırla
loss.backward()         # Gradyanları hesapla
optimizer.step()        # Parametreleri güncelle
```

Adam, bias-corrected first & second moment estimation uygular:
```
m̂ = m / (1 - β₁ᵗ)
v̂ = v / (1 - β₂ᵗ)
θ = θ - lr · m̂ / (√v̂ + ε)
```

### SGD Optimizatörü (Momentum Destekli)

```python
optimizer = nv.gravity.SGD(
    params=model.parameters(),
    lr=0.01,
    momentum=0.9   # 0 = klasik SGD, > 0 = momentum destekli
)
```

---

## 🧊 INT8 Kuantizasyon Motoru

### Neden Kuantizasyon?

FP32 ağırlıkları INT8'e dönüştürerek:
- **4x bellek tasarrufu** (4 byte → 1 byte per parametre)
- **Daha hızlı çıkarım** (INT8 aritmetiği daha ucuzdur)
- **Minimal doğruluk kaybı** (Per-Channel kuantizasyon ile)

### Tensör Düzeyinde Kuantizasyon

```python
import newton_vision as nv
import numpy as np

data = np.random.randn(4, 4).astype(np.float32)

# ── Global Kuantizasyon ───────────────────────────────────────────
q_int8, scale = nv.quantize_tensor(data)
print(f"INT8 veri tipi: {q_int8.dtype}")   # int8
print(f"Scale faktörü: {scale:.6f}")

# ── Geri Dönüştürme (Dequantize) ─────────────────────────────────
recovered = nv.dequantize_tensor(q_int8, scale)
error = np.mean(np.abs(data - recovered))
print(f"Ortalama kuantizasyon hatası: {error:.6f}")  # Tipik: < 0.02

# ── Per-Channel Kuantizasyon ──────────────────────────────────────
q_pc, scales = nv.quantize_tensor_per_channel(data, axis=0)
print(f"Kanal bazlı scale vektörü: {scales}")
```

**Per-Channel vs Global Kuantizasyon:**
- **Global:** Tüm tensör için tek bir `scale` değeri. Aşırı uç değerler (outliers) tüm kanalların hassasiyetini bozar.
- **Per-Channel:** Her filtre/kanal için bağımsız `scale_i` değeri. Outlier'lar sadece kendi kanallarını etkiler. **Her zaman Per-Channel tercih edin.**

### Model Düzeyinde Kuantizasyon

```python
model = nv.models.resnet18(num_classes=10)

# Tüm Linear ve Conv2d katmanlarını INT8'e dönüştür
stats = nv.quantize_model(model, per_channel=True)

print(f"Kuantize parametre sayısı: {stats['total_quantized_params']:,}")
print(f"FP32 bellek:  {stats['fp32_memory_kb']:.1f} KB")
print(f"INT8 bellek:  {stats['int8_memory_kb']:.1f} KB")
print(f"Tasarruf:     {stats['memory_reduction_percent']:.1f}%")  # ~75%
```

### QuantizedLinear — INT8 Lineer Katman

```python
q_linear = nv.QuantizedLinear(in_features=512, out_features=10, bias=True)

# FP32 ağırlıkları yükle (otomatik INT8'e dönüşür)
w_fp32 = np.random.randn(512, 10).astype(np.float32) * 0.01
q_linear.load_fp32_weights(w_fp32)

# INT8 çıkarım
x = np.random.randn(4, 512).astype(np.float32)
output = q_linear(x)  # INT8 matris çarpımı → FP32 çıktı
```

**Dahili INT8 matris çarpımı:**
```
Y_fp32 = (X_int8 @ W_int8).to_int32() × (scale_x × scale_w)
```

---

## 💾 JIT & Serileştirme Motoru

### Model Kaydetme & Yükleme

```python
model = nv.models.vit_tiny(num_classes=10)

# ── Format 1: .nv (Sıkıştırılmış NumPy) ──────────────────────────
nv.save_model(model, "my_model.nv")
nv.load_model(model, "my_model.nv")

# ── Format 2: .nv.bin (Saf C++ İkili) ────────────────────────────
# C++ uygulamalarında Python bağımlılığı olmadan yüklenebilir
nv.save_model_bin(model, "my_model.nv.bin")
nv.load_model_bin(model, "my_model.nv.bin")
```

**.nv.bin Formatı:** `NVBIN100` magic header + tensör adı + 4D boyut + FP32 veri. C++ tarafında `fread()` ile doğrudan okunabilir.

### ONNX Export

```python
dummy_input = np.random.randn(1, 3, 224, 224).astype(np.float32)
nv.export_onnx(model, dummy_input, "my_model.onnx")
```

Not: Mevcut ONNX export, graf tanımlayıcı üretir (giriş/çıkış boyutu, parametre sayısı). Tam ONNX operatör grafi desteği gelecek sürümlerde planlanmaktadır.

### InferenceEngine — Canlı Çıkarım Motoru

```python
model = nv.models.vit_tiny(num_classes=1000)
engine = nv.InferenceEngine(model)

# Tek kare çıkarımı
frame = np.random.randn(1, 3, 224, 224).astype(np.float32)
output, latency_ms, fps = engine.predict(frame)
print(f"Gecikme: {latency_ms:.2f} ms | FPS: {fps:.1f}")

# 100 kare akışı simülasyonu
for i in range(100):
    frame = np.random.randn(1, 3, 224, 224).astype(np.float32)
    output, lat, fps = engine.predict(frame)

# Ortalama istatistikler
avg_lat, avg_fps = engine.get_average_stats()
print(f"Ortalama Gecikme: {avg_lat:.2f} ms | Ortalama FPS: {avg_fps:.1f}")
```

---

## 🤝 PyTorch Ağırlık Aktarımı

### Mekanizma

`newton-vision`, PyTorch'un `state_dict()` sözlük yapısını birebir destekler:

```python
import torch
import newton_vision as nv

# ── PyTorch'ta Eğit ───────────────────────────────────────────────
torch_model = torch.nn.Sequential(
    torch.nn.Linear(784, 256),
    torch.nn.ReLU(),
    torch.nn.Linear(256, 10)
)
# ... eğitim kodu ...

# ── State Dict'i Çıkar ───────────────────────────────────────────
state_dict = {k: v.detach().cpu().numpy() for k, v in torch_model.state_dict().items()}

# ── newton-vision Modeline Yükle ──────────────────────────────────
nv_model = ...  # Aynı mimaride newton-vision modeli
nv.load_state_dict(nv_model, state_dict)
```

**Parametre Eşleme:**

| PyTorch Adı | newton-vision Adı |
|---|---|
| `weight` | `w` (Tensor) |
| `bias` | `bias` (Tensor) |
| `weight` (BatchNorm) | `gamma` (Tensor) |
| `bias` (BatchNorm) | `beta` (Tensor) |
| `running_mean` | `running_mean` (ndarray) |
| `running_var` | `running_var` (ndarray) |

**Dikkat:** PyTorch Linear ağırlıkları `(out_features, in_features)` şeklindedir. newton-vision `(in_features, out_features)` kullanır. Aktarım sırasında transpoz gerekebilir.

---

## 🖥️ Cihaz Yönetimi — CPU & CUDA

```python
import newton_vision as nv

# ── CUDA Kullanılabilirliği ───────────────────────────────────────
if nv.principia.is_cuda_available():
    print("CUDA GPU mevcut!")
    nv.principia.set_device("cuda")
else:
    print("CPU modu aktif")

# ── Mevcut Cihaz ─────────────────────────────────────────────────
print(nv.principia.get_device())  # "cpu" veya "cuda"

# ── Tensör Cihaz Transferi ────────────────────────────────────────
x = nv.Tensor(np.zeros((2, 3)), device="cpu")
x_gpu = x.cuda()
x_cpu = x_gpu.cpu()
```

**AVX2 SIMD Tespiti:**
C++ backend çalışma zamanında `CPUID` komutu ile CPU'nun AVX2 desteğini kontrol eder. AVX2 varsa SIMD hızlandırılmış GEMM kullanılır; yoksa fallback yoluna geçilir. Bu sayede ARM (Apple Silicon) veya eski x86 işlemcilerde `SIGILL` çökmesi yaşanmaz.

---

## ⚙️ C++ Backend Mimarisi

`newton-vision`'ın tüm ağır hesaplama işlemleri C++17 ile yazılmıştır:

### Dosya Yapısı

```
cpp/
├── layers.h           → Tüm fonksiyon imzaları (API)
├── layers.cpp         → CPU implementasyonları (im2col, GEMM, aktivasyonlar, backward)
├── simd_gemm.h        → AVX2 SIMD ile hızlandırılmış matris çarpımı
├── cuda_layers.h      → CUDA kernel imzaları
├── cuda_layers.cu     → CUDA GPU kernel implementasyonları
└── binding.cpp        → pybind11 Python bağlama katmanı
```

### C++ ile İmplemente Edilen Fonksiyonlar

| Fonksiyon | Açıklama |
|---|---|
| `im2col_cpu()` | 2D görüntüyü sütun matrisine dönüştürür (stride, dilation, padding destekli) |
| `gemm_cpu()` | Paralel matris çarpımı C = A × B + bias |
| `conv2d()` | Forward: im2col + GEMM tabanlı 2D evrişim |
| `conv2d_backward()` | Backward: ∂L/∂x, ∂L/∂w, ∂L/∂b gradyan hesaplama |
| `relu()` | Forward: max(0, x) |
| `relu_backward()` | Backward: x > 0 ? 1 : 0 |
| `leaky_relu()` | Forward: x > 0 ? x : αx |
| `sigmoid_fn()` | Forward: 1/(1+e⁻ˣ) |
| `tanh_fn()` | Forward: tanh(x) |
| `gelu_fn()` | Forward: x·Φ(x) Gaussian Error Linear Unit |
| `maxpool2d()` | Forward: bölgede maksimum değer |
| `maxpool2d_backward()` | Backward: maksimum konumuna gradyan yönlendirme |
| `avgpool2d()` | Forward: bölgede ortalama değer |
| `batchnorm2d()` | Forward: kanal bazlı normalizasyon |
| `layernorm()` | Forward: özellik boyutunda normalizasyon |
| `has_cuda()` | CUDA GPU mevcut mu? |
| `has_avx2_hardware()` | CPU AVX2 SIMD destekliyor mu? |

### im2col + GEMM Evrişim Stratejisi

Naif 6-katlı iç içe döngü yerine:

```
Giriş (N,C,H,W) → im2col → Sütun Matrisi (C×kH×kW, H_out×W_out)
                              × Filtre Matrisi (C_out, C×kH×kW)
                              = Çıkış Matrisi (C_out, H_out×W_out)
                              → reshape → (N, C_out, H_out, W_out)
```

Bu yaklaşım L1/L2 önbellek yerelliği (cache locality) sağlayarak **~10x hızlanma** verir.

---

## 📊 Benchmark Sonuçları

`Intel64 Family 6 (12 Threads)` üzerinde PyTorch v2.6.0 CPU ile dürüst ve istatistiksel karşılaştırma (`Warmup=5, Runs=20`):

| Model | Framework | Mean (ms) | Std (ms) | Min (ms) | Max (ms) | FPS | Karşılaştırma |
|---|---|---|---|---|---|---|---|
| **ViT-Tiny** | newton-vision | **210.62** | ±18.33 | 174.47 | 240.62 | **4.7** | **2.28x Hızlı** 🚀 |
| | PyTorch CPU | 472.23 | ±29.48 | 458.22 | 585.02 | 2.1 | Referans |
| **ResNet-18** | newton-vision | **119.95** | ±12.37 | 98.28 | 146.52 | **8.3** | 4.63x Yavaş |
| | PyTorch CPU | 25.90 | ±0.77 | 24.97 | 27.74 | 38.6 | Referans |
| **MobileNetV2** | newton-vision | **4842.70** | ±819.54 | 3619.07 | 7078.85 | **0.2** | 81.01x Yavaş |
| | PyTorch CPU | 59.78 | ±2.94 | 54.99 | 66.91 | 16.7 | Referans |

**Yorum:** Transformer mimarisinde (ViT-Tiny) PyTorch'u geçiyoruz çünkü saf matris operasyonlarında im2col+GEMM avantajlıdır. CNN mimarilerinde (ResNet, MobileNet) ise PyTorch'un yıllardır optimize edilmiş MKL/oneDNN backend'i nedeniyle arkadayız. Bu, beklenen ve dürüst bir sonuçtur. `newton-vision` birincil olarak eğitim/araştırma aracıdır, production CNN inference için PyTorch/TensorRT önerilir.

---

## 🤖 Transformer & LLM Yetkinliği

### Mevcut Durum (v1.1.x)

`newton-vision` aşağıdaki Transformer bileşenlerini **tamamen sıfırdan** implemente etmiştir:

| Bileşen | Durum | Açıklama |
|---|---|---|
| `MultiHeadAttention` | ✅ Tam | Q/K/V projeksiyonları, Scaled Dot-Product Attention, çıkış projeksiyonu |
| `LayerNorm` | ✅ Tam | Öğrenilebilir γ ve β parametreleri |
| `GELU` | ✅ Tam | Backward destekli |
| `TransformerBlock` | ✅ Tam | Pre-LN yapısı, MLP bloğu, Residual Connection |
| `PatchEmbedding` | ✅ Tam | Conv2d tabanlı patch tokenizasyonu |
| `VisionTransformer` | ✅ Tam | CLS token, Positional Embedding, Classification Head |
| `CrossEntropyLoss` | ✅ Tam | Autograd backward destekli |
| `Adam` | ✅ Tam | Bias-corrected moment estimation |

### LLM Eğitebilir mi?

**Kısa cevap: Yapı taşları mevcut, ancak henüz production-ready bir LLM eğitim pipeline'ı yok.**

**Mevcut olan:**
- Transformer encoder blokları (attention + MLP + residual)
- Autograd motoru (backward pass)
- Adam optimizatörü
- CrossEntropyLoss

**Henüz olmayan:**
- Causal/Masked Self-Attention (decoder-only mimariler için)
- Token Embedding ve Text Tokenizer
- Positional Encoding (sinüzoidal veya RoPE)
- Dağıtık eğitim (multi-GPU, data parallelism)
- Gradient checkpointing / mixed precision (FP16/BF16)
- Flash Attention veya benzeri memory-efficient attention
- Büyük veri seti yükleme pipeline'ı

**Sonuç:** `newton-vision` şu an Vision Transformer (ViT) ile **görsel sınıflandırma** eğitimi ve çıkarımı yapabilir. Metin tabanlı LLM (GPT, LLaMA tarzı) eğitimi için yukarıdaki bileşenlerin eklenmesi gerekmektedir. Transformer altyapısı mevcuttur ve bu bileşenler üzerine inşa edilebilir — bu, yol haritamızın bir parçasıdır.

---

## 📚 Örnek Projeler & Öğreticiler

Aşağıdaki dosyalar proje deposunda `examples/` ve `tutorials/` dizinlerinde bulunmaktadır.

### Örnek 1: MNIST LeNet Sınıflandırma (examples/01_image_classification_lenet.py)

LeNet-5 mimarisinde MNIST el yazısı rakam sınıflandırması:

```python
import newton_vision as nv
import numpy as np

# LeNet-5 Mimarisi
conv1 = nv.Conv2d(1, 6, kernel_size=5, padding=2)
conv2 = nv.Conv2d(6, 16, kernel_size=5)
pool = nv.MaxPool2d(2, 2)
relu = nv.ReLU()
fc1 = nv.Linear(16 * 5 * 5, 120)
fc2 = nv.Linear(120, 84)
fc3 = nv.Linear(84, 10)

# Forward Pass
def forward(x):
    x = pool(relu(conv1(x)))
    x = pool(relu(conv2(x)))
    N = x.data.shape[0]
    flat = nv.Tensor(x.data.reshape(N, -1), requires_grad=True)
    return fc3(relu(fc2(relu(fc1(flat)))))
```

### Örnek 2: PyTorch ResNet-18 Ağırlık Aktarımı (examples/02_resnet18_pytorch_weights.py)

```python
import torch
import torchvision.models as tmodels
import newton_vision as nv

# PyTorch pretrained ResNet-18
torch_resnet = tmodels.resnet18(weights=tmodels.ResNet18_Weights.DEFAULT)
state_dict = {k: v.cpu().numpy() for k, v in torch_resnet.state_dict().items()}

# newton-vision ResNet-18'e aktar
nv_resnet = nv.models.resnet18(num_classes=1000)
nv.load_state_dict(nv_resnet, state_dict)
```

### Örnek 3: ViT Transformer Çıkarımı (examples/03_vit_transformer_inference.py)

```python
import newton_vision as nv
import numpy as np

model = nv.models.vit_tiny(num_classes=1000)
engine = nv.InferenceEngine(model)

for i in range(10):
    frame = np.random.randn(1, 3, 224, 224).astype(np.float32)
    output, latency, fps = engine.predict(frame)
    print(f"Frame {i+1:02d} | {latency:.1f} ms | {fps:.1f} FPS")
```

### Örnek 4: INT8 Kuantizasyon Demosu (examples/04_int8_quantization_demo.py)

```python
import newton_vision as nv
import numpy as np

model = nv.models.resnet18(num_classes=10)

# Kuantizasyon öncesi çıkarım
x = nv.Tensor(np.random.randn(1, 3, 224, 224).astype(np.float32))
fp32_out = model(x)

# INT8 kuantizasyon uygula
stats = nv.quantize_model(model, per_channel=True)
int8_out = model(x)

# Karşılaştırma
diff = np.mean(np.abs(fp32_out.data - int8_out.data))
print(f"FP32 vs INT8 farkı: {diff:.6f}")
print(f"Bellek tasarrufu: {stats['memory_reduction_percent']:.1f}%")
```

### Örnek 5: ONNX Export (examples/05_onnx_export_guide.py)

```python
import newton_vision as nv
import numpy as np

model = nv.models.vit_tiny(num_classes=10)
dummy = np.random.randn(1, 3, 224, 224).astype(np.float32)
nv.export_onnx(model, dummy, "vit_tiny.onnx")
```

### Öğretici 1: Tekrarlanabilir MNIST Eğitimi (tutorials/01_train_mnist.py)

Seed=42 ile her zaman aynı sonucu veren tam eğitim pipeline'ı:

```python
import newton_vision as nv
import numpy as np

np.random.seed(42)

# Sentetik MNIST benzeri veri (gerçek MNIST için sklearn veya manual yükleme gerekir)
N_TRAIN, N_TEST = 600, 100
X_train = np.random.randn(N_TRAIN, 1, 28, 28).astype(np.float32)
y_train = np.random.randint(0, 10, N_TRAIN)
X_test = np.random.randn(N_TEST, 1, 28, 28).astype(np.float32)
y_test = np.random.randint(0, 10, N_TEST)

# Basit CNN
conv1 = nv.Conv2d(1, 8, 3, padding=1)
pool = nv.MaxPool2d(2, 2)
relu = nv.ReLU()
fc1 = nv.Linear(8 * 14 * 14, 64)
fc2 = nv.Linear(64, 10)

params = conv1.parameters() + fc1.parameters() + fc2.parameters()
optimizer = nv.gravity.Adam(params, lr=0.001)
loss_fn = nv.gravity.CrossEntropyLoss()

# Eğitim
for epoch in range(1, 11):
    x = nv.Tensor(X_train, requires_grad=True)
    h = pool(relu(conv1(x)))
    N = h.data.shape[0]
    h_flat = nv.Tensor(h.data.reshape(N, -1), requires_grad=True)
    logits = fc2(relu(fc1(h_flat)))

    loss = loss_fn(logits, y_train)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    acc = np.mean(np.argmax(logits.data, axis=1) == y_train) * 100
    print(f"Epoch {epoch:02d} | Loss: {float(loss.data):.4f} | Train Acc: {acc:.1f}%")
```

### Öğretici 2: 3 Aşamalı Canlı Demo (tutorials/live_3stage_demo.py)

3 aşamalı karşılaştırma: Saf Eğitim → PyTorch Aktarımı → INT8 Kuantizasyon.

```python
import newton_vision as nv
import numpy as np

print("=" * 60)
print("AŞAMA 1: Saf newton-vision Eğitimi")
print("=" * 60)

fc1 = nv.Linear(16, 32)
fc2 = nv.Linear(32, 3)
relu = nv.ReLU()
optimizer = nv.gravity.Adam(fc1.parameters() + fc2.parameters(), lr=0.01)
loss_fn = nv.gravity.CrossEntropyLoss()

X = np.random.randn(50, 16).astype(np.float32)
y = np.random.randint(0, 3, 50)

for ep in range(20):
    logits = fc2(relu(fc1(nv.Tensor(X, requires_grad=True))))
    loss = loss_fn(logits, y)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
print(f"Son Loss: {float(loss.data):.4f}")

print("\n" + "=" * 60)
print("AŞAMA 2: Model Kaydetme & Yükleme")
print("=" * 60)

# Model parametrelerini .nv formatında kaydet ve geri yükle
# (tam model serileştirme için wrapper gerekir)

print("\n" + "=" * 60)
print("AŞAMA 3: INT8 Kuantizasyon")
print("=" * 60)

q_fc1 = nv.QuantizedLinear(16, 32)
q_fc1.load_fp32_weights(fc1.w.data, fc1.bias.data if fc1.bias is not None else None)
q_out = q_fc1(X)
print(f"INT8 çıktı boyutu: {q_out.data.shape}")
```

### C++ Saf Çıkarım (examples/cpp_inference_demo.cpp)

Python bağımlılığı olmadan C++ ile çıkarım:

```cpp
#include "layers.h"
#include <vector>
#include <cstdio>
#include <fstream>

int main() {
    // .nv.bin dosyasından ağırlıkları oku
    FILE* f = fopen("model.nv.bin", "rb");
    // ... ağırlık yükleme kodu ...

    // Conv2d forward pass
    int H_out, W_out;
    auto output = nv::conv2d(input_data, input_shape,
                              weight_data, 64, 3, 3,
                              bias_data, 1, 1, 1, 1,
                              H_out, W_out);

    // ReLU
    auto activated = nv::relu(output.data(), output.size());

    printf("Output shape: (%d, %d)\n", H_out, W_out);
    return 0;
}
```

---

## ✅ Test Kapsamı

Proje aşağıdaki test dosyalarını içerir (tümü `tests/` dizininde):

| Test Dosyası | Kapsam |
|---|---|
| `test_autograd.py` | Tensor operasyonları, backward pass, gradient doğruluğu |
| `test_correctness.py` | Conv2d, Linear, ReLU çıktı doğruluğu (PyTorch ile karşılaştırma) |
| `test_models.py` | ResNet-18, MobileNetV2 forward pass boyut doğruluğu |
| `test_vit.py` | VisionTransformer, PatchEmbedding, TransformerBlock doğruluğu |
| `test_quantization.py` | INT8 kuantizasyon, dequantizasyon, QuantizedLinear doğruluğu |
| `test_jit.py` | Model kaydetme/yükleme, .nv ve .nv.bin formatları |
| `test_cpp_core.cpp` | C++ backend birim testleri |

Testleri çalıştırma:

```bash
python -m pytest tests/ -v
```

---

## 🤝 Katkıda Bulunma

1. Depoyu fork'layın
2. Feature branch oluşturun: `git checkout -b feature/yeni-ozellik`
3. Değişikliklerinizi commit'leyin: `git commit -m 'feat: yeni özellik ekle'`
4. Branch'inizi push'layın: `git push origin feature/yeni-ozellik`
5. Pull Request açın

**Commit Mesajı Formatı:** Conventional Commits (feat:, fix:, docs:, refactor:, test:, perf:)

**Kod Stili:** PEP 8 (Python), Google C++ Style Guide (C++)

---

## 🔒 Güvenlik Politikası

Güvenlik açığı bulursanız:
- **Public issue açmayın**
- E-posta ile bildirin: `info@newton-vision.org`
- 48 saat içinde yanıt alacaksınız

Desteklenen sürümler: v1.1.x (en güncel minor sürüm)

---

## 📋 Sürüm Geçmişi

### v1.1.4 (Güncel)
- README tamamen yeniden yazıldı (PyPI uyumlu, self-contained)
- Tüm dahili link bağımlılıkları kaldırıldı
- LLM yetkinlik durumu belgelendi

### v1.1.0
- Vision Transformer (ViT-Tiny, ViT-Base) eklendi
- MultiHeadAttention, LayerNorm, GELU katmanları eklendi
- PatchEmbedding ve TransformerBlock eklendi
- Per-Channel INT8 Kuantizasyon eklendi
- InferenceEngine (FPS/gecikme takibi) eklendi
- ONNX Export desteği eklendi

### v1.0.0
- İlk kararlı sürüm
- Conv2d (im2col + GEMM), Linear, ReLU, MaxPool2d, AvgPool2d, BatchNorm2d
- Reverse-mode Autograd motoru
- ResNet-18 ve MobileNetV2
- PyTorch state_dict uyumluluğu
- .nv ve .nv.bin serileştirme
- CPU/CUDA cihaz yönetimi
- AVX2 SIMD otomatik tespiti

---

## 📜 Lisans

Bu proje **MIT Lisansı** ile lisanslanmıştır. Telif hakkı (c) 2025 newton-vision Core Team.

```
MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software...
```

---

> **newton-vision** — Derin öğrenmenin fiziğini anla, motorunu kendin yaz. 🌌
