当前位置: 首页 > news >正文

神经网络基础[ANN网络的搭建]

神经网络

人工神经网络( Artificial Neural Network, 简写为ANN)也简称为神经网络(NN),是一种模仿生物神经网络结构和功能的计算模型。各个神经元传递复杂的电信号,树突接收到输入信号,然后对信号进行处理,通过轴突输出信号。下图是生物神经元示意图:

  1. 是一种计算模型
  2. 简称:NN

请添加图片描述

当电信号通过树突进入到细胞核时,会逐渐聚集电荷。达到一定的电位后,细胞就会被激活,通过轴突发出电信号。

NN

神经网络中信息只向一个方向移动,即从输入节点向前移动,通过隐藏节点,再向输出节点移动。其中的基本部分是:

1.输入层: 即输入 x 的那一层

2.输出层: 即输出 y 的那一层

3.隐藏层: 输入层和输出层之间都是隐藏层[作用:加权求和+激活]

特点

•同一层的神经元之间没有连接。

•第 N 层的每个神经元和第 N-1层 的所有神经元相连(这就是full connected的含义),这就是全连接神经网络。

•第N-1层神经元的输出就是第N层神经元的输入。

•每个连接都有一个权重值(w系数和b系数)。

请添加图片描述

激活函数

激活函数的作用

激活函数用于对 每层输出数据进行变换, 进而为整个网络注入了非线性因素。此时, 神经网络就可以拟合各种曲线。

在这里插入图片描述

如果不使用激活函数,无论网络搭建得再复杂也是线性模型

常用的激活函数
  • sigmoid

    常用于解决二分类问题

f ( x ) = 1 1 + e − x f(x) = \frac{1} {1 + e^{-x}} f(x)=1+ex1

导函数公式
f ′ ( x ) = f ( x ) ( 1 − f ( x ) ) f'(x) = f(x)(1 - f(x)) f(x)=f(x)(1f(x))

图像

在这里插入图片描述

f(x):定义域: (-∞,+∞)值域:(0,1)
有效区间:[-6,6]
f'(x)值域:(0,0.25]
不足:计算量大

