Bu proje VGG16 mimarisini baz alarak transfer learning metoduyla sınıflandırma yapan CNN modelidir. Model Tensorflow/Keras kullanıralarak eğitilmiş olup hava durumu veriseti ile birlikte hava durumunu ayırt edebilmektedir.
Verisetini doğrudan dataset/dataset.zip dosya yolundan indirip çıkarabilirsiniz. Veriseti train-test-validation olarak ayrılmış durumdadır.
## Proje Yapısı
├── assests/
│ ├── acc-graph.png
│ ├── loss-graph.png
│ └── confision-matrix.png
├── dataset/
│ └── dataset.zip
├── model/
│ └── best_model.keras
├── notebook/
│ └── weather_classification.ipynb
├── predict_images/
│ └── (Tahmin için örnek görseller, her görsel kendi klasöründe bulunmaktadır.)
├── predict.py
└── README.md
└── results.jpg
Model, VGG16 tabanlı transfer öğrenme yaklaşımını kullanır ve son katmanları fine-tune edilerek hava durumu sınıflandırması için özelleştirilmiştir.
inputs = Input(shape=(224, 224, 3))
x = data_augmentation(inputs)
base_model = VGG16(
weights='imagenet',
include_top=False,
input_tensor=x
)
fine_tune_at = 15
for layer in base_model.layers[:fine_tune_at]:
layer.trainable = False
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(256)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Dropout(0.3)(x)
x = Dense(128)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Dropout(0.3)(x)
x = Dense(64)(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Dropout(0.3)(x)
outputs = Dense(6)(x)
outputs = Activation('softmax')(outputs)
model = Model(inputs=inputs, outputs=outputs)┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer_4 (InputLayer) │ (None, 224, 224, 3) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ sequential_2 (Sequential) │ (None, 224, 224, 3) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block1_conv1 (Conv2D) │ (None, 224, 224, 64) │ 1,792 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block1_conv2 (Conv2D) │ (None, 224, 224, 64) │ 36,928 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block1_pool (MaxPooling2D) │ (None, 112, 112, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block2_conv1 (Conv2D) │ (None, 112, 112, 128) │ 73,856 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block2_conv2 (Conv2D) │ (None, 112, 112, 128) │ 147,584 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block2_pool (MaxPooling2D) │ (None, 56, 56, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block3_conv1 (Conv2D) │ (None, 56, 56, 256) │ 295,168 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block3_conv2 (Conv2D) │ (None, 56, 56, 256) │ 590,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block3_conv3 (Conv2D) │ (None, 56, 56, 256) │ 590,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block3_pool (MaxPooling2D) │ (None, 28, 28, 256) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block4_conv1 (Conv2D) │ (None, 28, 28, 512) │ 1,180,160 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block4_conv2 (Conv2D) │ (None, 28, 28, 512) │ 2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block4_conv3 (Conv2D) │ (None, 28, 28, 512) │ 2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block4_pool (MaxPooling2D) │ (None, 14, 14, 512) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block5_conv1 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block5_conv2 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block5_conv3 (Conv2D) │ (None, 14, 14, 512) │ 2,359,808 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ block5_pool (MaxPooling2D) │ (None, 7, 7, 512) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ global_average_pooling2d_1 │ (None, 512) │ 0 │
│ (GlobalAveragePooling2D) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_4 (Dense) │ (None, 256) │ 131,328 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_3 (Dropout) │ (None, 256) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_5 (Dense) │ (None, 128) │ 32,896 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_4 (Dropout) │ (None, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_6 (Dense) │ (None, 64) │ 8,256 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_5 (Dropout) │ (None, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_7 (Dense) │ (None, 6) │ 390 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
============================================================================
Total params: 14,887,558 (56.79 MB)
Trainable params: 7,252,294 (27.67 MB)
Non-trainable params: 7,635,264 (29.13 MB)
───────────────────────────────────────────────────────────────────────────
### Train & Validation Accuracy
Epoch 5/50
43/43 ━━━━━━━━━━━━━━━━━━━━ 0s 159ms/step - accuracy: 0.4549 - loss: 1.3796
Epoch 5: val_loss improved from 1.24472 to 1.02865, saving model to /content/drive/MyDrive/weather_classification/best_model.keras
43/43 ━━━━━━━━━━━━━━━━━━━━ 10s 226ms/step - accuracy: 0.4552 - loss: 1.3789 - val_accuracy: 0.6399 - val_loss: 1.0286
Epoch 6/50
43/43 ━━━━━━━━━━━━━━━━━━━━ 0s 162ms/step - accuracy: 0.4960 - loss: 1.3274
Epoch 6: val_loss improved from 1.02865 to 0.93046, saving model to /content/drive/MyDrive/weather_classification/best_model.keras
43/43 ━━━━━━━━━━━━━━━━━━━━ 9s 206ms/step - accuracy: 0.4963 - loss: 1.3266 - val_accuracy: 0.7098 - val_loss: 0.9305
Epoch 7/50
...
Epoch 39/50
43/43 ━━━━━━━━━━━━━━━━━━━━ 0s 166ms/step - accuracy: 0.8950 - loss: 0.4088
Epoch 39: val_loss did not improve from 0.27755
43/43 ━━━━━━━━━━━━━━━━━━━━ 8s 196ms/step - accuracy: 0.8950 - loss: 0.4095 - val_accuracy: 0.9196 - val_loss: 0.2781
Modelin verisetindeki yetersiz veri durumu gereği ve genelleme kabiliyetini artırmak için veri artırma kullanılmıştır.
data_augmentation = Sequential([
layers.RandomFlip("horizontal", input_shape=(224, 224, 3)),
layers.RandomRotation(0.3),
layers.RandomZoom(0.2),
layers.RandomContrast(0.2),
layers.RandomBrightness(0.2),
layers.RandomTranslation(0.2, 0.2)
])Modelin eğitim sırasında validation-loss değerini baz alarak en düşük değeri kaydeder. Bu da modelin en iyi parametreli halini daha iyisi gelene kadar değiştirmez.
Early Stopping kullanarak da eğitim esnasında değerlerde değişim olmuyorsa ya da negatif yönde bir değişim oluyorsa model eğtimi sonlandırılarak gereksiz eğitim yüküne gidilmez.
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.callbacks import ModelCheckpoint
checkpoint = ModelCheckpoint(
filepath="/content/drive/MyDrive/weather_classification/best_model.keras",
monitor='val_loss',
save_best_only=True,
mode='min',
verbose=1
)
early_stop = EarlyStopping(
monitor = 'val_loss',
patience = 4,
restore_best_weights=True,
min_delta=0.001,
)- Bu repoyu klonlayın
- Gerekli kütüphaneleri yükleyin:
pip install tensorflow numpy matplotlib notebook/weather_classification.ipynbdosyasını açarak modeli eğitin veya hazır modeli kullanmak içinmodel/best_model.kerasdosyasını indirin/koruyun.- Tahmin yapmak için görsellerinizi
predict_images/klasörüne koyun veyapredict_images/klasöründeki hazır dosyaları kullanabilirsiniz ardından:
cd Weather_Classification
python predict.pypredict.py betiği, belirtilen görsel üzerinde tahmin yapar ve sonuç etiketini güven skoru ile birlikte görsele yazar. Çıktı results.jpg olarak kaydedilir.
Eğitim tamamlandığında en iyi ağırlıklar model/best_model.keras dosyasına kaydedilir. Bu ağırlıkları yeniden eğitime gerek kalmadan doğrudan yükleyebilirsiniz:
from tensorflow.keras.models import load_model
model = load_model('model/best_model.keras')


