{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","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":30786,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Mind Cloud Task 1: Neural Network Implementation","metadata":{}},{"cell_type":"markdown","source":"## Objective:\n\nImplement a neural network from scratch using Python and NumPy, following Object-Oriented Programming (OOP) principles. The network should allow flexibility in size and number of neurons for customization.","metadata":{}},{"cell_type":"markdown","source":"## 1. Import Libraries:","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom matplotlib import pyplot as plt\n","metadata":{"execution":{"iopub.status.busy":"2024-10-17T20:42:35.415948Z","iopub.execute_input":"2024-10-17T20:42:35.416962Z","iopub.status.idle":"2024-10-17T20:42:35.425340Z","shell.execute_reply.started":"2024-10-17T20:42:35.416849Z","shell.execute_reply":"2024-10-17T20:42:35.423252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. Load Dataset:","metadata":{}},{"cell_type":"code","source":"class MNISTData:\n    def __init__(self, data_path):\n        self.data = pd.read_csv(data_path)\n        self.X_train, self.Y_train, self.X_dev, self.Y_dev = self.preprocess_data()\n\n    def preprocess_data(self):\n        data = np.array(self.data)\n        m, n = data.shape\n        np.random.shuffle(data)\n\n        data_dev = data[0:1000].T\n        Y_dev = data_dev[0]\n        X_dev = data_dev[1:n]\n        X_dev = X_dev / 255.  \n\n        data_train = data[1000:m].T\n        Y_train = data_train[0]\n        X_train = data_train[1:n]\n        X_train = X_train / 255.  \n\n        return X_train, Y_train, X_dev, Y_dev\n","metadata":{"execution":{"iopub.status.busy":"2024-10-17T20:42:50.167754Z","iopub.execute_input":"2024-10-17T20:42:50.169008Z","iopub.status.idle":"2024-10-17T20:42:50.178443Z","shell.execute_reply.started":"2024-10-17T20:42:50.168875Z","shell.execute_reply":"2024-10-17T20:42:50.177138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3. Neural Network Architecture","metadata":{}},{"cell_type":"code","source":"\nclass NeuralNetwork:\n    def __init__(self, input_size, hidden_size, output_size, alpha=0.01):\n        self.alpha = alpha\n        self.input_size = input_size\n        self.hidden_size = hidden_size\n        self.output_size = output_size\n        self.W1, self.b1, self.W2, self.b2 = self.init_params()\n\n    def init_params(self):\n        W1 = np.random.rand(self.hidden_size, self.input_size) - 0.5\n        b1 = np.random.rand(self.hidden_size, 1) - 0.5\n        W2 = np.random.rand(self.output_size, self.hidden_size) - 0.5\n        b2 = np.random.rand(self.output_size, 1) - 0.5\n        return W1, b1, W2, b2\n\n    def ReLU(self, Z):\n        return np.maximum(Z, 0)\n\n    def softmax(self, Z):\n        A = np.exp(Z) / np.sum(np.exp(Z), axis=0, keepdims=True)\n        return A\n\n    def forward_prop(self, X):\n        Z1 = np.dot(self.W1, X) + self.b1\n        A1 = self.ReLU(Z1)\n        Z2 = np.dot(self.W2, A1) + self.b2\n        A2 = self.softmax(Z2)\n        return Z1, A1, Z2, A2\n\n    def ReLU_deriv(self, Z):\n        return Z > 0\n\n    def one_hot(self, 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\n    def backward_prop(self, Z1, A1, Z2, A2, X, Y):\n        one_hot_Y = self.one_hot(Y)\n        m = X.shape[1]\n\n        dZ2 = A2 - one_hot_Y\n        dW2 = (1 / m) * np.dot(dZ2, A1.T)\n        db2 = (1 / m) * np.sum(dZ2, axis=1, keepdims=True)\n        dZ1 = np.dot(self.W2.T, dZ2) * self.ReLU_deriv(Z1)\n        dW1 = (1 / m) * np.dot(dZ1, X.T)\n        db1 = (1 / m) * np.sum(dZ1, axis=1, keepdims=True)\n\n        return dW1, db1, dW2, db2\n\n    def update_params(self, dW1, db1, dW2, db2):\n        self.W1 -= self.alpha * dW1\n        self.b1 -= self.alpha * db1\n        self.W2 -= self.alpha * dW2\n        self.b2 -= self.alpha * db2\n\n    def get_predictions(self, A2):\n        return np.argmax(A2, axis=0)\n\n    def get_accuracy(self, predictions, Y):\n        return np.mean(predictions == Y)\n\n    def train(self, X, Y, iterations):\n        accuracies = []\n\n        for i in range(iterations):\n            Z1, A1, Z2, A2 = self.forward_prop(X)\n            dW1, db1, dW2, db2 = self.backward_prop(Z1, A1, Z2, A2, X, Y)\n            self.update_params(dW1, db1, dW2, db2)\n\n            if i % 10 == 0:\n                predictions = self.get_predictions(A2)\n                accuracy = self.get_accuracy(predictions, Y)\n                accuracies.append(accuracy)\n                print(f\"Iteration: {i}, Accuracy: {accuracy}\")\n        \n        return accuracies\n\n    def test_prediction(self, index, X, Y):\n        Z1, A1, Z2, A2 = self.forward_prop(X[:, [index]])\n        prediction = np.argmax(A2, axis=0)\n        plt.imshow(X[:, index].reshape(28, 28), cmap=\"gray\")\n        plt.title(f\"Actual: {Y[index]}, Prediction: {prediction}\")\n        plt.show()\n        return prediction\n","metadata":{"execution":{"iopub.status.busy":"2024-10-17T20:43:00.069772Z","iopub.execute_input":"2024-10-17T20:43:00.070891Z","iopub.status.idle":"2024-10-17T20:43:00.095498Z","shell.execute_reply.started":"2024-10-17T20:43:00.070843Z","shell.execute_reply":"2024-10-17T20:43:00.094196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4. Training the Neural Network ","metadata":{}},{"cell_type":"code","source":"if __name__ == \"__main__\":\n    data_path = '/kaggle/input/digit-recognizer/train.csv'\n    mnist_data = MNISTData(data_path)\n\n    input_size = 784\n    hidden_size = 10\n    output_size = 10\n    alpha = 0.1\n    nn = NeuralNetwork(input_size, hidden_size, output_size, alpha)\n\n    iterations = 1000\n    accuracies = nn.train(mnist_data.X_train, mnist_data.Y_train, iterations)","metadata":{"execution":{"iopub.status.busy":"2024-10-17T21:02:01.763086Z","iopub.execute_input":"2024-10-17T21:02:01.763532Z","iopub.status.idle":"2024-10-17T21:04:08.874232Z","shell.execute_reply.started":"2024-10-17T21:02:01.763491Z","shell.execute_reply":"2024-10-17T21:04:08.872597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 5.Deploy and Evaluate the model","metadata":{}},{"cell_type":"code","source":"    for i in range(4):\n        prediction = nn.test_prediction(i, mnist_data.X_dev, mnist_data.Y_dev)\n\n    epochs = list(range(0, iterations, 10))\n    plt.plot(epochs, accuracies)\n    plt.xlabel('Epochs')\n    plt.ylabel('Accuracy')\n    plt.title('Accuracy vs Epochs')\n    plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-10-17T21:04:49.990826Z","iopub.execute_input":"2024-10-17T21:04:49.991360Z","iopub.status.idle":"2024-10-17T21:04:51.418577Z","shell.execute_reply.started":"2024-10-17T21:04:49.991310Z","shell.execute_reply":"2024-10-17T21:04:51.417199Z"},"trusted":true},"execution_count":null,"outputs":[]}]}