{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","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":31040,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom scipy.signal import correlate2d\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\nimport matplotlib.pyplot as plt\n%matplotlib inline","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:03.137114Z","iopub.execute_input":"2025-06-24T03:53:03.137431Z","iopub.status.idle":"2025-06-24T03:53:03.150766Z","shell.execute_reply.started":"2025-06-24T03:53:03.137407Z","shell.execute_reply":"2025-06-24T03:53:03.149842Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = pd.read_csv(\"../input/digit-recognizer/train.csv\")\ntest_df = pd.read_csv(\"../input/digit-recognizer/test.csv\")\nsample_df = pd.read_csv(\"../input/digit-recognizer/sample_submission.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:03.152429Z","iopub.execute_input":"2025-06-24T03:53:03.153283Z","iopub.status.idle":"2025-06-24T03:53:07.058036Z","shell.execute_reply.started":"2025-06-24T03:53:03.153253Z","shell.execute_reply":"2025-06-24T03:53:07.056873Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.059575Z","iopub.execute_input":"2025-06-24T03:53:07.059922Z","iopub.status.idle":"2025-06-24T03:53:07.074853Z","shell.execute_reply.started":"2025-06-24T03:53:07.059889Z","shell.execute_reply":"2025-06-24T03:53:07.073779Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = train_df.iloc[:, 1:].values.reshape((-1, 28, 28)) / 255\ny = np.eye(10)[train_df[\"label\"].values].astype(int)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.077171Z","iopub.execute_input":"2025-06-24T03:53:07.077418Z","iopub.status.idle":"2025-06-24T03:53:07.249565Z","shell.execute_reply.started":"2025-06-24T03:53:07.077398Z","shell.execute_reply":"2025-06-24T03:53:07.248456Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.imshow(X[0])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.250456Z","iopub.execute_input":"2025-06-24T03:53:07.250694Z","iopub.status.idle":"2025-06-24T03:53:07.428220Z","shell.execute_reply.started":"2025-06-24T03:53:07.250676Z","shell.execute_reply":"2025-06-24T03:53:07.427395Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.429252Z","iopub.execute_input":"2025-06-24T03:53:07.429587Z","iopub.status.idle":"2025-06-24T03:53:07.436218Z","shell.execute_reply.started":"2025-06-24T03:53:07.429565Z","shell.execute_reply":"2025-06-24T03:53:07.435165Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def sigmoid(x):\n    return 1 / (1 + np.exp(-x))\n\ndef softmax(x):\n    x = x - np.max(x)\n    exps = np.exp(x)\n    return exps / np.sum(exps)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.437357Z","iopub.execute_input":"2025-06-24T03:53:07.437676Z","iopub.status.idle":"2025-06-24T03:53:07.452525Z","shell.execute_reply.started":"2025-06-24T03:53:07.437654Z","shell.execute_reply":"2025-06-24T03:53:07.451534Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 順番に書いてみる","metadata":{}},{"cell_type":"code","source":"X_batch = X[:32].reshape((32, 784))\ny_batch = y[:32]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.453582Z","iopub.execute_input":"2025-06-24T03:53:07.453976Z","iopub.status.idle":"2025-06-24T03:53:07.471458Z","shell.execute_reply.started":"2025-06-24T03:53:07.453942Z","shell.execute_reply":"2025-06-24T03:53:07.470331Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_batch.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.472513Z","iopub.execute_input":"2025-06-24T03:53:07.472892Z","iopub.status.idle":"2025-06-24T03:53:07.492191Z","shell.execute_reply.started":"2025-06-24T03:53:07.472844Z","shell.execute_reply":"2025-06-24T03:53:07.491180Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"W1 = np.random.normal(size=(784, 256))\nb1 = np.random.normal(size=(1, 256))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.495614Z","iopub.execute_input":"2025-06-24T03:53:07.495889Z","iopub.status.idle":"2025-06-24T03:53:07.516371Z","shell.execute_reply.started":"2025-06-24T03:53:07.495867Z","shell.execute_reply":"2025-06-24T03:53:07.514853Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"out1_batch = sigmoid(X_batch @ W1 + b1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.517280Z","iopub.execute_input":"2025-06-24T03:53:07.517540Z","iopub.status.idle":"2025-06-24T03:53:07.523262Z","shell.execute_reply.started":"2025-06-24T03:53:07.517519Z","shell.execute_reply":"2025-06-24T03:53:07.522255Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"W2 = np.random.normal(size=(256, 128))\nb2 = np.random.normal(size=(1, 128))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.524419Z","iopub.execute_input":"2025-06-24T03:53:07.525291Z","iopub.status.idle":"2025-06-24T03:53:07.542597Z","shell.execute_reply.started":"2025-06-24T03:53:07.525260Z","shell.execute_reply":"2025-06-24T03:53:07.541660Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"out2_batch = sigmoid(out1_batch @ W2 + b2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.544337Z","iopub.execute_input":"2025-06-24T03:53:07.544595Z","iopub.status.idle":"2025-06-24T03:53:07.561810Z","shell.execute_reply.started":"2025-06-24T03:53:07.544574Z","shell.execute_reply":"2025-06-24T03:53:07.561073Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"W3 = np.random.normal(size=(128, 10))\nb3 = np.random.normal(size=(1, 10))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.562728Z","iopub.execute_input":"2025-06-24T03:53:07.562986Z","iopub.status.idle":"2025-06-24T03:53:07.583031Z","shell.execute_reply.started":"2025-06-24T03:53:07.562966Z","shell.execute_reply":"2025-06-24T03:53:07.582119Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"out = softmax(out2_batch @ W3 + b3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.584372Z","iopub.execute_input":"2025-06-24T03:53:07.584631Z","iopub.status.idle":"2025-06-24T03:53:07.601604Z","shell.execute_reply.started":"2025-06-24T03:53:07.584608Z","shell.execute_reply":"2025-06-24T03:53:07.600633Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"out.argmax(axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.602588Z","iopub.execute_input":"2025-06-24T03:53:07.602935Z","iopub.status.idle":"2025-06-24T03:53:07.624664Z","shell.execute_reply.started":"2025-06-24T03:53:07.602897Z","shell.execute_reply":"2025-06-24T03:53:07.623706Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_batch.argmax(axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.625499Z","iopub.execute_input":"2025-06-24T03:53:07.625795Z","iopub.status.idle":"2025-06-24T03:53:07.644140Z","shell.execute_reply.started":"2025-06-24T03:53:07.625771Z","shell.execute_reply":"2025-06-24T03:53:07.643089Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"エレガントに書く","metadata":{}},{"cell_type":"code","source":"def sigmoid(x):\n    return 1 / (1 + np.exp(-x))\n\ndef sigmoid_deriv(x):\n    s = sigmoid(x)\n    return s * (1 - s)\n\ndef softmax(x):\n    x = x - np.max(x)\n    exps = np.exp(x)\n    return exps / np.sum(exps)\n\ndef cross_entropy(pred, target):\n    return -np.sum(target * np.log(pred + 1e-9))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.645173Z","iopub.execute_input":"2025-06-24T03:53:07.645509Z","iopub.status.idle":"2025-06-24T03:53:07.663836Z","shell.execute_reply.started":"2025-06-24T03:53:07.645485Z","shell.execute_reply":"2025-06-24T03:53:07.663017Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class FullyConnectedLayer:\n    \n    def __init__(self, input_dim, output_dim):\n        self.W = np.random.randn(input_dim, output_dim) * np.sqrt(2. / input_dim)\n        self.b = np.zeros(output_dim)\n\n    def forward(self, x):\n        self.input = x\n        self.z = x @ self.W + self.b\n        return self.z\n\n    def backward(self, grad_output, lr=0.01):\n        grad_input = grad_output @ self.W.T\n        grad_W = np.outer(self.input, grad_output)\n        grad_b = grad_output\n\n        self.W -= lr * grad_W\n        self.b -= lr * grad_b\n\n        return grad_input","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.665153Z","iopub.execute_input":"2025-06-24T03:53:07.665461Z","iopub.status.idle":"2025-06-24T03:53:07.683030Z","shell.execute_reply.started":"2025-06-24T03:53:07.665437Z","shell.execute_reply":"2025-06-24T03:53:07.682114Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fc1 = FullyConnectedLayer(784, 128)\nfc2 = FullyConnectedLayer(128, 64)\nfc3 = FullyConnectedLayer(64, 10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.684526Z","iopub.execute_input":"2025-06-24T03:53:07.684827Z","iopub.status.idle":"2025-06-24T03:53:07.705937Z","shell.execute_reply.started":"2025-06-24T03:53:07.684794Z","shell.execute_reply":"2025-06-24T03:53:07.704823Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 順伝播\nz1 = fc1.forward(X_batch)\na1 = sigmoid(z1)\nz2 = fc2.forward(a1)\na2 = sigmoid(z2)\nz3 = fc3.forward(a2)\ny_pred = softmax(z3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.707239Z","iopub.execute_input":"2025-06-24T03:53:07.707519Z","iopub.status.idle":"2025-06-24T03:53:07.714226Z","shell.execute_reply.started":"2025-06-24T03:53:07.707495Z","shell.execute_reply":"2025-06-24T03:53:07.713398Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred.argmax(axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.715127Z","iopub.execute_input":"2025-06-24T03:53:07.715504Z","iopub.status.idle":"2025-06-24T03:53:07.734221Z","shell.execute_reply.started":"2025-06-24T03:53:07.715472Z","shell.execute_reply":"2025-06-24T03:53:07.733350Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"loss = cross_entropy(y_pred, y_batch)\nacc = (y_pred.argmax(axis=1) == y_batch.argmax(axis=1)).mean()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.735257Z","iopub.execute_input":"2025-06-24T03:53:07.735585Z","iopub.status.idle":"2025-06-24T03:53:07.755008Z","shell.execute_reply.started":"2025-06-24T03:53:07.735562Z","shell.execute_reply":"2025-06-24T03:53:07.754121Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"loss","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.755844Z","iopub.execute_input":"2025-06-24T03:53:07.756095Z","iopub.status.idle":"2025-06-24T03:53:07.779727Z","shell.execute_reply.started":"2025-06-24T03:53:07.756074Z","shell.execute_reply":"2025-06-24T03:53:07.778607Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"acc","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:07.780690Z","iopub.execute_input":"2025-06-24T03:53:07.781029Z","iopub.status.idle":"2025-06-24T03:53:07.798837Z","shell.execute_reply.started":"2025-06-24T03:53:07.780998Z","shell.execute_reply":"2025-06-24T03:53:07.797829Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train = X[:10000].reshape((10000, 784))\ny_train = y[:10000]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:23.926261Z","iopub.execute_input":"2025-06-24T03:53:23.926842Z","iopub.status.idle":"2025-06-24T03:53:23.931379Z","shell.execute_reply.started":"2025-06-24T03:53:23.926813Z","shell.execute_reply":"2025-06-24T03:53:23.930402Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train():\n\n    for epoch in range(5):\n        acc = 0\n        total_loss = 0\n        for i in range(10000):  # 少量でテスト\n            x = X_train[i]\n            y = y_train[i]\n\n            # 順伝播\n            z1 = fc1.forward(x)\n            a1 = sigmoid(z1)\n            z2 = fc2.forward(a1)\n            a2 = sigmoid(z2)\n            z3 = fc3.forward(a2)\n            y_pred = softmax(z3)\n\n            # 損失と精度\n            total_loss += cross_entropy(y_pred, y)\n            acc += int(np.argmax(y_pred) == np.argmax(y))\n\n            # Backward\n            grad_z3 = y_pred - y\n            grad_a2 = fc3.backward(grad_z3)\n            \n            grad_z2 = sigmoid_deriv(z2)\n            grad_a1 = fc2.backward(grad_a2 * grad_z2)\n            \n            grad_z1 = sigmoid_deriv(z1)\n            _ = fc1.backward(grad_a1 * grad_z1)\n\n        print(f\"Epoch {epoch+1}: Loss={total_loss/10000:.4f}, Accuracy={acc/10000}%\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:24.407730Z","iopub.execute_input":"2025-06-24T03:53:24.408080Z","iopub.status.idle":"2025-06-24T03:53:24.415371Z","shell.execute_reply.started":"2025-06-24T03:53:24.408025Z","shell.execute_reply":"2025-06-24T03:53:24.414458Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:28.121261Z","iopub.execute_input":"2025-06-24T03:53:28.121632Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_test = X[10000:20000].reshape((10000, 784))\ny_test = y[10000:20000]","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"z1 = fc1.forward(X_test)\na1 = sigmoid(z1)\nz2 = fc2.forward(a1)\na2 = sigmoid(z2)\nz3 = fc3.forward(a2)\ny_pred = softmax(z3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:08.524196Z","iopub.status.idle":"2025-06-24T03:53:08.524480Z","shell.execute_reply.started":"2025-06-24T03:53:08.524354Z","shell.execute_reply":"2025-06-24T03:53:08.524366Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"np.mean(y_pred.argmax(axis=1) == y_test.argmax(axis=1))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-24T03:53:08.525825Z","iopub.status.idle":"2025-06-24T03:53:08.526210Z","shell.execute_reply.started":"2025-06-24T03:53:08.526016Z","shell.execute_reply":"2025-06-24T03:53:08.526032Z"}},"outputs":[],"execution_count":null}]}