第3周学习:ResNet+ResNeXt

  • 一、ResNet+ResNeXt
  • 二、cat vs dog
  • 三、Q&A

一、ResNet+ResNeXt

  1. ResNet
  • 网络结构

    • 亮点:超深的网络结构,residual模块,使用batchNormalization加速训练;可以解决梯度消失以及退化问题:深层模型反而取得更低的训练和测试误差。
    • 主要使用两种残差结构,左边的残差结构用于层数较少的网络使用,如18-layer、34-layer,右边用于层数较深的网络,如50-layer,101-layer,152-layer。虚线表示需要shortcut需要经过1x1的卷积核进行维度处理,即bottleneck模块。注意,主分支与shortcut的输出矩阵必须相同。
  • conv2每一block的第一层,stride默认为1,经过计算后,表示第一次只改变深度,不改变宽高。
  • BatchNormalization

    • BN操作是为了使一个batch的数据更集中,然后在我们验证以及预测过程中,就使用统计得到的均值和方差进行标准化处理,目的就是使我们的feature map满足均值为0,方差为1的分布规律,加快收敛速度。

      其中前两个参数是正向传播得到的,反向传播时利用均值和方差参数不断优化,最后使其满足均值为0,方差为1的分布规律。
  • 迁移学习

    • 使用迁移学习能够快速的训练出一个理想的结果,当数据集较小时也能训练出理想的结果。主要是使用预训练模型参数(要注意别人的预处理方式)

    • 其他:padding = (kernel_size-1)/2

  1. ResNeXt
    将原ResNet网络中的block替换成由group分组的block,两者得到的feature map一致,只是参数量更少了。并且当block层数≥3时才有意义。经过验证,group数一般设置为32会取得最好的效果,每组卷积核4d,d表示倍数。



二、cat vs dog

首先上kaggle官网加载所提供的对应的数据集,可以省去上传本地数据集至云盘的时间,但colab使用达到限额,故转向本地。

使用ResNet34提供的预训练权重进行3个epoch的训练,由于本地GPU能力不足,训练所需时间过长,只能使用一部分的数据集进行训练,准确率及代码如下所示。
train.py

import os
import torch
import torchvision
import torch.nn as nn
import torch.optim as optim
from torchvision import transforms, datasets, models
from tqdm import tqdm
import numpy as np
from PIL import Image
import torch.nn.functional as F
import matplotlib.pyplot as plt
from Resnet_model import resnet34data_transforms = {'train': transforms.Compose([# transforms.RandomResizedCrop(224),transforms.Resize([224, 224]),transforms.CenterCrop(224),#        transforms.RandomHorizontalFlip(),transforms.ToTensor(),  # range [0, 255] -> [0.0,1.0]transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])]),'val': transforms.Compose([# transforms.Resize(256),transforms.Resize([224, 224]),# transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
}data_dir = 'datasets'image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x])for x in ['train', 'val']}dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=32, shuffle=True)for x in ['train', 'val']}dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}class_names = image_datasets['train'].classesdevice = torch.device("cuda:0")inputs, classes = next(iter(dataloaders['train']))model = resnet34()
model_weight_path = "resnet34-pre.pth"
model.load_state_dict(torch.load(model_weight_path, map_location="cpu"))
in_channel = model.fc.in_features
model.fc = nn.Linear(in_channel, 2)
model.to(device)criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-5)# 训练函数
def train(model):model.train()# 从train_loader里,64个样本一个batch为单位提取样本进行训练for batch_idx, (images, labels) in enumerate(dataloaders['train']):images, labels = images.to(device), labels.to(device)optimizer.zero_grad()output = model(images)loss = criterion(output, labels)loss.backward()optimizer.step()if batch_idx % 100 == 0:print('Train: [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(batch_idx * len(images), len(dataloaders['train'].dataset),100. * batch_idx / len(dataloaders['train']), loss.item()))# 测试函数
def val(model):model.eval()test_loss = 0correct = 0total = 0best_acc = 0save_path = 'resNet34.pth'with torch.no_grad():  # 不需要梯度,减少计算量for images, labels in dataloaders['val']:images, labels = images.to(device), labels.to(device)output = model(images)_, predicted = torch.max(output.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()accuracy = 100. * correct / totalif accuracy > best_acc:best_acc = acctorch.save(model.state_dict(), save_path)print('accuracy on test set: %d %% ' % accuracy)return accuracyif __name__ == '__main__':accuracy_list = []epoch_list = []acc = 0for epoch in range(1):train(model)acc = val(model)accuracy_list.append(acc)epoch_list.append(epoch)plt.plot(epoch_list, accuracy_list)plt.xlabel(epoch)plt.ylabel(accuracy_list)plt.show()
# inputs, classes = next(iter(dataloaders['val']))
#
# out = torchvision.utils.make_grid(inputs)

