{"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":"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 导入必要库","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib\nimport matplotlib.pyplot as plt\n\nimport torch\nimport torch.nn as nn\n\nfrom torchvision.models.vgg import vgg16\nfrom torchvision import transforms\n\nimport warnings\nwarnings.simplefilter('ignore')","metadata":{"execution":{"iopub.status.busy":"2023-04-09T14:50:17.285837Z","iopub.execute_input":"2023-04-09T14:50:17.286686Z","iopub.status.idle":"2023-04-09T14:50:19.861364Z","shell.execute_reply.started":"2023-04-09T14:50:17.286630Z","shell.execute_reply":"2023-04-09T14:50:19.860359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 查看数据集","metadata":{}},{"cell_type":"code","source":"import os\nfor root, dirs, files in os.walk(\"/kaggle\"):\n    for file in dirs:\n        print(os.path.join(root, file))\n    for file in files:\n        print(os.path.join(root, file))","metadata":{"execution":{"iopub.status.busy":"2023-04-09T14:50:19.865980Z","iopub.execute_input":"2023-04-09T14:50:19.866509Z","iopub.status.idle":"2023-04-09T14:50:19.875449Z","shell.execute_reply.started":"2023-04-09T14:50:19.866474Z","shell.execute_reply":"2023-04-09T14:50:19.874337Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/Kannada-MNIST/train.csv')\ntest = pd.read_csv('/kaggle/input/Kannada-MNIST/test.csv')\ntest_id = test['id']\ntrain_label = train['label']\ntrain = train.iloc[:, 1:]\ntest = test.iloc[:, 1:]","metadata":{"execution":{"iopub.status.busy":"2023-04-09T14:50:19.876996Z","iopub.execute_input":"2023-04-09T14:50:19.877645Z","iopub.status.idle":"2023-04-09T14:50:25.137181Z","shell.execute_reply.started":"2023-04-09T14:50:19.877607Z","shell.execute_reply":"2023-04-09T14:50:25.136049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"maxx = train.max()\nminn = train.min()\n\ntrain = (train - minn) / (maxx - minn)\ntest = (test - minn) / (maxx - minn)\n\nvalid = train.iloc[40000:, :]\ntrain = train.iloc[:40000, :]\n\nvalid_label = train_label.iloc[40000:]\ntrain_label = train_label.iloc[:40000]","metadata":{"execution":{"iopub.status.busy":"2023-04-09T14:50:25.143150Z","iopub.execute_input":"2023-04-09T14:50:25.143949Z","iopub.status.idle":"2023-04-09T14:50:25.696125Z","shell.execute_reply.started":"2023-04-09T14:50:25.143910Z","shell.execute_reply":"2023-04-09T14:50:25.694953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.utils.data import Dataset, DataLoader\n\n# 直接参与PyTorch模型训练的数据必须是tensor\nclass MNISTDataset(Dataset):\n    def __init__(self, x, y=None):\n        if isinstance(x, pd.core.frame.DataFrame):\n            x = x.to_numpy().reshape(-1, 28, 28)\n        if y is not None and (isinstance(y, pd.core.frame.DataFrame) or isinstance(y, pd.core.frame.Series)):\n            y = y.to_numpy()\n        #print(type(x))\n        self.x = x\n        self.y = y\n        #print('selfx:', x.shape)\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        #print('xi:', xi.shape)\n        if self.y is None:\n            return xi\n        else:\n            yi = torch.tensor(self.y[item]).long()\n            # 注意，多分类需要用到CrossEntropyLoss\n            return xi, yi\n\n\ntrain_ds = MNISTDataset(train, train_label)\nvalid_ds = MNISTDataset(valid, valid_label)\ntest_ds = MNISTDataset(test)\n\n\ntrain_dl = DataLoader(train_ds, \n                      shuffle=True, \n                      batch_size=16)\nvalid_dl = DataLoader(valid_ds, \n                     shuffle=False, \n                     batch_size=16)\ntest_dl = DataLoader(test_ds, \n                     shuffle=False, \n                     batch_size=16)","metadata":{"execution":{"iopub.status.busy":"2023-04-09T14:50:25.698491Z","iopub.execute_input":"2023-04-09T14:50:25.699165Z","iopub.status.idle":"2023-04-09T14:50:25.711077Z","shell.execute_reply.started":"2023-04-09T14:50:25.699120Z","shell.execute_reply":"2023-04-09T14:50:25.710315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg = vgg16(pretrained = True)\nprint(vgg)","metadata":{"execution":{"iopub.status.busy":"2023-04-09T14:50:25.712693Z","iopub.execute_input":"2023-04-09T14:50:25.713367Z","iopub.status.idle":"2023-04-09T14:50:31.202935Z","shell.execute_reply.started":"2023-04-09T14:50:25.713329Z","shell.execute_reply":"2023-04-09T14:50:31.201850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg.features[0]=nn.Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n\nvgg.classifier.add_module('7', nn.ReLU(inplace=True))\nvgg.classifier.add_module('8', nn.Dropout(p=0.5, inplace=False))\nvgg.classifier.add_module('9', nn.Linear(in_features=1000, out_features=10, bias=True))\n\nvgg.classifier[0]=nn.Linear(in_features=25088, out_features=4096, bias=False)\nvgg.classifier[3]=nn.Linear(in_features=4096, out_features=4096, bias=False)\nvgg.classifier[6]=nn.Linear(in_features=4096, out_features=1000, bias=False)\nvgg.classifier[9]=nn.Linear(in_features=1000, out_features=10, bias=False)\nprint(vgg)","metadata":{"execution":{"iopub.status.busy":"2023-04-09T14:50:31.207355Z","iopub.execute_input":"2023-04-09T14:50:31.209690Z","iopub.status.idle":"2023-04-09T14:50:32.391806Z","shell.execute_reply.started":"2023-04-09T14:50:31.209646Z","shell.execute_reply":"2023-04-09T14:50:32.389920Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 手算图片大小变化\nVGG(  \n  (features): Sequential(                                                           【1，28，28】  \n    -------------------------------------------------------------------------------------------(行 + 2·padding数 - kernel)/stride + 1  \n    (0): Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))           【64，(28+2·1-3)/1+1=28，28】  \n    (1): ReLU(inplace=True)  \n    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))          【64，28，28】  \n    (3): ReLU(inplace=True)  \n    -------------------------------------------------------------------------------------------(行 + 2·padding数 - 1·(kernel-1) -1)/stride + 1  \n    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) 【128，(28 + 2·1 - 1·(2-1) - 1)/2+1= 15，15】  \n    (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))         【128，(15 + 2·1 - 3)/1+1 = 15，15】  \n    (6): ReLU(inplace=True)    \n    (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))        【128,15，15】  \n    (8): ReLU(inplace=True)  \n    (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) 【128，(15 + 2·1 - 1·(2-1) - 1)/2 +1= 8，8】  \n    (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))       【256，8，8】  \n    (11): ReLU(inplace=True)  \n    (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))       【256，8，8】  \n    (13): ReLU(inplace=True)  \n    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))       【256，8，8】  \n    (15): ReLU(inplace=True)  \n    (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)【256，(8 + 2·1 - 1·(2-1) - 1)/2 +1= 5，5】  \n    (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))       【256，5，5】  \n    (18): ReLU(inplace=True)     \n    (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))       【512，5，5】  \n    (20): ReLU(inplace=True)  \n    (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))       【512，5，5】  \n    (22): ReLU(inplace=True)  \n    (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)【512，(5 + 2·1 - 1·(2-1) - 1)/2 +1= 3，3】  \n    (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))       【512，3，3】  \n    (25): ReLU(inplace=True)    \n    (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))       【512，3，3】  \n    (27): ReLU(inplace=True)  \n    (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))       【512，3，3】  \n    (29): ReLU(inplace=True)  \n    (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)【512，(3 + 2·1 - 1·(2-1) - 1)/2 +1= 2，2】  \n  )  \n  (avgpool): AdaptiveAvgPool2d(output_size=(7, 7))                                  【512，7, 7】  \n  (classifier): Sequential(  \n    (0): Linear(in_features=25088, out_features=4096, bias=True)  \n    (1): ReLU(inplace=True)  \n    (2): Dropout(p=0.5, inplace=False)  \n    (3): Linear(in_features=4096, out_features=4096, bias=True)  \n    (4): ReLU(inplace=True)  \n    (5): Dropout(p=0.5, inplace=False)  \n    (6): Linear(in_features=4096, out_features=1000, bias=True)  \n    (7): ReLU(inplace=True)  \n    (8): Dropout(p=0.5, inplace=False)  \n    (9): Linear(in_features=1000, out_features=10, bias=True)  \n  )  \n)  ","metadata":{}},{"cell_type":"markdown","source":"## 开始训练","metadata":{}},{"cell_type":"code","source":"vgg = vgg.cuda()\nresize = transforms.Resize([256,256])\n\n# 使用交叉熵损失函数\nloss_func = torch.nn.CrossEntropyLoss().cuda()\n\n# 使用Adam下降优化器\noptimizer = torch.optim.Adam(vgg.parameters(), lr=0.009)\n\n# 设置迭代次数\nfor epoch in range(0,0):\n    vgg.train()    #开启模型训练模式\n    for batch_idx, (data, target) in enumerate(train_dl):\n        data = data.reshape(-1, 1,28, 28)\n        data = resize(data)\n        #print(data.shape)\n        data = data.cuda()\n        # 将计算的数据与目标数据求误差损失\n        prediction = vgg(data)\n        #tmp = prediction\n        #print(tmp.shape)\n        target = target.cuda()\n        loss = loss_func(prediction, target)\n\n        optimizer.zero_grad() # 清除之前的梯度\n        loss.backward()       # 进行反向传播，计算梯度\n        optimizer.step()      # 执行梯度下降\n        \n        # 打印训练过程中loss变化\n        if batch_idx % 200 == 0:\n            print('训练: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(\n                epoch, batch_idx * len(data), len(train_dl.dataset),\n                       100. * batch_idx / len(train_dl), loss.item()))\n        \n    vgg.eval()     #开启模型评估（验证）模式\n    test_loss = 0\n    correct = 0\n    for data, target in valid_dl:\n        data = data.reshape(-1, 1, 28, 28)\n        data = resize(data)\n        data = data.cuda()\n        prediction = vgg(data)\n        target = target.cuda()\n        test_loss += loss_func(prediction, target).item()\n        # 取出概率最大值的索引编号，即预测值\n        pred = prediction.data.argmax(dim=1)\n        # 统计正确预测的个数\n        correct += pred.eq(target.data).sum()\n\n    test_loss /= len(valid_dl.dataset)\n    # 打印输出测试误差及准确率\n    print('\\n测试: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n        test_loss, correct, len(valid_dl.dataset),\n        100. * correct / len(valid_dl.dataset)))","metadata":{"execution":{"iopub.status.busy":"2023-04-09T14:50:33.654782Z","iopub.execute_input":"2023-04-09T14:50:33.655373Z","iopub.status.idle":"2023-04-09T15:51:54.905604Z","shell.execute_reply.started":"2023-04-09T14:50:33.655332Z","shell.execute_reply":"2023-04-09T15:51:54.904495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"myvgg = nn.Sequential(\n    nn.Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),\n    nn.Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),\n    nn.Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),\n    nn.Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),\n    nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),\n    nn.ReLU(inplace=True),\n    nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),\n    nn.AdaptiveAvgPool2d(output_size=(7, 7)),\n    nn.Linear(in_features=25088, out_features=4096, bias=False),#True),\n    nn.ReLU(inplace=True),\n    nn.Dropout(p=0.5, inplace=False),\n    nn.Linear(in_features=4096, out_features=4096, bias=False),#True),\n    nn.ReLU(inplace=True),\n    nn.Dropout(p=0.5, inplace=False),\n    nn.Linear(in_features=4096, out_features=1000, bias=False),#True),\n    nn.ReLU(inplace=True),\n    nn.Dropout(p=0.5, inplace=False),\n    nn.Linear(in_features=1000, out_features=10, bias=False),#True)\n)\nprint(myvgg)","metadata":{"execution":{"iopub.status.busy":"2023-04-09T15:51:54.909301Z","iopub.execute_input":"2023-04-09T15:51:54.909654Z","iopub.status.idle":"2023-04-09T15:51:54.917937Z","shell.execute_reply.started":"2023-04-09T15:51:54.909621Z","shell.execute_reply":"2023-04-09T15:51:54.916575Z"},"trusted":true},"execution_count":null,"outputs":[]}]}