YOLOv5改进 | Neck篇 | Slim-Neck替换特征融合层实现超级涨点 (又轻量又超级涨点)

news2024/9/20 6:16:15

一、本文介绍

本文给大家带来的改进机制是Slim-neck提出的Neck部分Slim-neck是一种设计用于优化卷积神经网络中neck部分的结构。在我们YOLOv5中,neck是连接主干网络(backbone)和头部网络(head)的部分,负责特征融合和处理,以便提高检测的准确性和效率。亲测在小目标检测和大尺度目标检测的数据集上都有大幅度的涨点效果(mAP直接涨了大概有0.04左右,值得一提的是这个Slim-neck还可以减少GFLOPs,非常适合轻量化的读者)。

推荐指数:⭐⭐⭐⭐⭐

涨点效果:⭐⭐⭐⭐⭐

 专栏回顾:YOLOv5改进专栏——持续复现各种顶会内容——内含100+创新

训练结果对比图->  

目录

一、本文介绍

二、Slim-neck原理

2.1 Slim-neck的基本原理

2.2 GSConv的引入

2.3 模块元素

2.4 灵活性

三、 Slim-neck的完整代码

四、手把手教你添加Slim-neck模块

4.1 Slim-neck的添加教程

4.1.1 修改一

​4.1.2 修改二

4.1.3 修改三 

4.1.4 修改四

4.2 Slim-neck的yaml文件

4.2.1 Slim-neck文件一(实验版本)

4.2.2 Slim-neck的yaml文件二 

4.3 Slim-neck运行成功截图

五、本文总结


二、Slim-neck原理

论文地址:官方论文地址

代码地址:官方代码地址


2.1 Slim-neck的基本原理

Slim-neck是一种设计用于优化卷积神经网络(CNN)中“neck”部分的结构。在目标检测器中,"neck"是连接CNN的主干网络(backbone)和头部网络(head)的部分,负责特征融合和处理,以便提高检测的准确性和效率。

我们可以将Slim-neck的基本原理分为以下几点:

1. GSConv的引入:GSConv是为了在卷积神经网络(CNN)中加快图像的预测计算。在传统的CNN中,空间信息逐渐转换成通道信息,而这一过程在每一次特征图空间压缩和通道扩张时都会导致语义信息的部分丢失。GSConv旨在在保持较低时间复杂度的同时,尽可能地保留通道之间的隐藏连接。

2. 模块元素:GSConv之后,研究者继续引入GS瓶颈(GS bottleneck)和跨阶段部分网络(GSCSP)模块VoV-GSCSP,这些模块设计用于进一步提升性能。在实际应用中,更简单的结构模块由于更易于硬件实现,更有可能被采用。

3. 灵活性:论文提出了需要灵活使用GSConv、GS瓶颈和VoV-GSCSP这四个模块。可以像搭乐高一样构建Slim-neck层。

下面我为大家展示应用于YOLOv5模型的Slim-neck架构。这种架构使用了GSConvVoV-GSCSP模块,以构建一个高效的神经网络“颈部”。在这个架构中,不同尺度的特征图(P3, P4, P5)首先通过GSConv模块处理,然后通过上采样(upsample)和拼接(Concat)操作与其他尺度的特征图结合。这样处理后的特征图再次通过GSConv模块,最后使用VoV-GSCSP模块来进一步提取和融合特征,以准备最终的检测头(head-1, head-2, head-3)进行目标检测。

通过这种模块化和分层的方法,Slim-neck架构能够在保持高准确度的同时减少计算复杂性和推理时间,这对于在自动驾驶车辆等计算资源受限的环境中的应用尤其重要。


2.2 GSConv的引入

GSConv的引入是为了解决在卷积神经网络(CNN)中预测计算的速度问题。在CNN的骨干网络(backbone)中,输入图像几乎总是经历一个类似的转换过程:空间信息逐步向通道传递。每一次特征图的空间(宽度和高度)压缩和通道扩张都会导致语义信息的部分丢失。通道密集型的卷积计算(SC)最大限度地保留了每个通道之间的隐含连接,而通道稀疏的卷积(DSC)则完全切断了这些连接。GSConv尽可能地保持这些连接,并且具有更低的时间复杂度。

上面提到的时间复杂度通常由浮点运算(FLOPs)来定义。因此,SC、DSC和GSConv的时间复杂度分别为:

- SC:O(W \cdot H \cdot K_1 \cdot K_2 \cdot C_1 \cdot C_2)
- DSC:O(W \cdot H \cdot K_1 \cdot K_2 \cdot C_1)
- GSConv:O([W \cdot H \cdot K_1 \cdot K_2 \cdot C_2] / 2 \cdot (C_1 + 1))

其中W是输出特征图的宽度,H是高度,K_1 \cdot K_2是卷积核的大小,C_{1}是每个卷积核的通道数,也是输入特征图的通道数,C_{2}是输出特征图的通道数。

下图为大家展示了GSConv模块的结构

1. 卷积层(Conv):输入特征图首先通过一个卷积层,该层的输出通道数为C2/2。

2. 深度可分离卷积层(DWConv):该层标记为蓝色,表示深度可分离卷积(DSC)操作。它对输入特征图的每个通道独立进行卷积。

3. 拼接(Concat):将Conv层和DWConv层的输出进行拼接。

4. 随机排列(Shuffle):拼接后的特征图经过一个shuffle操作,以重新排列特征通道,提高特征间的信息流动。

5. 输出:最终输出的特征图有C2个通道。

我将通过下图为大家清晰展示标准卷积(SC)和深度可分离卷积(DSC)的计算过程。标准卷积是通道密集型的计算,而深度可分离卷积是通道稀疏的计算。

上图强调了在传统的标准卷积和现代轻量级深度可分离卷积之间的差异,其中后者在保持足够精确度的同时,减少了计算的复杂性,这对于计算资源受限的环境尤其有益。这种方法通常用于移动和边缘设备的神经网络架构中,以提高运行效率。 


2.3 模块元素

模块元素是构成Slim-neck架构的基础部分,设计它们的目的是为了减少计算成本,同时保持或提高模型的学习能力。模块元素可以灵活使用,像搭积木一样组合成Slim-neck层,提供了构建高效深度学习模型的灵活性和效率

1. GSConv:是一种减少计算复杂性的轻量级卷积,它的计算成本约为标准卷积(SC)的一半,但在模型的学习能力方面与SC相当。

2. GS bottleneck:基于GSConv,这是一种增强模块,用于提高特征的非线性表达和信息的复用。

3. VoV-GSCSP:利用一次性聚合方法设计的跨阶段部分网络模块,用于在不同阶段的特征图之间进行有效的信息融合。

下图显示了GS bottleneck模块VoV-GSCSP模块的结构:

(a) GS bottleneck模块,其中包含GSConv模块的一个或多个实例。 (b), (c), (d) 分别展示了不同设计方案的VoV-GSCSP模块。

GS bottleneck模块是为了进一步增强网络处理特征的能力,通过GSConv模块的堆叠来提高模型的学习能力。而VoV-GSCSP模块是利用不同的结构设计方案,以提高特征利用效率和网络性能。这些模块设计是Slim-neck理念的体现,旨在减少计算复杂性和推理时间,同时保持准确性。通过这样的模块化设计,可以根据需要灵活地构建出适合特定任务的网络架构。


2.4 灵活性

灵活性是指使用四种模块:GSConv、GS bottleneck和VoV-GSCSP,以及能够根据需要构建Slim-neck层的能力,类似于搭建乐高积木一样。这种灵活性允许研究者和工程师根据不同的需求和应用场景,调整和优化网络结构,从而实现特定目标的高效性和准确性。


三、 Slim-neck的完整代码

复制下面的代码在'ultralytics/nn/modules'目录下新建一个py文件粘贴进去,我这里的名字是Slimneck(大家注意不要带-否则会找不到文件的!!!)其它的具体使用方式看章节四。

import torch
import torch.nn as nn
import math


def autopad(k, p=None):  # kernel, padding
    # Pad to 'same'
    if p is None:
        p = k // 2 if isinstance(k, int) else [x // 2 for x in k]  # auto-pad
    return p


class Conv(nn.Module):
    # Standard convolution
    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups
        super().__init__()
        self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)
        self.bn = nn.BatchNorm2d(c2)
        self.act = nn.Mish() if act else nn.Identity()

    def forward(self, x):
        return self.act(self.bn(self.conv(x)))

    def forward_fuse(self, x):
        return self.act(self.conv(x))


class GSConv(nn.Module):
    # GSConv https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=1, s=1, g=1, act=True):
        super().__init__()
        c_ = c2 // 2
        self.cv1 = Conv(c1, c_, k, s, None, g, act)
        self.cv2 = Conv(c_, c_, 5, 1, None, c_, act)

    def forward(self, x):
        x1 = self.cv1(x)
        x2 = torch.cat((x1, self.cv2(x1)), 1)
        b, n, h, w = x2.data.size()
        b_n = b * n // 2
        y = x2.reshape(b_n, 2, h * w)
        y = y.permute(1, 0, 2)
        y = y.reshape(2, -1, n // 2, h, w)

        return torch.cat((y[0], y[1]), 1)


class GSConvns(GSConv):
    # GSConv with a normative-shuffle https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=1, s=1, g=1, act=True):
        super().__init__(c1, c2, k=1, s=1, g=1, act=True)
        c_ = c2 // 2
        self.shuf = nn.Conv2d(c_ * 2, c2, 1, 1, 0, bias=False)

    def forward(self, x):
        x1 = self.cv1(x)
        x2 = torch.cat((x1, self.cv2(x1)), 1)
        # normative-shuffle, TRT supported
        return nn.ReLU(self.shuf(x2))


class GSBottleneck(nn.Module):
    # GS Bottleneck https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=3, s=1, e=0.5):
        super().__init__()
        c_ = int(c2*e)
        # for lighting
        self.conv_lighting = nn.Sequential(
            GSConv(c1, c_, 1, 1),
            GSConv(c_, c2, 3, 1, act=False))
        self.shortcut = Conv(c1, c2, 1, 1, act=False)

    def forward(self, x):
        return self.conv_lighting(x) + self.shortcut(x)


class DWConv(Conv):
    # Depth-wise convolution class
    def __init__(self, c1, c2, k=1, s=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups
        super().__init__(c1, c2, k, s, g=math.gcd(c1, c2), act=act)


class GSBottleneckC(GSBottleneck):
    # cheap GS Bottleneck https://github.com/AlanLi1997/slim-neck-by-gsconv
    def __init__(self, c1, c2, k=3, s=1):
        super().__init__(c1, c2, k, s)
        self.shortcut = DWConv(c1, c2, k, s, act=False)


class VoVGSCSP(nn.Module):
    # VoVGSCSP module with GSBottleneck
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c1, c_, 1, 1)
        self.gsb = nn.Sequential(*(GSBottleneck(c_, c_, e=1.0) for _ in range(n)))
        self.res = Conv(c_, c_, 3, 1, act=False)
        self.cv3 = Conv(2 * c_, c2, 1)  #

    def forward(self, x):
        x1 = self.gsb(self.cv1(x))
        y = self.cv2(x)
        return self.cv3(torch.cat((y, x1), dim=1))


class VoVGSCSPC(VoVGSCSP):
    # cheap VoVGSCSP module with GSBottleneck
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
        super().__init__(c1, c2)
        c_ = int(c2 * 0.5)  # hidden channels
        self.gsb = GSBottleneckC(c_, c_, 1, 1)


四、手把手教你添加Slim-neck模块

4.1 Slim-neck的添加教程

4.1.1 修改一

我们找到如下的目录'yolov5-master/models'在这个目录下创建一整个文件目录(注意是目录,因为我这个专栏会出很多的更新,这里用一种一劳永逸的方法)文件目录起名modules,然后在下面新建一个文件,将我们的代码复制粘贴进去,下面的图片和本文的内容无关,名字随便起最好跟文章模型有关。


​4.1.2 修改二

然后新建一个__init__.py文件,然后我们在里面添加一行代码。注意标记一个'.',按照下图进行导入模块。

​​


4.1.3 修改三 

然后我们找到如下文件''models/yolo.py''在开头的地方导入我们的模块按照如下修改->

​​


4.1.4 修改四

然后我们找到parse_model方法,按照如下修改->

到此就修改完成了,复制下面的ymal文件即可运行。


4.2 Slim-neck的yaml文件

4.2.1 Slim-neck文件一(实验版本)

# YOLOv5 🚀 by Ultralytics, AGPL-3.0 license

# Parameters
nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.25  # layer channel multiple
anchors:
  - [10,13, 16,30, 33,23]  # P3/8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

# YOLOv5 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, C3, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 6, C3, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, C3, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# YOLOv5 v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, VoVGSCSP, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, VoVGSCSP, [256, False]],  # 17 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, VoVGSCSP, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, VoVGSCSP, [1024, False]],  # 23 (P5/32-large)

   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

4.2.2 Slim-neck的yaml文件二 

# YOLOv5 🚀 by Ultralytics, AGPL-3.0 license

# Parameters
nc: 80  # number of classes
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.25  # layer channel multiple
anchors:
  - [10,13, 16,30, 33,23]  # P3/8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

# YOLOv5 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, VoVGSCSP, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 6, VoVGSCSP, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, VoVGSCSP, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, VoVGSCSP, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# YOLOv5 v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, VoVGSCSP, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, VoVGSCSP, [256, False]],  # 17 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, VoVGSCSP, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, VoVGSCSP, [1024, False]],  # 23 (P5/32-large)

   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

4.3 Slim-neck运行成功截图

附上我的运行记录确保我的教程是可用的。 


五、本文总结

到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv5改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,目前本专栏免费阅读(暂时,大家尽早关注不迷路~),如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

专栏回顾:YOLOv5改进专栏——持续复现各种顶会内容——内含100+创新

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springCloud项目打包如何把jar放到指定目录下

springCloud项目打包如何把jar发放到指定目录下 maven-antrun-plugin springCloud微服务打包jar,模块过多;我的项目模块结构如下: 我把实体类相关的单独抽离一个模块在service-api下服务单独写在service某块下, 每个模块的jar都…

模拟实验中经常遇到的问题和常用技巧

简介 最近在进行新文章的数值模拟阶段。上一次已经跟读者们分享了模拟实验的大致流程,见:数值模拟流程记录和分享 。 本文是在前提下,汇总了小编在模拟实验中经常遇到的问题和常用技巧。 文章目录 简介1. 隐藏输出结果自动创建文件夹保存多…

nginx_rtmp_module 之 ngx_rtmp_live_module模块

模块作用 直播模块代码 ngx_rtmp_live_module.c,主要作用是:当客户端推流或者拉流的时候,创建的rtmp session会加入到 live 模块的存储链表中。 模块配置命令 static ngx_command_t ngx_rtmp_live_commands[] {{ ngx_string("live&…

java SSM兼职平台系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM兼职平台系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和 数据库,系统主要采用B/…

【ArkTS】样式复用

如下代码,可以发现每个元素的样式一致,这时就可以将公共样式封装起来 此时可以使用Styles修饰符将公共样式进行封装 Styles修饰符 Entry Component struct Index{build() {Column(){Text(我是Text).ComStyle()Button(我是Button).ComStyle()Image().Co…

在Node.js中MongoDB的连接查询操作

本文主要介绍在Node.js中MongoDB的连接查询操作。 目录 Node.js中MongoDB的连接查询操作使用原生的mongodb驱动程序进行连接查询操作使用Mongoose库进行连接查询操作注意项 Node.js中MongoDB的连接查询操作 在Node.js中使用MongoDB进行连接操作,可以使用原生的mong…

时序预测 | Python实现CNN电力需求预测

时序预测 | Python实现CNN电力需求预测 目录 时序预测 | Python实现CNN电力需求预测预测效果基本描述程序设计参考资料预测效果 基本描述 该数据集因其每小时的用电量数据以及 TSO 对消耗和定价的相应预测而值得注意,从而可以将预期预测与当前最先进的行业预测进行比较。使用该…

Win7系统桌面出现白色透明框的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

边缘分布函数

以二维随机变量说明。 二维随机变量的分布函数为,随机变量的分布函数为,随机变量的分布函数为。 称为二维随机变量关于的边缘分布函数。 称为二维随机变量关于的边缘分布函数。

会声会影怎么使用? 会声会影2024快速掌握入门技巧

一听说视频剪辑我们就不由得联想到电影、电视等一些高端的视频剪辑技术,大家都觉得视频剪辑是一个非常复杂而且需要很昂贵的设备才可以完成的技术活,这对很多“门外汉”来说都可望而不可及。实际上,使用会声会影剪辑视频不仅是很多人都可以操…

《Linux C编程实战》笔记:目录操作

目录的创建和删除 mkdir函数 #include <sys/stat.h> #include <sys/types.h> int mkdir(const char *pathname, mode_t mode); mkdir创建一个新的空目录。空目录中会自动创建.和..目录项。所创建的目录的存取许可权由mode (mode &~umask)指定。 新创建目录的…

MuMu模拟器12如何连接adb?

一、MuMu模拟器12端口查看 MuMu模拟器12现已支持adb同时连接多个模拟器进行调试的操作&#xff0c;可以参考以下步骤操作&#xff0c;查看MuMu模拟器12本体以及多开模拟器的adb端口&#xff1a; 单开的MUMU模拟器12可通过模拟器右上角菜单-问题诊断&#xff0c;获取ADB调试端…

医药行业的数据安全革新者:上海迅软DSE成功案例揭秘

随着网络化办公在医药企业中不断的深入应用&#xff0c;企业内部的药品保密配方、研发成果、技术资料等重要信息都散布在电脑或流转于网络之中&#xff0c;同时各种内部系统又集中存放着大量的敏感数据&#xff0c;一旦这些数据资产发生泄密&#xff0c;将对企业的持续运营造成…

消息队列有哪些应用场景?

分布式系统不同模块之间的通信&#xff0c;除了远程服务调用以外&#xff0c;消息中间件是另外一个重要的手段&#xff0c;在各种互联网系统设计中&#xff0c;消息队列有着广泛的应用。从本文开始&#xff0c;专栏进入分布式消息的模块&#xff0c;将讨论消息队列使用中的高频…

前端如何设置模板参数

1.背景&#xff1a; 最近接到一个需求&#xff0c;在一个类似chatGpt的聊天工具中&#xff0c;要在对话框中设置模板&#xff0c;后端提供了很多模板参数&#xff0c;然后要求将后端返回的特殊字符转成按钮&#xff0c;编辑完成后在相应的位置拼接成字符串。 2.效果&#xff1a…

Java 并发编程(六)-Fork/Join异步回调

一、并发编程 1、Fork/Join分支合并框架 Fork/Join它可以将一个大的任务拆分成多个子任务进行并行处理&#xff0c;最后将子任务结果合并成最后的计算结果&#xff0c;并进行输出。Fork/Join框架要完成两件事情&#xff1a; Fork&#xff1a;把一个复杂任务进行分拆&#xff0…

嵌入式系统基础

嵌入式系统学习的3条路线 路线差别 单片机入门&#xff08;HAL&#xff09; 简单、快速&#xff0c;实际上工作中涉及单片机编程时&#xff0c;也提倡使用HAL库。对于学习来说&#xff0c;HAL库封装了很多技术细节&#xff0c;对技术成长帮助不大。 比如&#xff0c;可能接触…

前后端开发鄙视链的真相,希望对从事前后端开发的小伙伴有些帮助

一、常规的工资对比 前后端的工资情况怎么样?过来人可以负责任的告诉大家:据我所知,至少在杭的网易、阿里,前端跟后端是一个批发价。

探索泰勒级数在机器学习中的作用:从函数逼近到模型优化

一、介绍 泰勒级数是数学中的一个基本概念&#xff0c;在机器学习领域有着重要的应用。本文将探讨泰勒级数的基础知识、它在机器学习中的相关性以及一些具体应用。 揭开复杂性&#xff1a;利用泰勒级数增强机器学习应用的理解和效率。 二、理解泰勒级数 在数学中&#xff0c;泰…

excel手撕神经网络(只需高中数学基础)

神经网络最基础部分是由神经元组成&#xff0c;一个神经元相当于是一个一次函数&#xff0c;yaxb 即在已知x&#xff0c;和y情况下&#xff0c;怎么使用神经网络求解a和b 如下是使用excel求解的神经网络&#xff0c;可以方便理解神经网络运行原理 excel玩具神经网络下载地址 百…