{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# 导入了需要用到的库\nimport pandas as pd\nimport numpy as np\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import DataLoader, TensorDataset\nimport torchvision.transforms as transforms\nimport matplotlib.pyplot as plt\n\n# 读取训练数据和测试数据\ntrain_data = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\ntest_data = pd.read_csv('/kaggle/input/digit-recognizer/test.csv')\n\n# 将训练数据和测试数据中的标签和图像数据分别存储\ntrain_labels = train_data['label'].values\ntrain_images = train_data.iloc[:, 1:].values / 255.0\ntest_images = test_data.values / 255.0 # 将图像数据进行了归一化处理\n\n# 数据预处理\ntrain_images = torch.Tensor(train_images.reshape(-1, 1, 28, 28))\ntest_images = torch.Tensor(test_images.reshape(-1, 1, 28, 28)) # 将 train_images 和 test_images转换为 PyTorch张量\ntrain_labels = torch.LongTensor(train_labels) # 将 train_labels 转换为 LongTensor 类型\n\n# 定义数据集和数据加载器\ntrain_dataset = TensorDataset(train_images, train_labels)\ntrain_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)# 使用 DataLoader 对其进行批量处理和随机打乱\n\n# 可视化图像和标签\nimgs=torch.from_numpy(np.array( train_images))\nimgs = imgs.to(torch.float32)\n# 随机选择一张图像\nindex = np.random.randint(0, len(train_data))\nimage = train_images[index].reshape(28, 28)\n\nplt.imshow(image, cmap='gray')\nplt.title('Label: {}'.format(train_labels[index]))\nplt.show()\n\n# 定义CNN模型\nclass Net(nn.Module):\n    def __init__(self):\n        super(Net, self).__init__()\n        self.conv1 = nn.Conv2d(1, 32, 3, padding=1) # 第一层卷积层 输入通道数为1，输出通道数为32，卷积核大小为3\n        self.conv2 = nn.Conv2d(32, 64, 3, padding=1) # 第二层卷积层 输入通道数为32，输出通道数为64，卷积核大小为3\n        self.pool = nn.MaxPool2d(2, 2) # 定义最大池化层，池化核大小为2，步长为2\n        self.fc1 = nn.Linear(64 * 7 * 7, 128) # 定义第一层全连接层，输入节点数为64 * 7 * 7，输出节点数为128\n        self.fc2 = nn.Linear(128, 10) # 定义第二层全连接层，输入节点数为128，输出节点数为10\n\n    def forward(self, x):\n        x = self.pool(nn.functional.relu(self.conv1(x))) # 对输入数据进行第一次卷积操作，然后进行relu激活，再进行最大池化操作\n        x = self.pool(nn.functional.relu(self.conv2(x))) # 对上一步的输出进行第二次卷积操作，然后进行relu激活，再进行最大池化操作\n        x = x.view(-1, 64 * 7 * 7) # 将上一步的输出转化为一维向量\n        x = nn.functional.relu(self.fc1(x)) \n        x = nn.functional.dropout(x, training=self.training) # 使用ReLU激活函数和dropout防止过拟合\n        x = self.fc2(x) # 对上一步的输出进行第二层全连接操作，得到最终的输出结果\n        return x\n\nnet = Net() # 创建实例\n\ncriterion = nn.CrossEntropyLoss() # 损失函数\noptimizer = torch.optim.Adam(net.parameters(), lr=0.001) # 定义损失函数和优化器\n\n\nnum_epoches = 10 # 训练轮数\nlosses=[]\nacces=[]\npreds=[] # 定义预测结果变量\n\nfor epoch in range(num_epoches):\n    train_loss=0\n    train_acc=0\n    net.train()\n    for img,label in train_loader:\n        #将图片和标签放入GPU设备\n        device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n        img=img.to(device)\n        label=label.to(device)\n        #计算结果\n        out=net(img)\n        #计算损失\n        loss=criterion(out,label)\n        #将梯度清零\n        optimizer.zero_grad()\n        #反向传播\n        loss.backward()\n        #更新网络参数\n        optimizer.step()\n        \n        #记录训练损失\n        train_loss+=loss.item()\n        #记录训练准确度\n        _,pred=out.max(1)\n        num_correct=(pred==label).sum().item()\n        acc=num_correct/img.shape[0]\n        train_acc+=acc\n        \n        #记录预测结果\n        preds.extend(pred.cpu().numpy())\n        \n    losses.append(train_loss/len(train_loader))\n    acces.append(train_acc/len(train_loader))\n    print('epoch:{},Train Loss:{:.4f},Train Acc:{:.4f}'.format(epoch,train_loss/len(train_loader),train_acc/len(train_loader)))\n\n# 绘制 train loss 曲线\nplt.plot(losses)\nplt.title('Train Loss')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.show()\n\n# 绘制 train acc 曲线\nplt.plot(acces)\nplt.title('Train Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.show()\n\n# 保存预测结果\ntest_labels = np.zeros((len(test_images)))\ntest_dataset = TensorDataset(test_images, torch.LongTensor(test_labels))\ntest_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)\n\npreds = []\nnet.eval()\nfor img, _ in test_loader:\n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    img = img.to(device)\n    out = net(img)\n    _, pred = out.max(1)\n    preds.extend(pred.cpu().numpy())\n\nsubmission = pd.DataFrame({'ImageId': np.arange(1, len(test_images) + 1), 'Label': preds})\n\nsubmission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-06-12T06:32:13.560220Z","iopub.execute_input":"2023-06-12T06:32:13.560684Z","iopub.status.idle":"2023-06-12T06:32:17.926351Z","shell.execute_reply.started":"2023-06-12T06:32:13.560655Z","shell.execute_reply":"2023-06-12T06:32:17.924381Z"},"trusted":true},"execution_count":null,"outputs":[]}]}