{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Iris Classification with TensorFlow (Python)\n",
    "This notebook trains a neural network on the Iris dataset using only `iris.json`, splits it into training/testing sets, and plots training/validation accuracy and loss."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install pandas numpy tensorflow scikit-learn matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Dense\n",
    "from sklearn.preprocessing import LabelBinarizer\n",
    "from sklearn.model_selection import train_test_split\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# Upload iris.json\n",
    "from google.colab import files\n",
    "uploaded = files.upload()  # Upload iris.json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load the JSON file\n",
    "iris_data = json.load(open('iris.json'))\n",
    "\n",
    "# Convert to numpy arrays\n",
    "X = np.array([[item['sepal_length'], item['sepal_width'], item['petal_length'], item['petal_width']] for item in iris_data])\n",
    "y_raw = [item['species'] for item in iris_data]\n",
    "\n",
    "# One-hot encode the labels\n",
    "encoder = LabelBinarizer()\n",
    "y = encoder.fit_transform(y_raw)\n",
    "\n",
    "# Split into training and testing sets (80/20)\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Build the neural network\n",
    "model = Sequential([\n",
    "    Dense(5, input_shape=(4,), activation='sigmoid'),\n",
    "    Dense(3, activation='sigmoid'),\n",
    "    Dense(3, activation='sigmoid')\n",
    "])\n",
    "\n",
    "# Compile the model using categorical_crossentropy for classification\n",
    "model.compile(\n",
    "    optimizer=tf.keras.optimizers.Adam(learning_rate=0.06),\n",
    "    loss='categorical_crossentropy',\n",
    "    metrics=['accuracy']\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Train the model\n",
    "history = model.fit(\n",
    "    X_train, y_train,\n",
    "    epochs=100,\n",
    "    verbose=1,\n",
    "    validation_data=(X_test, y_test)\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Plot training & validation accuracy and loss\n",
    "plt.figure(figsize=(12,5))\n",
    "\n",
    "plt.subplot(1,2,1)\n",
    "plt.plot(history.history['accuracy'], label='Train Accuracy')\n",
    "plt.plot(history.history['val_accuracy'], label='Validation Accuracy')\n",
    "plt.title('Model Accuracy')\n",
    "plt.xlabel('Epoch')\n",
    "plt.ylabel('Accuracy')\n",
    "plt.legend()\n",
    "\n",
    "plt.subplot(1,2,2)\n",
    "plt.plot(history.history['loss'], label='Train Loss')\n",
    "plt.plot(history.history['val_loss'], label='Validation Loss')\n",
    "plt.title('Model Loss')\n",
    "plt.xlabel('Epoch')\n",
    "plt.ylabel('Loss')\n",
    "plt.legend()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Evaluate / Predict on testing set\n",
    "predictions = model.predict(X_test)\n",
    "\n",
    "print(\"Predictions (probabilities):\")\n",
    "print(predictions)\n",
    "\n",
    "# Convert predictions to labels\n",
    "predicted_labels = encoder.inverse_transform(np.round(predictions))\n",
    "print(\"Predicted species:\")\n",
    "print(predicted_labels)\n",
    "\n",
    "# Compare with actual labels\n",
    "actual_labels = encoder.inverse_transform(y_test)\n",
    "print(\"Actual species:\")\n",
    "print(actual_labels)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}