{ "cells": [ { "cell_type": "markdown", "id": "457956e0", "metadata": {}, "source": [ "# Lesson 28: TensorFlow/Keras classification activity\n", "\n", "## Activity Goal\n", "\n", "In this activity, you will build and train a neural network using TensorFlow/Keras to predict room occupancy based on environmental sensor data. The activity will guide you through data preparation, creating a logistic regression baseline for comparison, and then building a neural network using Keras' Sequential API to see how deep learning performs on this binary classification task.\n", "\n", "## Notebook set up\n", "\n", "### Vocareum compatibility\n", "\n", "Check the notebook path to determine if we are running in Vocareum, if so, install TensorFlow 2.17 and Keras 3.2.0 via pip." ] }, { "cell_type": "code", "execution_count": null, "id": "88591257", "metadata": {}, "outputs": [], "source": [ "from pathlib import Path\n", "\n", "# Get the parts of the current directory path as a tuple\n", "path_parts = Path.cwd().parts\n", "\n", "# Check if 'voc' is the first directory level\n", "is_voc_root = len(path_parts) > 1 and path_parts[1] == \"voc\"\n", "\n", "# If we are in a Vocareum instance, upgrade TensorFlow and Keras\n", "if is_voc_root:\n", " print(\"Running in Vocareum environment\")\n", "\n", " get_ipython().run_line_magic(\n", " \"pip\", \"install -qq --no-warn-script-location tensorflow==2.17.0 keras==3.2.0\"\n", " )" ] }, { "cell_type": "markdown", "id": "c20db720", "metadata": {}, "source": [ "### Imports" ] }, { "cell_type": "code", "execution_count": null, "id": "1ca8575f", "metadata": {}, "outputs": [], "source": [ "# Suppress noisy TensorFlow logs before importing\n", "import os\n", "os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'\n", "\n", "# Third party imports\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "import tensorflow as tf\n", "\n", "from sklearn.linear_model import LogisticRegression\n", "from sklearn.metrics import accuracy_score, classification_report, ConfusionMatrixDisplay\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.preprocessing import StandardScaler\n", "from tensorflow import keras\n", "from tensorflow.keras import layers" ] }, { "cell_type": "markdown", "id": "e749a9df", "metadata": {}, "source": [ "### GPU configuration (if present)" ] }, { "cell_type": "code", "execution_count": null, "id": "4bcea4ad", "metadata": {}, "outputs": [], "source": [ "# Configure GPU settings\n", "gpus = tf.config.list_physical_devices('GPU')\n", "\n", "if gpus:\n", " try:\n", " # Use only GPU 0\n", " tf.config.set_visible_devices(gpus[0], 'GPU')\n", "\n", " # Enable memory growth\n", " tf.config.experimental.set_memory_growth(gpus[0], True)\n", "\n", " # Get GPU\n", " details = tf.config.experimental.get_device_details(gpus[0])\n", " cc = details.get('compute_capability', (0, 0))\n", " device = details.get('device_name', '')\n", "\n", " print(f'Using GPU: {device}, compute capability {cc[0]}.{cc[1]}')\n", " print('Memory growth enabled')\n", "\n", " except RuntimeError as e:\n", " print(e)\n", "\n", "else:\n", " print('No GPU found')" ] }, { "cell_type": "markdown", "id": "f5271c9d", "metadata": {}, "source": [ "## 1. Data preparation\n", "\n", "### 1.1. Load occupancy data" ] }, { "cell_type": "code", "execution_count": null, "id": "0776b899", "metadata": {}, "outputs": [], "source": [ "occupancy_df = pd.read_csv('https://gperdrizet.github.io/FSA_devops/assets/data/unit4/occupancy_data.csv')\n", "occupancy_df.head()" ] }, { "cell_type": "code", "execution_count": null, "id": "388df321", "metadata": {}, "outputs": [], "source": [ "occupancy_df.info()" ] }, { "cell_type": "code", "execution_count": null, "id": "42232b35", "metadata": {}, "outputs": [], "source": [ "label = 'Occupancy'\n", "features = ['Temperature','Humidity','Light','CO2','HumidityRatio']" ] }, { "cell_type": "markdown", "id": "cae08764", "metadata": {}, "source": [ "### 1.2. Train test split\n", "\n", "Split the data into training and testing sets. Remember to set a random state for reproducibility." ] }, { "cell_type": "code", "execution_count": null, "id": "a04f9e25", "metadata": {}, "outputs": [], "source": [ "# TODO: Split the data" ] }, { "cell_type": "markdown", "id": "e80d04ed", "metadata": {}, "source": [ "### 1.3. Standard scale\n", "\n", "Scale the features to improve model performance. Consider which data should be used for fitting the scaler." ] }, { "cell_type": "code", "execution_count": null, "id": "d835cc05", "metadata": {}, "outputs": [], "source": [ "# TODO: Scale the features" ] }, { "cell_type": "markdown", "id": "d2346c36", "metadata": {}, "source": [ "## 2. Logistic regression baseline\n", "\n", "Create a baseline model to compare against the neural network.\n", "\n", "### 2.1. Fit" ] }, { "cell_type": "code", "execution_count": null, "id": "7e2635d5", "metadata": {}, "outputs": [], "source": [ "# TODO: Create and fit the model" ] }, { "cell_type": "markdown", "id": "42b30c63", "metadata": {}, "source": [ "### 2.2. Test set evaluation" ] }, { "cell_type": "code", "execution_count": null, "id": "42f41ab0", "metadata": {}, "outputs": [], "source": [ "# TODO: Evaluate on test set" ] }, { "cell_type": "markdown", "id": "2bdbd84c", "metadata": {}, "source": [ "## 3. Keras Sequential API model\n", "\n", "The Sequential API is the simplest way to build a neural network in Keras. It allows you to create models layer-by-layer in a linear stack.\n", "\n", "### 3.1. Build model\n", "\n", "Build a sequential neural network with an appropriate architecture for binary classification. Consider:\n", "- What input shape is needed based on the number of features\n", "- How many hidden layers and neurons per layer\n", "- What activation functions to use\n", "- The output layer configuration for binary classification\n", "- The optimizer, loss function, and metrics for compilation" ] }, { "cell_type": "code", "execution_count": null, "id": "8d0511fe", "metadata": {}, "outputs": [], "source": [ "# TODO: Build and compile the model" ] }, { "cell_type": "markdown", "id": "7edbedf4", "metadata": {}, "source": [ "### 3.2. Train model\n", "\n", "Train the model on your prepared data. You'll need to specify the number of epochs, batch size, and validation strategy." ] }, { "cell_type": "code", "execution_count": null, "id": "158b7c29", "metadata": {}, "outputs": [], "source": [ "# TODO: Train the model and review final metrics" ] }, { "cell_type": "markdown", "id": "e855aa43", "metadata": {}, "source": [ "### 3.3. Learning curves\n", "\n", "Visualize how the model's loss and accuracy changed during training." ] }, { "cell_type": "code", "execution_count": null, "id": "79038e76", "metadata": {}, "outputs": [], "source": [ "# TODO: Plot learning curves" ] }, { "cell_type": "markdown", "id": "b9edb80f", "metadata": {}, "source": [ "### 3.4. Test set evaluation\n", "\n", "Evaluate your neural network on the test set. Remember that the model outputs probabilities that need to be converted to class predictions." ] }, { "cell_type": "code", "execution_count": null, "id": "ca8f111b", "metadata": {}, "outputs": [], "source": [ "# TODO: Make predictions and calculate accuracy" ] }, { "cell_type": "markdown", "id": "e36bf90d", "metadata": {}, "source": [ "### 3.5. Performance analysis\n", "\n", "Create a confusion matrix to better understand model performance on different classes." ] }, { "cell_type": "code", "execution_count": null, "id": "b4d06622", "metadata": {}, "outputs": [], "source": [ "# TODO: Display confusion matrix" ] }, { "cell_type": "markdown", "id": "13a53d68", "metadata": {}, "source": [ "## 4. Model comparison\n", "\n", "Compare the performance of your logistic regression baseline with the neural network." ] }, { "cell_type": "code", "execution_count": null, "id": "61f7c586", "metadata": {}, "outputs": [], "source": [ "# TODO: Compare model accuracies" ] }, { "cell_type": "code", "execution_count": null, "id": "3bc8200f", "metadata": {}, "outputs": [], "source": [ "# TODO: Create side-by-side confusion matrix visualization" ] } ], "metadata": { "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 5 }