Bu proje, Udemy platformundaki Derin Öğrenme 2026: 100 Günlük Kamp kapsamında geliştirilmiştir ve eğitimin ikinci uygulamalı projesidir.
Projenin amacı, PyTorch kullanılarak çok sınıflı (multi-class) bir sınıflandırma problemini Çok Katmanlı Algılayıcı (MLP) modeli ile çözmektir.
Repo iki kısımdan oluşur:
- Model geliştirme —
02-assignmentMultClas.ipynbnotebook'u: veri analizi, eğitim, değerlendirme ve modelin diske kaydedilmesi. - Web uygulaması — eğitilen modeli tarayıcı üzerinden kullanılabilir hâle getiren FastAPI backend'i ve saf HTML/CSS/JS arayüzü.
.
├── 02-assignmentMultClas.ipynb # Veri analizi, model eğitimi ve değerlendirme
├── backend/
│ ├── main.py # FastAPI uygulaması (/predict, /health, /features)
│ ├── model.py # Notebook'taki BeanClassifier mimarisinin birebir kopyası
│ ├── requirements.txt # Web uygulaması bağımlılıkları
│ ├── bean_classification_model.pth # Eğitilmiş model (state_dict)
│ ├── scaler.pkl # Notebook'ta fit edilen StandardScaler (joblib)
│ └── label_encoder.pkl # Notebook'ta fit edilen LabelEncoder (joblib)
├── frontend/
│ ├── index.html # Tek sayfalık arayüz
│ ├── style.css
│ └── app.js # Form + fetch + olasılık barları
└── README.md
Projede Dry_Bean_Dataset.xlsx adlı, 7 farklı kuru fasulye türüne ait görüntü işleme yöntemleriyle çıkarılmış geometrik özellikleri içeren veri seti kullanılmıştır.
Not: Dosya boyutu nedeniyle veri seti bu repoya dahil edilmemiştir. Notebook'u çalıştırmadan önce aşağıdaki adımları izleyin:
- Veri setini Kaggle - Dry Bean Dataset sayfasından indirin.
- İndirilen
Dry_Bean_Dataset.xlsxdosyasını bu notebook (02-assignmentMultClas.ipynb) ile aynı klasöre yerleştirin.Web uygulaması veri setine ihtiyaç duymaz; eğitilmiş model, scaler ve encoder dosyaları
backend/klasöründe hazır durumdadır.
- Örneklem Sayısı: 13.611
- Özellikler (Features): 16 adet sayısal geometrik özellik —
Area,Perimeter,MajorAxisLength,MinorAxisLength,AspectRation,Eccentricity,ConvexArea,EquivDiameter,Extent,Solidity,roundness,Compactness,ShapeFactor1-4 - Hedef (Target):
Class— 7 fasulye türü:BARBUNYA,BOMBAY,CALI,DERMASON,HOROZ,SEKER,SIRA - Ön İşleme: Hedef sütun
LabelEncoderile sayısal değerlere (0-6) dönüştürülmüş, özelliklerStandardScalerile standartlaştırılmıştır (ölçek farklılıkları modelin öğrenmesini olumsuz etkilediği için normalizasyon zorunlu hale gelmiştir).
Geliştirilen yapay sinir ağı modeli, aralarında doğrusal olmayan yapıyı öğrenebilmesi için ReLU aktivasyon fonksiyonları ve aşırı öğrenmeyi (overfitting) azaltmak için Dropout katmanları bulunan 4 Doğrusal (Linear) katmandan oluşmaktadır:
- Gizli Katman 1: 16 girdi -> 128 nöron (Aktivasyon: ReLU, Dropout: 0.2)
- Gizli Katman 2: 128 nöron -> 128 nöron (Aktivasyon: ReLU, Dropout: 0.2)
- Gizli Katman 3: 128 nöron -> 128 nöron (Aktivasyon: ReLU, Dropout: 0.2)
- Çıktı Katmanı: 128 nöron -> 7 çıktı (7 sınıf için logit)
- Kayıp Fonksiyonu (Loss Function): Çok sınıflı sınıflandırma problemi olduğu için
nn.CrossEntropyLoss()kullanılmıştır. - Optimizasyon (Optimizer):
Adamalgoritması tercih edilmiş olup Öğrenme Oranı (Learning Rate)0.001olarak belirlenmiştir. - Veri Bölme: %80 Eğitim (Train), %20 Test (
stratify=yile sınıf dağılımı korunarak bölünmüştür) - Epoch Sayısı: Model toplam 321 epoch eğitilmiştir (
epochs = 321, yani 0–320 aralığı). - Değerlendirme Metriği:
torchmetricskütüphanesindenMulticlassAccuracykullanılmıştır.
Model, eğitim sonunda yaklaşık %94.3 eğitim doğruluğu ve %93.5 test doğruluğu elde etmiştir.
İlk denemelerde, Dropout katmanı eklenmeden önce eğitim ve test doğruluğu arasındaki farkın epoch sayısı arttıkça büyüdüğü (hafif overfitting) gözlemlenmiştir. Modele her gizli katmandan sonra Dropout(0.2) eklenerek bu fark belirgin şekilde azaltılmış, modelin genelleme kapasitesi iyileştirilmiştir.
Karışıklık matrisi (confusion matrix) incelendiğinde, modelin özellikle DERMASON ve SIRA türleri ile BARBUNYA ve CALI türleri arasında bazı yanlış sınıflandırmalar yaptığı görülmüştür. Bu durum modelin bir hatası değil, bu fasulye türlerinin geometrik özellikler açısından birbirine gerçekten benzemesinden kaynaklanan, veri setine özgü doğal bir zorluktur.
Sonuçlar MulticlassConfusionMatrix ile hesaplanmış ve seaborn heatmap ile görselleştirilerek modelin hangi sınıfları birbirine karıştırdığı analiz edilmiştir.
Eğitilen model bir REST API arkasına alınmış ve tek sayfalık bir web arayüzüyle kullanılabilir hâle getirilmiştir. Kullanıcı 16 geometrik özelliği girer, uygulama fasulye türünü ve her sınıf için olasılığı döner.
- Backend: FastAPI + PyTorch.
backend/model.pyiçindekiBeanClassifiersınıfı notebook'taki mimarinin birebir kopyasıdır (katman isimleri dahil — aksi hâldestate_dictyüklenemez). Notebook'tafitedilenStandardScalerveLabelEncoderjoblibile yüklenip aynen kullanılır. - Frontend: Bağımlılık ve derleme adımı olmadan, saf HTML/CSS/JS.
Tahmin akışı: JSON girdi → StandardScaler.transform → model (logit) → softmax → argmax → LabelEncoder.inverse_transform ile sınıf ismi.
- 16 özellik için sayısal giriş formu (etiketler Türkçe, parantez içinde veri setindeki sütun adı)
- Örnek veri doldur: veri setinden alınmış gerçek satırları sırayla yükler. Her sınıf için o sınıfın medyanına en yakın (türü en iyi temsil eden) satır seçilmiştir; hangi sınıfın satırı olduğu forma yazılır, böylece tahminin doğruluğu anında görülebilir.
- Tahmin Et: tahmin edilen türü ve 7 sınıfın olasılığını büyükten küçüğe barlar hâlinde gösterir
- Sağ üstteki gösterge backend'in ayakta olup olmadığını bildirir
- Mobil/tablet için responsive; koyu tema desteklenir
Backend varsayılan olarak http://127.0.0.1:8000 adresinde çalışır. İnteraktif dokümantasyon: http://127.0.0.1:8000/docs
Servisin ve modelin durumu:
{
"status": "ok",
"model_loaded": true,
"num_features": 16,
"num_classes": 7,
"features": ["Area", "..."],
"classes": ["BARBUNYA", "..."]
}Arayüzün form alanlarını doğru sırayla kurabilmesi için özellik ve sınıf listesini döner.
İstek gövdesi — 16 alanın tamamı zorunlu, isimler veri setindeki sütun adlarıyla aynı (AspectRation ve roundness yazımına dikkat):
{
"Area": 39339,
"Perimeter": 721.525,
"MajorAxisLength": 250.34786140984878,
"MinorAxisLength": 200.3269470472531,
"AspectRation": 1.2496963843351376,
"Eccentricity": 0.5997407642045551,
"ConvexArea": 39685,
"EquivDiameter": 223.80341921055756,
"Extent": 0.7789284017107556,
"Solidity": 0.9912813405568854,
"roundness": 0.9495774943278767,
"Compactness": 0.8939697665088704,
"ShapeFactor1": 0.006363859310349749,
"ShapeFactor2": 0.002507215468336906,
"ShapeFactor3": 0.7991819434319243,
"ShapeFactor4": 0.9987347851328043
}Yanıt:
{
"prediction": "SEKER",
"predicted_index": 5,
"confidence": 99.72,
"probabilities": [
{ "class_name": "BARBUNYA", "probability": 0.000271, "percentage": 0.03 },
{ "class_name": "BOMBAY", "probability": 0.0, "percentage": 0.0 }
]
}probabilities her zaman 7 sınıfı label_encoder.classes_ sırasıyla döner; percentage değerleri toplamı %100'dür. Eksik veya geçersiz alan gönderilirse 422 döner.
Örnek istek (yukarıdaki gövdeyi ornek.json olarak kaydedip):
curl -X POST http://127.0.0.1:8000/predict \
-H "Content-Type: application/json" \
-d @ornek.jsonPython 3.10 veya üzeri gereklidir. Aşağıdaki tüm komutlar depo kök klasöründen (bu README'nin bulunduğu yerden) başlar.
Windows (PowerShell):
python -m venv .venv
.\.venv\Scripts\Activate.ps1macOS / Linux:
python3 -m venv .venv
source .venv/bin/activateOrtam aktifken bağımlılıkları kurun. Web uygulaması için:
pip install -r backend/requirements.txtNotebook'u da çalıştıracaksanız ek olarak (.xlsx okuma, görselleştirme ve metrikler için):
pip install jupyter openpyxl pandas matplotlib seaborn torchmetricsbackend/requirements.txt zaten torch, scikit-learn, joblib ve numpy
içerdiği için bunları tekrar kurmanız gerekmez — tek sanal ortam her iki kısım
için yeterlidir.
Veri setini Kaggle üzerinden indirip depo köküne koyduktan sonra:
jupyter notebook 02-assignmentMultClas.ipynbNotebook, model ve ön işleme dosyalarını kendi bulunduğu klasöre (yani depo köküne) kaydeder. Yeni eğitilen modeli web uygulamasında kullanmak için oluşan bean_classification_model.pth, scaler.pkl ve label_encoder.pkl dosyalarını backend/ klasörüne kopyalayın.
Sadece web uygulamasını denemek istiyorsanız bu adımı atlayabilirsiniz; backend/ içindeki eğitilmiş dosyalar hazırdır.
cd backend
python main.pyAlternatif olarak, kod değişikliklerinde otomatik yenileme için:
cd backend
uvicorn main:app --reload --port 8000Her iki komut da
backendklasörünün içinden çalıştırılmalıdır;main.py,model.pymodülünü doğrudan import ediyor.
python main.pysunucuyu0.0.0.0üzerinde açar, yani aynı ağdaki diğer cihazlardan da erişilebilir. Yalnızca kendi bilgisayarınızda kullanacaksanızuvicorn main:app --host 127.0.0.1 --port 8000tercih edilebilir.
Sunucunun ayakta olduğunu http://127.0.0.1:8000/health adresinden doğrulayabilirsiniz.
Backend çalışırken frontend/index.html dosyasını tarayıcıda açmanız yeterlidir (CORS açık olduğu için file:// üzerinden de çalışır). Alternatif olarak küçük bir statik sunucu:
cd frontend
python -m http.server 5500Ardından http://127.0.0.1:5500 adresini açın.
Backend farklı bir port veya host'ta çalışıyorsa frontend/app.js dosyasının en üstündeki API_URL değerini güncelleyin.
backend/main.pyiçinde modeleval()moduna alınır; aksi hâldeDropoutaktif kalacağı için aynı girdi her istekte farklı sonuç verirdi.- Özellik sırası
backend/model.pyiçindekiFEATURE_NAMESlistesiyle sabitlenmiştir.StandardScalerbu sıraya görefitedildiği için sıra değiştirilemez. - Model, scaler ve encoder uygulama açılışında bir kez yüklenir; her istekte yeniden okunmaz.
- Veri seti (
Dry_Bean_Dataset.xlsx) ve sanal ortam (.venv/).gitignoreiçindedir.