Rose_classification / src /rose_model.py
Terence9's picture
Upload 4 files
eac85ba verified
import os
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import layers, models
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, classification_report
import tensorflow as tf
# Set the paths to your image folders
BASE_DIR = os.path.join(os.getcwd(), 'dataset')
train_dir = os.path.join(BASE_DIR, 'train')
validation_dir = os.path.join(BASE_DIR, 'validation')
test_dir = os.path.join(BASE_DIR, 'test')
# Set the parameters for the data generators
batch_size = 32
img_height, img_width = 256, 256
# Create data generators with data augmentation for training and validation
train_datagen = ImageDataGenerator(
rescale=1.0 / 255.0,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
vertical_flip=True
)
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical'
)
validation_datagen = ImageDataGenerator(rescale=1.0 / 255.0)
validation_generator = validation_datagen.flow_from_directory(
validation_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical'
)
# Create a CNN model
cnn_model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(img_height, img_width, 3)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(128, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(train_generator.num_classes, activation='softmax')
])
# Compile the CNN model
cnn_model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# Train the CNN model
epochs = 10
history = cnn_model.fit(
train_generator,
epochs=epochs,
validation_data=validation_generator
)
# Save the trained model
model_path = os.path.join(os.getcwd(), 'models', 'rose_model.h5')
os.makedirs(os.path.dirname(model_path), exist_ok=True)
cnn_model.save(model_path)
# Save class names
class_names = list(train_generator.class_indices.keys())
class_names_path = os.path.join(os.getcwd(), 'models', 'class_names.json')
import json
with open(class_names_path, 'w') as f:
json.dump(class_names, f)
# Evaluate the model
test_datagen = ImageDataGenerator(rescale=1.0 / 255.0)
test_generator = test_datagen.flow_from_directory(
test_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical',
shuffle=False
)
# Make predictions
test_predictions = cnn_model.predict(test_generator)
predicted_labels = np.argmax(test_predictions, axis=1)
true_labels = test_generator.classes
# Calculate and print metrics
print("\nClassification Report:")
print(classification_report(true_labels, predicted_labels, target_names=class_names))
# Plot training history
plt.figure(figsize=(12, 4))
# Plot training & validation accuracy
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model Accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Validation'], loc='upper left')
# Plot training & validation loss
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model Loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Validation'], loc='upper left')
plt.tight_layout()
plt.savefig(os.path.join(os.getcwd(), 'models', 'training_history.png'))
plt.close()
print("\nModel saved to:", model_path)
print("Class names saved to:", class_names_path)
print("Training history plot saved to:", os.path.join(os.getcwd(), 'models', 'training_history.png'))