{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "ceedc8f9", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import tensorflow as tf\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "from tensorflow.keras.models import Sequential, load_model\n", "from tensorflow.keras.layers import LSTM, Bidirectional, Dense, Dropout\n", "from tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping\n", "from sklearn.preprocessing import LabelEncoder\n", "from sklearn.metrics import classification_report, confusion_matrix" ] }, { "cell_type": "markdown", "id": "98ef0040", "metadata": {}, "source": [ "## 1. Data Loading and Preprocessing" ] }, { "cell_type": "code", "execution_count": null, "id": "b85b2bfc", "metadata": {}, "outputs": [], "source": [ "# Dataset path\n", "PATH = \"UCI HAR Dataset/\"" ] }, { "cell_type": "code", "execution_count": null, "id": "42787451", "metadata": {}, "outputs": [], "source": [ "# Load training and test data\n", "X_train = np.loadtxt(PATH + \"train/X_train.txt\")\n", "X_test = np.loadtxt(PATH + \"test/X_test.txt\")\n", "y_train = np.loadtxt(PATH + \"train/y_train.txt\")\n", "y_test = np.loadtxt(PATH + \"test/y_test.txt\")" ] }, { "cell_type": "code", "execution_count": null, "id": "ec4ab34f", "metadata": {}, "outputs": [], "source": [ "# Reshape for LSTM (batch_size, timesteps, features)\n", "X_train = X_train.reshape(X_train.shape[0], 1, X_train.shape[1])\n", "X_test = X_test.reshape(X_test.shape[0], 1, X_test.shape[1])" ] }, { "cell_type": "code", "execution_count": null, "id": "9661f547", "metadata": {}, "outputs": [], "source": [ "# Label encoding\n", "encoder = LabelEncoder()\n", "y_train = encoder.fit_transform(y_train)\n", "y_test = encoder.transform(y_test)" ] }, { "cell_type": "markdown", "id": "ae516913", "metadata": {}, "source": [ "## 2. LSTM Model Creation and Training" ] }, { "cell_type": "code", "execution_count": null, "id": "a02036f5", "metadata": {}, "outputs": [], "source": [ "# Model creation\n", "model = Sequential([\n", " Bidirectional(LSTM(128, return_sequences=True, activation=\"tanh\"), input_shape=(X_train.shape[1], X_train.shape[2])),\n", " Dropout(0.2),\n", " Bidirectional(LSTM(64, return_sequences=False, activation=\"tanh\")),\n", " Dropout(0.2),\n", " Dense(64, activation=\"relu\"),\n", " Dropout(0.1),\n", " Dense(len(np.unique(y_train)), activation=\"softmax\")\n", "])" ] }, { "cell_type": "code", "execution_count": null, "id": "c1eae86c", "metadata": {}, "outputs": [], "source": [ "# Model compilation\n", "optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)\n", "model.compile(loss=\"sparse_categorical_crossentropy\", optimizer=optimizer, metrics=[\"accuracy\"])" ] }, { "cell_type": "code", "execution_count": null, "id": "5421c2a2-c39f-400d-a06e-50617c27b1b1", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "21b40e87", "metadata": {}, "outputs": [], "source": [ "# Callbacks to adjust learning rate and stop training early\n", "reduce_lr = ReduceLROnPlateau(monitor=\"val_loss\", factor=0.5, patience=5, min_lr=0.00001, verbose=1)\n", "early_stop = EarlyStopping(monitor=\"val_loss\", patience=10, restore_best_weights=True, verbose=1)" ] }, { "cell_type": "code", "execution_count": null, "id": "5bc38cd5", "metadata": {}, "outputs": [], "source": [ "# Model training\n", "history = model.fit(X_train, y_train, epochs=100, batch_size=128, validation_data=(X_test, y_test), callbacks=[reduce_lr, early_stop])" ] }, { "cell_type": "markdown", "id": "164393aa", "metadata": {}, "source": [ "## 3. Model Evaluation" ] }, { "cell_type": "code", "execution_count": null, "id": "82798c6b", "metadata": {}, "outputs": [], "source": [ "loss, accuracy = model.evaluate(X_test, y_test)\n", "print(f\"Test Accuracy: {accuracy:.4f}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "971d6071", "metadata": {}, "outputs": [], "source": [ "# Save the model\n", "model.save(\"optimized_lstm_human_activity.h5\")\n", "print(\"āœ… Optimized model successfully saved!\")" ] }, { "cell_type": "code", "execution_count": null, "id": "6bf569ae", "metadata": {}, "outputs": [], "source": [ "# Predictions on test set\n", "predictions = model.predict(X_test)\n", "predicted_labels = np.argmax(predictions, axis=1)" ] }, { "cell_type": "code", "execution_count": null, "id": "41a82991", "metadata": {}, "outputs": [], "source": [ "# Classification report\n", "class_labels = [str(label) for label in np.unique(y_test)]\n", "print(\"\\nšŸ”¹ Classification Report:\")\n", "print(classification_report(y_test, predicted_labels, target_names=class_labels))" ] }, { "cell_type": "code", "execution_count": null, "id": "2a89410f", "metadata": {}, "outputs": [], "source": [ "# Confusion matrix\n", "cm = confusion_matrix(y_test, predicted_labels)\n", "plt.figure(figsize=(8,6))\n", "sns.heatmap(cm, annot=True, fmt=\"d\", cmap=\"Blues\", xticklabels=class_labels, yticklabels=class_labels)\n", "plt.xlabel(\"Predicted Class\")\n", "plt.ylabel(\"True Class\")\n", "plt.title(\"Confusion Matrix - Optimized Model\")\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "edc4005a", "metadata": {}, "source": [ "## 4. Validation on Synthetic Data" ] }, { "cell_type": "code", "execution_count": null, "id": "7120363c", "metadata": {}, "outputs": [], "source": [ "# Load the saved model\n", "model = load_model(\"optimized_lstm_human_activity.h5\")" ] }, { "cell_type": "code", "execution_count": null, "id": "0687a5ac", "metadata": {}, "outputs": [], "source": [ "# Generate synthetic data based on mean and standard deviation of each class\n", "samples_per_class = 50\n", "generated_data = []\n", "generated_labels = []" ] }, { "cell_type": "code", "execution_count": null, "id": "0b8f027e", "metadata": {}, "outputs": [], "source": [ "for activity in range(1, 7): # Classes from 1 to 6\n", " class_data = X_train[y_train == activity]\n", " feature_mean = np.mean(class_data, axis=0)\n", " feature_std = np.std(class_data, axis=0)\n", " \n", " for _ in range(samples_per_class):\n", " synthetic_sample = np.random.normal(loc=feature_mean, scale=feature_std)\n", " generated_data.append(synthetic_sample)\n", " generated_labels.append(activity)" ] }, { "cell_type": "code", "execution_count": null, "id": "695de361", "metadata": {}, "outputs": [], "source": [ "# Convert to array\n", "generated_data = np.array(generated_data).reshape(len(generated_data), 1, -1)\n", "generated_labels = np.array(generated_labels)" ] }, { "cell_type": "code", "execution_count": null, "id": "0f4a73d0", "metadata": {}, "outputs": [], "source": [ "# Predictions\n", "predictions = model.predict(generated_data)\n", "predicted_labels = np.argmax(predictions, axis=1) + 1" ] }, { "cell_type": "markdown", "id": "fc8e71c0", "metadata": {}, "source": [ "## 5. Visualization of Results on Synthetic Data" ] }, { "cell_type": "code", "execution_count": null, "id": "aec02a8d", "metadata": {}, "outputs": [], "source": [ "# Confusion matrix\n", "cm = confusion_matrix(generated_labels, predicted_labels)\n", "plt.figure(figsize=(8,6))\n", "sns.heatmap(cm, annot=True, fmt=\"d\", cmap=\"Blues\", xticklabels=range(1,7), yticklabels=range(1,7))\n", "plt.xlabel(\"Predicted Class\")\n", "plt.ylabel(\"True Class\")\n", "plt.title(\"Confusion Matrix - Synthetic Data\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "id": "97b59f79", "metadata": {}, "outputs": [], "source": [ "# Classification report\n", "print(\"\\nšŸ”¹ Classification Report:\")\n", "print(classification_report(generated_labels, predicted_labels))" ] } ], "metadata": { "jupytext": { "cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all" }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }