{"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,"isSourceIdPinned":false,"sourceType":"competition"}],"dockerImageVersionId":31192,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:23.389012Z","iopub.execute_input":"2025-12-04T18:28:23.392876Z","iopub.status.idle":"2025-12-04T18:28:23.417874Z","shell.execute_reply.started":"2025-12-04T18:28:23.392807Z","shell.execute_reply":"2025-12-04T18:28:23.416556Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"In this notebook, a simple Artificial Neural Network (ANN) is implemented completely from scratch using only NumPy, without relying on deep learning frameworks such as TensorFlow or PyTorch.","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:23.420701Z","iopub.execute_input":"2025-12-04T18:28:23.421178Z","iopub.status.idle":"2025-12-04T18:28:23.427362Z","shell.execute_reply.started":"2025-12-04T18:28:23.421146Z","shell.execute_reply":"2025-12-04T18:28:23.425856Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\ndf","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:23.429679Z","iopub.execute_input":"2025-12-04T18:28:23.430055Z","iopub.status.idle":"2025-12-04T18:28:26.207333Z","shell.execute_reply.started":"2025-12-04T18:28:23.430016Z","shell.execute_reply":"2025-12-04T18:28:26.205964Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"m, n = df.shape\ndf = df.sample(frac=1).reset_index(drop=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:26.208259Z","iopub.execute_input":"2025-12-04T18:28:26.208547Z","iopub.status.idle":"2025-12-04T18:28:26.798664Z","shell.execute_reply.started":"2025-12-04T18:28:26.208526Z","shell.execute_reply":"2025-12-04T18:28:26.797339Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = df.to_numpy() \nf_col = 0\ny = df[:, f_col].astype(int)\nx = np.delete(df, f_col, axis=1).astype(float)\n\nx = x / (np.max(x, axis=0, keepdims=True) + 1e-12)\n\nx = x.T\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:26.802298Z","iopub.execute_input":"2025-12-04T18:28:26.802689Z","iopub.status.idle":"2025-12-04T18:28:27.188660Z","shell.execute_reply.started":"2025-12-04T18:28:26.802663Z","shell.execute_reply":"2025-12-04T18:28:27.187294Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"split = int(0.7 * m)\nx_train = x[:, :split]\ny_train = y[:split]\n\nx_dev = x[:, split:]\ny_dev = y[split:]\n\ninput_size = x_train.shape[0]\nnum_classes = int(np.max(y)) + 1\n\nprint(\"input size:\", input_size)\nprint(\"classes:\", num_classes)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:27.189745Z","iopub.execute_input":"2025-12-04T18:28:27.190011Z","iopub.status.idle":"2025-12-04T18:28:27.199829Z","shell.execute_reply.started":"2025-12-04T18:28:27.189990Z","shell.execute_reply":"2025-12-04T18:28:27.198691Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def initialize_para():\n    hidden = 64\n    w1 = np.random.randn(hidden, input_size) * np.sqrt(2 / input_size)\n    b1 = np.zeros((hidden,1)) \n    w2 = np.random.randn(num_classes, hidden) * np.sqrt(2 / hidden)\n    b2 = np.zeros((num_classes,1)) \n    return w1,b1,w2,b2","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:27.201412Z","iopub.execute_input":"2025-12-04T18:28:27.201706Z","iopub.status.idle":"2025-12-04T18:28:27.226052Z","shell.execute_reply.started":"2025-12-04T18:28:27.201683Z","shell.execute_reply":"2025-12-04T18:28:27.224876Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def relu(z):\n    return np.maximum(0,z)\n\ndef derivative_relu(z):\n    return z > 0\n\ndef softmax(z):\n    z = z - np.max(z,axis=0, keepdims=True)\n    exp_z = np.exp(z)\n    return exp_z / np.sum(exp_z,axis=0, keepdims=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:27.227418Z","iopub.execute_input":"2025-12-04T18:28:27.227691Z","iopub.status.idle":"2025-12-04T18:28:27.253026Z","shell.execute_reply.started":"2025-12-04T18:28:27.227668Z","shell.execute_reply":"2025-12-04T18:28:27.251785Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def forword_propagation(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","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:27.254178Z","iopub.execute_input":"2025-12-04T18:28:27.254613Z","iopub.status.idle":"2025-12-04T18:28:27.277883Z","shell.execute_reply.started":"2025-12-04T18:28:27.254585Z","shell.execute_reply":"2025-12-04T18:28:27.276702Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def one_hot(y):\n    one_hot_y = np.zeros((num_classes, y.size))\n    one_hot_y[y, np.arange(y.size)] = 1\n    return one_hot_y","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:27.279496Z","iopub.execute_input":"2025-12-04T18:28:27.279780Z","iopub.status.idle":"2025-12-04T18:28:27.303728Z","shell.execute_reply.started":"2025-12-04T18:28:27.279757Z","shell.execute_reply":"2025-12-04T18:28:27.302408Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def compute_loss(a2, y):\n    return -np.mean(np.log(a2[y, np.arange(y.size)] + 1e-9))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:27.305033Z","iopub.execute_input":"2025-12-04T18:28:27.305454Z","iopub.status.idle":"2025-12-04T18:28:27.324315Z","shell.execute_reply.started":"2025-12-04T18:28:27.305422Z","shell.execute_reply":"2025-12-04T18:28:27.322988Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def back_propagation(z1,a1,z2,a2,w2,x,y):\n    m = y.size\n    one_hot_y = one_hot(y)\n\n    dz2 = a2 - one_hot_y\n    dw2 = (1/m) * dz2.dot(a1.T)\n    db2 = (1/m) * np.sum(dz2, axis=1, keepdims=True)\n                                                \n    dz1 = w2.T.dot(dz2) * derivative_relu(z1)\n    dw1 = (1/m) * dz1.dot(x.T)\n    db1 = (1/m) * np.sum(dz1, axis=1, keepdims=True)\n\n    return dw1,db1,dw2,db2","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:27.325792Z","iopub.execute_input":"2025-12-04T18:28:27.326091Z","iopub.status.idle":"2025-12-04T18:28:27.347802Z","shell.execute_reply.started":"2025-12-04T18:28:27.326068Z","shell.execute_reply":"2025-12-04T18:28:27.346504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def update_para(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-12-04T18:28:27.348765Z","iopub.execute_input":"2025-12-04T18:28:27.349703Z","iopub.status.idle":"2025-12-04T18:28:27.374902Z","shell.execute_reply.started":"2025-12-04T18:28:27.349671Z","shell.execute_reply":"2025-12-04T18:28:27.373724Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_predictions(a2):\n    return np.argmax(a2, axis=0)\n\ndef get_accuracy(predictions, y):\n    return (np.sum(predictions == y) / y.size) * 100","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:27.378367Z","iopub.execute_input":"2025-12-04T18:28:27.378802Z","iopub.status.idle":"2025-12-04T18:28:27.403288Z","shell.execute_reply.started":"2025-12-04T18:28:27.378762Z","shell.execute_reply":"2025-12-04T18:28:27.401526Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def gradient_decent(x,y,iterations,alpha):\n    w1,b1,w2,b2 = initialize_para()\n\n    for i in range(iterations):\n        z1,a1,z2,a2 = forword_propagation(w1,b1,w2,b2,x)\n        dw1,db1,dw2,db2 = back_propagation(z1,a1,z2,a2,w2,x,y)\n\n        lr = alpha * (0.95 ** (i // 50))\n        w1,b1,w2,b2 = update_para(w1,b1,w2,b2,dw1,db1,dw2,db2,lr)\n\n        if i % 10 == 0:\n            acc = get_accuracy(get_predictions(a2), y)\n            loss = compute_loss(a2, y)\n            print(\"i:\", i, \"|| loss:\", round(loss,4), \"|| acc:\", round(acc,2))\n\n    return w1,b1,w2,b2","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:27.404614Z","iopub.execute_input":"2025-12-04T18:28:27.404904Z","iopub.status.idle":"2025-12-04T18:28:27.426130Z","shell.execute_reply.started":"2025-12-04T18:28:27.404881Z","shell.execute_reply":"2025-12-04T18:28:27.425002Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"w1,b1,w2,b2 = gradient_decent(x_train, y_train, 300, 0.1)\n\nz1t,a1t,z2t,train_out = forword_propagation(w1,b1,w2,b2,x_train)\nz1d,a1d,z2d,dev_out   = forword_propagation(w1,b1,w2,b2,x_dev)\n\nprint(\"Train accuracy:\", get_accuracy(get_predictions(train_out), y_train))\nprint(\"Dev accuracy:\",   get_accuracy(get_predictions(dev_out), y_dev))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-04T18:28:27.427179Z","iopub.execute_input":"2025-12-04T18:28:27.427628Z","iopub.status.idle":"2025-12-04T18:30:10.718735Z","shell.execute_reply.started":"2025-12-04T18:28:27.427595Z","shell.execute_reply":"2025-12-04T18:30:10.717497Z"}},"outputs":[],"execution_count":null}]}