{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":16017,"databundleVersionId":708189,"sourceType":"competition"}],"dockerImageVersionId":30626,"isInternetEnabled":false,"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","execution":{"iopub.status.busy":"2023-12-19T16:34:35.040157Z","iopub.execute_input":"2023-12-19T16:34:35.040573Z","iopub.status.idle":"2023-12-19T16:34:35.050038Z","shell.execute_reply.started":"2023-12-19T16:34:35.040540Z","shell.execute_reply":"2023-12-19T16:34:35.049047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 导入必要的包\nimport torch\nimport pandas as pd\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport matplotlib.pyplot as plt\nfrom torch.utils.data import DataLoader, TensorDataset\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:34:35.052220Z","iopub.execute_input":"2023-12-19T16:34:35.052948Z","iopub.status.idle":"2023-12-19T16:34:35.065325Z","shell.execute_reply.started":"2023-12-19T16:34:35.052916Z","shell.execute_reply":"2023-12-19T16:34:35.064502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/Kannada-MNIST/train.csv')\n\ntest_df = pd.read_csv('/kaggle/input/Kannada-MNIST/test.csv')","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:34:35.066587Z","iopub.execute_input":"2023-12-19T16:34:35.067025Z","iopub.status.idle":"2023-12-19T16:34:40.094180Z","shell.execute_reply.started":"2023-12-19T16:34:35.066988Z","shell.execute_reply":"2023-12-19T16:34:40.093039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.shape, test_df.shape","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:34:40.095619Z","iopub.execute_input":"2023-12-19T16:34:40.096055Z","iopub.status.idle":"2023-12-19T16:34:40.103461Z","shell.execute_reply.started":"2023-12-19T16:34:40.096026Z","shell.execute_reply":"2023-12-19T16:34:40.102204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_label = train_df['label'].values\ntrain = train_df.iloc[:, 1:].values\ntest = test_df.iloc[:, 1:].values","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:34:40.106859Z","iopub.execute_input":"2023-12-19T16:34:40.107184Z","iopub.status.idle":"2023-12-19T16:34:40.121563Z","shell.execute_reply.started":"2023-12-19T16:34:40.107156Z","shell.execute_reply":"2023-12-19T16:34:40.120373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 注意，深度学习模型输入一般需要进行标准化，否则可能会导致梯度爆炸等问题\nmu = train.mean()\nstd = train.std()\ntrain = (train - mu) / std\ntest = (test - mu) / std","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:34:40.123046Z","iopub.execute_input":"2023-12-19T16:34:40.123424Z","iopub.status.idle":"2023-12-19T16:34:40.707029Z","shell.execute_reply.started":"2023-12-19T16:34:40.123396Z","shell.execute_reply":"2023-12-19T16:34:40.706070Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 划分训练和验证集\nvalid = train[40000:]\ntrain = train[:40000]\nvalid_label = train_label[40000:]\ntrain_label = train_label[:40000]","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:34:40.708647Z","iopub.execute_input":"2023-12-19T16:34:40.709053Z","iopub.status.idle":"2023-12-19T16:34:40.715071Z","shell.execute_reply.started":"2023-12-19T16:34:40.709026Z","shell.execute_reply":"2023-12-19T16:34:40.714036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.utils.data import Dataset\n\n\n# 构造Dataset\nclass MNISTDataset(Dataset):\n    def __init__(self, x, y=None):\n        self.x = x\n        self.y = y\n\n    def __len__(self):\n        return len(self.x)\n\n    def __getitem__(self, item):\n        xi = torch.tensor(self.x[item]).float()\n        if self.y is None:\n            return xi\n        else:\n            # 在多数分类中，label一般不需要为float类型，避免有的情况出错\n            yi = torch.tensor(self.y[item]).long()\n            return xi, yi","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:34:40.716515Z","iopub.execute_input":"2023-12-19T16:34:40.716922Z","iopub.status.idle":"2023-12-19T16:34:40.727442Z","shell.execute_reply.started":"2023-12-19T16:34:40.716886Z","shell.execute_reply":"2023-12-19T16:34:40.726416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ds = MNISTDataset(train, train_label)\nvalid_ds = MNISTDataset(valid, valid_label)\ntest_ds = MNISTDataset(test)\ntrain_dl = DataLoader(train_ds, shuffle=True, batch_size=32)\nvalid_dl = DataLoader(valid_ds, shuffle=True, batch_size=32)\ntest_dl = DataLoader(test_ds, shuffle=False, batch_size=32)","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:34:40.728668Z","iopub.execute_input":"2023-12-19T16:34:40.729032Z","iopub.status.idle":"2023-12-19T16:34:40.743017Z","shell.execute_reply.started":"2023-12-19T16:34:40.729004Z","shell.execute_reply":"2023-12-19T16:34:40.742040Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):\n    \"\"\"绘制图像列表\"\"\"\n    figsize = (num_cols * scale, num_rows * scale)\n    _, axes = plt.subplots(num_rows, num_cols, figsize=figsize)\n    axes = axes.flatten()\n    imgs = imgs.reshape(-1, 28, 28)\n    for i, (ax, img) in enumerate(zip(axes, imgs)):\n        if torch.is_tensor(img):\n            # 图片张量\n            ax.imshow(img.numpy())\n        else:\n            # PIL图片\n            ax.imshow(img)\n            ax.axes.get_xaxis().set_visible(False)\n            ax.axes.get_yaxis().set_visible(False)\n            if titles:\n                ax.set_title(titles[i])\n    return axes","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:34:59.274623Z","iopub.execute_input":"2023-12-19T16:34:59.275848Z","iopub.status.idle":"2023-12-19T16:34:59.285795Z","shell.execute_reply.started":"2023-12-19T16:34:59.275800Z","shell.execute_reply":"2023-12-19T16:34:59.284808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for x, y in train_dl:\n    break\nshow_images(x, 4, 4)","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:35:07.924948Z","iopub.execute_input":"2023-12-19T16:35:07.925388Z","iopub.status.idle":"2023-12-19T16:35:10.101036Z","shell.execute_reply.started":"2023-12-19T16:35:07.925353Z","shell.execute_reply":"2023-12-19T16:35:10.099924Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 定义模型\nclass Net(torch.nn.Module):\n    def __init__(self):\n        super(Net, self).__init__()\n        self.fc1 = torch.nn.Linear(784, 256)\n        self.fc2 = torch.nn.Linear(256, 128)\n        self.fc3 = torch.nn.Linear(128, 10)\n        self.relu = torch.nn.ReLU()\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.relu(x)\n        x = self.fc2(x)\n        x = self.relu(x)\n        logits = self.fc3(x)\n        return logits\n\n\nmodel = Net()\nmodel","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:35:21.409949Z","iopub.execute_input":"2023-12-19T16:35:21.410904Z","iopub.status.idle":"2023-12-19T16:35:21.425205Z","shell.execute_reply.started":"2023-12-19T16:35:21.410868Z","shell.execute_reply":"2023-12-19T16:35:21.424196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = torch.optim.Adam(model.parameters(), lr=0.0003)\nloss_func = torch.nn.CrossEntropyLoss() # 使用交叉熵损失函数\n\n# 设置迭代次数\nfor epoch in range(5):\n    model.train()\n    for batch_idx, (data, target) in enumerate(train_dl):\n        cal_data = model(data)\n        # 将计算的数据与目标数据求误差损失\n        loss = loss_func(cal_data, target)\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        # 每隔200 * batchSize(200) = 40000 打印输出结果\n        if batch_idx % 200 == 0:\n            print('训练: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(\n                epoch,\n                batch_idx * len(data),\n                len(train_dl.dataset),\n                100. * batch_idx / len(train_dl),\n                loss.item()))\n# 验证\nmodel.eval()\ntest_loss = 0\ncorrect = 0\n\nfor data, target in valid_dl:\n    logits = model(data)\n    test_loss += loss_func(logits, target).item()\n    # 取出预测最大值的索引编号，即预测值\n    pred = logits.data.argmax(dim=1)\n    # 统计正确预测的个数\n    correct += pred.eq(target.data).sum()\n    test_loss /= len(valid_dl.dataset)\n    # 打印输出测试误差及准确率\n    print('测试: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n        test_loss,\n        correct,\n        len(valid_dl.dataset),\n        100. * correct / len(valid_dl.dataset)))","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:35:56.576261Z","iopub.execute_input":"2023-12-19T16:35:56.576918Z","iopub.status.idle":"2023-12-19T16:36:18.343074Z","shell.execute_reply.started":"2023-12-19T16:35:56.576878Z","shell.execute_reply":"2023-12-19T16:36:18.340812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 预测测试集合\n# model.eval()\npreds = []\n\nfor data in test_dl:\n    logits = model(data)\n    preds.append(logits.argmax(dim=1).cpu().numpy()) # 选择预测概率最高的类别作为预测结果","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:36:39.111233Z","iopub.execute_input":"2023-12-19T16:36:39.111647Z","iopub.status.idle":"2023-12-19T16:36:39.290240Z","shell.execute_reply.started":"2023-12-19T16:36:39.111614Z","shell.execute_reply":"2023-12-19T16:36:39.289289Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = np.concatenate(preds)","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:36:50.432857Z","iopub.execute_input":"2023-12-19T16:36:50.433275Z","iopub.status.idle":"2023-12-19T16:36:50.440379Z","shell.execute_reply.started":"2023-12-19T16:36:50.433244Z","shell.execute_reply":"2023-12-19T16:36:50.439114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds[:10]","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:36:57.212906Z","iopub.execute_input":"2023-12-19T16:36:57.213632Z","iopub.status.idle":"2023-12-19T16:36:57.220836Z","shell.execute_reply.started":"2023-12-19T16:36:57.213591Z","shell.execute_reply":"2023-12-19T16:36:57.219574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df = pd.DataFrame({'id':test_df['id'], 'label':preds})\nsubmission_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:37:11.146386Z","iopub.execute_input":"2023-12-19T16:37:11.147317Z","iopub.status.idle":"2023-12-19T16:37:11.160669Z","shell.execute_reply.started":"2023-12-19T16:37:11.147278Z","shell.execute_reply":"2023-12-19T16:37:11.159844Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_file_dir = './'\nname = 'submission.csv'\nsubmission_path = submission_file_dir + name\n\nsubmission_df.to_csv(submission_path, index=False)","metadata":{"execution":{"iopub.status.busy":"2023-12-19T16:37:23.625359Z","iopub.execute_input":"2023-12-19T16:37:23.626445Z","iopub.status.idle":"2023-12-19T16:37:23.645552Z","shell.execute_reply.started":"2023-12-19T16:37:23.626409Z","shell.execute_reply":"2023-12-19T16:37:23.644586Z"},"trusted":true},"execution_count":null,"outputs":[]}]}