{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.18","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"tpu1vmV38","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":31089,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Loading all of the datasets, packages, slicing up the data, to improve performance\n\nimport numpy as np\nimport pandas as pd\nfrom matplotlib import pyplot as plt\n\ndata_train_raw = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\ndata_test_raw = pd.read_csv('/kaggle/input/digit-recognizer/test.csv')\n\ndata_train = np.array(data_train_raw)\nnp.random.shuffle(data_train)\n\nY_train = data_train[:, 0]\nX_train = data_train[:, 1:].T\nX_train = X_train / 255.\n\nX_test = np.array(data_test_raw).T / 255.","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T08:00:11.712786Z","iopub.execute_input":"2025-08-29T08:00:11.713158Z","iopub.status.idle":"2025-08-29T08:00:15.458214Z","shell.execute_reply.started":"2025-08-29T08:00:11.713128Z","shell.execute_reply":"2025-08-29T08:00:15.454324Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def init_params():\n    # Corrected input layer size to 784 (28*28)\n    W1 = np.random.rand(64, 784) - 0.5\n    b1 = np.random.rand(64, 1) - 0.5\n    W2 = np.random.rand(10, 64) - 0.5\n    b2 = np.random.rand(10, 1) - 0.5\n    return W1, b1, W2, b2\n\ndef ReLU(Z):\n    return np.maximum(0, Z)\n\ndef softmax(Z):\n    A = np.exp(Z) / np.sum(np.exp(Z), axis=0)\n    return A\n\ndef forward_prop(W1, b1, W2, b2, X):\n    Z1 = W1.dot(X) + b1\n    A1 = ReLU(Z1)\n    Z2 = W2.dot(A1) + b2\n    A2 = softmax(Z2)\n    return Z1, A1, Z2, A2\n\ndef one_hot(Y):\n    one_hot_Y = np.zeros((Y.size, Y.max() + 1))\n    one_hot_Y[np.arange(Y.size), Y] = 1\n    one_hot_Y = one_hot_Y.T\n    return one_hot_Y\n\ndef derive_ReLU(Z):\n    return Z > 0\n    \ndef back_prop(Z1, A1, Z2, A2, W2, X, Y):\n    m = Y.size\n    one_hot_Y = one_hot(Y)\n    dZ2 = A2 - one_hot_Y\n    dW2 = 1 / m * dZ2.dot(A1.T)\n    db2 = 1 / m * np.sum(dZ2)\n    \n    dZ1 = W2.T.dot(dZ2) * derive_ReLU(Z1)\n    dW1 = 1 / m * dZ1.dot(X.T)\n    db1 = 1 / m * np.sum(dZ1)\n\n    return dW1, db1, dW2, db2\n\ndef update_params(W1, b1, W2, b2, dW1, db1, dW2, db2, alpha):\n    W1 = W1 - alpha * dW1\n    b1 = b1 - alpha * db1\n    W2 = W2 - alpha * dW2\n    b2 = b2 - alpha * db2\n    return W1, b1, W2, b2","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T08:00:17.397571Z","iopub.execute_input":"2025-08-29T08:00:17.397855Z","iopub.status.idle":"2025-08-29T08:00:17.414136Z","shell.execute_reply.started":"2025-08-29T08:00:17.397828Z","shell.execute_reply":"2025-08-29T08:00:17.408916Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_predictions(A2):\n    return np.argmax(A2, 0)\n\ndef get_accuracy(predictions, Y):\n    print(predictions, Y)\n    return np.sum(predictions == Y) / Y.size\n\ndef gradient_descent(X, Y, iterations, alpha):\n    W1, b1, W2, b2 = init_params()\n    for i in range(iterations):\n        Z1, A1, Z2, A2 = forward_prop(W1, b1, W2, b2, X)\n        dW1, db1, dW2, db2 = back_prop(Z1, A1, Z2, A2, W2, X, Y)\n        W1, b1, W2, b2 = update_params(W1, b1, W2, b2, dW1, db1, dW2, db2, alpha)\n        if i % 50 == 0:\n            print(\"Iteration: \", i)\n            print(\"Accuracy: \", get_accuracy(get_predictions(A2), Y))\n            \n    return W1, b1, W2, b2\n        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T08:00:19.634189Z","iopub.execute_input":"2025-08-29T08:00:19.634450Z","iopub.status.idle":"2025-08-29T08:00:19.646617Z","shell.execute_reply.started":"2025-08-29T08:00:19.634425Z","shell.execute_reply":"2025-08-29T08:00:19.641753Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"W1, b1, W2, b2 = gradient_descent(X_train, Y_train, 5000, 0.01)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T08:00:21.239624Z","iopub.execute_input":"2025-08-29T08:00:21.239908Z","iopub.status.idle":"2025-08-29T08:05:16.021917Z","shell.execute_reply.started":"2025-08-29T08:00:21.239867Z","shell.execute_reply":"2025-08-29T08:05:16.015372Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def make_predictions(X, W1, b1, W2, b2):\n    _, _, _, A2 = forward_prop(W1, b1, W2, b2, X)\n    predictions = get_predictions(A2)\n    return predictions","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T08:05:20.712459Z","iopub.execute_input":"2025-08-29T08:05:20.712751Z","iopub.status.idle":"2025-08-29T08:05:20.722737Z","shell.execute_reply.started":"2025-08-29T08:05:20.712718Z","shell.execute_reply":"2025-08-29T08:05:20.718734Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions = make_predictions(X_test, W1, b1, W2, b2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T08:05:22.046542Z","iopub.execute_input":"2025-08-29T08:05:22.046862Z","iopub.status.idle":"2025-08-29T08:05:22.082834Z","shell.execute_reply.started":"2025-08-29T08:05:22.046833Z","shell.execute_reply":"2025-08-29T08:05:22.075065Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission_data = {\n    'ImageId': data_test_raw.index + 1,\n    'Label': predictions\n}\nsubmission_df = pd.DataFrame(submission_data)\nsubmission_df.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-29T08:05:26.016966Z","iopub.execute_input":"2025-08-29T08:05:26.017292Z","iopub.status.idle":"2025-08-29T08:05:26.053305Z","shell.execute_reply.started":"2025-08-29T08:05:26.017265Z","shell.execute_reply":"2025-08-29T08:05:26.050128Z"}},"outputs":[],"execution_count":null}]}