test.py

# coding=utf-8
#test
class Dataset(torch.utils.data.Dataset):def __init__(self):self.images = []self.name = []self.test_transform = transforms.Compose([# transforms.Resize(256),transforms.Resize([224, 224]),# transforms.CenterCrop(224),transforms.ToTensor(),# transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])filepath = '/content/datasets/test'for filename in tqdm(os.listdir(filepath)):image = Image.open(os.path.join(filepath, filename))image = self.test_transform(image)self.images.append(image)self.name.append(filename)def __getitem__(self, item):return self.images[item]def __len__(self):images = np.array(self.images)len = images.shape[0]return lentest_datasets = Dataset()
device = torch.device("cuda:0")
testloaders = torch.utils.data.DataLoader(test_datasets, shuffle=False)
print(testloaders)
testset_sizes = len(test_datasets)
#加载之前保存的pth
model = resnet34(num_classes=2).to(device)
model_weight_path = "/content/drive/MyDrive/Colab/deep learning/cat_dog/resNet34.pth"
model.load_state_dict(torch.load(model_weight_path, map_location=device))
model.to(device)dic = {}def test(model):model.eval()cnt = 0for inputs in tqdm(testloaders):inputs = inputs.to(device)outputs = model(inputs)_, preds = torch.max(outputs.data, 1)key = test_datasets.name[cnt].split('.')[0]dic[key] = preds[0]cnt += 1with open("/content/drive/MyDrive/Colab/deep learning/cat_dog/result.csv", 'a+') as f:f.write("{},{}\n".format(key, dic[key]))
test(model)

经过测试后,生成csv文件提交审核

三、Q&A

1、Residual learning
我们设计的深层次网络是有很多网络层为冗余层的。那么我们希望这些冗余层能够完成恒等映射,保证经过该恒等层的输入和输出完全相同。通过学习残差F(x)=0来让该层网络恒等映射上一层。因此可以避免退化问题,通过更深层的网络获取更多的特征。
2、Batch Normailization 的原理
通过正向传播计算一个batch中同一channel的mean和std参数,我们在训练过程中要去不断的计算每个batch的均值和方差,并使用移动平均(moving average)的方法记录统计的均值和方差,在训练完后我们可以近似认为所统计的均值和方差就等于整个训练集的均值和方差,整个训练样本集所对应feature map的数据都要满足正态分布规律,使数据更集中,所以每次卷积操作都要BatchNorm2d。

其中是用来调整数值分布的方差大小,是用来调节数值均值的位置。这两个参数是在反向传播过程中学习得到的,的默认值是1,的默认值是0。

3、为什么分组卷积可以提升准确率?即然分组卷积可以提升准确率,同时还能降低计算量,分数数量尽量多不行吗?
分组卷积常用在轻量型高效网络中,因为它用少量的参数量和运算量就能生成大量的 feature map,大量的 feature map 意味着能够编码更多的信息。
从分组卷积的角度来看,分组数就像一个控制旋钮,最小值是1,此时的卷积就是普通卷积;最大值是输入 feature map 的通道数,此时的卷积就是 depthwise sepereable convolution,即深度分离卷积。DW卷积 完成后的 Feature map 数量与输入层的通道数相同,无法扩展 Feature map。而且这种运算对输入层的每个通道独立进行卷积运算,没有有效的利用不同通道在相同空间位置上的feature信息。

ResNet和ResNeXt相关推荐

  1. 经典卷积神经系列(Inception v1\v2\v3\v4、ResNet、ResNext、DenseNet、SENet)

    写在前面:此文只记录了下本人感觉需要注意的地方,不全且不一定准确.详细内容可以参考文中帖的链接,比较好!!! 经典的CNN:Inception v1\v2\v3\v4.Resnet.Resnext.D ...

  2. CNN经典分类网络发展历程GoogLeNet、SqueezeNet、ResNet、ResNeXt、DenseNet

    本篇博文主要介绍2015年之后出现的经典分类网络的发展历程,前期经典分类网络网上有很多解析,主要包括LeNet.AlexNet.VGG等. 本篇博文主要介绍GoogLeNet.SqueezeNet.R ...

  3. ResNet家族:ResNet、ResNeXt、SE Net、SE ResNeXt

    目录 ResNet DenseNet ResNeXt SE-ResNet, SE-ResNeXt (2018 Apr) 涉及到的其他知识: Global average pooling (GAP) 梯 ...

  4. ResNet、ResNeXt详解以及代码实现

    目录 ResNet网络结构详解 resnet的创新 残差块Residul Block 整体网络结构 ResNet代码实现 ResNeXt详解 组卷积 更新了Block ResNeXt整体结构 ResN ...

  5. unet是残差网络吗_深度学习系列(三)卷积神经网络模型(ResNet、ResNeXt、DenseNet、DenceUnet)...

    深度学习系列(三)卷积神经网络模型(ResNet.ResNeXt.DenseNet.Dence Unet) 内容目录 1.ResNet2.ResNeXt3.DenseNet4.Dence Unet 1 ...

  6. CNN分类,ResNet V1 ,ResNet V2,ResNeXt,DenseNet

    一.CNN分类 1.基于空间利用的CNN 2.基于深度的CNN 3.基于多路径的CNN 4.基于宽度的多连接 5.基于特征图的CNN 6.基于通道的CNN 7.基于注意力的CNN 二,ResNet V ...

  7. 残差网络ResNet到ResNeXt解读,最强ResNeXt预训练模型已开源及如何使用

    它叫ResNeXt WSL,有超过8亿个参数,用Instagram上面的9.4亿张图做了 (弱监督预训练) ,用ImageNet做了微调. 背景介绍:残差网络的发展 ● ResNet (2015) 传 ...

  8. 聊一聊ResNet系列(ResNet、ResNeXt)

    摘要:终于到了介绍ResNet系列的时候了.ResNet真的很好用,特别时shortcut的想法真的厉害.最近,又推出了改进版本ResNeXt,新版本结合了Inception多支路的思想. 关键字:深 ...

  9. ResNet、ResNeXt网络详解及复现

    网络详解: ResNet网络详解 ResNeXt网络详解 torch复现: import torch.nn as nn import torch''' 对应着18层和34层的残差结构 既要拥有实现部分 ...

最新文章

  1. PCL:点云中的超体素数据
  2. vs的资源管理器中一次性添加整个文件夹
  3. bzoj4472: [Jsoi2015]salesman(树形dp)
  4. 爬虫:验证码识别准确率(Tesseract-OCR)
  5. mysql总结 博客园_mysql 总结
  6. spring(java,js,html) 截图上传
  7. php pg_fetch_row,pg_fetch_row
  8. 瑞士行-少女峰,峡谷徒步
  9. ProFile配置节属serializeAs
  10. OpenCV-数组加权和cv::addWeighted
  11. 基于VHDL的vivado2017.4使用教程
  12. 控制继电器(esp32+继电器)
  13. VOC2007数据集解析
  14. ant如何形成时间轴和图库_弯弓新媒体创始人梅波:企业如何构建私域流量
  15. POJ-3580-SuperMemo(splay的各种操作)
  16. 微信小程序 身份证号码验证 15/18位身份证号码验证的正则表达式总结(详细版)
  17. Android SDK 字段及功能的分析详解
  18. excel熵值法计算权重_指标合成的客观权重法之熵权法
  19. 考出PMP证书到底有没有用?
  20. python:机器学习(五):(TensorFlow)

热门文章

  1. Python基础---面试题汇总
  2. XShell 和 WinScp 教程
  3. 克服 iOS HTML5 音频的局限
  4. 7-1 0-1背包 (50分)
  5. KDZD绝缘油介质损耗电阻率测试仪参数
  6. SSL==证书相关概念
  7. Xilinx - iMPACT在win10 64位系统中闪退的问题
  8. Android 修改屏幕背光方案
  9. Go time 时间的各种格式转换
  10. win10电脑屏幕颜色突然变成灰色