{"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":"import numpy as np\nimport pandas as pd\nimport torch.nn as nn\nimport torch\nimport torch.nn.functional as F\nimport torchvision\nimport os\nimport random\nimport matplotlib.image as img\nimport matplotlib.pyplot as plt\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision.transforms as transforms\nimport glob\nimport gc","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-05-01T16:02:45.512706Z","iopub.execute_input":"2022-05-01T16:02:45.51302Z","iopub.status.idle":"2022-05-01T16:02:47.222299Z","shell.execute_reply.started":"2022-05-01T16:02:45.512939Z","shell.execute_reply":"2022-05-01T16:02:47.221571Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SEED = 42\ndevice = 'cuda:0' if torch.cuda.is_available() else 'cpu'\ndevice","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:02:47.223893Z","iopub.execute_input":"2022-05-01T16:02:47.224632Z","iopub.status.idle":"2022-05-01T16:02:47.282613Z","shell.execute_reply.started":"2022-05-01T16:02:47.224601Z","shell.execute_reply":"2022-05-01T16:02:47.281788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_list = []\n# test_list = []\n# label_list = []\n\n# for dirname, _, filenames in os.walk('../input/imagenetmini-1000/imagenet-mini/train/'):\n#     label_list.append(str(dirname).split('/')[5])\n# label_list = list(set(label_list))[1:]\n\n# for dirname, _, filenames in os.walk('../input/imagenetmini-1000/imagenet-mini/train/'):\n#     for filename in filenames:\n#         train_list.append(str(os.path.join(dirname, filename)))\n        \n# for dirname, _, filenames in os.walk('../input/imagenetmini-1000/imagenet-mini/val/'):\n#     for filename in filenames:\n#         train_list.append(str(os.path.join(dirname, filename)))\n\n# train_list = glob.glob('../input/imagenetmini-1000/imagenet-mini/train/**/*.JPEG')\n# test_list = glob.glob('../input/imagenetmini-1000/imagenet-mini/val/**/*.JPEG')","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:02:47.283813Z","iopub.execute_input":"2022-05-01T16:02:47.284423Z","iopub.status.idle":"2022-05-01T16:02:47.294364Z","shell.execute_reply.started":"2022-05-01T16:02:47.28437Z","shell.execute_reply":"2022-05-01T16:02:47.29302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def seed_everything(seed):\n    np.random.seed(seed)\n    random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    \nseed_everything(SEED)","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:02:47.297052Z","iopub.execute_input":"2022-05-01T16:02:47.297573Z","iopub.status.idle":"2022-05-01T16:02:47.305668Z","shell.execute_reply.started":"2022-05-01T16:02:47.297509Z","shell.execute_reply":"2022-05-01T16:02:47.304961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# gray_list = []\n# for i in range(len(train_list)):\n#     image = img.imread(train_list[i])\n#     if(len(image.shape) == 2):\n#         gray_list.append(train_list[i])\n# for i in range(len(gray_list)):\n#     train_list.remove(gray_list[i])\n# print(len(gray_list))\n\n# gray_list = []\n# for i in range(len(test_list)):\n#     image = img.imread(test_list[i])\n#     if(len(image.shape) == 2):\n#         gray_list.append(test_list[i])\n# for i in range(len(gray_list)):\n#     test_list.remove(gray_list[i])\n# print(len(gray_list))\n    \n# gc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:02:47.308038Z","iopub.execute_input":"2022-05-01T16:02:47.30832Z","iopub.status.idle":"2022-05-01T16:02:47.315092Z","shell.execute_reply.started":"2022-05-01T16:02:47.308296Z","shell.execute_reply":"2022-05-01T16:02:47.314412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# class MiniImageNetDataset(Dataset):\n#     def __init__(self, x, y, transform=None):\n#         self.list_x = x\n#         self.list_y = y\n#         self.transform = transform\n    \n#     def __len__(self):\n#         return len(self.list_x)\n    \n#     def __getitem__(self, idx):\n#         image = img.imread(self.list_x[idx])\n#         label = self.list_y.index(self.list_x[idx].split('/')[5])\n#         label = torch.as_tensor(label).to(device)\n#         if self.transform is not None:\n#             image = self.transform(image).to(device)\n        \n#         return {'image': image, 'label': label}","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:02:47.316483Z","iopub.execute_input":"2022-05-01T16:02:47.316967Z","iopub.status.idle":"2022-05-01T16:02:47.323181Z","shell.execute_reply.started":"2022-05-01T16:02:47.316925Z","shell.execute_reply":"2022-05-01T16:02:47.322312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_dataset = MiniImageNetDataset(train_list, label_list, train_transform)\n# train_dataloader = DataLoader(train_dataset, shuffle=True, batch_size=32)\n# for i, item in enumerate(train_dataloader):\n#     plt.imshow(np.array(item['image'].cpu()).transpose([0, 2, 3, 1])[0])\n#     plt.title(np.array(item['label'].cpu())[0])\n#     plt.show()\n#     break\n# len(train_dataset)","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:02:47.324879Z","iopub.execute_input":"2022-05-01T16:02:47.325555Z","iopub.status.idle":"2022-05-01T16:02:47.332772Z","shell.execute_reply.started":"2022-05-01T16:02:47.325505Z","shell.execute_reply":"2022-05-01T16:02:47.331984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class BasicConv2d(nn.Module):\n    def __init__(self, in_channels, out_channels, **kwargs):\n        super(BasicConv2d, self).__init__()\n        self.conv = nn.Conv2d(in_channels, out_channels, **kwargs)\n        self.relu = nn.ReLU(inplace=True)\n\n    def forward(self, x):\n        x = self.conv(x)\n        x = self.relu(x)\n        return x\n\n#inception结构\nclass Inception(nn.Module):\n    def __init__(self, in_channels, ch1x1, ch3x3reduce, ch3x3, ch5x5reduce, ch5x5, pool_proj):\n        super(Inception, self).__init__()\n\n        self.branch1 = BasicConv2d(in_channels, ch1x1, kernel_size=1)\n\n        self.branch2 = nn.Sequential(\n            BasicConv2d(in_channels, ch3x3reduce, kernel_size=1),\n            BasicConv2d(ch3x3reduce, ch3x3, kernel_size=3, padding=1)   # 保证输出大小等于输入大小\n        )\n\n        self.branch3 = nn.Sequential(\n            BasicConv2d(in_channels, ch5x5reduce, kernel_size=1),\n            BasicConv2d(ch5x5reduce, ch5x5, kernel_size=5, padding=2)   # 保证输出大小等于输入大小\n        )\n\n        self.branch4 = nn.Sequential(\n            nn.MaxPool2d(kernel_size=3, stride=1, padding=1),\n            BasicConv2d(in_channels, pool_proj, kernel_size=1)\n        )\n\n    def forward(self, x):\n        branch1 = self.branch1(x)\n        branch2 = self.branch2(x)\n        branch3 = self.branch3(x)\n        branch4 = self.branch4(x)\n\n        outputs = [branch1, branch2, branch3, branch4]\n        return torch.cat(outputs, 1)","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:02:47.334237Z","iopub.execute_input":"2022-05-01T16:02:47.334733Z","iopub.status.idle":"2022-05-01T16:02:47.348115Z","shell.execute_reply.started":"2022-05-01T16:02:47.334685Z","shell.execute_reply":"2022-05-01T16:02:47.347376Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#辅助分类器\nclass InceptionAux(nn.Module):\n    def __init__(self, in_channels, num_classes):\n        super(InceptionAux, self).__init__()\n        self.averagePool = nn.AvgPool2d(kernel_size=5, stride=3)\n        self.conv = BasicConv2d(in_channels, 128, kernel_size=1)  # output[batch, 128, 4, 4]\n\n        self.fc1 = nn.Linear(2048, 1024)\n        self.fc2 = nn.Linear(1024, num_classes)\n\n    def forward(self, x):\n        # aux1: N x 512 x 14 x 14, aux2: N x 528 x 14 x 14\n        x = self.averagePool(x)\n        # aux1: N x 512 x 4 x 4, aux2: N x 528 x 4 x 4\n        x = self.conv(x)\n        # N x 128 x 4 x 4\n        x = torch.flatten(x, 1)\n        x = F.dropout(x, 0.5, training=self.training)\n        # N x 2048\n        x = F.relu(self.fc1(x), inplace=True)\n        x = F.dropout(x, 0.5, training=self.training)\n        # N x 1024\n        x = self.fc2(x)\n        # N x num_classes\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:02:47.349562Z","iopub.execute_input":"2022-05-01T16:02:47.350053Z","iopub.status.idle":"2022-05-01T16:02:47.360285Z","shell.execute_reply.started":"2022-05-01T16:02:47.350016Z","shell.execute_reply":"2022-05-01T16:02:47.359499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class GoogLeNet(nn.Module):\n    def __init__(self, num_classes=1000, aux_logits=True, init_weights=False):\n        super(GoogLeNet, self).__init__()\n        self.aux_logits = aux_logits\n\n        self.conv1 = BasicConv2d(3, 64, kernel_size=7, stride=2, padding=3)\n        self.maxpool1 = nn.MaxPool2d(3, stride=2, ceil_mode=True)\n        self.lrn1 = nn.LocalResponseNorm(size=2)\n\n        self.conv2 = BasicConv2d(64, 64, kernel_size=1)\n        self.conv3 = BasicConv2d(64, 192, kernel_size=3, padding=1)\n        self.lrn2 = nn.LocalResponseNorm(size=2)\n        self.maxpool2 = nn.MaxPool2d(3, stride=2, ceil_mode=True)\n\n        self.inception3a = Inception(192, 64, 96, 128, 16, 32, 32)\n        self.inception3b = Inception(256, 128, 128, 192, 32, 96, 64)\n        self.maxpool3 = nn.MaxPool2d(3, stride=2, ceil_mode=True)\n\n        self.inception4a = Inception(480, 192, 96, 208, 16, 48, 64)\n        self.inception4b = Inception(512, 160, 112, 224, 24, 64, 64)\n        self.inception4c = Inception(512, 128, 128, 256, 24, 64, 64)\n        self.inception4d = Inception(512, 112, 144, 288, 32, 64, 64)\n        self.inception4e = Inception(528, 256, 160, 320, 32, 128, 128)\n        self.maxpool4 = nn.MaxPool2d(3, stride=2, ceil_mode=True)\n\n        self.inception5a = Inception(832, 256, 160, 320, 32, 128, 128)\n        self.inception5b = Inception(832, 384, 192, 384, 48, 128, 128)\n\n        if self.aux_logits:\n            self.aux1 = InceptionAux(512, num_classes)\n            self.aux2 = InceptionAux(528, num_classes)\n\n        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))\n        self.dropout = nn.Dropout(0.4)\n        self.fc = nn.Linear(1024, num_classes)\n        if init_weights:\n            self._initialize_weights()\n\n    def forward(self, x):\n        # N x 3 x 224 x 224\n        x = self.conv1(x)\n        # N x 64 x 112 x 112\n        x = self.maxpool1(x)\n        x = self.lrn1(x)\n        # N x 64 x 56 x 56\n        x = self.conv2(x)\n        # N x 64 x 56 x 56\n        x = self.conv3(x)\n        x = self.lrn2(x)\n        # N x 192 x 56 x 56\n        x = self.maxpool2(x)\n\n        # N x 192 x 28 x 28\n        x = self.inception3a(x)\n        # N x 256 x 28 x 28\n        x = self.inception3b(x)\n        # N x 480 x 28 x 28\n        x = self.maxpool3(x)\n        # N x 480 x 14 x 14\n        x = self.inception4a(x)\n        # N x 512 x 14 x 14\n        if self.training and self.aux_logits:    # eval model lose this layer\n            aux1 = self.aux1(x)\n\n        x = self.inception4b(x)\n        # N x 512 x 14 x 14\n        x = self.inception4c(x)\n        # N x 512 x 14 x 14\n        x = self.inception4d(x)\n        # N x 528 x 14 x 14\n        if self.training and self.aux_logits:    # eval model lose this layer\n            aux2 = self.aux2(x)\n\n        x = self.inception4e(x)\n        # N x 832 x 14 x 14\n        x = self.maxpool4(x)\n        # N x 832 x 7 x 7\n        x = self.inception5a(x)\n        # N x 832 x 7 x 7\n        x = self.inception5b(x)\n        # N x 1024 x 7 x 7\n\n        x = self.avgpool(x)\n        # N x 1024 x 1 x 1\n        x = torch.flatten(x, 1)\n        # N x 1024\n        x = self.dropout(x)\n        x = self.fc(x)\n        # N x 1000 (num_classes)\n        if self.training and self.aux_logits:   # eval model lose this layer\n            return x, aux2, aux1\n        return x\n\n    def _initialize_weights(self):\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')\n                if m.bias is not None:\n                    nn.init.constant_(m.bias, 0)\n            elif isinstance(m, nn.Linear):\n                nn.init.normal_(m.weight, 0, 0.01)\n                nn.init.constant_(m.bias, 0)\n","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:02:47.362413Z","iopub.execute_input":"2022-05-01T16:02:47.362848Z","iopub.status.idle":"2022-05-01T16:02:47.386268Z","shell.execute_reply.started":"2022-05-01T16:02:47.362812Z","shell.execute_reply":"2022-05-01T16:02:47.385548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_transform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.RandomHorizontalFlip(),\n    transforms.Resize([224, 224]),\n])\ntest_transform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Resize([224, 224]),\n])","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:02:47.38786Z","iopub.execute_input":"2022-05-01T16:02:47.388187Z","iopub.status.idle":"2022-05-01T16:02:47.397226Z","shell.execute_reply.started":"2022-05-01T16:02:47.388151Z","shell.execute_reply":"2022-05-01T16:02:47.396498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_dataset = MiniImageNetDataset(train_list, label_list, train_transform)\n# train_dataloader = DataLoader(train_dataset, shuffle=True, batch_size=32)\n# test_dataset = MiniImageNetDataset(test_list, label_list, test_transform)\n# test_dataloader = DataLoader(test_dataset, shuffle=True, batch_size=32)\ntrain_dataset = torchvision.datasets.CIFAR100(root = './', train = True, transform = train_transform, download = True)\ntrain_dataloader = DataLoader(train_dataset, shuffle=True, batch_size=32)\ntest_dataset = torchvision.datasets.CIFAR100(root = './', train = False, transform = train_transform, download = True)\ntest_dataloader = DataLoader(test_dataset, shuffle=False, batch_size=32)","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:02:47.398765Z","iopub.execute_input":"2022-05-01T16:02:47.399269Z","iopub.status.idle":"2022-05-01T16:02:55.085086Z","shell.execute_reply.started":"2022-05-01T16:02:47.399233Z","shell.execute_reply":"2022-05-01T16:02:55.084354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net = GoogLeNet(num_classes=100, aux_logits=True, init_weights=True)\nnet.to(device)\n# net.load_state_dict(torch.load('../input/googlenet-weights/googleNet.pth'))\nloss_function = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(net.parameters(), lr=1e-4)\n\nbest_acc = 0.0\nsave_path = './googleNet.pth'\nfor epoch in range(60):\n    # train\n    net.train()\n    running_loss = 0.0\n    for step, data in enumerate(train_dataloader):\n        images, labels = data\n        optimizer.zero_grad()\n        logits, aux_logits2, aux_logits1 = net(images.to(device))\n        loss0 = loss_function(logits, labels.to(device))\n        loss1 = loss_function(aux_logits1, labels.to(device))\n        loss2 = loss_function(aux_logits2, labels.to(device))\n        loss = loss0 + loss1 * 0.3 + loss2 * 0.3\n        loss.backward()\n        optimizer.step()\n\n        # print statistics\n        running_loss += loss.item()\n        # print train process\n        rate = (step + 1) / len(train_dataloader)\n        a = \"*\" * int(rate * 50)\n        b = \".\" * int((1 - rate) * 50)\n        print(\"\\rtrain loss: {:^3.0f}%[{}->{}]{:.3f}\".format(int(rate * 100), a, b, loss), end=\"\")\n    print()\n\n    # validate\n    net.eval()\n    acc = 0.0  # accumulate accurate number / epoch\n    with torch.no_grad():\n        for val_data in test_dataloader:\n            val_images, val_labels = val_data\n            outputs = net(val_images.to(device))\n            predict_y = torch.max(outputs, dim=1)[1]\n            acc += (predict_y == val_labels.to(device)).sum().item()\n        val_accurate = acc / len(test_dataset)\n        if val_accurate > best_acc:\n            best_acc = val_accurate\n            torch.save(net.state_dict(), save_path)\n        print('[epoch %d] train_loss: %.3f  test_accuracy: %.3f' %\n              (epoch + 1, running_loss / step, val_accurate))\n\nprint('Finished Training')","metadata":{"execution":{"iopub.status.busy":"2022-05-01T16:11:44.425059Z","iopub.execute_input":"2022-05-01T16:11:44.425733Z"},"trusted":true},"execution_count":null,"outputs":[]}]}