{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## 数据读取与分析" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "train = pd.read_csv('data/train.csv')\n", "emotion_prop = (train.label.value_counts() / len(train)).to_frame().sort_index(ascending=True)\n", "emotions = ['Angry','Disgust','Fear','Happy','Sad','Surprise','Neutral']\n", "palette = ['orchid', 'lightcoral', 'orange', 'gold', 'lightgreen', 'deepskyblue', 'cornflowerblue']\n", "\n", "plt.figure(figsize=[12,6])\n", "\n", "plt.bar(x=emotions, height=emotion_prop['label'], color=palette, edgecolor='black')\n", " \n", "plt.xlabel('Emotion')\n", "plt.ylabel('Proportion')\n", "plt.title('Proportion of Emotion Labels')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "显然7种情绪在训练集的分布并不均衡" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " label feature Usage\n", "0 0 157 94 9 35 30 20 23 21 23 23 22 21 22 23 26 2... Training\n", "1 2 77 72 59 54 46 45 41 70 69 76 70 66 66 69 63 7... Training\n", "2 0 86 83 118 128 138 149 153 156 162 166 170 178 ... Training\n", "3 6 183 87 51 48 40 35 31 33 45 80 161 198 212 221... Training\n", "4 6 107 107 107 107 107 107 107 107 107 107 107 10... Training\n", "Plotting all emotions...\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def plot_all_emotions(data):\n", " print('Plotting all emotions...')\n", " train_images = np.zeros(shape=(len(data), 48, 48))\n", " train_labels = np.array(list(map(int, data['label'])))\n", " \n", " for i, row in enumerate(data.index):\n", " image = np.fromstring(data.loc[row, 'feature'], dtype=int, sep=' ')\n", " image = np.reshape(image, (48, 48))\n", " train_images[i] = image\n", " fig, axs = plt.subplots(1, 7, figsize=(30, 12))\n", " fig.subplots_adjust(hspace = .2, wspace=.2)\n", " axs = axs.ravel()\n", " for i in range(7):\n", " idx = data[data['label']==i].index[i]\n", " axs[i].imshow(train_images[idx], cmap='gray')\n", " axs[i].set_title(emotions[train_labels[idx]])\n", " axs[i].set_xticklabels([])\n", " axs[i].set_yticklabels([])\n", "if __name__ == '__main__':\n", " print(train.head())\n", " plot_all_emotions(train)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "数据为48x48的单通道灰度图,以上为7种情绪的展示,可以看出仅凭肉眼很难区分" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 保存数据" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(16000, 2304)\n", "(2000, 2304)\n", "(2000, 2304)\n", "Save data finish!\n" ] } ], "source": [ "import csv\n", "import os\n", "import numpy as np\n", "import h5py\n", "\n", "file = 'data/train.csv'\n", "\n", "\n", "Training_x = []\n", "Training_y = []\n", "PublicTest_x = []\n", "PublicTest_y = []\n", "PrivateTest_x = []\n", "PrivateTest_y = []\n", "\n", "datapath = os.path.join('data','data.h5')\n", "if not os.path.exists(os.path.dirname(datapath)):\n", " os.makedirs(os.path.dirname(datapath))\n", "\n", "with open(file,'r') as csvin:\n", " data=csv.reader(csvin)\n", " for row in data:\n", " if row[-1] == 'Training':\n", " temp_list = []\n", " for pixel in row[1].split( ):\n", " temp_list.append(int(pixel))\n", " I = np.asarray(temp_list)\n", " Training_y.append(int(row[0]))\n", " Training_x.append(I.tolist())\n", "\n", " if row[-1] == \"PublicTest\" :\n", " temp_list = []\n", " for pixel in row[1].split( ):\n", " temp_list.append(int(pixel))\n", " I = np.asarray(temp_list)\n", " PublicTest_y.append(int(row[0]))\n", " PublicTest_x.append(I.tolist())\n", "\n", " if row[-1] == 'PrivateTest':\n", " temp_list = []\n", " for pixel in row[1].split( ):\n", " temp_list.append(int(pixel))\n", " I = np.asarray(temp_list)\n", "\n", " PrivateTest_y.append(int(row[0]))\n", " PrivateTest_x.append(I.tolist())\n", "\n", "print(np.shape(Training_x))\n", "print(np.shape(PublicTest_x))\n", "print(np.shape(PrivateTest_x))\n", "\n", "datafile = h5py.File(datapath, 'w')\n", "datafile.create_dataset(\"Training_pixel\", dtype = 'uint8', data=Training_x)\n", "datafile.create_dataset(\"Training_label\", dtype = 'int64', data=Training_y)\n", "datafile.create_dataset(\"PublicTest_pixel\", dtype = 'uint8', data=PublicTest_x)\n", "datafile.create_dataset(\"PublicTest_label\", dtype = 'int64', data=PublicTest_y)\n", "datafile.create_dataset(\"PrivateTest_pixel\", dtype = 'uint8', data=PrivateTest_x)\n", "datafile.create_dataset(\"PrivateTest_label\", dtype = 'int64', data=PrivateTest_y)\n", "datafile.close()\n", "\n", "print(\"Save data finish!\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "由于Leaderboard分为Public和Private两部分,故我将2w个训练集划分为8:1:1的\n", "Training & PublicTest & PrivateTest 三部分,并保存为h5文件,方便后续训练" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import torch\n", "import torch.nn as nn\n", "import torch.optim as optim\n", "import torchvision.transforms as transforms\n", "import numpy as np\n", "import os\n", "from torch.autograd import Variable\n", "from PIL import Image\n", "import torch.utils.data as data\n", "import h5py\n", "class dataset(data.Dataset):\n", " def __init__(self, split='Training', transform=None):\n", " self.transform = transform\n", " self.split = split # training set or test set\n", " self.data = h5py.File('./data/data.h5', 'r', driver='core')\n", " # now load the picked numpy arrays\n", " if self.split == 'Training':\n", " self.train_data = self.data['Training_pixel']\n", " self.train_labels = self.data['Training_label']\n", " self.train_data = np.asarray(self.train_data)\n", " self.train_data = self.train_data.reshape((16000, 48, 48))\n", "\n", " elif self.split == 'PublicTest':\n", " self.PublicTest_data = self.data['PublicTest_pixel']\n", " self.PublicTest_labels = self.data['PublicTest_label']\n", " self.PublicTest_data = np.asarray(self.PublicTest_data)\n", " self.PublicTest_data = self.PublicTest_data.reshape((2000, 48, 48))\n", "\n", " else:\n", " self.PrivateTest_data = self.data['PrivateTest_pixel']\n", " self.PrivateTest_labels = self.data['PrivateTest_label']\n", " self.PrivateTest_data = np.asarray(self.PrivateTest_data)\n", " self.PrivateTest_data = self.PrivateTest_data.reshape((2000, 48, 48))\n", "\n", " def __getitem__(self, index):\n", " \"\"\"\n", " Args:\n", " index (int): Index\n", "\n", " Returns:\n", " tuple: (image, target) where target is index of the target class.\n", " \"\"\"\n", " if self.split == 'Training':\n", " img, target = self.train_data[index], self.train_labels[index]\n", " elif self.split == 'PublicTest':\n", " img, target = self.PublicTest_data[index], self.PublicTest_labels[index]\n", " else:\n", " img, target = self.PrivateTest_data[index], self.PrivateTest_labels[index]\n", "\n", " # 进行以下操作可以返回pil的图像数据,以确保在其他数据集中也能使用\n", " img = img[:, :, np.newaxis]\n", " img = np.concatenate((img, img, img), axis=2)\n", " img = Image.fromarray(img)\n", " if self.transform is not None:\n", " img = self.transform(img)\n", " return img, target\n", "\n", " def __len__(self):\n", " if self.split == 'Training':\n", " return len(self.train_data)\n", " elif self.split == 'PublicTest':\n", " return len(self.PublicTest_data)\n", " else:\n", " return len(self.PrivateTest_data)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "dataset类,以及一些内置方法" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "from torch.autograd import Variable\n", "\n", "\n", "cfg = {\n", " 'VGG11': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],\n", " 'VGG13': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],\n", " 'VGG16': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],\n", " 'VGG19': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],\n", "}\n", "\n", "\n", "class VGG(nn.Module):\n", " def __init__(self, vgg_name):\n", " super(VGG, self).__init__()\n", " self.features = self._make_layers(cfg[vgg_name])\n", " self.classifier = nn.Linear(512, 7)\n", "\n", " def forward(self, x):\n", " out = self.features(x)\n", " out = out.view(out.size(0), -1)\n", " out = F.dropout(out, p=0.5, training=self.training)\n", " out = self.classifier(out)\n", " return out\n", "\n", " def _make_layers(self, cfg):\n", " layers = []\n", " in_channels = 3\n", " for x in cfg:\n", " if x == 'M':\n", " layers += [nn.MaxPool2d(kernel_size=2, stride=2)]\n", " else:\n", " layers += [nn.Conv2d(in_channels, x, kernel_size=3, padding=1),\n", " nn.BatchNorm2d(x),\n", " nn.ReLU(inplace=True)]\n", " in_channels = x\n", " layers += [nn.AvgPool2d(kernel_size=1, stride=1)]\n", " return nn.Sequential(*layers)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "神经网络模型vgg类,实测vgg19效果最佳" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "\n", "from torch.autograd import Variable\n", "\n", "\n", "class BasicBlock(nn.Module):\n", " expansion = 1\n", "\n", " def __init__(self, in_planes, planes, stride=1):\n", " super(BasicBlock, self).__init__()\n", " self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)\n", " self.bn1 = nn.BatchNorm2d(planes)\n", " self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False)\n", " self.bn2 = nn.BatchNorm2d(planes)\n", "\n", " self.shortcut = nn.Sequential()\n", " if stride != 1 or in_planes != self.expansion*planes:\n", " self.shortcut = nn.Sequential(\n", " nn.Conv2d(in_planes, self.expansion*planes, kernel_size=1, stride=stride, bias=False),\n", " nn.BatchNorm2d(self.expansion*planes)\n", " )\n", "\n", " def forward(self, x):\n", " out = F.relu(self.bn1(self.conv1(x)))\n", " out = self.bn2(self.conv2(out))\n", " out += self.shortcut(x)\n", " out = F.relu(out)\n", " return out\n", "\n", "\n", "class Bottleneck(nn.Module):\n", " expansion = 4\n", "\n", " def __init__(self, in_planes, planes, stride=1):\n", " super(Bottleneck, self).__init__()\n", " self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, bias=False)\n", " self.bn1 = nn.BatchNorm2d(planes)\n", " self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)\n", " self.bn2 = nn.BatchNorm2d(planes)\n", " self.conv3 = nn.Conv2d(planes, self.expansion*planes, kernel_size=1, bias=False)\n", " self.bn3 = nn.BatchNorm2d(self.expansion*planes)\n", "\n", " self.shortcut = nn.Sequential()\n", " if stride != 1 or in_planes != self.expansion*planes:\n", " self.shortcut = nn.Sequential(\n", " nn.Conv2d(in_planes, self.expansion*planes, kernel_size=1, stride=stride, bias=False),\n", " nn.BatchNorm2d(self.expansion*planes)\n", " )\n", "\n", " def forward(self, x):\n", " out = F.relu(self.bn1(self.conv1(x)))\n", " out = F.relu(self.bn2(self.conv2(out)))\n", " out = self.bn3(self.conv3(out))\n", " out += self.shortcut(x)\n", " out = F.relu(out)\n", " return out\n", "\n", "\n", "class ResNet(nn.Module):\n", " def __init__(self, block, num_blocks, num_classes=7):\n", " super(ResNet, self).__init__()\n", " self.in_planes = 64\n", "\n", " self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False)\n", " self.bn1 = nn.BatchNorm2d(64)\n", " self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)\n", " self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)\n", " self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)\n", " self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)\n", " self.linear = nn.Linear(512, num_classes)\n", "\n", " def _make_layer(self, block, planes, num_blocks, stride):\n", " strides = [stride] + [1]*(num_blocks-1)\n", " layers = []\n", " for stride in strides:\n", " layers.append(block(self.in_planes, planes, stride))\n", " self.in_planes = planes * block.expansion\n", " return nn.Sequential(*layers)\n", "\n", " def forward(self, x):\n", " out = F.relu(self.bn1(self.conv1(x)))\n", " out = self.layer1(out)\n", " out = self.layer2(out)\n", " out = self.layer3(out)\n", " out = self.layer4(out)\n", " out = F.avg_pool2d(out, 4)\n", " out = out.view(out.size(0), -1)\n", " out = F.dropout(out, p=0.5, training=self.training)\n", " out = self.linear(out)\n", " return out\n", "\n", "\n", "def ResNet18():\n", " return ResNet(BasicBlock, [2,2,2,2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "神经网络模型resnet18,对比得知分数高于vgg19" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os\n", "import sys\n", "import time\n", "import torch\n", "import torch.nn as nn\n", "term_width = 80 \n", "\n", "TOTAL_BAR_LENGTH = 30.\n", "last_time = time.time()\n", "begin_time = last_time\n", "\n", "def progress_bar(current, total, msg=None):\n", " ' Displays or updates a console progress bar. '\n", " global last_time, begin_time\n", " if current == 0:\n", " begin_time = time.time() # Reset for new bar.\n", "\n", " cur_len = int(TOTAL_BAR_LENGTH*current/total)\n", " rest_len = int(TOTAL_BAR_LENGTH - cur_len) - 1\n", "\n", " sys.stdout.write(' [')\n", " for i in range(cur_len):\n", " sys.stdout.write('=')\n", " sys.stdout.write('>')\n", " for i in range(rest_len):\n", " sys.stdout.write('.')\n", " sys.stdout.write(']')\n", "\n", " cur_time = time.time()\n", " step_time = cur_time - last_time\n", " last_time = cur_time\n", " tot_time = cur_time - begin_time\n", "\n", " L = []\n", " if msg:\n", " L.append(' | ' + msg)\n", "\n", " msg = ''.join(L)\n", " sys.stdout.write(msg)\n", " for i in range(term_width-int(TOTAL_BAR_LENGTH)-len(msg)-3):\n", " sys.stdout.write(' ')\n", "\n", " # Go back to the center of the bar.\n", " for i in range(term_width-int(TOTAL_BAR_LENGTH/2)+2):\n", " sys.stdout.write('\\b')\n", " sys.stdout.write(' %d/%d ' % (current+1, total))\n", "\n", " if current < total-1:\n", " sys.stdout.write('\\r')\n", " else:\n", " sys.stdout.write('\\n')\n", " sys.stdout.flush()\n", "\n", "def set_lr(optimizer, lr):\n", " ' Sets the learning rate to the given value '\n", " for group in optimizer.param_groups:\n", " group['lr'] = lr\n", "\n", "def clip_gradient(optimizer, grad_clip):\n", " 'Clips gradients computed during backpropagation to avoid explosion of gradients.'\n", " for group in optimizer.param_groups:\n", " #print(group['params'])\n", " for param in group['params']:\n", " param.grad.data.clamp_(-grad_clip, grad_clip)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "训练过程中的三个辅助函数,progress_bar、set_lr、clip_gradient" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "path = 'model/'\n", "batch_size = 128\n", "learning_rate = 0.01\n", "\n", "use_cuda = torch.cuda.is_available()\n", "best_PublicTest_acc = 0 # best PublicTest accuracy\n", "best_PublicTest_acc_epoch = 0\n", "best_PrivateTest_acc = 0 # best PrivateTest accuracy\n", "best_PrivateTest_acc_epoch = 0\n", "start_epoch = 0 # start from epoch 0 or last checkpoint epoch\n", "\n", "learning_rate_decay_start = 80 # 50\n", "learning_rate_decay_every = 5 # 5\n", "learning_rate_decay_rate = 0.9 # 0.9\n", "\n", "cut_size = 44\n", "total_epoch = 250\n", "#以上的默认超参数设置\n", "\n", "# Data\n", "print('==> Preparing data..')\n", "transform_train = transforms.Compose([\n", " transforms.RandomCrop(44),\n", " transforms.RandomHorizontalFlip(),\n", " transforms.ToTensor(),\n", "])\n", "\n", "transform_test = transforms.Compose([\n", " transforms.TenCrop(cut_size),\n", " transforms.Lambda(lambda crops: torch.stack([transforms.ToTensor()(crop) for crop in crops])),\n", "])\n", "\n", "trainset = dataset(split = 'Training', transform=transform_train)\n", "trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True)\n", "PublicTestset = dataset(split = 'PublicTest', transform=transform_test)\n", "PublicTestloader = torch.utils.data.DataLoader(PublicTestset, batch_size=batch_size, shuffle=False)\n", "PrivateTestset = dataset(split = 'PrivateTest', transform=transform_test)\n", "PrivateTestloader = torch.utils.data.DataLoader(PrivateTestset, batch_size=batch_size, shuffle=False)\n", "\n", "# Model\n", "print('==> Building model..')\n", "#net = VGG('VGG19')\n", "net = ResNet18()\n", "\n", "\n", "if use_cuda:\n", " net.cuda()\n", "\n", "criterion = nn.CrossEntropyLoss()\n", "optimizer = optim.SGD(net.parameters(), lr=learning_rate, momentum=0.9, weight_decay=5e-4)\n", "\n", "# Training\n", "def train(epoch):\n", " print('\\nEpoch: %d' % epoch)\n", " global Train_acc\n", " net.train()\n", " train_loss = 0\n", " correct = 0\n", " total = 0\n", "\n", " if epoch > learning_rate_decay_start and learning_rate_decay_start >= 0:\n", " frac = (epoch - learning_rate_decay_start) // learning_rate_decay_every\n", " decay_factor = learning_rate_decay_rate ** frac\n", " current_lr = learning_rate * decay_factor\n", " set_lr(optimizer, current_lr) # set the decayed rate\n", " else:\n", " current_lr = learning_rate\n", " print('learning_rate: %s' % str(current_lr))\n", "\n", " for batch_idx, (inputs, targets) in enumerate(trainloader):\n", " if use_cuda:\n", " inputs, targets = inputs.cuda(), targets.cuda()\n", " optimizer.zero_grad()\n", " with torch.no_grad():\n", " inputs, targets = Variable(inputs), Variable(targets)\n", " outputs = net(inputs)\n", " loss = criterion(outputs, targets)\n", " loss.backward()\n", " clip_gradient(optimizer, 0.1)\n", " optimizer.step()\n", " train_loss += loss.item()\n", " _, predicted = torch.max(outputs.data, 1)\n", " total += targets.size(0)\n", " correct += predicted.eq(targets.data).cpu().sum()\n", "\n", " progress_bar(batch_idx, len(trainloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'\n", " % (train_loss/(batch_idx+1), 100.*correct/total, correct, total))\n", "\n", " Train_acc = 100.*correct/total\n", "\n", "def PublicTest(epoch):\n", " global PublicTest_acc\n", " global best_PublicTest_acc\n", " global best_PublicTest_acc_epoch\n", " net.eval()\n", " PublicTest_loss = 0\n", " correct = 0\n", " total = 0\n", " for batch_idx, (inputs, targets) in enumerate(PublicTestloader):\n", " bs, ncrops, c, h, w = np.shape(inputs)\n", " inputs = inputs.view(-1, c, h, w)\n", " if use_cuda:\n", " inputs, targets = inputs.cuda(), targets.cuda()\n", " with torch.no_grad():\n", " inputs, targets = Variable(inputs), Variable(targets)\n", " outputs = net(inputs)\n", " outputs_avg = outputs.view(bs, ncrops, -1).mean(1) # avg over crops\n", " loss = criterion(outputs_avg, targets)\n", " PublicTest_loss += loss.item()\n", " _, predicted = torch.max(outputs_avg.data, 1)\n", " total += targets.size(0)\n", " correct += predicted.eq(targets.data).cpu().sum()\n", "\n", " progress_bar(batch_idx, len(PublicTestloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'\n", " % (PublicTest_loss / (batch_idx + 1), 100. * correct / total, correct, total))\n", " \n", " # Save checkpoint.\n", " PublicTest_acc = 100.*correct/total\n", " if PublicTest_acc > best_PublicTest_acc:\n", " print('Saving..')\n", " print(\"best_PublicTest_acc: %0.3f\" % PublicTest_acc)\n", " state = {\n", " 'net': net.state_dict() if use_cuda else net,\n", " 'acc': PublicTest_acc,\n", " 'epoch': epoch,\n", " }\n", " if not os.path.isdir(path):\n", " os.mkdir(path)\n", " torch.save(state, os.path.join(path,'PublicTest_model.t7'))\n", " best_PublicTest_acc = PublicTest_acc\n", " best_PublicTest_acc_epoch = epoch\n", "\n", "def PrivateTest(epoch):\n", " global PrivateTest_acc\n", " global best_PrivateTest_acc\n", " global best_PrivateTest_acc_epoch\n", " net.eval()\n", " PrivateTest_loss = 0\n", " correct = 0\n", " total = 0\n", " for batch_idx, (inputs, targets) in enumerate(PrivateTestloader):\n", " bs, ncrops, c, h, w = np.shape(inputs)\n", " inputs = inputs.view(-1, c, h, w)\n", " if use_cuda:\n", " inputs, targets = inputs.cuda(), targets.cuda()\n", " with torch.no_grad():\n", " inputs, targets = Variable(inputs), Variable(targets)\n", " outputs = net(inputs)\n", " outputs_avg = outputs.view(bs, ncrops, -1).mean(1) # avg over crops\n", " loss = criterion(outputs_avg, targets)\n", " PrivateTest_loss += loss.item()\n", " _, predicted = torch.max(outputs_avg.data, 1)\n", " total += targets.size(0)\n", " correct += predicted.eq(targets.data).cpu().sum()\n", "\n", " progress_bar(batch_idx, len(PublicTestloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'\n", " % (PrivateTest_loss / (batch_idx + 1), 100. * correct / total, correct, total))\n", " # Save checkpoint.\n", " PrivateTest_acc = 100.*correct/total\n", "\n", " if PrivateTest_acc > best_PrivateTest_acc:\n", " print('Saving..')\n", " print(\"best_PrivateTest_acc: %0.3f\" % PrivateTest_acc)\n", " state = {\n", " 'net': net.state_dict() if use_cuda else net,\n", "\t 'best_PublicTest_acc': best_PublicTest_acc,\n", " 'best_PrivateTest_acc': PrivateTest_acc,\n", " \t 'best_PublicTest_acc_epoch': best_PublicTest_acc_epoch,\n", " 'best_PrivateTest_acc_epoch': epoch,\n", " }\n", " if not os.path.isdir(path):\n", " os.mkdir(path)\n", " torch.save(state, os.path.join(path,'PrivateTest_model.t7'))\n", " best_PrivateTest_acc = PrivateTest_acc\n", " best_PrivateTest_acc_epoch = epoch\n", "\n", "for epoch in range(start_epoch, total_epoch):\n", " train(epoch)\n", " PublicTest(epoch)\n", " PrivateTest(epoch)\n", "\n", "print(\"best_PublicTest_acc: %0.3f\" % best_PublicTest_acc)\n", "print(\"best_PublicTest_acc_epoch: %d\" % best_PublicTest_acc_epoch)\n", "print(\"best_PrivateTest_acc: %0.3f\" % best_PrivateTest_acc)\n", "print(\"best_PrivateTest_acc_epoch: %d\" % best_PrivateTest_acc_epoch)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "==> Preparing data..
\n", "==> Building model..
\n", "==> Training..
\n", "\n", "best_PublicTest_acc: 69.300
\n", "best_PublicTest_acc_epoch: 156
\n", "best_PrivateTest_acc: 67.250
\n", "best_PrivateTest_acc_epoch: 103
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "训练的主体代码,使用显卡为Quadro RTX 8000的linux服务器运行" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import csv\n", "import numpy as np\n", "import torchvision.transforms as transforms\n", "from PIL import Image\n", "Test_x = []\n", "with open('data//test.csv','r') as csvin:\n", " data=csv.reader(csvin)\n", " for row in data:\n", " if row[1] == 'feature':\n", " continue\n", " temp_list = []\n", " for pixel in row[1].split( ):\n", " temp_list.append(int(pixel))\n", " I = np.asarray(temp_list)\n", " Test_x.append(I.tolist())\n", "test_data = np.asarray(Test_x)\n", "test_data = test_data.reshape((8500, 48, 48))\n", "#net = VGG('VGG19')\n", "net = ResNet18()\n", "checkpoint = torch.load(os.path.join('model', 'PublicTest_model.t7'))\n", "# 两份模型可以跑出两个结果\n", "#checkpoint = torch.load(os.path.join('model', 'PrivateTest_model.t7'))\n", "net.load_state_dict(checkpoint['net'])\n", "net.cuda()\n", "net.eval()\n", "cut_size = 44\n", "transform_test = transforms.Compose([\n", " transforms.TenCrop(cut_size),\n", " transforms.Lambda(lambda crops: torch.stack([transforms.ToTensor()(crop) for crop in crops])),\n", "])\n", "pred = []\n", "for gray in test_data:\n", " img = gray[:, :, np.newaxis]\n", " img = np.concatenate((img, img, img), axis=2)\n", " img = Image.fromarray(np.uint8(img))\n", " inputs = transform_test(img)\n", " ncrops, c, h, w = np.shape(inputs)\n", " inputs = inputs.view(-1, c, h, w)\n", " inputs = inputs.cuda()\n", " with torch.no_grad():\n", " inputs = Variable(inputs)\n", " outputs = net(inputs)\n", " _, predicted = torch.max(outputs.data, 1)\n", " pred.append(predicted.cpu().numpy())\n", " #写入csv文件\n", "with open('submission.csv', 'w') as f:\n", " f.write('id,label\\n')\n", " for i in range(len(pred)):\n", " f.write(f'{i+1},{pred[i][0]}\\n')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "把准备提交的结果保存,由于test有两部分,故可以用两个保存下来的模型得到两个结果。因为private数据是未知的,所以两次提交的public分数高低也是未知的" ] } ], "metadata": { "interpreter": { "hash": "8c0d8dfaf6a7fb4d6df79c3eeeb9d072c60b2f8d57beb74a7d49398d3aae5815" }, "kernelspec": { "display_name": "Python 3.8.12 64-bit ('torch': conda)", "language": "python", "name": "python3" }, "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.8.12" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }