Backbone 之 Inception:纵横交错 (Pytorch实现及代码解析)

import torch

from torch import nn

import torch.nn.functional as F

###定义一个包含卷积和ReLU池化的基础卷积块

class BasicConv2d(nn.Module):

def init(self, in_channels, out_channels, kernel_size, padding=0):

super(BasicConv2d, self).init()

self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, padding=padding)

def forward(self, x):

x = self.conv(x)

return F.relu(x, inplace=True)

###Inceptionv1 类,初始时需要提供各个子模块的通道数大小

class Inceptionv1(nn.Module):

def init(self, in_dim, hid_1_1, hid_2_1, hid_2_3, hid_3_1, out_3_5, out_4_1):

super(Inceptionv1, self).init()

###四个子模块各自的网络定义

self.branch1x1 = BasicConv2d(in_dim, hid_1_1, 1)

self.branch3x3 = nn.Sequential(

BasicConv2d(in_dim, hid_2_1, 1),

BasicConv2d(hid_2_1, hid_2_3, 3, padding=1)

)

self.branch5x5 = nn.Sequential(

BasicConv2d(in_dim, hid_3_1, 1),

BasicConv2d(hid_3_1, out_3_5, 5, padding=2)

)

self.branch_pool = nn.Sequential(

nn.MaxPool2d(3, stride=1, padding=1),

BasicConv2d(in_dim, out_4_1, 1)

)

###定义前向传播

def forward(self, x):

b1 = self.branch1x1(x)

b2 = self.branch3x3(x)

b3 = self.branch5x5(x)

b4 = self.branch_pool(x)

###将这四个子模块沿着通道方向进行拼接

output = torch.cat((b1, b2, b3, b4), dim=1)

return output


Inception v2特点:

  • 增加BN层

  • 利用两个3*3来代替5x5卷积,减小了参数量,也提升网络的非线性能力

Inception v2结构示意图:

img

代码如下:

import torch

from torch import nn

import torch.nn.functional as F

class BasicConv2d(nn.Module):

def init(self, in_channels, out_channels, kernel_size, padding=0):

super(BasicConv2d, self).init()

self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, padding=padding)

self.bn = nn.BatchNorm2d(out_channels, eps=0.001)

def forward(self, x):

x = self.conv(x)

x = self.bn(x)

return F.relu(x, inplace=True)

class Inceptionv2(nn.Module):

def init(self):

super(Inceptionv2, self).init()

self.branch1 = BasicConv2d(192, 96, 1, 0)

self.branch2 = nn.Sequential(

BasicConv2d(192, 48, 1, 0),

BasicConv2d(48, 64, 3, 1)

)

self.branch3 = nn.Sequential(

BasicConv2d(192, 64, 1, 0),

BasicConv2d(64, 96, 3, 1),

BasicConv2d(96, 96, 3, 1)

)

self.branch4 = nn.Sequential(

nn.AvgPool2d(3, stride=1, padding=1, count_include_pad=False),

BasicConv2d(192, 64, 1, 0)

)

def forward(self, x):

x0 = self.branch1(x)

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

总结

上述知识点,囊括了目前互联网企业的主流应用技术以及能让你成为“香饽饽”的高级架构知识,每个笔记里面几乎都带有实战内容。

很多人担心学了容易忘,这里教你一个方法,那就是重复学习。

打个比方,假如你正在学习 spring 注解,突然发现了一个注解@Aspect,不知道干什么用的,你可能会去查看源码或者通过博客学习,花了半小时终于弄懂了,下次又看到@Aspect 了,你有点郁闷了,上次好像在哪哪哪学习,你快速打开网页花了五分钟又学会了。

从半小时和五分钟的对比中可以发现多学一次就离真正掌握知识又近了一步。

人的本性就是容易遗忘,只有不断加深印象、重复学习才能真正掌握,所以很多书我都是推荐大家多看几遍。哪有那么多天才,他只是比你多看了几遍书。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

