{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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\n\n# You can write up to 5GB 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","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom torch.nn import functional as F\nfrom matplotlib import pyplot as plt\nfrom PIL import Image\nfrom torchvision import transforms as tsf\nimport csv\n%pylab inline","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"BAM"},{"metadata":{"trusted":true},"cell_type":"code","source":"import math\n\nclass Flatten(nn.Module):\n    def forward(self, x):\n        return x.view(x.size(0), -1)\nclass ChannelGate(nn.Module):\n    def __init__(self, gate_channel, reduction_ratio=16, num_layers=1):\n        super(ChannelGate, self).__init__()\n        #self.gate_activation = gate_activation\n        self.gate_c = nn.Sequential()\n        self.gate_c.add_module( 'flatten', Flatten() )\n        gate_channels = [gate_channel]\n        gate_channels += [gate_channel // reduction_ratio] * num_layers\n        gate_channels += [gate_channel]\n        for i in range( len(gate_channels) - 2 ):\n            self.gate_c.add_module( 'gate_c_fc_%d'%i, nn.Linear(gate_channels[i], gate_channels[i+1]) )\n            self.gate_c.add_module( 'gate_c_bn_%d'%(i+1), nn.BatchNorm1d(gate_channels[i+1]) )\n            self.gate_c.add_module( 'gate_c_relu_%d'%(i+1), nn.ReLU() )\n        self.gate_c.add_module( 'gate_c_fc_final', nn.Linear(gate_channels[-2], gate_channels[-1]) )\n    def forward(self, in_tensor):\n        avg_pool = F.avg_pool2d( in_tensor, in_tensor.size(2), stride=in_tensor.size(2) )\n        return self.gate_c( avg_pool ).unsqueeze(2).unsqueeze(3).expand_as(in_tensor)\n\nclass SpatialGate(nn.Module):\n    def __init__(self, gate_channel, reduction_ratio=16, dilation_conv_num=2, dilation_val=4):\n        super(SpatialGate, self).__init__()\n        self.gate_s = nn.Sequential()\n        self.gate_s.add_module( 'gate_s_conv_reduce0', nn.Conv2d(gate_channel, gate_channel//reduction_ratio, kernel_size=1))\n        self.gate_s.add_module( 'gate_s_bn_reduce0',\tnn.BatchNorm2d(gate_channel//reduction_ratio) )\n        self.gate_s.add_module( 'gate_s_relu_reduce0',nn.ReLU() )\n        for i in range( dilation_conv_num ):\n            self.gate_s.add_module( 'gate_s_conv_di_%d'%i, nn.Conv2d(gate_channel//reduction_ratio, gate_channel//reduction_ratio, kernel_size=3, \\\n\t\t\t\t\t\tpadding=dilation_val, dilation=dilation_val) )\n            self.gate_s.add_module( 'gate_s_bn_di_%d'%i, nn.BatchNorm2d(gate_channel//reduction_ratio) )\n            self.gate_s.add_module( 'gate_s_relu_di_%d'%i, nn.ReLU() )\n        self.gate_s.add_module( 'gate_s_conv_final', nn.Conv2d(gate_channel//reduction_ratio, 1, kernel_size=1) )\n    def forward(self, in_tensor):\n        return self.gate_s( in_tensor ).expand_as(in_tensor)\nclass BAM(nn.Module):\n    def __init__(self, gate_channel):\n        super(BAM, self).__init__()\n        self.channel_att = ChannelGate(gate_channel)\n        self.spatial_att = SpatialGate(gate_channel)\n    def forward(self,in_tensor):\n        att = 1 + F.sigmoid( self.channel_att(in_tensor) * self.spatial_att(in_tensor) )\n        return att * in_tensor\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"CBAM"},{"metadata":{"trusted":true},"cell_type":"code","source":"class BasicConv(nn.Module):\n    def __init__(self, in_planes, out_planes, kernel_size, stride=1, padding=0, dilation=1, groups=1, relu=True, bn=True, bias=False):\n        super(BasicConv, self).__init__()\n        self.out_channels = out_planes\n        self.conv = nn.Conv2d(in_planes, out_planes, kernel_size=kernel_size, stride=stride, padding=padding, dilation=dilation, groups=groups, bias=bias)\n        self.bn = nn.BatchNorm2d(out_planes,eps=1e-5, momentum=0.01, affine=True) if bn else None\n        self.relu = nn.ReLU() if relu else None\n\n    def forward(self, x):\n        x = self.conv(x)\n        if self.bn is not None:\n            x = self.bn(x)\n        if self.relu is not None:\n            x = self.relu(x)\n        return x\n\nclass CFlatten(nn.Module):\n    def forward(self, x):\n        return x.view(x.size(0), -1)\n\nclass CChannelGate(nn.Module):\n    def __init__(self, gate_channels, reduction_ratio=16, pool_types=['avg', 'max']):\n        super(CChannelGate, self).__init__()\n        self.gate_channels = gate_channels\n        self.mlp = nn.Sequential(\n            Flatten(),\n            nn.Linear(gate_channels, gate_channels // reduction_ratio),\n            nn.ReLU(),\n            nn.Linear(gate_channels // reduction_ratio, gate_channels)\n            )\n        self.pool_types = pool_types\n    def forward(self, x):\n        channel_att_sum = None\n        for pool_type in self.pool_types:\n            if pool_type=='avg':\n                avg_pool = F.avg_pool2d( x, (x.size(2), x.size(3)), stride=(x.size(2), x.size(3)))\n                channel_att_raw = self.mlp( avg_pool )\n            elif pool_type=='max':\n                max_pool = F.max_pool2d( x, (x.size(2), x.size(3)), stride=(x.size(2), x.size(3)))\n                channel_att_raw = self.mlp( max_pool )\n            elif pool_type=='lp':\n                lp_pool = F.lp_pool2d( x, 2, (x.size(2), x.size(3)), stride=(x.size(2), x.size(3)))\n                channel_att_raw = self.mlp( lp_pool )\n            elif pool_type=='lse':\n                # LSE pool only\n                lse_pool = logsumexp_2d(x)\n                channel_att_raw = self.mlp( lse_pool )\n\n            if channel_att_sum is None:\n                channel_att_sum = channel_att_raw\n            else:\n                channel_att_sum = channel_att_sum + channel_att_raw\n\n        scale = F.sigmoid( channel_att_sum ).unsqueeze(2).unsqueeze(3).expand_as(x)\n        return x * scale\n\ndef logsumexp_2d(tensor):\n    tensor_flatten = tensor.view(tensor.size(0), tensor.size(1), -1)\n    s, _ = torch.max(tensor_flatten, dim=2, keepdim=True)\n    outputs = s + (tensor_flatten - s).exp().sum(dim=2, keepdim=True).log()\n    return outputs\n\nclass ChannelPool(nn.Module):\n    def forward(self, x):\n        return torch.cat( (torch.max(x,1)[0].unsqueeze(1), torch.mean(x,1).unsqueeze(1)), dim=1 )\n\nclass CSpatialGate(nn.Module):\n    def __init__(self):\n        super(CSpatialGate, self).__init__()\n        kernel_size = 7\n        self.compress = ChannelPool()\n        self.spatial = BasicConv(2, 1, kernel_size, stride=1, padding=(kernel_size-1) // 2, relu=False)\n    def forward(self, x):\n        x_compress = self.compress(x)\n        x_out = self.spatial(x_compress)\n        scale = F.sigmoid(x_out) # broadcasting\n        return x * scale\n\nclass CBAM(nn.Module):\n    def __init__(self, gate_channels, reduction_ratio=16, pool_types=['avg', 'max'], no_spatial=False):\n        super(CBAM, self).__init__()\n        self.CChannelGate = CChannelGate(gate_channels, reduction_ratio, pool_types)\n        self.no_spatial=no_spatial\n        if not no_spatial:\n            self.CSpatialGate = CSpatialGate()\n    def forward(self, x):\n        x_out = self.CChannelGate(x)\n        if not self.no_spatial:\n            x_out = self.CSpatialGate(x_out)\n        return x_out","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import glob\nimport os\nimport numpy as np\n#获取到数据集中的图像路径\ndef csv_reader(path):\n    with open(path, \"r\") as f:\n        breast = list(csv.reader(f))\n    return breast\ndef get_datas(image_dir,suffix=\".png\"):\n    '''\n    image_dir:包含图像的文件夹\n    suffix:图像的后缀\n    '''\n    image_paths = []\n    labels = []\n    train=csv_reader(\"../input/aptos2019-blindness-detection/train.csv\")\n    for i in train[1:]:\n        #y_this=[0.0,0.0,0.0,0.0,0.0]\n        #y_this[int(i[1])]=1.0\n        image_paths.append(image_dir+'/'+i[0]+'.png')\n        labels.append(int(i[1]))\n        \n    return image_paths,labels\n#随机展示25张图像\ndef show_batch(img_paths):\n    '''\n    img_paths:list, 所有图像的路径\n    '''\n    randomed = []\n    #获取到一部分图像路径的编号\n    if len(img_paths) <= 25:\n        randomed = list(range(0, len(img_paths)))\n    else:\n        for i in range(0, len(img_paths)):\n            random = np.random.randint(0, len(img_paths))\n            if random not in randomed:\n                randomed.append(random)\n            if len(randomed) == 25:\n                break\n    #展示图像\n    plt.figure(dpi=224)\n    for i in range(len(randomed)):\n        img = Image.open(img_paths[randomed[i]])\n        plt.subplot(5, 5, i+1) #构建子图区域\n        plt.imshow(img)\n        plt.xticks([])\n        plt.yticks([])\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_dir = os.path.abspath('../input/aptos2019-blindness-detection/train_images')\nshuffix = \".png\"\nimg_paths, labels = get_datas(img_dir, suffix=shuffix) #获取到数据集中图像路径和图像的标签\n#show_batch(img_paths) #展示25张图像","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch.nn as nn\nimport math\nimport torch.utils.model_zoo as model_zoo\n\n\n__all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101',\n           'resnet152']\n\n\nmodel_urls = {\n    'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',\n    'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',\n    'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',\n    'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',\n    'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',\n}\n\n\ndef conv3x3(in_planes, out_planes, stride=1):\n    \"3x3 convolution with padding\"\n    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,\n                     padding=1, bias=False)\n\n\nclass BasicBlock(nn.Module):\n    expansion = 1\n\n    def __init__(self, inplanes, planes, stride=1, downsample=None, use_cbam=False):\n        super(BasicBlock, self).__init__()\n        self.conv1 = conv3x3(inplanes, planes, stride)\n        self.bn1 = nn.BatchNorm2d(planes)\n        self.relu = nn.ReLU(inplace=True)\n        self.conv2 = conv3x3(planes, planes)\n        self.bn2 = nn.BatchNorm2d(planes)\n        self.downsample = downsample\n        self.stride = stride\n        if use_cbam:\n            self.cbam = CBAM( planes, 16 )\n        else:\n            self.cbam = None\n    def forward(self, x):\n        residual = 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        if self.downsample is not None:\n            residual = self.downsample(x)\n        if not self.cbam is None:\n            out = self.cbam(out)\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass Bottleneck(nn.Module):\n    expansion = 4\n\n    def __init__(self, inplanes, planes, stride=1, downsample=None, use_cbam=False):\n        super(Bottleneck, self).__init__()\n        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(planes)\n        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,\n                               padding=1, bias=False)\n        self.bn2 = nn.BatchNorm2d(planes)\n        self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)\n        self.bn3 = nn.BatchNorm2d(planes * 4)\n        self.relu = nn.ReLU(inplace=True)\n        self.downsample = downsample\n        self.stride = stride\n        if use_cbam:\n            self.cbam = CBAM( planes * 4, 16 )\n        else:\n            self.cbam = None\n        \n    def forward(self, x):\n        residual = 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        if self.downsample is not None:\n            residual = self.downsample(x)\n        if not self.cbam is None:\n            out = self.cbam(out)\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass ResNet(nn.Module):\n\n    def __init__(self, block, layers, num_classes=1000, att_type=None):\n        self.inplanes = 64\n        super(ResNet, self).__init__()\n        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3,\n                               bias=False)\n        self.bn1 = nn.BatchNorm2d(64)\n        self.relu = nn.ReLU(inplace=True)\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        if att_type=='BAM':\n            self.bam1 = BAM(64*block.expansion)\n            self.bam2 = BAM(128*block.expansion)\n            self.bam3 = BAM(256*block.expansion)\n        else:\n            self.bam1, self.bam2, self.bam3 = None, None, None\n        self.layer1 = self._make_layer(block, 64, layers[0], att_type=att_type)\n        self.layer2 = self._make_layer(block, 128, layers[1], stride=2, att_type=att_type)\n        self.layer3 = self._make_layer(block, 256, layers[2], stride=2, att_type=att_type)\n        self.layer4 = self._make_layer(block, 512, layers[3], stride=2, att_type=att_type)\n        self.avgpool = nn.AdaptiveAvgPool2d(1)\n        self.fc = nn.Linear(512 * block.expansion, 1000)\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels\n                m.weight.data.normal_(0, math.sqrt(2. / n))\n            elif isinstance(m, nn.BatchNorm2d):\n                m.weight.data.fill_(1)\n                m.bias.data.zero_()\n\n    def _make_layer(self, block, planes, blocks, stride=1,att_type=None):\n        downsample = None\n        if stride != 1 or self.inplanes != planes * block.expansion:\n            downsample = nn.Sequential(\n                nn.Conv2d(self.inplanes, planes * block.expansion,\n                          kernel_size=1, stride=stride, bias=False),\n                nn.BatchNorm2d(planes * block.expansion),\n            )\n\n        layers = []\n        layers.append(block(self.inplanes, planes, stride, downsample, use_cbam=att_type=='CBAM'))\n        self.inplanes = planes * block.expansion\n        for i in range(1, blocks):\n            layers.append(block(self.inplanes, planes, use_cbam=att_type=='CBAM'))\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        if not self.bam1 is None:\n            x = self.bam1(x)\n        x = self.layer2(x)\n        if not self.bam2 is None:\n            x = self.bam2(x)\n        x = self.layer3(x)\n        if not self.bam3 is None:\n            x = self.bam3(x)\n        feat = self.layer4(x)\n\n        x = self.avgpool(feat)\n        x = x.view(x.size(0), -1)\n        x = self.fc(x)\n\n        return feat, x\n\n\ndef resnet18(pretrained=False, att_type=None):\n    \"\"\"Constructs a ResNet-18 model.\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n    \"\"\"\n    model = ResNet(BasicBlock, [2, 2, 2, 2], att_type=att_type)\n    if pretrained:\n        save_model = model_zoo.load_url(model_urls['resnet18'])\n        model_dict =  model.state_dict()\n        state_dict = {k:v for k,v in save_model.items() if k in model_dict.keys()}\n        model_dict.update(state_dict)\n        model.load_state_dict(model_dict)\n    return model\n\n\ndef resnet34(pretrained=False, att_type=None):\n    \"\"\"Constructs a ResNet-34 model.\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n    \"\"\"\n    model = ResNet(BasicBlock, [3, 4, 6, 3], att_type=att_type)\n    if pretrained:\n        model.load_state_dict(model_zoo.load_url(model_urls['resnet34']))\n    return model\n\n\ndef resnet50(pretrained=False, **kwargs):\n    \"\"\"Constructs a ResNet-50 model.\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n    \"\"\"\n    model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs)\n    if pretrained:\n        model.load_state_dict(model_zoo.load_url(model_urls['resnet50']))\n    return model\n\n\ndef resnet101(pretrained=False, att_type=None):\n    \"\"\"Constructs a ResNet-101 model.\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n    \"\"\"\n    model = ResNet(Bottleneck, [3, 4, 23, 3], att_type=att_type)\n    if pretrained:\n        save_model = model_zoo.load_url(model_urls['resnet101'])\n        model_dict =  model.state_dict()\n        state_dict = {k:v for k,v in save_model.items() if k in model_dict.keys()}\n        model_dict.update(state_dict)\n        model.load_state_dict(model_dict)\n    return model\n\n\ndef resnet152(pretrained=False, att_type=None):\n    \"\"\"Constructs a ResNet-152 model.\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n    \"\"\"\n    model = ResNet(Bottleneck, [3, 8, 36, 3], att_type=att_type)\n    if pretrained:\n        save_model = model_zoo.load_url(model_urls['resnet152'])\n        model_dict =  model.state_dict()\n        state_dict = {k:v for k,v in save_model.items() if k in model_dict.keys()}\n        model_dict.update(state_dict)\n        model.load_state_dict(model_dict)\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from torch.utils.data import Dataset\n\nclass EyeDataset(Dataset):\n    def __init__(self, img_paths, labels, gray=False, transform=None):\n        super(EyeDataset, self).__init__()\n        self.img_paths = img_paths\n        self.labels = labels\n        self.gray = gray\n        self.transform = transform\n        self.length = len(img_paths)\n    \n    def __len__(self):\n        return self.length\n    \n    def __getitem__(self, index):\n        img_path = self.img_paths[index]\n        label = self.labels[index]\n        img = Image.open(img_path)\n        if self.gray:\n            img.convert(\"L\")\n        else:\n            img.convert(\"RGB\")\n        \n        if self.transform is not None:\n            img = self.transform(img)\n        \n        return img, label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#划分验证集和训练集#划分验证集和训练集\nfrom torch.utils.data.sampler import WeightedRandomSampler\nfrom sklearn.model_selection import train_test_split\ntrain_paths, val_paths, train_labels, val_labels = train_test_split(img_paths, labels, test_size=0.3, random_state=0, stratify=labels)\n#定义训练数据集对象和验证数据集对象\nimg_size = 224\ntrain_transform = tsf.Compose([\n    tsf.Resize((img_size, img_size)),\n    tsf.RandomHorizontalFlip(),\n    tsf.RandomVerticalFlip(),\n    tsf.ToTensor(),\n    tsf.Normalize(mean=[0.5, 0.5, 0.5], std=[0.25, 0.25, 0.25])\n])\nval_transform = tsf.Compose([\n    tsf.Resize((img_size, img_size)),\n    tsf.ToTensor(),\n    tsf.Normalize(mean=[0.5, 0.5, 0.5], std=[0.25, 0.25, 0.25])\n])\ntrain_dataset =EyeDataset(train_paths, torch.tensor(train_labels), transform=train_transform)\nval_dataset = EyeDataset(val_paths, torch.tensor(val_labels), transform=val_transform)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#定义训练集和测试集的加载器\nfrom torch.utils.data import DataLoader\nwights=[]\ntrain_time=[1,5,2,9,6]\nfor i in train_labels:\n    wights.append(train_time[int(i)])\nsampler = WeightedRandomSampler(wights, len(wights),replacement=True)\ntrain_loader = DataLoader(train_dataset, shuffle=False, batch_size=8, num_workers=4, sampler=sampler) #备注：在windows系统中多线程可能存在问题，所以设置num_workers为0\nval_loader = DataLoader(val_dataset, shuffle=False, batch_size=1, num_workers=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_for(x,label,opt,model,losses,total,number,count):\n    for _ in range(number):\n        x = x.to(device, dtype=torch.float32)\n        label = label.to(device, dtype=torch.long)\n        batch = x.size(0)\n        total += batch\n        opt.zero_grad() #清除累积的梯度\n        _,pred = model(x)\n        loss = criterion(pred, label)\n        loss.backward()\n        pred = torch.max(pred, dim=1)[1]\n        for i in range(len(pred)):\n            if int(pred[i])==int(label[i]):\n                count+=1\n        if total%128==0:\n            print(loss)\n            print(total)\n            print(\"acc: \"+str(count/128))\n            count=0\n        opt.step() #更新权重\n        losses += loss.item() * batch\n    return opt,model,losses,total,count","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import random\nmodel = resnet101(pretrained=True,att_type='BAM')\n#model=DenseNet121()\nmodel.fc= nn.Linear(2048, 5)\nopt = torch.optim.SGD(model.parameters(),lr=0.004, momentum=0.9, nesterov=True)\nscheduler = torch.optim.lr_scheduler.StepLR(opt, step_size = 6, gamma = 0.1, last_epoch=-1)\ncriterion = nn.CrossEntropyLoss()\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel.to(device)\nfor __ in range(1):\n    for epoch in range(40):\n        losses = 0.0\n        total = 0\n        count=0\n        corrects = 0\n        model.train()\n        for x, label in train_loader:\n            opt,model,losses,total,count=train_for(x,label,opt,model,losses,total,1,count)\n        print(\"avg loss: \"+str(losses))\n        scheduler.step()\n        #在验证集上验证模型的效果\ntorch.save(model,\"./model.pkl\")\ntorch.save(model.state_dict(),\"model.pth\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.eval()\nwith torch.no_grad():\n    losses = 0.0\n    total = 0\n    corrects = 0\n    tbie=[0,0,0,0,0]\n    bie=[0,0,0,0,0]\n    pre=[0,0,0,0,0]\n    alls=[[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]]\n    count=0\n    for x, label in val_loader:\n        x = x.to(device, dtype=torch.float32)          \n        label = label.to(device, dtype=torch.long)\n        batch = x.size(0)\n        total += batch\n        _,pred = model(x)\n        loss = criterion(pred, label)\n        losses += loss.item() * batch\n        pred = torch.max(pred, dim=1)[1]\n        for i in range(len(pred)):\n            if int(pred[i])==int(label[i]):\n                count+=1\n        if total%128==0:\n            print(loss)\n            print(total)\n            print(\"acc: \"+str(count))\n            count=0\n        for i in range(len(pred)):\n            cc=pred[i]\n            cd=label[i]\n            tbie[int(cd)]+=1\n            alls[cc][cd]+=1\n            if int(cc)==int(cd):\n                corrects=corrects+1\n                bie[int(cc)]+=1\n    print(\"correct: \"+str(corrects/total))\n    for z in range(5):\n        print(\"class \"+str(z)+\" correct \"+str(bie[z]/tbie[z]))\n        print(\"which are \"+str(alls[z]))\n    print(bie)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dir = os.path.abspath('../input/aptos2019-blindness-detection/test_images')\ntest_paths = glob.glob(os.path.join(test_dir, \"*.png\"))\nfilenames = []\npreds = []\nwith torch.no_grad():\n    model.eval()\n    for path in test_paths:\n        filename = os.path.basename(path)\n        filenames.append(filename)\n        img = Image.open(path)\n        img = val_transform(img)\n        img=img.unsqueeze(0)\n        img = img.to(device)\n        _,pred = model(img)\n        pred = torch.max(pred, dim=1)[1]\n        preds.append(int(pred))\n\noutput_dict = {\n    \"filename\":filenames,\n    \"pred\":preds\n}\n\nimport pandas as pd\noutput = pd.DataFrame(output_dict)\noutput.to_csv(\"./submission.csv\", index=False, encoding=\"utf-8\")","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}