Kaggle-猫狗图像分类全流程实践(支持迁移学习和其他分类任务迁移)

1、insatll environment|安装环境

!pip install torchtoolbox
!pip install torchsummary

2、import package|导入三方库

# 基础库
import os
import time
import random
import shutil
import pandas as pd
import csv
from math import exp
from PIL import Image
import numpy as np
import math
import cv2
from tqdm import tqdm
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from mpl_toolkits.axes_grid1 import ImageGrid
%matplotlib inline
# torch
import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
from torch.autograd import Variable
import torchvision
from torchvision import datasets, models, transforms
import torch.nn.functional as F
from torchsummary import summary
# 混合精度
from torch.optim.lr_scheduler import CosineAnnealingLR
scaler = torch.cuda.amp.GradScaler()
# Kaggle文件下载
from IPython.display import FileLink
# 其他数据增强
from torchtoolbox.tools import mixup_data, mixup_criterion
from torchtoolbox.transform import Cutout

3、set random seed|固定随机种子

The random seed is the initial value used in the pseudo-random number generator to generate pseudo-random numbers. For a pseudo-random number generator, starting from the same random number seed, the same random number sequence can be obtained. Set a random seed so that the same training effect can be produced later.

随机数种子(random seed)是在伪随机数生成器中用于生成伪随机数的初始数值。对于一个伪随机数生成器,从相同的随机数种子出发,可以得到相同的随机数序列。设置随机种子,便于后期产生相同的训练效果。

def seed_torch(seed=3407):random.seed(seed)os.environ['PYTHONHASHSEED'] = str(seed)np.random.seed(seed)torch.manual_seed(seed)torch.cuda.manual_seed(seed)torch.cuda.manual_seed_all(seed) # if you are using multi-GPU.torch.backends.cudnn.benchmark = Falsetorch.backends.cudnn.deterministic = True
seed_torch()

4、split datastes|划分数据集

The dataset is divided into training set, validation set and test set. The training set is used for model training, the validation set is used to verify the training effect of the model, used for parameter adjustment, etc., and the test set is used to test the prediction ability of the final model.This part divides the training and validation ratio as 8:2.

数据集分为训练集、验证集和测试集。训练集用于模型训练,验证集用于验证模型的训练效果,用于参数调整等,测试集用于测试最终模型的预测能力。本部分划分训练、验证比例为8:2。

# 指定数据集路径
ori_dataset_path = '../input/comp6101-assignment2-group2/train'
dataset_path = './'
# 验证集比例
test_frac = 0.2
classes = os.listdir(ori_dataset_path)
# 创建 train 文件夹
if not os.path.exists(os.path.join(dataset_path, 'train')):os.makedirs(os.path.join(dataset_path, 'train'))
# 创建 val 文件夹
if not os.path.exists(os.path.join(dataset_path, 'val')):os.makedirs(os.path.join(dataset_path, 'val'))
# 在 train 和 val 文件夹中创建各类别子文件夹
for label in classes:if not os.path.exists(os.path.join(dataset_path, 'train', label)):os.makedirs(os.path.join(dataset_path, 'train', label))if not os.path.exists(os.path.join(dataset_path, 'val', label)):os.makedirs(os.path.join(dataset_path, 'val', label))
df = pd.DataFrame()
print('{:^18} {:^18} {:^18}'.format('类别', '训练集数据个数', '测试集数据个数'))
for sigle_label in classes: # 遍历每个类别# 读取该类别的所有图像文件名old_dir = os.path.join(ori_dataset_path, sigle_label)images_filename = os.listdir(old_dir)random.shuffle(images_filename) # 随机打乱# 划分训练集和验证集testset_numer = int(len(images_filename) * test_frac) # 验证集图像个数testset_images = images_filename[:testset_numer]      # 获取拟移动至 val 目录的测试集图像文件名trainset_images = images_filename[testset_numer:]     # 获取拟移动至 train 目录的训练集图像文件名# 移动图像至 val 目录for image in testset_images:old_img_path = os.path.join(ori_dataset_path, sigle_label, image)         # 获取原始文件路径new_test_path = os.path.join(dataset_path, 'val', sigle_label, image) # 获取 val 目录的新文件路径shutil.copy(old_img_path, new_test_path) # 移动文件# 移动图像至 train 目录for image in trainset_images:old_img_path = os.path.join(ori_dataset_path, sigle_label, image)           # 获取原始文件路径new_train_path = os.path.join(dataset_path, 'train', sigle_label, image) # 获取 train 目录的新文件路径shutil.copy(old_img_path, new_train_path) # 移动文件# 工整地输出每一类别的数据个数print('{:^18} {:^18} {:^18}'.format(sigle_label, len(trainset_images), len(testset_images)))