的本性就是容易遗忘,只有不断加深印象、重复学习才能真正掌握,所以很多书我都是推荐大家多看几遍。哪有那么多天才,他只是比你多看了几遍书。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-reqmdyrZ-1712838015399)]

  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是 Faster RCNN 的 PyTorch 实现代码及注释: ```python import torch import torch.nn as nn import torchvision.models as models import torchvision.ops as ops class FasterRCNN(nn.Module): def __init__(self, num_classes=21): super(FasterRCNN, self).__init__() # 加载预训练的 ResNet-50 模型 self.backbone = models.resnet50(pretrained=True) # 将 ResNet-50 模型的最后一层卷积层替换为3x3卷积层 self.backbone.layer4[2] = nn.Conv2d(2048, 512, kernel_size=3, stride=1, padding=1) # RPN网络 self.rpn_anchor_generator = ops.MultiScaleAnchorGenerator(sizes=((32, 64, 128, 256, 512),), aspect_ratios=((0.5, 1.0, 2.0),)) self.rpn_head = ops.RPNHead(in_channels=512, feat_channels=512, anchor_generator=self.rpn_anchor_generator) self.rpn_box_coder = ops.BoxCoder(weights=(1.0, 1.0, 1.0, 1.0)) # Fast R-CNN网络 self.roi_align = ops.RoIAlign(output_size=(7, 7), spatial_scale=1.0 / 16.0, sampling_ratio=-1) self.head = nn.Sequential( nn.Linear(7 * 7 * 512, 4096), nn.ReLU(inplace=True), nn.Linear(4096, 4096), nn.ReLU(inplace=True)) self.cls_score = nn.Linear(4096, num_classes) self.bbox_pred = nn.Linear(4096, num_classes * 4) def forward(self, x, gt_boxes=None, gt_labels=None): features = self.backbone(x) rpn_cls_scores, rpn_bbox_preds = self.rpn_head(features) if self.training: gt_boxes = gt_boxes.float() gt_labels = gt_labels.long() rpn_targets = ops.RPNTargets(self.rpn_anchor_generator, gt_boxes, gt_labels, features.shape[2:]) rpn_cls_loss, rpn_bbox_loss = ops.rpn_loss(rpn_cls_scores, rpn_bbox_preds, rpn_targets) rpn_loss = rpn_cls_loss + rpn_bbox_loss rpn_rois = ops.generate_proposals(rpn_cls_scores, rpn_bbox_preds, self.rpn_anchor_generator) rois, roi_indices = ops.box_roi_pool(features, rpn_rois, output_size=(7, 7), spatial_scale=1.0 / 16.0) cls_score, bbox_pred = self.head(rois.view(rois.size(0), -1)), self.bbox_pred(rois.view(rois.size(0), -1)) cls_score, bbox_pred = cls_score.mean(0, keepdim=True), bbox_pred.mean(0, keepdim=True) cls_loss, bbox_loss = ops.fast_rcnn_loss(cls_score, bbox_pred, roi_indices, gt_boxes, gt_labels) fast_rcnn_loss = cls_loss + bbox_loss return rpn_loss, fast_rcnn_loss else: rpn_rois = ops.generate_proposals(rpn_cls_scores, rpn_bbox_preds, self.rpn_anchor_generator) rois, roi_indices = ops.box_roi_pool(features, rpn_rois, output_size=(7, 7), spatial_scale=1.0 / 16.0) cls_score, bbox_pred = self.head(rois.view(rois.size(0), -1)), self.bbox_pred(rois.view(rois.size(0), -1)) cls_score, bbox_pred = cls_score.mean(0, keepdim=True), bbox_pred.mean(0, keepdim=True) return cls_score, bbox_pred ``` 这是一个比较基础的 Faster RCNN 实现,使用了预训练的 ResNet-50 模型作为特征提取器,然后通过 RPN 网络生成候选框,最后通过 Fast R-CNN 网络对候选框进行分类和回归。 在 `__init__` 函数中,我们首先加载预训练的 ResNet-50 模型,并将其最后一层卷积层替换为3x3卷积层。然后定义了 RPN 网络和 Fast R-CNN 网络。在 RPN 网络中,我们使用了 `MultiScaleAnchorGenerator` 作为 anchor 生成器,`RPNHead` 作为 RPN 网络的头部,`BoxCoder` 用来对 RPN 网络生成的 bbox 进行编码。在 Fast R-CNN 网络中,我们使用了 `RoIAlign` 作为 RoI pooling 层,`Sequential` 定义了 Fast R-CNN 网络的全连接层,最后使用 `Linear` 分别对分类和回归结果进行输出。 在 `forward` 函数中,我们首先将输入的图像通过 ResNet-50 模型得到特征,然后通过 RPN 网络生成候选框。如果是训练模式,我们需要计算 RPN 网络的 loss 和 Fast R-CNN 网络的 loss,然后返回总的 loss。如果是推理模式,我们只需要将候选框输入 Fast R-CNN 网络,然后返回分类和回归结果。在计算 loss 和输出结果时,我们都是先使用 `generate_proposals` 对 RPN 网络生成的 bbox 进行进一步筛选,然后使用 `box_roi_pool` 对候选框进行 RoI pooling,最后将 RoI pooling 的结果输入 Fast R-CNN 网络。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值