├── assets └── xception.PNG ├── README.md └── Xception_pytorch.ipynb /assets/xception.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoya012/pytorch-Xception/HEAD/assets/xception.PNG -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pytorch-Xception 2 | Simple Code Implementation of ["Xception"](https://arxiv.org/abs/1610.02357) architecture using PyTorch. 3 | 4 | ![](https://github.com/hoya012/pytorch-Xception/blob/master/assets/xception.PNG) 5 | 6 | For simplicity, i write codes in `ipynb`. So, you can easliy test my code. 7 | 8 | *Last update : 2018/12/19* 9 | 10 | ## Contributor 11 | * hoya012 12 | 13 | ## Requirements 14 | Python 3.5 15 | ``` 16 | numpy 17 | matplotlib 18 | torch=1.0.0 19 | torchvision 20 | ``` 21 | 22 | ## Usage 23 | You only run `Xception_pytorch.ipynb`. 24 | For test, i used `CIFAR-10` Dataset and resize image scale from 32x32 to 299x299. 25 | If you want to use own dataset, you can simply resize images. 26 | 27 | ## depthwise separable convolution impelemtation. 28 | In Xception, there are many depthwise separable convolution operation. This is my simple implemenatation. 29 | 30 | ``` 31 | class depthwise_separable_conv(nn.Module): 32 | def __init__(self, nin, nout, kernel_size, padding, bias=False): 33 | super(depthwise_separable_conv, self).__init__() 34 | self.depthwise = nn.Conv2d(nin, nin, kernel_size=kernel_size, padding=padding, groups=nin, bias=bias) 35 | self.pointwise = nn.Conv2d(nin, nout, kernel_size=1, bias=bias) 36 | 37 | def forward(self, x): 38 | out = self.depthwise(x) 39 | out = self.pointwise(out) 40 | return out 41 | ``` 42 | 43 | -------------------------------------------------------------------------------- /Xception_pytorch.ipynb: -------------------------------------------------------------------------------- 1 | {"nbformat":4,"nbformat_minor":0,"metadata":{"anaconda-cloud":{},"kernelspec":{"display_name":"pytorch_1.0","language":"python","name":"pytorch"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.5.4"},"colab":{"name":"Xception_pytorch.ipynb","provenance":[],"collapsed_sections":[]},"accelerator":"GPU","widgets":{"application/vnd.jupyter.widget-state+json":{"abb964e12a0c484f9ca2283b4d3b6ec4":{"model_module":"@jupyter-widgets/controls","model_name":"HBoxModel","state":{"_view_name":"HBoxView","_dom_classes":[],"_model_name":"HBoxModel","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.5.0","box_style":"","layout":"IPY_MODEL_afefca8955d84f2490b85803d1475a86","_model_module":"@jupyter-widgets/controls","children":["IPY_MODEL_9d2de6d746644b7fa45bed2369510424","IPY_MODEL_351a7afa56334748a807ed0c4e76e762"]}},"afefca8955d84f2490b85803d1475a86":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"9d2de6d746644b7fa45bed2369510424":{"model_module":"@jupyter-widgets/controls","model_name":"IntProgressModel","state":{"_view_name":"ProgressView","style":"IPY_MODEL_e477ba7734c24bbd8d0ab4ebf6eaa374","_dom_classes":[],"description":"","_model_name":"IntProgressModel","bar_style":"info","max":1,"_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":1,"_view_count":null,"_view_module_version":"1.5.0","orientation":"horizontal","min":0,"description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_c1041eef6e9540dba74eade5d37f3851"}},"351a7afa56334748a807ed0c4e76e762":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","state":{"_view_name":"HTMLView","style":"IPY_MODEL_ffd77bd3647949489baff9183e82fae0","_dom_classes":[],"description":"","_model_name":"HTMLModel","placeholder":"​","_view_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","value":"170500096it [00:30, 15909372.39it/s]","_view_count":null,"_view_module_version":"1.5.0","description_tooltip":null,"_model_module":"@jupyter-widgets/controls","layout":"IPY_MODEL_797c1c3c9f6647ed97ba8b81d21eadef"}},"e477ba7734c24bbd8d0ab4ebf6eaa374":{"model_module":"@jupyter-widgets/controls","model_name":"ProgressStyleModel","state":{"_view_name":"StyleView","_model_name":"ProgressStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","bar_color":null,"_model_module":"@jupyter-widgets/controls"}},"c1041eef6e9540dba74eade5d37f3851":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}},"ffd77bd3647949489baff9183e82fae0":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","state":{"_view_name":"StyleView","_model_name":"DescriptionStyleModel","description_width":"","_view_module":"@jupyter-widgets/base","_model_module_version":"1.5.0","_view_count":null,"_view_module_version":"1.2.0","_model_module":"@jupyter-widgets/controls"}},"797c1c3c9f6647ed97ba8b81d21eadef":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","state":{"_view_name":"LayoutView","grid_template_rows":null,"right":null,"justify_content":null,"_view_module":"@jupyter-widgets/base","overflow":null,"_model_module_version":"1.2.0","_view_count":null,"flex_flow":null,"width":null,"min_width":null,"border":null,"align_items":null,"bottom":null,"_model_module":"@jupyter-widgets/base","top":null,"grid_column":null,"overflow_y":null,"overflow_x":null,"grid_auto_flow":null,"grid_area":null,"grid_template_columns":null,"flex":null,"_model_name":"LayoutModel","justify_items":null,"grid_row":null,"max_height":null,"align_content":null,"visibility":null,"align_self":null,"height":null,"min_height":null,"padding":null,"grid_auto_rows":null,"grid_gap":null,"max_width":null,"order":null,"_view_module_version":"1.2.0","grid_template_areas":null,"object_position":null,"object_fit":null,"grid_auto_columns":null,"margin":null,"display":null,"left":null}}}}},"cells":[{"cell_type":"code","metadata":{"id":"7jBZ5w9065Pl","colab_type":"code","colab":{}},"source":["import torch\n","import torchvision\n","import torchvision.transforms as transforms\n","from torchvision.utils import save_image\n","import torch.nn as nn\n","import torch.nn.functional as F\n","import torch.optim as optim\n","import numpy as np\n","import os\n","import glob\n","import PIL\n","from PIL import Image\n","from torch.utils import data as D\n","from torch.utils.data.sampler import SubsetRandomSampler\n","import random"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"uf3TCIeB65Pr","colab_type":"code","colab":{}},"source":["batch_size = 16\n","validation_ratio = 0.1\n","random_seed = 10"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"J164BT6q65Pv","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":121,"referenced_widgets":["abb964e12a0c484f9ca2283b4d3b6ec4","afefca8955d84f2490b85803d1475a86","9d2de6d746644b7fa45bed2369510424","351a7afa56334748a807ed0c4e76e762","e477ba7734c24bbd8d0ab4ebf6eaa374","c1041eef6e9540dba74eade5d37f3851","ffd77bd3647949489baff9183e82fae0","797c1c3c9f6647ed97ba8b81d21eadef"]},"outputId":"4004b53c-d4a7-4903-9d82-76fe44552c8b","executionInfo":{"status":"ok","timestamp":1584338333889,"user_tz":-540,"elapsed":22685,"user":{"displayName":"hoya012","photoUrl":"https://lh3.googleusercontent.com/-995djavMjjs/AAAAAAAAAAI/AAAAAAAAAVk/modB75beBwU/s64/photo.jpg","userId":"15725788610401702262"}}},"source":["transform_train = transforms.Compose([\n"," transforms.Resize(299),\n"," transforms.RandomCrop(299, padding=38),\n"," transforms.RandomHorizontalFlip(),\n"," transforms.ToTensor(),\n"," transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616))])\n","\n","transform_validation = transforms.Compose([\n"," transforms.Resize(299),\n"," transforms.ToTensor(),\n"," transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616))])\n","\n","\n","transform_test = transforms.Compose([\n"," transforms.Resize(299),\n"," transforms.ToTensor(),\n"," transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616))])\n","\n","trainset = torchvision.datasets.CIFAR10(\n"," root='./data', train=True, download=True, transform=transform_train)\n","\n","validset = torchvision.datasets.CIFAR10(\n"," root='./data', train=True, download=True, transform=transform_validation)\n","\n","testset = torchvision.datasets.CIFAR10(\n"," root='./data', train=False, download=True, transform=transform_test)\n","\n","#trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,\n","# shuffle=True, num_workers=0)\n","\n","num_train = len(trainset)\n","indices = list(range(num_train))\n","split = int(np.floor(validation_ratio * num_train))\n","\n","np.random.seed(random_seed)\n","np.random.shuffle(indices)\n","\n","train_idx, valid_idx = indices[split:], indices[:split]\n","train_sampler = SubsetRandomSampler(train_idx)\n","valid_sampler = SubsetRandomSampler(valid_idx)\n","\n","train_loader = torch.utils.data.DataLoader(\n"," trainset, batch_size=batch_size, sampler=train_sampler, num_workers=0\n",")\n","\n","valid_loader = torch.utils.data.DataLoader(\n"," validset, batch_size=batch_size, sampler=valid_sampler, num_workers=0\n",")\n","\n","test_loader = torch.utils.data.DataLoader(\n"," testset, batch_size=batch_size, shuffle=False, num_workers=0\n",")\n","\n","classes = ('plane', 'car', 'bird', 'cat',\n"," 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')\n","\n","initial_lr = 0.045"],"execution_count":3,"outputs":[{"output_type":"stream","text":["Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data/cifar-10-python.tar.gz\n"],"name":"stdout"},{"output_type":"display_data","data":{"application/vnd.jupyter.widget-view+json":{"model_id":"abb964e12a0c484f9ca2283b4d3b6ec4","version_minor":0,"version_major":2},"text/plain":["HBox(children=(IntProgress(value=1, bar_style='info', max=1), HTML(value='')))"]},"metadata":{"tags":[]}},{"output_type":"stream","text":["Extracting ./data/cifar-10-python.tar.gz to ./data\n","Files already downloaded and verified\n","Files already downloaded and verified\n"],"name":"stdout"}]},{"cell_type":"code","metadata":{"id":"ObTXJ0dL65P1","colab_type":"code","colab":{}},"source":["class depthwise_separable_conv(nn.Module):\n"," def __init__(self, nin, nout, kernel_size, padding, bias=False):\n"," super(depthwise_separable_conv, self).__init__()\n"," self.depthwise = nn.Conv2d(nin, nin, kernel_size=kernel_size, padding=padding, groups=nin, bias=bias)\n"," self.pointwise = nn.Conv2d(nin, nout, kernel_size=1, bias=bias)\n","\n"," def forward(self, x):\n"," out = self.depthwise(x)\n"," out = self.pointwise(out)\n"," return out"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"8JNdBwbf65P4","colab_type":"code","colab":{}},"source":["class Xception(nn.Module):\n"," def __init__(self, input_channel, num_classes=10):\n"," super(Xception, self).__init__()\n"," \n"," # Entry Flow\n"," self.entry_flow_1 = nn.Sequential(\n"," nn.Conv2d(input_channel, 32, kernel_size=3, stride=2, padding=1, bias=False),\n"," nn.BatchNorm2d(32),\n"," nn.ReLU(True),\n"," \n"," nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),\n"," nn.BatchNorm2d(64),\n"," nn.ReLU(True)\n"," )\n"," \n"," self.entry_flow_2 = nn.Sequential(\n"," depthwise_separable_conv(64, 128, 3, 1),\n"," nn.BatchNorm2d(128),\n"," nn.ReLU(True),\n"," \n"," depthwise_separable_conv(128, 128, 3, 1),\n"," nn.BatchNorm2d(128),\n"," nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n"," )\n"," \n"," self.entry_flow_2_residual = nn.Conv2d(64, 128, kernel_size=1, stride=2, padding=0)\n"," \n"," self.entry_flow_3 = nn.Sequential(\n"," nn.ReLU(True),\n"," depthwise_separable_conv(128, 256, 3, 1),\n"," nn.BatchNorm2d(256),\n"," \n"," nn.ReLU(True),\n"," depthwise_separable_conv(256, 256, 3, 1),\n"," nn.BatchNorm2d(256),\n"," \n"," nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n"," )\n"," \n"," self.entry_flow_3_residual = nn.Conv2d(128, 256, kernel_size=1, stride=2, padding=0)\n"," \n"," self.entry_flow_4 = nn.Sequential(\n"," nn.ReLU(True),\n"," depthwise_separable_conv(256, 728, 3, 1),\n"," nn.BatchNorm2d(728),\n"," \n"," nn.ReLU(True),\n"," depthwise_separable_conv(728, 728, 3, 1),\n"," nn.BatchNorm2d(728),\n"," \n"," nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n"," )\n"," \n"," self.entry_flow_4_residual = nn.Conv2d(256, 728, kernel_size=1, stride=2, padding=0)\n"," \n"," # Middle Flow\n"," self.middle_flow = nn.Sequential(\n"," nn.ReLU(True),\n"," depthwise_separable_conv(728, 728, 3, 1),\n"," nn.BatchNorm2d(728),\n"," \n"," nn.ReLU(True),\n"," depthwise_separable_conv(728, 728, 3, 1),\n"," nn.BatchNorm2d(728),\n"," \n"," nn.ReLU(True),\n"," depthwise_separable_conv(728, 728, 3, 1),\n"," nn.BatchNorm2d(728)\n"," )\n"," \n"," # Exit Flow\n"," self.exit_flow_1 = nn.Sequential(\n"," nn.ReLU(True),\n"," depthwise_separable_conv(728, 728, 3, 1),\n"," nn.BatchNorm2d(728),\n"," \n"," nn.ReLU(True),\n"," depthwise_separable_conv(728, 1024, 3, 1),\n"," nn.BatchNorm2d(1024),\n"," \n"," nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n"," )\n"," self.exit_flow_1_residual = nn.Conv2d(728, 1024, kernel_size=1, stride=2, padding=0)\n"," self.exit_flow_2 = nn.Sequential(\n"," depthwise_separable_conv(1024, 1536, 3, 1),\n"," nn.BatchNorm2d(1536),\n"," nn.ReLU(True),\n"," \n"," depthwise_separable_conv(1536, 2048, 3, 1),\n"," nn.BatchNorm2d(2048),\n"," nn.ReLU(True)\n"," )\n"," \n"," self.linear = nn.Linear(2048, num_classes)\n"," \n"," def forward(self, x):\n"," entry_out1 = self.entry_flow_1(x)\n"," entry_out2 = self.entry_flow_2(entry_out1) + self.entry_flow_2_residual(entry_out1)\n"," entry_out3 = self.entry_flow_3(entry_out2) + self.entry_flow_3_residual(entry_out2)\n"," entry_out = self.entry_flow_4(entry_out3) + self.entry_flow_4_residual(entry_out3)\n"," \n"," middle_out = self.middle_flow(entry_out) + entry_out\n"," \n"," for i in range(7):\n"," middle_out = self.middle_flow(middle_out) + middle_out\n","\n"," exit_out1 = self.exit_flow_1(middle_out) + self.exit_flow_1_residual(middle_out)\n"," exit_out2 = self.exit_flow_2(exit_out1)\n","\n"," exit_avg_pool = F.adaptive_avg_pool2d(exit_out2, (1, 1)) \n"," exit_avg_pool_flat = exit_avg_pool.view(exit_avg_pool.size(0), -1)\n","\n"," output = self.linear(exit_avg_pool_flat)\n"," \n"," return output"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"850wCUVF65P7","colab_type":"code","colab":{}},"source":["net = Xception(3, 10) #ResNet-18"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"P5rgRS2565QA","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":35},"outputId":"1f13fa0c-14cf-40db-9bbf-a2e19f80c9cb","executionInfo":{"status":"ok","timestamp":1584338342308,"user_tz":-540,"elapsed":768,"user":{"displayName":"hoya012","photoUrl":"https://lh3.googleusercontent.com/-995djavMjjs/AAAAAAAAAAI/AAAAAAAAAVk/modB75beBwU/s64/photo.jpg","userId":"15725788610401702262"}}},"source":["device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n","print(device)"],"execution_count":7,"outputs":[{"output_type":"stream","text":["cuda:0\n"],"name":"stdout"}]},{"cell_type":"code","metadata":{"id":"K1nTbMKw65QD","colab_type":"code","colab":{"base_uri":"https://localhost:8080/","height":1000},"outputId":"787b2db5-c6c9-409d-957c-651a6aba8a6a","executionInfo":{"status":"ok","timestamp":1584338352085,"user_tz":-540,"elapsed":9125,"user":{"displayName":"hoya012","photoUrl":"https://lh3.googleusercontent.com/-995djavMjjs/AAAAAAAAAAI/AAAAAAAAAVk/modB75beBwU/s64/photo.jpg","userId":"15725788610401702262"}}},"source":["net.to(device)"],"execution_count":8,"outputs":[{"output_type":"execute_result","data":{"text/plain":["Xception(\n"," (entry_flow_1): Sequential(\n"," (0): Conv2d(3, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n"," (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (2): ReLU(inplace=True)\n"," (3): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n"," (4): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (5): ReLU(inplace=True)\n"," )\n"," (entry_flow_2): Sequential(\n"," (0): depthwise_separable_conv(\n"," (depthwise): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=64, bias=False)\n"," (pointwise): Conv2d(64, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (2): ReLU(inplace=True)\n"," (3): depthwise_separable_conv(\n"," (depthwise): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=128, bias=False)\n"," (pointwise): Conv2d(128, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (4): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (5): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\n"," )\n"," (entry_flow_2_residual): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2))\n"," (entry_flow_3): Sequential(\n"," (0): ReLU(inplace=True)\n"," (1): depthwise_separable_conv(\n"," (depthwise): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=128, bias=False)\n"," (pointwise): Conv2d(128, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (3): ReLU(inplace=True)\n"," (4): depthwise_separable_conv(\n"," (depthwise): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=256, bias=False)\n"," (pointwise): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (5): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (6): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\n"," )\n"," (entry_flow_3_residual): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2))\n"," (entry_flow_4): Sequential(\n"," (0): ReLU(inplace=True)\n"," (1): depthwise_separable_conv(\n"," (depthwise): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=256, bias=False)\n"," (pointwise): Conv2d(256, 728, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (2): BatchNorm2d(728, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (3): ReLU(inplace=True)\n"," (4): depthwise_separable_conv(\n"," (depthwise): Conv2d(728, 728, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=728, bias=False)\n"," (pointwise): Conv2d(728, 728, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (5): BatchNorm2d(728, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (6): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\n"," )\n"," (entry_flow_4_residual): Conv2d(256, 728, kernel_size=(1, 1), stride=(2, 2))\n"," (middle_flow): Sequential(\n"," (0): ReLU(inplace=True)\n"," (1): depthwise_separable_conv(\n"," (depthwise): Conv2d(728, 728, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=728, bias=False)\n"," (pointwise): Conv2d(728, 728, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (2): BatchNorm2d(728, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (3): ReLU(inplace=True)\n"," (4): depthwise_separable_conv(\n"," (depthwise): Conv2d(728, 728, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=728, bias=False)\n"," (pointwise): Conv2d(728, 728, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (5): BatchNorm2d(728, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (6): ReLU(inplace=True)\n"," (7): depthwise_separable_conv(\n"," (depthwise): Conv2d(728, 728, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=728, bias=False)\n"," (pointwise): Conv2d(728, 728, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (8): BatchNorm2d(728, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," )\n"," (exit_flow_1): Sequential(\n"," (0): ReLU(inplace=True)\n"," (1): depthwise_separable_conv(\n"," (depthwise): Conv2d(728, 728, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=728, bias=False)\n"," (pointwise): Conv2d(728, 728, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (2): BatchNorm2d(728, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (3): ReLU(inplace=True)\n"," (4): depthwise_separable_conv(\n"," (depthwise): Conv2d(728, 728, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=728, bias=False)\n"," (pointwise): Conv2d(728, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (5): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (6): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\n"," )\n"," (exit_flow_1_residual): Conv2d(728, 1024, kernel_size=(1, 1), stride=(2, 2))\n"," (exit_flow_2): Sequential(\n"," (0): depthwise_separable_conv(\n"," (depthwise): Conv2d(1024, 1024, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=1024, bias=False)\n"," (pointwise): Conv2d(1024, 1536, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (1): BatchNorm2d(1536, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (2): ReLU(inplace=True)\n"," (3): depthwise_separable_conv(\n"," (depthwise): Conv2d(1536, 1536, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=1536, bias=False)\n"," (pointwise): Conv2d(1536, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n"," )\n"," (4): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n"," (5): ReLU(inplace=True)\n"," )\n"," (linear): Linear(in_features=2048, out_features=10, bias=True)\n",")"]},"metadata":{"tags":[]},"execution_count":8}]},{"cell_type":"code","metadata":{"id":"8dALFTuL65QH","colab_type":"code","colab":{}},"source":["criterion = nn.CrossEntropyLoss()\n","optimizer = optim.SGD(net.parameters(), lr=initial_lr, momentum=0.9)\n","\n","for epoch in range(100): # 데이터셋을 수차례 반복합니다.\n"," if epoch == 0:\n"," lr = initial_lr\n"," elif epoch % 2 == 0 and epoch != 0:\n"," lr *= 0.94\n"," optimizer = optim.SGD(net.parameters(), lr=lr, momentum=0.9)\n"," \n"," running_loss = 0.0\n"," for i, data in enumerate(train_loader, 0):\n"," inputs, labels = data\n"," inputs, labels = inputs.to(device), labels.to(device)\n","\n"," optimizer.zero_grad()\n","\n"," outputs = net(inputs)\n"," loss = criterion(outputs, labels)\n"," loss.backward()\n"," optimizer.step()\n"," \"\"\"\n"," running_loss += loss.item()\n"," \n"," show_period = 250\n"," if i % show_period == show_period-1: # print every \"show_period\" mini-batches\n"," print('[%d, %5d] loss: %.7f' %\n"," (epoch + 1, i + 1, running_loss / show_period))\n"," running_loss = 0.0\n"," \"\"\"\n"," \n"," #validation part\n"," correct = 0\n"," total = 0\n"," for i, data in enumerate(valid_loader, 0):\n"," inputs, labels = data\n"," inputs, labels = inputs.to(device), labels.to(device)\n"," outputs = net(inputs)\n"," \n"," _, predicted = torch.max(outputs.data, 1)\n"," total += labels.size(0)\n"," correct += (predicted == labels).sum().item()\n"," \n"," print('[%d epoch] Accuracy of the network on the validation images: %d %%' % \n"," (epoch, 100 * correct / total)\n"," )\n","\n","print('Finished Training')"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"2J2bpOsr65QL","colab_type":"code","colab":{}},"source":["dataiter = iter(testloader)\n","images, labels = dataiter.next()\n","images, labels = images.to(device), labels.to(device)\n","\n","outputs = net(images)\n","_, predicted = torch.max(outputs, 1)\n","\n","print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]\n"," for j in range(64)))"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"WM4hcitG65QO","colab_type":"code","colab":{}},"source":["correct = 0\n","total = 0\n","with torch.no_grad():\n"," for data in testloader:\n"," images, labels = data\n"," images, labels = images.to(device), labels.to(device)\n"," outputs = net(images)\n"," _, predicted = torch.max(outputs.data, 1)\n"," total += labels.size(0)\n"," correct += (predicted == labels).sum().item()\n","\n","print('Accuracy of the network on the 10000 test images: %d %%' % (\n"," 100 * correct / total))"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"dYQ6TjYe65QR","colab_type":"code","colab":{}},"source":["class_correct = list(0. for i in range(10))\n","class_total = list(0. for i in range(10))\n","with torch.no_grad():\n"," for data in testloader:\n"," images, labels = data\n"," images, labels = images.to(device), labels.to(device)\n"," outputs = net(images)\n"," _, predicted = torch.max(outputs, 1)\n"," c = (predicted == labels).squeeze()\n"," \n"," for i in range(labels.shape[0]):\n"," label = labels[i]\n"," class_correct[label] += c[i].item()\n"," class_total[label] += 1\n","\n","\n","for i in range(10):\n"," print('Accuracy of %5s : %2d %%' % (\n"," classes[i], 100 * class_correct[i] / class_total[i]))"],"execution_count":0,"outputs":[]},{"cell_type":"code","metadata":{"id":"yjkHTRvH65QU","colab_type":"code","colab":{}},"source":[""],"execution_count":0,"outputs":[]}]} --------------------------------------------------------------------------------