5、visual some datasets|可视化部分数据

folder_path = './train/cat/'
# 可视化图像的个数
N = 36
# n 行 n 列
n = math.floor(np.sqrt(N))
# 获取数据
images = []
for each_img in os.listdir(folder_path)[:N]:img_path = os.path.join(folder_path, each_img)img_bgr = cv2.imread(img_path)img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)images.append(img_rgb)
# 可视化
fig = plt.figure(figsize=(10, 10))
grid = ImageGrid(fig, 111,  # 类似绘制子图 subplot(111)nrows_ncols=(n, n),  # 创建 n 行 m 列的 axes 网格axes_pad=0.02,  # 网格间距share_all=True)
# 遍历每张图像
for ax, im in zip(grid, images):ax.imshow(im)ax.axis('off')
plt.tight_layout()
plt.show()

6、data preprocessing|数据预处理

It mainly includes data enhancement and DataLoader loading.

主要包括数据增强和DataLoader装载。

# 基于imagenet上的std和mean
std_nums = [0.229, 0.224, 0.225]
mean_nums = [0.485, 0.456, 0.406]
# 训练集上进行的数据增强
train_dataTrans = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),#Cutout(),#transforms.RandomHorizontalFlip(),  # 水平翻转#transforms.RandomVerticalFlip(),  # 垂直翻转#transforms.RandomRotation(5),#transforms.GaussianBlur(kernel_size=(5, 5), sigma=(0.1, 1)),#transforms.ColorJitter(brightness=0.5, contrast=0.5, hue=0.5),#transforms.RandomHorizontalFlip(0.5),transforms.ToTensor(),transforms.Normalize(mean_nums, std_nums)
])
# 验证集上进行的数据增强
val_dataTrans = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean_nums, std_nums)
])# 数据装载
train_data_dir = './train'
val_data_dir = './val'
train_dataset = datasets.ImageFolder(train_data_dir, train_dataTrans)
val_dataset = datasets.ImageFolder(val_data_dir, val_dataTrans)image_datasets = {'train':train_dataset,'val':val_dataset}
shuff = {'train':True,'val':False}dataloders = {x: torch.utils.data.DataLoader(image_datasets[x],batch_size=32,num_workers=2,shuffle=shuff[x]) for x in ['train', 'val']}train_loader = torch.utils.data.DataLoader(train_dataset,batch_size=32,num_workers=2,shuffle=True)val_loader = torch.utils.data.DataLoader(val_dataset,batch_size=32,num_workers=2,shuffle=True)dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}print(dataset_sizes)

7、trian model|训练模型

7.1、自设计模型

class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.relu = nn.ReLU()self.sigmoid = nn.Sigmoid()self.conv1 = nn.Sequential(nn.Conv2d(in_channels=3,out_channels=16,kernel_size=3,stride=2,),nn.BatchNorm2d(16),nn.ReLU(),nn.MaxPool2d(kernel_size=2),)self.conv2 = nn.Sequential(nn.Conv2d(in_channels=16,out_channels=32,kernel_size=3,stride=2,),nn.BatchNorm2d(32),nn.ReLU(),nn.MaxPool2d(kernel_size=2),)self.conv3 = nn.Sequential(nn.Conv2d(in_channels=32,out_channels=64,kernel_size=3,stride=2,),nn.BatchNorm2d(64),nn.ReLU(),nn.MaxPool2d(kernel_size=2),)self.fc1 = nn.Linear(3 * 3 * 64, 64)self.fc2 = nn.Linear(64, 10)self.out = nn.Linear(10, 2)def forward(self, x):x = self.conv1(x)x = self.conv2(x)x = self.conv3(x)# print(x.size())x = x.view(x.shape[0], -1)x = self.relu(self.fc1(x))x = self.relu(self.fc2(x))x = self.out(x)x = F.log_softmax(x, dim=1)return x
# 打印网络
CNN().to('cuda')

