# Complete Python notebook using Keras for downloading, splitting, augmenting dataset, and training/testing CNN model

# Step 1: Install Kaggle
!pip install kaggle

# Step 2: Upload kaggle.json
from google.colab import files
files.upload()

# Step 3: Set up kaggle.json
!mkdir ~/.kaggle
!cp kaggle.json ~/.kaggle/
!chmod 600 ~/.kaggle/kaggle.json

# Step 4: Download Dataset from Kaggle (Flowers Dataset)
!kaggle datasets download -d alxmamaev/flowers-recognition

# Step 5: Unzip Dataset
!unzip flowers-recognition.zip -d ./dataset

# Step 6: Splitting dataset into train, validation, and test
import os
import shutil
from sklearn.model_selection import train_test_split

data_dir = './dataset/flowers'  # original dataset location
base_dir = './dataset/split'  # new split dataset location

train_ratio = 0.7
val_ratio = 0.15
test_ratio = 0.15

categories = os.listdir(data_dir)

for category in categories:
    os.makedirs(f'{base_dir}/train/{category}', exist_ok=True)
    os.makedirs(f'{base_dir}/val/{category}', exist_ok=True)
    os.makedirs(f'{base_dir}/test/{category}', exist_ok=True)

    images = os.listdir(f'{data_dir}/{category}')

    train_images, test_images = train_test_split(images, test_size=(1 - train_ratio))
    val_images, test_images = train_test_split(test_images, test_size=test_ratio/(test_ratio + val_ratio))

    for img in train_images:
        shutil.copy(f'{data_dir}/{category}/{img}', f'{base_dir}/train/{category}/{img}')
    for img in val_images:
        shutil.copy(f'{data_dir}/{category}/{img}', f'{base_dir}/val/{category}/{img}')
    for img in test_images:
        shutil.copy(f'{data_dir}/{category}/{img}', f'{base_dir}/test/{category}/{img}')

# Step 7: Applying data augmentation
from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=20,
    zoom_range=0.15,
    horizontal_flip=True
)

val_test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
    f'{base_dir}/train',
    target_size=(150, 150),
    batch_size=32,
    class_mode='categorical'
)

val_generator = val_test_datagen.flow_from_directory(
    f'{base_dir}/val',
    target_size=(150, 150),
    batch_size=32,
    class_mode='categorical'
)

test_generator = val_test_datagen.flow_from_directory(
    f'{base_dir}/test',
    target_size=(150, 150),
    batch_size=32,
    class_mode='categorical'
)

# Step 8: Building and Training the CNN Model
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense

model = Sequential([
    Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)),
    MaxPooling2D(2,2),
    Conv2D(64, (3,3), activation='relu'),
    MaxPooling2D(2,2),
    Flatten(),
    Dense(128, activation='relu'),
    Dense(len(categories), activation='softmax')
])

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

history = model.fit(
    train_generator,
    epochs=10,
    validation_data=val_generator
)

# Step 9: Evaluating the model
test_loss, test_acc = model.evaluate(test_generator)
print(f'Test accuracy: {test_acc:.2f}')
