{"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":"markdown","source":"Resnet50_model","metadata":{}},{"cell_type":"code","source":"import torch.nn as nn\nimport torch\n\n\nclass BasicBlock(nn.Module):\n    expansion = 1\n\n    def __init__(self, in_channel, out_channel, stride=1, downsample=None, **kwargs):\n        super(BasicBlock, self).__init__()\n        self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=out_channel,\n                               kernel_size=3, stride=stride, padding=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(out_channel)\n        self.relu = nn.ReLU()\n        self.conv2 = nn.Conv2d(in_channels=out_channel, out_channels=out_channel,\n                               kernel_size=3, stride=1, padding=1, bias=False)\n        self.bn2 = nn.BatchNorm2d(out_channel)\n        self.downsample = downsample\n\n    def forward(self, x):\n        identity = x\n        if self.downsample is not None:\n            identity = self.downsample(x)\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n\n        out += identity\n        out = self.relu(out)\n\n        return out\n\n\nclass Bottleneck(nn.Module):\n    expansion = 4\n\n    def __init__(self, in_channel, out_channel, stride=1, downsample=None,\n                 groups=1, width_per_group=64):\n        super(Bottleneck, self).__init__()\n\n        width = int(out_channel * (width_per_group / 64.)) * groups\n\n        self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=width,\n                               kernel_size=1, stride=1, bias=False)  # squeeze channels\n        self.bn1 = nn.BatchNorm2d(width)\n        # -----------------------------------------\n        self.conv2 = nn.Conv2d(in_channels=width, out_channels=width, groups=groups,\n                               kernel_size=3, stride=stride, bias=False, padding=1)\n        self.bn2 = nn.BatchNorm2d(width)\n        # -----------------------------------------\n        self.conv3 = nn.Conv2d(in_channels=width, out_channels=out_channel*self.expansion,\n                               kernel_size=1, stride=1, bias=False)  # unsqueeze channels\n        self.bn3 = nn.BatchNorm2d(out_channel*self.expansion)\n        self.relu = nn.ReLU(inplace=True)\n        self.downsample = downsample\n\n    def forward(self, x):\n        identity = x\n        if self.downsample is not None:\n            identity = self.downsample(x)\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        out += identity\n        out = self.relu(out)\n\n        return out\n\n\nclass ResNet(nn.Module):\n\n    def __init__(self,\n                 block,\n                 blocks_num,\n                 num_classes=1000,\n                 include_top=True,\n                 groups=1,\n                 width_per_group=64):\n        super(ResNet, self).__init__()\n        self.include_top = include_top\n        self.in_channel = 64\n\n        self.groups = groups\n        self.width_per_group = width_per_group\n\n        self.conv1 = nn.Conv2d(3, self.in_channel, kernel_size=7, stride=2,\n                               padding=3, bias=False)\n        self.bn1 = nn.BatchNorm2d(self.in_channel)\n        self.relu = nn.ReLU(inplace=True)\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        self.layer1 = self._make_layer(block, 64, blocks_num[0])\n        self.layer2 = self._make_layer(block, 128, blocks_num[1], stride=2)\n        self.layer3 = self._make_layer(block, 256, blocks_num[2], stride=2)\n        self.layer4 = self._make_layer(block, 512, blocks_num[3], stride=2)\n        if self.include_top:\n            self.avgpool = nn.AdaptiveAvgPool2d((1, 1))  # output size = (1, 1)\n            self.fc1 = nn.Linear(512 * block.expansion, 512 * block.expansion)\n            self.drop = nn.Dropout(p=0.5)\n            self.fc = nn.Linear(512 * block.expansion, num_classes)\n\n\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\n    def _make_layer(self, block, channel, block_num, stride=1):\n        downsample = None\n        if stride != 1 or self.in_channel != channel * block.expansion:\n            downsample = nn.Sequential(\n                nn.Conv2d(self.in_channel, channel * block.expansion, kernel_size=1, stride=stride, bias=False),\n                nn.BatchNorm2d(channel * block.expansion))\n\n        layers = []\n        layers.append(block(self.in_channel,\n                            channel,\n                            downsample=downsample,\n                            stride=stride,\n                            groups=self.groups,\n                            width_per_group=self.width_per_group))\n        self.in_channel = channel * block.expansion\n\n        for _ in range(1, block_num):\n            layers.append(block(self.in_channel,\n                                channel,\n                                groups=self.groups,\n                                width_per_group=self.width_per_group))\n\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.bn1(x)\n        x = self.relu(x)\n        x = self.maxpool(x)\n\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n\n        if self.include_top:\n            x = self.avgpool(x)\n            x = torch.flatten(x, 1)\n            x = self.fc(x)\n\n        return x\n\n\ndef resnet50(num_classes=1000, include_top=True):\n    return ResNet(Bottleneck, [3, 4, 6, 3], num_classes=num_classes, include_top=include_top)","metadata":{"execution":{"iopub.status.busy":"2022-01-23T12:35:13.978154Z","iopub.execute_input":"2022-01-23T12:35:13.978414Z","iopub.status.idle":"2022-01-23T12:35:14.014542Z","shell.execute_reply.started":"2022-01-23T12:35:13.978383Z","shell.execute_reply":"2022-01-23T12:35:14.013846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"import os\nimport json\n\nimport torch\nimport torch.nn as nn\nfrom torchvision import transforms, datasets, utils\nimport torch.optim as optim\n\n\ndata_transform = {\n    \"train\": transforms.Compose([transforms.RandomResizedCrop(224),\n                                 transforms.RandomHorizontalFlip(),\n                                 transforms.ToTensor(),\n                                 transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]),\n    \"val\": transforms.Compose([transforms.Resize((224, 224)),  \n                               transforms.ToTensor(),\n                               transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])}\n\nimage_path = \"../input/dataset\"\ntrain_dataset = datasets.ImageFolder(root=os.path.join(image_path, \"train\"),\n                                     transform=data_transform[\"train\"])\ntrain_num = len(train_dataset)\n\nbatch_size = 64\nnw = min([os.cpu_count(), batch_size if batch_size > 1 else 0, 8])  # number of workers\nprint('Using {} dataloader workers every process'.format(nw))\n\ntrain_loader = torch.utils.data.DataLoader(train_dataset,\n                                           batch_size=batch_size, shuffle=True,\n                                           num_workers=nw)\n\nvalidate_dataset = datasets.ImageFolder(root=os.path.join(image_path, \"val\"),\n                                        transform=data_transform[\"val\"])\nval_num = len(validate_dataset)\nvalidate_loader = torch.utils.data.DataLoader(validate_dataset,\n                                              batch_size=4, shuffle=False,\n                                              num_workers=nw)\n\nprint(\"using {} images for training, {} images for validation.\".format(train_num, val_num))","metadata":{"execution":{"iopub.status.busy":"2022-01-23T12:35:14.016983Z","iopub.execute_input":"2022-01-23T12:35:14.017239Z","iopub.status.idle":"2022-01-23T12:35:20.570472Z","shell.execute_reply.started":"2022-01-23T12:35:14.017205Z","shell.execute_reply":"2022-01-23T12:35:20.569741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cassava_leaf_disease_list = train_dataset.class_to_idx\ncla_dict = dict((val, key) for key, val in cassava_leaf_disease_list.items())\n# write dict into json file\njson_str = json.dumps(cla_dict, indent=4)\nwith open('class_indices.json', 'w') as json_file:\n    json_file.write(json_str)","metadata":{"execution":{"iopub.status.busy":"2022-01-23T12:35:20.571693Z","iopub.execute_input":"2022-01-23T12:35:20.572047Z","iopub.status.idle":"2022-01-23T12:35:20.577739Z","shell.execute_reply.started":"2022-01-23T12:35:20.572009Z","shell.execute_reply":"2022-01-23T12:35:20.576938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"myDevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nnum_classes = 5\nmyModel = resnet50()\n\npre = torch.load(\"../input/resnet50-325pth/resnet50_325.pth\", map_location=myDevice)\ndelkey = []\nfor key, value in pre.items():\n    if \"fc\" in key:\n        delkey.append(key)\nfor key in delkey:\n    del pre[key]\nmyModel.load_state_dict(pre, strict=False)\ninchannel = myModel.fc.in_features\nmyModel.fc = nn.Linear(inchannel, num_classes)\ni = 1\nfor par in myModel.parameters():\n    if i < 140:\n        par.requires_grad = False\n    i += 1\n\nmyModel = myModel.to(myDevice)\nprint(myModel.fc)\nlearning_rate = 0.001\n# myOptimzier = optim.SGD(myModel.parameters(), lr=learning_rate, momentum=0.9)\nmyOptimzier = optim.SGD(filter(lambda p: p.requires_grad, myModel.parameters()), lr=learning_rate, momentum=0.9)\nmyLoss = torch.nn.CrossEntropyLoss()","metadata":{"execution":{"iopub.status.busy":"2022-01-23T12:35:20.579359Z","iopub.execute_input":"2022-01-23T12:35:20.580232Z","iopub.status.idle":"2022-01-23T12:35:21.187120Z","shell.execute_reply.started":"2022-01-23T12:35:20.580197Z","shell.execute_reply":"2022-01-23T12:35:21.186378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for _epoch in range(20):\n    training_loss = 0.0\n    for _step, input_data in enumerate(train_loader):\n        image, label = input_data[0].to(myDevice), input_data[1].to(myDevice)  # GPU加速\n        predict_label = myModel.forward(image)\n        loss = myLoss(predict_label, label)\n        myOptimzier.zero_grad()\n        loss.backward()\n        myOptimzier.step()\n\n        training_loss = training_loss + loss.item()\n        if _step % 10 == 0:\n            print(\n                '[iteration - %3d] training loss: %.3f' % (_epoch * len(train_loader) + _step, training_loss / 10))\n            training_loss = 0.0\n            print()\n    correct = 0\n    total = 0\n    best_acc = 0.0\n    myModel.eval()\n    for images, labels in validate_loader:\n        images = images.to(myDevice)\n        labels = labels.to(myDevice)\n        outputs = myModel(images)\n        numbers, predicted = torch.max(outputs.data, 1)\n        total += labels.size(0)\n        correct += (predicted == labels).sum().item()\n    acc = correct / total\n    import csv\n \n    with open(\"submission.csv\",\"w\") as csvfile:\n        writer = csv.writer(csvfile)\n        writer.writerow([acc])\n    \n    print('Testing Accuracy : %.3f ----------------lines---------------' % (acc))","metadata":{"execution":{"iopub.status.busy":"2022-01-23T12:35:21.188977Z","iopub.execute_input":"2022-01-23T12:35:21.189711Z"},"trusted":true},"execution_count":null,"outputs":[]}]}