7.2、迁移学习

# 迁移学习
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model_ft = models.resnet50(pretrained=True)
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs, 2)
model_ft.to(DEVICE)
Downloading: "https://download.pytorch.org/models/resnet50-0676ba61.pth" to /root/.cache/torch/hub/checkpoints/resnet50-0676ba61.pth0%|          | 0.00/97.8M [00:00<?, ?B/s]ResNet((conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)(layer1): Sequential((0): Bottleneck((conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(2): Bottleneck((conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)))(layer2): Sequential((0): Bottleneck((conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(2): Bottleneck((conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(3): Bottleneck((conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)))(layer3): Sequential((0): Bottleneck((conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(2): Bottleneck((conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(3): Bottleneck((conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(4): Bottleneck((conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(5): Bottleneck((conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)))(layer4): Sequential((0): Bottleneck((conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True))(2): Bottleneck((conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)))(avgpool): AdaptiveAvgPool2d(output_size=(1, 1))(fc): Linear(in_features=2048, out_features=2, bias=True)
)
# 设置全局参数
modellr = 1e-4
BATCH_SIZE = 32
EPOCHS = 6
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
alpha=0.2# 实例化模型并且移动到GPU
criterion = nn.CrossEntropyLoss()
# 自定义模型
#model_ft = CNN()
#model_ft.to(DEVICE)
optimizer = optim.Adam(model_ft.parameters(), lr=modellr)
cosine_schedule = optim.lr_scheduler.CosineAnnealingLR(optimizer=optimizer,T_max=2,eta_min=1e-9)
train_loss_list = []
val_loss_list = []
val_acc_list = []# 定义训练过程
def train(model, device, train_loader, optimizer, epoch):print('=====train====')model.train()sum_loss = 0total_num = len(train_loader.dataset)for batch_idx, (data, target) in enumerate(train_loader):data, target = data.to(device, non_blocking=True), target.to(device, non_blocking=True)data, labels_a, labels_b, lam = mixup_data(data, target, alpha)optimizer.zero_grad()output = model(data)loss = mixup_criterion(criterion, output, labels_a, labels_b, lam)# 普通训练loss.backward()optimizer.step()# 混合精度训练#scaler.scale(loss).backward()#scaler.step(optimizer)#scaler.update()lr = optimizer.state_dict()['param_groups'][0]['lr']print_loss = loss.data.item()sum_loss += print_lossif (batch_idx + 1) % 100 == 0:print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}\tLR:{:.9f}'.format(epoch, (batch_idx + 1) * len(data), len(train_loader.dataset),100. * (batch_idx + 1) / len(train_loader), loss.item(),lr))ave_loss = sum_loss / len(train_loader)print('epoch:{},loss:{}'.format(epoch, ave_loss))train_loss_list.append(ave_loss)ACC=0
# 验证过程
def val(model, device, test_loader):global ACCprint('=====valid====')model.eval()test_loss = 0correct = 0total_num = len(test_loader.dataset)with torch.no_grad():for data, target in test_loader:data, target = Variable(data).to(device), Variable(target).to(device)output = model(data)loss = criterion(output, target)_, pred = torch.max(output.data, 1)correct += torch.sum(pred == target)print_loss = loss.data.item()test_loss += print_losscorrect = correct.data.item()acc = correct / total_numavgloss = test_loss / len(test_loader)val_loss_list.append(avgloss)print('\nVal set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(avgloss, correct, len(test_loader.dataset), 100 * acc))val_acc_list.append(acc)if acc > ACC:torch.save(model_ft.state_dict(), '66model_' + str(epoch) + '_' + str(round(acc, 3)) + '.pth')ACC = accprint('当前最好模型精度:{}%'.format(ACC*100))# 迭代训练
for epoch in range(1, EPOCHS + 1):train(model_ft, DEVICE, train_loader, optimizer, epoch)cosine_schedule.step()val(model_ft, DEVICE, val_loader)plt.plot(val_loss_list, label='loss')
plt.plot(val_acc_list, label='accuracy')
plt.legend()
plt.title('Valid loss and accuracy')
plt.show()

8、visual inference|可视化推理

infer_transformation = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean_nums, std_nums)
])IMAGES_KEY = 'images'
MODEL_INPUT_KEY = 'images'
LABEL_OUTPUT_KEY = 'predicted_label'
MODEL_OUTPUT_KEY = 'scores'def decode_image(file_content):image = Image.open(file_content)image = image.convert('RGB')return imagedef cnn(model_path):model = CNN()model.load_state_dict(torch.load(model_path,map_location ='cuda:0'))return modeldef trans_learning(model_path):model = models.resnet50(pretrained=False)num_ftrs = model.fc.in_featuresmodel.fc = nn.Linear(num_ftrs, 2)model.load_state_dict(torch.load(model_path,map_location ='cuda:0'))model.eval()return modeldef predict(file_name):LABEL_LIST = ['cat', 'dog']# 迁移学习模型model = trans_learning('../input/weightsresnet/model_2_0.992.pth')# 自定义模型#model = cnn('./55model_9_0.837.pth')image1 = decode_image(file_name)input_img = infer_transformation(image1)input_img = torch.autograd.Variable(torch.unsqueeze(input_img, dim=0).float(), requires_grad=False)logits_list =  model(input_img)[0].detach().numpy().tolist()maxlist=max(logits_list)z_exp = [exp(i-maxlist) for i in  logits_list]sum_z_exp = sum(z_exp)softmax = [round(i / sum_z_exp, 3) for i in z_exp]labels_to_logits = {LABEL_LIST[i]: s for i, s in enumerate(softmax)}predict_result = {LABEL_OUTPUT_KEY: max(labels_to_logits, key=labels_to_logits.get),MODEL_OUTPUT_KEY: labels_to_logits}return predict_resultfile_name = '../input/comp6101-assignment2-group2/test/test/7.jpg'
result = predict(file_name)
import matplotlib.pyplot as pltplt.figure(figsize=(10,10))
img = decode_image(file_name)
plt.imshow(img)
plt.show()print('结果:',result)


在这里插入图片描述

结果: {'predicted_label': 'cat', 'scores': {'cat': 0.987, 'dog': 0.013}}

9、inference and submission|推理和提交

import csv
from tqdm import tqdmfor i  in range(2):headers = ['id','category']f = open('results.csv','w', newline='')writer = csv.writer(f)writer.writerow(headers)for i in tqdm(range(5000)):file_name='../input/comp6101-assignment2-group2/test/test/'+str(i)+'.jpg'result = predict(file_name)if result['predicted_label']=='cat':value=0if result['predicted_label']=='dog':value=1writer.writerow([str(i),int(value)])
100%|██████████| 5000/5000 [52:24<00:00,  1.59it/s] 
100%|██████████| 5000/5000 [51:26<00:00,  1.62it/s] 
FileLink('results.csv')

results.csv

FileLink('./66model_2_0.992.pth')
模型预训练lr优化器损失函数学习率训轮次验证集ACC线上提交ACC权重下载CSV结果ACC-Loss图
自设计CNN-CosineAnnealingLRCrossEntropyLoss1e-3100.836750.7336【点击查看】【点击查看】【点击查看】
Resnet50CosineAnnealingLRCrossEntropyLoss1e-460.9920.98880【点击查看】【点击查看】【点击查看】

10、Summarize|总结

本次作业,该.ipynb实现了以下内容:

  1. 构建了一个简单的CNN模型,在训练ACC上上达到0.83准确率,线上提交分数在0.73;
  2. 引入:Resize、CenterCrop、Cutout、RandomHorizontalFlip、RandomVerticalFlip等众多增强方案;
  3. 引入mixup_data、mixup_criterion等方法,提升训练精度;
  4. 内嵌torch.cuda.amp.GradScaler混合精度训练,不影响精度下加速模型训练过程;
  5. 引入迁移学习,多种torchvision.models模型任意调用,并在Resnet50迁移学习上达到0.988的成绩;
  6. 任意模型结构可视化,任意模型权重保存与加载;
  7. 训练和验证ACCloss图输出对比,模型效果简单直观;
  8. 完整流程:数据划分->部分数据可视化->数据预处理->模型构建->模型训练->可视化推理->批量推理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/43245.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

神经网络实战--使用迁移学习完成猫狗分类

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 今天来学习一下如何使用基于tensorflow和keras的迁移学习完成猫狗分类&#xff0c;欢迎大家一起前来探讨学习~ 本文目录&#xff1a; 一、加载数据集1.调用库函数2.加载数据集3.数据集管理 二、猫狗数据集介绍1.猫狗数据集…

基于Pytorch的猫狗分类

无偿分享~ 猫狗二分类文件下载地址 在下一章说 猫狗分类这个真是困扰我好几天&#xff0c;找了好多资料都是以TensorFlow的猫狗分类&#xff0c;但我们要求的是以pytorch的猫狗分类。刚开始我找到了也运行成功了觉得可以了&#xff0c;最后看了一眼实践要求傻眼了&#xff0c;…

猫舍 靶场

目标url:http://117.41.229.122:8003/?id1 第一步&#xff0c;判断是否存在sql注入漏洞 构造 ?id1 and 11 &#xff0c;回车 页面返回正常 构造 ?id1 and 12 ,回车 页面不正常&#xff0c;初步判断这里 可能 存在一个注入漏洞 第二步:判断字段数 构造 ?id1 and 11 order…

Olaparib 有望治疗 UBQLN4 过表达型肿瘤

基因组的不稳定性是人类遗传病和癌症的一大特点。在这篇文章当中&#xff0c;研究人员在常染色体隐性遗传病家族中发现了有害的 UBQLN4 突变。蛋白酶体穿梭因子UBQLN4 被 ATM 磷酸化并与泛素化的 MRE11 相互作用&#xff0c;从而介导早期的同源重组修复 (HRR)。在体外和体内实验…

神经内分泌肿瘤治疗新进展,神经内分泌肿瘤进展

脑肿瘤复发 。 颅内及椎管内肿瘤【概述】1&#xff0e;原发性肿瘤&#xff1a;起源于头颅、椎管内各种组织结构&#xff0c;如颅骨、脑膜、脑组织、颅神经、脑血管、脑垂体、松果体、脉络丛、颅内结缔组织、胚胎残余组织、脊膜、脊神经、脊髓、脊髓血管及脂肪组织等&#xff…

Nature Cancer | 发现非肿瘤药物的抗癌潜力

今天给大家介绍美国Broad Institute of MIT and Harvard的 Todd R. Golub团队发表在Nature cancer上的一篇文章&#xff1a;“Discovering the anticancer potential of nononcology drugs by systematic viability profiling“。在这个研究中&#xff0c;作者试图创建一个公共…

文献分享:定义的肿瘤抗原特异性T细胞增强了个性化的TCR-T细胞治疗和免疫治疗反应的预测

《Defifined tumor antigen-specifific T cells potentiate personalized TCR-T cell therapy and prediction of immunotherapy response》 简介 从患者体内自然发生的肿瘤抗原特异性T(Tas)细胞中提取的T细胞受体(TCRs)设计的T细胞将靶向其肿瘤中的个人TSAs。为了建立这种个性…

Irinotecan和vandetanib在治疗胰腺癌患者时产生协同效应(Irinotecan and vandetanib create synergies for t)

1. 摘要 背景:在胰腺癌(PAAD)中最常突变的基因对是KRAS和TP53&#xff0c;文章的目标是阐明KRAS/TP53突变的多组学和分子动力学图景&#xff0c;并为KRAS和TP53突变的PAAD患者获得有前景的新药物。此外&#xff0c;文章根据多组学数据尝试发现KRAS与TP53之间可能的联系。    …

癌症/肿瘤免疫治疗最新研究进展(2022年4月)

近年来&#xff0c;免疫治疗一直都是国内外肿瘤治疗研究领域的火爆热点&#xff0c;可以称之为革命性的突破。 除了大家熟知的PD-1/PD-L1已经先后斩获了包括肺癌、胃肠道肿瘤、乳腺癌、泌尿系统肿瘤、皮肤癌、淋巴瘤等在内的近20大实体肿瘤&#xff0c;成为免疫治疗的第一张王牌…

MCE | 癌症诊断和靶向治疗的“遍地开花”

据研究报道&#xff0c;很多癌细胞分泌的外泌体 (Exosome) 比正常细胞分泌的多 10 倍以上。外泌体参与了癌症的发生、进展、转移和耐药性&#xff0c;并通过转运蛋白和核酸&#xff0c;建立与肿瘤微环境的联系。例如&#xff0c;外泌体可导致免疫逃逸&#xff0c;癌细胞的免疫逃…

泛癌分析·找出各个癌症的预后相关基因

泛癌分析找出各个癌症的预后相关基因 ` 其他相关文章: 万物皆可pan分析高分文章登山梯for循环的熟练操作 前言 pan分析的第二篇我想写一下如何在TCGA整个基因集内实现COX单因素分析,将所有的预后相关基因筛选出来,同时得到这些基因的基本参数、统计量等信息。这样的分析的…

饮食干预减轻癌症治疗相关症状和毒性

现代化疗&#xff0c;放射疗法在摧毁癌细胞的同时&#xff0c;对健康细胞也造成了伤害&#xff0c;引发相关毒性&#xff0c;反应例如便秘&#xff0c;腹泻&#xff0c;疲劳&#xff0c;恶心&#xff0c;呕吐等。 癌症患者的营养状况可能是癌症治疗相关毒性的核心决定因素&…

边缘计算,是在炒概念吗?

导读&#xff1a;边缘计算概念刚出来的时候&#xff0c;很多人的第一反应是“这是哪个行业组织或者公司为了拉动市场需求而创造出来的新词汇吧&#xff1f;” 边缘计算究竟是什么&#xff1f;为什么会有边缘计算&#xff1f;它是一个全新的概念吗&#xff1f;谁在担任边缘计算的…

移动边缘计算笔记

该篇文章是阅读《移动边缘计算综述》所整理的笔记和心得&#xff0c;仅供参考&#xff0c;欢迎指正。 移动边缘计算&#xff08;MEC&#xff09;&#xff0c;mobile edgecomputing&#xff0c;后来慢慢过渡为“多接入边缘计算”&#xff08;multi-access edge computing&#x…

关于边缘计算和边云协同,看这一篇就够了~

几年前&#xff0c;大多数人都期望将物联网部署至云端&#xff0c;这的确可以给个人用户带来便捷的使用体验&#xff0c;但构建企业级的物联网解决方案&#xff0c;仍然需要采用云计算和边缘计算的结合方案。与纯粹的云端解决方案相比&#xff0c;包含边缘侧的混合方案可以减少…

边缘计算简介以及几款边缘计算开源平台

边缘计算中的边缘&#xff08;edge&#xff09;指的是网络边缘上的计算和存储资源&#xff0c;这里的网络边缘与数据中心相对&#xff0c;无论是从地理距离还是网络距离上来看都更贴近用户。作为一种新的计算范式&#xff0c;边缘计算将计算任务部署于接近数据产生源的网络边缘…

什么是边缘计算?

注&#xff1a;本篇翻译自施巍松教授的论文《Edge Computing : Vision and Challenges》 目录 文章目录 摘要简介什么是边缘计算什么是边缘计算边缘计算的优点 案例研究云卸载视频分析智能家居智慧城市 机遇和挑战编程可行性命名数据抽象服务管理私密性最优化指标 小结 摘要 …

中国电信边缘计算最佳实践

大数据、云计算、AI 等新一代信息技术的高速发展&#xff0c;在为新兴互联网行业提供强劲驱动之外&#xff0c;也在引领传统行业实施数字化、智能能化转型&#xff0c;并催生出智能制造、智慧金融等一系列全新智能产业生态。在中国电信 MEC 平台中&#xff0c;中国电信正依托自…

为什么需要边缘计算?哪些场景需要边缘计算?

为什么需要边缘计算&#xff1f; 边缘计算&#xff08;Edge Computing&#xff09;是一种将数据处理和计算功能移到接近数据源头的边缘设备上进行的计算模式。相比传统的云计算模式&#xff0c;边缘计算能够在接近数据源头的地方进行实时的数据处理&#xff0c;这为计算机视觉…

边缘计算是啥?

边缘计算&#xff0c;指的是在靠近物或数据源头的一侧&#xff0c;采用网络、计算、存储、应用核心能力为一体的开放平台&#xff0c;就近提供服务。与云计算作对比有助于更好地理解其特性&#xff0c;如果说云计算是集中化、规模化的&#xff0c;那么边缘计算就是分布式的、去…