一般来说, sigmoid 网络在5 层之内就会产生梯度消失现象。而且,该激活函数并不是以 0 为中心的,所以在实践中这种激活函数使用的很少

  • tanh

    类似sigmoid

    f ( x ) = e x − e − x e x + e − x = 1 − e − 2 x 1 + e − 2 x f(x) =\frac{e^x - e^{-x}}{e^x + e^{-x}}=\frac{1 - e^{-2x}}{1 + e^{-2x}} f(x)=ex+exexex=1+e2x1e2x

    f ′ ( x ) = 1 − f 2 ( x ) f'(x) = 1 - f^2(x) f(x)=1f2(x)

    f(x):值域:(-1,1)有效区间:[-3,3]
    特点:- 收敛速度比sigmoid快- 存在梯度消失问题
    

    图像


    在这里插入图片描述

  • softmax

    softmax用于多分类过程中,它是二分类函数sigmoid在多分类上的推广,目的是将多分类的结果以概率的形式展现出来。计算方法如下所示
    s o f t m a x ( z i ) = e z i Σ j e z j softmax(z_i) = \frac{e ^ {z_i}}{Σ_j e ^{z_j}} softmax(zi)=Σjezjezi

  • ReLu

    f ( x ) = m a x ( 0 , x ) f(x) = max(0,x) f(x)=max(0,x)

    f ′ ( x ) = { 0 , x < 0 1 , x ≥ 0 f'(x) = \begin{cases}0 & {,x < 0}\\1 & ,x \geq 0 \end{cases} f(x)={01,x<0,x0

    优点:- 计算量小,是最常用的一种激活函数- Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。
    缺点:- 存在 '神经元死亡' 问题
    

随着训练的推进,部分输入会落入小于0区域,导致对应权重无法更新。这种现象被称为 神经元死亡。

图像

在这里插入图片描述

在这里插入图片描述

代码
def show(activation, *args):""":param activation: (激活函数:接收其内存地址) torch.sigmoid | torch.tanh | torch.relu:return: None"""_, axes = plt.subplots(1, 2)x = torch.linspace(-20, 20, 1000)y = activation(x)axes[0].plot(x, y)axes[0].grid()axes[0].set_title(str(activation).split(' ')[2])x = torch.linspace(-20, 20, 1000, requires_grad=True)print(activation(x, *args).sum())activation(x, *args).sum().backward()axes[1].plot(x.detach(), x.grad)axes[1].grid()axes[1].set_title(f"{str(activation).split(' ')[2]}'s Derived")plt.show()def softmax_show():""":return:"""score = torch.tensor([0.2, 0.02, 0.15, 0.15, 0.15, 0.15, 1, 3.14])probabilities = torch.softmax(score, dim=0)print(probabilities)print(sum(probabilities))def elu():elu = torch.nn.ELU(alpha=1)_, axes = plt.subplots(1, 2)x = torch.linspace(-40, 40, 1000)y = elu(x)axes[0].plot(x, y)axes[0].grid()axes[0].set_title('elu')x = torch.linspace(-40, 40, 1000, requires_grad=True)print(elu(x).sum())elu(x).sum().backward()axes[1].plot(x.detach(), x.grad)axes[1].grid()axes[1].set_title(f"elu's Derived")plt.show()if __name__ == '__main__':# show(torch.sigmoid)# show(torch.tanh)# show(torch.relu)# show(torch.celu, 0.001)softmax_show()

参数的初始化

在神经网络中,参数初始化(Parameter Initialization)指的是在训练开始之前设置网络权重(weights)和偏置(biases)的初始值。合适的初始化策略对于神经网络的训练过程至关重要。好的初始化方法能够加速收敛,提高模型的性能,避免一些常见的问题,如梯度消失或梯度爆炸。

参数初始化的作用

  1. 加速收敛
    • 一个好的初始化策略能帮助模型更快地收敛。合适的初始化会避免在训练初期陷入困境,使得梯度在反向传播时不会因为初始值太小或太大而导致学习困难。
  2. 避免梯度消失和梯度爆炸
    • 如果初始化过小或过大,可能导致梯度在反向传播时变得非常小(梯度消失)或非常大(梯度爆炸),从而影响训练的稳定性。
    • 例如,深度网络中的梯度消失问题会导致模型训练速度极慢,甚至无法更新参数;而梯度爆炸则可能导致训练过程中权重更新过快,导致权重的值极大,进而造成不稳定的训练。
  3. 确保每个神经元有不同的学习路径
    • 如果所有神经元的初始权重相同,那么每个神经元将执行相同的操作,导致它们在训练过程中学习到相同的特征,这会大大降低模型的表现。
    • 通过合理的初始化方法,确保每个神经元从不同的初始值开始学习,使得它们能学习到不同的特征,提高模型的多样性和表现。
  4. 避免对称性破坏
    • 如果所有权重被初始化为相同的值,所有神经元的输出也将相同,导致网络在训练过程中无法破除对称性,使得每个神经元的更新是一样的,无法发挥出网络的深度特性。合理初始化权重能够避免这一问题。
基本初始化
示例
import torch
import torch.nn as nn# 1.均匀分布初始化
def test01():linear = nn.Linear(5, 3)# 从 0-1的均匀分布产生参数nn.init.uniform_(linear.weight)print(linear.weight.data)# 2.固定初始化
def test02():linear = nn.Linear(5, 3)nn.init.constant_(linear.weight, 5)print(linear.weight.data)# 3. 全0初始化
def test03():linear = nn.Linear(5, 3)nn.init.zeros_(linear.weight)print(linear.weight.data)# 4. 全1初始化
def test04():linear = nn.Linear(5, 3)nn.init.ones_(linear.weight)print(linear.weight.data)# 5.正态分布随机初始化
def test05():linear = nn.Linear(5, 3)nn.init.normal_(linear.weight, mean=0.0, std=1.0)print(linear.weight.data)
常用初始化
  • kaiming 初始化,也叫做 HE 初始化
    1.正态化的he初始化
    stddev = sqrt(2 / fan_in)
    2.均匀分布的he初始化
    它从 [-limit,limit] 中的均匀分布中抽取样本, limit是 sqrt(6 / fan_in)

    fan_in 输入神经元的个数

  • xavier 初始化,也叫做 Glorot初始化
    1.正态化的Xavier初始化
    stddev = sqrt(2 / (fan_in + fan_out))
    2.均匀分布的Xavier初始化
    从[-limit,limit] 中的均匀分布中抽取样本, limit 是 sqrt(6 / (fan_in + fan_out))

    fan_in 是输入神经元的个数, fan_out 是输出的神经元个数

代码:
# 6.kaiming初始化
def test06():linear = nn.Linear(5, 3)nn.init.kaiming_normal_(linear.weight)print(f'kaiming标准正态初始化:{linear.weight.data}')nn.init.uniform_(linear.weight)print(f'kaiming均匀分布初始化:{linear.weight.data}')# 7.xavier初始化
def test07():linear = nn.Linear(5, 3)nn.init.xavier_normal_(linear.weight)print(f'xavier标准正态初始化:{linear.weight.data}')nn.init.xavier_uniform_(linear.weight)print(f'xavier均匀分布初始化:{linear.weight.data}')

神经网络的搭建

在PyTorch中定义深度神经网络其实就是层堆叠的过程

1.自定义类,继承自nn.Module
2.实现两个方法:__init__方法:定义网络中的层结构,主要是全连接层,并进行初始化  - 作用:[定义网络层]forward方法:在实例化模型的时候,底层会自动调用该函数。该函数中可以定义学习率,为初始化定义的layer传入数据等。 - 作用:[串联网络层]

示例:搭建如图所示的神经网络

在这里插入图片描述

编码设计如下:

1.第1个隐藏层:权重初始化采用标准化的xavier初始化 激活函数使用sigmoid
2.第2个隐藏层:权重初始化采用标准化的He初始化 激活函数采用relu
3.out输出层线性层:假若二分类,采用softmax做数据归一化
思路说明:

在这里插入图片描述

代码实现:
import torch
import torch.nn as nn
from torchsummary import summary  # 计算参数模型# 1.创建神经网络模块
# 1.1 一个继承
class Model(nn.Module):# 1.2 两个方法 __init__ forwarddef __init__(self):super(Model, self).__init__()  # 调用父类的初始化属性方法# 创建第一个隐藏层self.linear1 = nn.Linear(3, 3)nn.init.xavier_normal_(self.linear1.weight)# 创建第二个隐藏层self.linear2 = nn.Linear(3, 2)# kaiming初始化nn.init.kaiming_normal_(self.linear2.weight)# 创建输出层模型self.out = nn.Linear(2, 2)def forward(self, x):# 数据经过第一个线性层x = self.linear1(x)# 使用sigmoid激活x = torch.sigmoid(x)# 数据经过第二个线性层x = self.linear2(x)# 使用relu激活x = torch.relu(x)# 数据经过输出层x = self.out(x)# 使用softmax激活# dim = -1: 每一个维度的行数据 相加为1x = torch.softmax(x, dim=-1)return x
使用网络
model = Model()# 随机产生一组数据
data = torch.randn(5, 3)
print(f'data.shape->{data.shape}')# 前向传播
output = model(data)
print(f'output.shape->:{output.shape}')# 计算模型参数
summary(model, input_size=(3,), batch_size=5)# 查看模型参数
print('=' * 20 + '查看模型参数' + '=' * 20)
for name, parameter in model.named_parameters():print(name, parameter)

神经网络总结

1.优点
  • 精度高,性能优于其他的机器学习算法,甚至在某些领域超过了人类

  • 可以近似任意的非线性函数

  • 近年来在学界和业界受到了热捧,有大量的框架和库可供调

2.缺点
  • 黑箱,很难解释模型是怎么工作的

  • 训练时间长,需要大量的计算资源

  • 网络结构复杂,需要调整超参数

  • 部分数据集上表现不佳,容易发生过拟合

相关文章:

  • Flutter 在全新 Platform 和 UI 线程合并后,出现了什么大坑和变化?
  • 【MinerU】:一款将PDF转化为机器可读格式的工具——RAG加强(Docker版本)
  • 2025年Google Play审核策略全面解析
  • 1.ArkUI Text的介绍和使用
  • 基于Keras3.x使用CNN实现简单的猫狗分类
  • PS Mac Photoshop 2025 for Mac图像处理 PS 2025安装笔记
  • Axure大屏可视化模板:多领域数据决策的新引擎
  • 2025年3月电子学会青少年机器人技术(四级)等级考试试卷-实际操作
  • 关于按键映射软件的探索(其一)
  • 详解springcloudalibaba采用prometheus+grafana实现服务监控
  • 2025.04.24【3D】3D绘图入门指南
  • 【高并发】 MySQL锁优化策略
  • 容器修仙传 我的灵根是Pod 第9章 时空禁术(Job与CronJob)
  • k8s 1.26版部署
  • 【数据可视化-28】2017-2025 年每月产品零售价数据可视化分析
  • JavaScript 页面刷新:从传统到现代的全面解析
  • 10天学会嵌入式技术之51单片机-day-6
  • 动态渲染页面智能嗅探:机器学习判定AJAX加载触发条件
  • Spring Boot默认缓存管理
  • tzdata 安装失败的一种处理
  • 破解160年基因谜题,我国科学家补上豌豆遗传研究最后拼图
  • 中国与肯尼亚签署共同发展经济伙伴关系框架协定
  • 央行25日开展6000亿元MLF操作,期限为1年期
  • 长三角议事厅|国际产业转移对中国产业链韧性的影响与对策
  • 天问三号计划2028年前后发射实施,开放20千克质量资源
  • 出发!陈冬、陈中瑞、王杰三名航天员领命出征