repvggnet实现花的种类识别

  • 7aE05d44zW
    了解作者
  • Python
    开发工具
  • 119.3MB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • 10 积分
    下载积分
  • 0
    下载次数
  • 2022-05-21 17:26
    上传日期
repvgg代码复现,可以做花的种类识别,精确度还可以,需要自取
Test3_vggnet.rar
  • Test3_vggnet
  • .idea
  • inspectionProfiles
  • misc.xml
    324B
  • workspace.xml
    26.2KB
  • modules.xml
    276B
  • Test3_vggnet.iml
    524B
  • __pycache__
  • se_block.cpython-36.pyc
    1.1KB
  • repvgg.cpython-36.pyc
    6.9KB
  • model.cpython-36.pyc
    2.4KB
  • RepVGG-A0-deploy1.pth
    31.7MB
  • class_indices.json
    108B
  • train.py
    4.7KB
  • se_block.py
    867B
  • repvgg.py
    10.4KB
  • repvgg_deploy.pth
    31.7MB
  • model.py
    3KB
  • predict.py
    2KB
  • convert.py
    1.2KB
  • RepVGG-A0-deploy.pth
    31.7MB
  • vgg16Net.pth
    34.9MB
内容介绍
import torch.nn as nn import numpy as np import torch import copy from se_block import SEBlock def conv_bn(in_channels, out_channels, kernel_size, stride, padding, groups=1): result = nn.Sequential() result.add_module('conv', nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)) result.add_module('bn', nn.BatchNorm2d(num_features=out_channels)) return result class RepVGGBlock(nn.Module): def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, padding_mode='zeros', deploy=False, use_se=False): super(RepVGGBlock, self).__init__() self.deploy = deploy self.groups = groups self.in_channels = in_channels assert kernel_size == 3 assert padding == 1 padding_11 = padding - kernel_size // 2 self.nonlinearity = nn.ReLU() if use_se: self.se = SEBlock(out_channels, internal_neurons=out_channels // 16) else: self.se = nn.Identity() if deploy:#是,就只定义3*3卷积 self.rbr_reparam = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, padding=padding, dilation=dilation, groups=groups, bias=True, padding_mode=padding_mode) else:#如果不是展示,定义一个3*3卷积和1*1的卷积和残差结构 self.rbr_identity = nn.BatchNorm2d(num_features=in_channels) if out_channels == in_channels and stride == 1 else None self.rbr_dense = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups) self.rbr_1x1 = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=stride, padding=padding_11, groups=groups) print('RepVGG Block, identity = ', self.rbr_identity) def forward(self, inputs): if hasattr(self, 'rbr_reparam'): return self.nonlinearity(self.se(self.rbr_reparam(inputs))) if self.rbr_identity is None: id_out = 0 else: id_out = self.rbr_identity(inputs) return self.nonlinearity(self.se(self.rbr_dense(inputs) + self.rbr_1x1(inputs) + id_out)) # Optional. This improves the accuracy and facilitates quantization. # 1. Cancel the original weight decay on rbr_dense.conv.weight and rbr_1x1.conv.weight. # 2. Use like this. # loss = criterion(....) # for every RepVGGBlock blk: # loss += weight_decay_coefficient * 0.5 * blk.get_cust_L2() # optimizer.zero_grad() # loss.backward() def get_custom_L2(self):#L2正则化 K3 = self.rbr_dense.conv.weight K1 = self.rbr_1x1.conv.weight t3 = (self.rbr_dense.bn.weight / ((self.rbr_dense.bn.running_var + self.rbr_dense.bn.eps).sqrt())).reshape(-1, 1, 1, 1).detach() t1 = (self.rbr_1x1.bn.weight / ((self.rbr_1x1.bn.running_var + self.rbr_1x1.bn.eps).sqrt())).reshape(-1, 1, 1, 1).detach() l2_loss_circle = (K3 ** 2).sum() - (K3[:, :, 1:2, 1:2] ** 2).sum() # The L2 loss of the "circle" of weights in 3x3 kernel. Use regular L2 on them. eq_kernel = K3[:, :, 1:2, 1:2] * t3 + K1 * t1 # The equivalent resultant central point of 3x3 kernel. l2_loss_eq_kernel = (eq_kernel ** 2 / (t3 ** 2 + t1 ** 2)).sum() # Normalize for an L2 coefficient comparable to regular L2. return l2_loss_eq_kernel + l2_loss_circle # This func derives the equivalent kernel and bias in a DIFFERENTIABLE way. # You can get the equivalent kernel and bias at any time and do whatever you want, # for example, apply some penalties or constraints during training, just like you do to the other models. # May be useful for quantization or pruning. def get_equivalent_kernel_bias(self):#将identity和1*1,3*3融合到一起的参数变化 kernel3x3, bias3x3 = self._fuse_bn_tensor(self.rbr_dense) kernel1x1, bias1x1 = self._fuse_bn_tensor(self.rbr_1x1) kernelid, biasid = self._fuse_bn_tensor(self.rbr_identity) return kernel3x3 + self._pad_1x1_to_3x3_tensor(kernel1x1) + kernelid, bias3x3 + bias1x1 + biasid def _pad_1x1_to_3x3_tensor(self, kernel1x1): if kernel1x1 is None: return 0 else: return torch.nn.functional.pad(kernel1x1, [1,1,1,1]) def _fuse_bn_tensor(self, branch): if branch is None: return 0, 0 if isinstance(branch, nn.Sequential): kernel = branch.conv.weight running_mean = branch.bn.running_mean running_var = branch.bn.running_var gamma = branch.bn.weight beta = branch.bn.bias eps = branch.bn.eps else: assert isinstance(branch, nn.BatchNorm2d) if not hasattr(self, 'id_tensor'): input_dim = self.in_channels // self.groups kernel_value = np.zeros((self.in_channels, input_dim, 3, 3), dtype=np.float32) for i in range(self.in_channels): kernel_value[i, i % input_dim, 1, 1] = 1 self.id_tensor = torch.from_numpy(kernel_value).to(branch.weight.device) kernel = self.id_tensor running_mean = branch.running_mean running_var = branch.running_var gamma = branch.weight beta = branch.bias eps = branch.eps std = (running_var + eps).sqrt() t = (gamma / std).reshape(-1, 1, 1, 1) return kernel * t, beta - running_mean * gamma / std def switch_to_deploy(self):#如何将多分支结构转换为单分支结构 if hasattr(self, 'rbr_reparam'): return kernel, bias = self.get_equivalent_kernel_bias() self.rbr_reparam = nn.Conv2d(in_channels=self.rbr_dense.conv.in_channels, out_channels=self.rbr_dense.conv.out_channels, kernel_size=self.rbr_dense.conv.kernel_size, stride=self.rbr_dense.conv.stride, padding=self.rbr_dense.conv.padding, dilation=self.rbr_dense.conv.dilation, groups=self.rbr_dense.conv.groups, bias=True) self.rbr_reparam.weight.data = kernel self.rbr_reparam.bias.data = bias for para in self.parameters():#消除梯度更新 para.detach_() self.__delattr__('rbr_dense')#删掉没用的分支 self.__delattr__('rbr_1x1') if hasattr(self, 'rbr_identity'): self.__delattr__('rbr_identity') if hasattr(self, 'id_tensor'): self.__delattr__('id_tensor') self.deploy = True class RepVGG(nn.Module): def __init__(self, num_blocks, num_classes, width_multiplier=None, override_groups_map=None, deploy=False, use_se=False): super(RepVGG, self).__init__() assert len(width_multiplier) == 4 self.deploy = deploy self.override_groups_map = override_groups_map or dict() self.use_se = use_se assert 0 not in self.override_groups_map self.in_planes = min(64, int(64 * width_multiplier[0])) self.stage0 = RepVGGBlock(in_channels=3, out_channels=self.in_planes, kernel_size=3, stride=2, padding=1, deploy=self.deploy, use_se=self.use_se) self.cur_layer_idx = 1 self.stage1 = self._make_stage(int(64 * width_multiplier[0]), num_blocks[0], stride=2) self.stage2 = self._make_stage(int(128 * width_multiplier[1]), num_blocks[1], stride=2) self.stage3 = self._make_stage(int(256 * width_multiplier[2]), num_blocks[2], stride=2) self.stage4 = self._make_stage(int(512 * width_multiplier[3]), num_blocks[3], stride=2) self.gap = nn.AdaptiveAvgPool2d(out
评论
    相关推荐
    • ZCls:对象分类代码库
      «ZCls»是一个分类模型基准代码库 内容列表 背景 为了进一步提高算法性能,通常需要对现有模型进行改进,至少要就涉及到代码转换。创建本仓库,并作为新模型/优化方法的CodeBase ,可以也记录下自定义模型与已有...
    • MutualGuide:[ACCV2020]“本地化进行分类分类以进行本地化
      本地化分类和本地化分类:对象检测中的相互指导 张衡,Elisa FROMONT,塞巴斯蒂安·莱菲弗,布鲁诺·阿维尼翁 规划 添加主干。 添加主干。 添加主干。 添加脖子。 添加TensorRT转换代码以加快推理速度。 添加...
    • libiconv-1.1.tar.gz
      字符集转换程序
    • VisualC++.rar
      vc++数字图像处理 ,是一本很不错的介绍数字图像方面的书籍,这里有本书的全部源码
    • sharewareluncher.zip
      执行和去除共享软件日期限制的程序
    • opctkit.rar
      opc client 的开发工具
    • 一个XML留言本源代码(C#).rar
      用C#编写的XML源程序
    • VB6MultiThread.rar
      VB多线程源代码
    • ScrollBitmap_demo.zip
      Displaying a large bitmap file on a dialog box, in its original size, is quite difficult in the VC++ environment. However, it is possible to display a large bitmap to a predefined area of the dialog by using the StretchBlt( ) function.The major disadvantage of this is that the clarity of the image will be lost. Check out this article for displaying large bitmaps into the desired area of your dialog box in its original size with a scrolling technique used to show the entire bitmap. 滚动显示位图 在VC++环境下,在一个对话框中显示一个原始尺寸的大小的位图文件相当是困难的。然而,通过使用 StretchBlt()函数一个给定的区域显示一个大的位图是可能的。主要的缺点是图像将会失真。看了这篇通过卷动技术显示整个位图技术的文章,你将能够以它的原始尺寸在给定对话框的区域内显示一个大位图。 来源: http://www.codeguru.com/bitmap/ScrollBitmap.html