{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":31192,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nfrom tensorflow.keras.datasets import mnist","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:04.704830Z","iopub.execute_input":"2025-12-08T17:33:04.705199Z","iopub.status.idle":"2025-12-08T17:33:04.710097Z","shell.execute_reply.started":"2025-12-08T17:33:04.705176Z","shell.execute_reply":"2025-12-08T17:33:04.708988Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"(x_train,y_train),(x_test,y_test) = mnist.load_data()\n\nn = 5000\nx_train = x_train[:n]\ny_train = y_train[:n]\n\nx_train = x_train.astype(np.float32)/255.0\nx_train = x_train.reshape(n,784)\ny_train = np.eye(10)[y_train]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:04.712005Z","iopub.execute_input":"2025-12-08T17:33:04.712315Z","iopub.status.idle":"2025-12-08T17:33:05.064592Z","shell.execute_reply.started":"2025-12-08T17:33:04.712294Z","shell.execute_reply":"2025-12-08T17:33:05.063620Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"X shape:\", x_train.shape)   \nprint(\"Y shape:\", y_train.shape)  ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:05.065514Z","iopub.execute_input":"2025-12-08T17:33:05.065866Z","iopub.status.idle":"2025-12-08T17:33:05.071739Z","shell.execute_reply.started":"2025-12-08T17:33:05.065831Z","shell.execute_reply":"2025-12-08T17:33:05.070610Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"input_dim = 784\nhidden_dim = 128\noutput_dim = 10\n\nw1 = np.random.randn(hidden_dim,input_dim)*np.sqrt(2/input_dim)\n\nw2 = np.random.randn(output_dim,hidden_dim)*np.sqrt(2/hidden_dim)\n\nb1 = np.zeros((hidden_dim, 1))\nb2 = np.zeros((output_dim, 1))\n\n\nprint(\"W1:\", w1.shape)  \nprint(\"b1:\", b1.shape)  \nprint(\"W2:\", w2.shape)  \nprint(\"b2:\", b2.shape)  ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:05.074191Z","iopub.execute_input":"2025-12-08T17:33:05.074494Z","iopub.status.idle":"2025-12-08T17:33:05.096423Z","shell.execute_reply.started":"2025-12-08T17:33:05.074472Z","shell.execute_reply":"2025-12-08T17:33:05.095453Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def relu(z):\n    return np.maximum(0,z)\n\ndef softmax(z):\n    exp = np.exp(z-np.max(z,axis=0,keepdims=True))\n    return exp/np.sum(exp,axis=0,keepdims=True)\ndef forward_pass(x,w1,b1,w2,b2):\n    z1 = w1@x.T+b1\n    a1 = relu(z1)\n    z2 = w2@a1+b2\n    a2 = softmax(z2)\n    return z1,a1,z2,a2\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:05.097749Z","iopub.execute_input":"2025-12-08T17:33:05.098110Z","iopub.status.idle":"2025-12-08T17:33:05.113291Z","shell.execute_reply.started":"2025-12-08T17:33:05.098082Z","shell.execute_reply":"2025-12-08T17:33:05.112111Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"batch = x_train[:32] \nZ1, A1, Z2, A2 = forward_pass(batch, w1, b1, w2, b2)\n\nprint(\"Output probabilities shape:\", A2.shape) \nprint(\"Predicted labels shape:\", np.argmax(A2, axis=0).shape) \n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:05.114438Z","iopub.execute_input":"2025-12-08T17:33:05.114812Z","iopub.status.idle":"2025-12-08T17:33:05.134171Z","shell.execute_reply.started":"2025-12-08T17:33:05.114786Z","shell.execute_reply":"2025-12-08T17:33:05.133327Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def compute_loss(y,a2):\n    m = y.shape[0]\n    y = y.T\n    log_probs = np.log(a2+1e-9)\n    loss = -np.sum(y*log_probs)/m\n    return loss\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:05.135286Z","iopub.execute_input":"2025-12-08T17:33:05.135706Z","iopub.status.idle":"2025-12-08T17:33:05.148862Z","shell.execute_reply.started":"2025-12-08T17:33:05.135672Z","shell.execute_reply":"2025-12-08T17:33:05.147832Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def backward_pass(X, Y, Z1, A1, A2, W2):\n\n    m = X.shape[0] \n    Y = Y.T\n    dZ2 = A2 - Y \n    dW2 = (dZ2 @ A1.T) / m    \n    db2 = np.sum(dZ2, axis=1, keepdims=True)\n    dA1 = W2.T @ dZ2\n    dZ1 = dA1 * (Z1 > 0)\n    dW1 = (dZ1 @ X) / m \n    db1 = np.sum(dZ1, axis=1, keepdims=True) / m\n\n    return dW1, db1, dW2, db2\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:05.149621Z","iopub.execute_input":"2025-12-08T17:33:05.149957Z","iopub.status.idle":"2025-12-08T17:33:05.166728Z","shell.execute_reply.started":"2025-12-08T17:33:05.149885Z","shell.execute_reply":"2025-12-08T17:33:05.165726Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def update_parameters(w1,b1,w2,b2,dw1,db1,dw2,db2,lr=0.01):\n    w1 -= lr * dw1\n    b1 -= lr * db1\n    w2 -= lr * dw2\n    b2 -= lr * db2\n    return w1, b1, w2, b2","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:05.169113Z","iopub.execute_input":"2025-12-08T17:33:05.169448Z","iopub.status.idle":"2025-12-08T17:33:05.185118Z","shell.execute_reply.started":"2025-12-08T17:33:05.169425Z","shell.execute_reply":"2025-12-08T17:33:05.183857Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train(x_train, y_train, w1, b1, w2, b2, epochs=20, batch_size=32, lr=0.01):\n\n    n_samples = x_train.shape[0]\n    loss_history = []\n    accuracy_history = []\n\n    for epoch in range(epochs):\n        indices = np.random.permutation(n_samples)\n        X_train = x_train[indices]\n        Y_train = y_train[indices]\n\n        epoch_loss = 0\n        correct_predictions = 0\n        for i in range(0, n_samples, batch_size):\n            \n            X_batch = X_train[i:i+batch_size]\n            Y_batch = Y_train[i:i+batch_size]\n\n            # Forward pass\n            Z1, A1, Z2, A2 = forward_pass(X_batch, w1, b1, w2, b2)\n\n            # Compute loss\n            loss = compute_loss(Y_batch, A2)\n            epoch_loss += loss\n\n            # Accuracy in current batch\n            predictions = np.argmax(A2, axis=0)\n            true_labels = np.argmax(Y_batch, axis=1)\n            correct_predictions += np.sum(predictions == true_labels)\n\n            # Backprop\n            dW1, db1, dW2, db2 = backward_pass(X_batch, Y_batch, Z1, A1, A2, w2)\n\n            # Update parameters\n            W1, b1, W2, b2 = update_parameters(w1, b1, w2, b2, dW1, db1, dW2, db2, lr)\n\n\n        avg_loss = epoch_loss / (n_samples // batch_size)\n        accuracy = correct_predictions / n_samples\n\n        loss_history.append(avg_loss)\n        accuracy_history.append(accuracy)\n\n        print(f\"Epoch {epoch+1}/{epochs} | Loss: {avg_loss:.4f} | Accuracy: {accuracy:.4f}\")\n\n    return W1, b1, W2, b2, loss_history, accuracy_history\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:05.186166Z","iopub.execute_input":"2025-12-08T17:33:05.186424Z","iopub.status.idle":"2025-12-08T17:33:05.205689Z","shell.execute_reply.started":"2025-12-08T17:33:05.186405Z","shell.execute_reply":"2025-12-08T17:33:05.204735Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"W1, b1, W2, b2, loss_history, accuracy_history = train(\n    x_train, y_train, w1, b1, w2, b2,\n    epochs=20, batch_size=64, lr=0.01\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:05.206728Z","iopub.execute_input":"2025-12-08T17:33:05.207140Z","iopub.status.idle":"2025-12-08T17:33:07.458190Z","shell.execute_reply.started":"2025-12-08T17:33:05.207110Z","shell.execute_reply":"2025-12-08T17:33:07.457287Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def evaluate(x_test, y_test, w1, b1, w2, b2):\n    \n    Z1, A1, Z2, A2 = forward_pass(x_test, w1, b1, w2, b2)\n\n    # Predictions (class index)\n    predictions = np.argmax(A2, axis=0)\n\n    # True labels (decode one-hot)\n    true_labels = np.argmax(y_test, axis=1)\n\n    # Accuracy\n    accuracy = np.mean(predictions == true_labels)\n\n    return accuracy\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:07.459150Z","iopub.execute_input":"2025-12-08T17:33:07.459540Z","iopub.status.idle":"2025-12-08T17:33:07.465882Z","shell.execute_reply.started":"2025-12-08T17:33:07.459510Z","shell.execute_reply":"2025-12-08T17:33:07.464895Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_test = x_test.astype(np.float32) / 255.0\nx_test = x_test.reshape(x_test.shape[0], 784)\ny_test = np.eye(10)[y_test]\ntest_accuracy = evaluate(x_test, y_test, W1, b1, W2, b2)\nprint(f\"Test Accuracy: {test_accuracy:.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:07.466828Z","iopub.execute_input":"2025-12-08T17:33:07.467103Z","iopub.status.idle":"2025-12-08T17:33:07.597738Z","shell.execute_reply.started":"2025-12-08T17:33:07.467052Z","shell.execute_reply":"2025-12-08T17:33:07.596634Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# ---- Loss Curve ----\nplt.figure(figsize=(6,4))\nplt.plot(loss_history, marker='o')\nplt.title(\"Training Loss Over Epochs\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Loss\")\nplt.grid(True)\nplt.show()\n\n# ---- Accuracy Curve ----\nplt.figure(figsize=(6,4))\nplt.plot(accuracy_history, marker='o', color='green')\nplt.title(\"Training Accuracy Over Epochs\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy\")\nplt.grid(True)\nplt.show()\n\n\nplt.figure(figsize=(7,5))\nplt.plot(loss_history, label=\"Loss\")\nplt.plot(accuracy_history, label=\"Accuracy\")\nplt.xlabel(\"Epoch\")\nplt.title(\"Training Metrics\")\nplt.legend()\nplt.grid(True)\nplt.show()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:33:07.598940Z","iopub.execute_input":"2025-12-08T17:33:07.599253Z","iopub.status.idle":"2025-12-08T17:33:08.182270Z","shell.execute_reply.started":"2025-12-08T17:33:07.599220Z","shell.execute_reply":"2025-12-08T17:33:08.181339Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def predict(X, W1, b1, W2, b2):\n    _, _, _, A2 = forward_pass(X, W1, b1, W2, b2)\n    predictions = np.argmax(A2, axis=0)\n    return predictions\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:34:11.049746Z","iopub.execute_input":"2025-12-08T17:34:11.051111Z","iopub.status.idle":"2025-12-08T17:34:11.056572Z","shell.execute_reply.started":"2025-12-08T17:34:11.051081Z","shell.execute_reply":"2025-12-08T17:34:11.055733Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"preds = predict(x_test, W1, b1, W2, b2)\nprint(preds[:20])  # print first 20 predictions\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:34:28.858738Z","iopub.execute_input":"2025-12-08T17:34:28.859479Z","iopub.status.idle":"2025-12-08T17:34:28.947392Z","shell.execute_reply.started":"2025-12-08T17:34:28.859453Z","shell.execute_reply":"2025-12-08T17:34:28.946455Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"true_labels = np.argmax(y_test, axis=1)\n\nfor i in range(10):\n    print(f\"Image {i}: Predicted = {preds[i]}, True = {true_labels[i]}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:34:47.867422Z","iopub.execute_input":"2025-12-08T17:34:47.867747Z","iopub.status.idle":"2025-12-08T17:34:47.874155Z","shell.execute_reply.started":"2025-12-08T17:34:47.867724Z","shell.execute_reply":"2025-12-08T17:34:47.873241Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nidx = 5 \n\nplt.imshow(x_test[idx].reshape(28,28), cmap='gray')\nplt.title(f\"Predicted: {preds[idx]} | True: {true_labels[idx]}\")\nplt.axis('off')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T17:35:09.937301Z","iopub.execute_input":"2025-12-08T17:35:09.937664Z","iopub.status.idle":"2025-12-08T17:35:10.033602Z","shell.execute_reply.started":"2025-12-08T17:35:09.937621Z","shell.execute_reply":"2025-12-08T17:35:10.032723Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}