神经网络基础——激活函数的选择、参数初始化

一、神经网络

1、神经网络

        人工神经网络(Artificial Neural Network,即ANN也简称为神经网络(NN是一种模仿生物神经网络结构 和功能的计算模型。

 2、基本部分

        输入层:输入 x

        输出层:输出 y

        隐藏层:输入与输出之间所有层

3、特点

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

        第 N 层的每个神经元和第 N-1层 的所有神经元相连(full connected),即全连接神经网络

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

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

二、激活函数

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

        1、sigmoid 激活函数

            公式:

             求导公式:

             绘制函数图像:

import torch
import matplotlib.pyplot as plt

# 函数图像
x = torch.linspace(-20,20,1000)
# 输入值x 通过 sigmoid函数 转换成 激活值y
y = torch.sigmoid(x)

# 创建画布、坐标轴
plt.plot(x,y)
plt.grid()
plt.show()

# 导数图像
x = torch.linspace(-20,20,1000,requires_grad=True)
# 自动微分
torch.sigmoid(x).sum().backward()

plt.plot(x.detach(),x.grad)
plt.grid()
plt.show()

        sigmoid 函数可以将任意的输入映射到 (0, 1) 之间,当输入的值大致在 <-6 或者 >6 时,意味着输入任何值 得到的激活值都是差不多的,这样会丢失部分信息。比如:输入 100 和输出 10000 经过 sigmoid 的激活值几乎都是等于 1 的,但是输入的数据之间相差 100 倍的信息就丢失了。

        对于 sigmoid 函数而言,输入值在 [-6, 6] 之间输出值才会有明显差异,输入值在 [-3, 3] 之间才会有比较好的效果

        通过上述导数图像,我们发现 导数 数值范围是 (0, 0.25) ,当输入 <-6 或者 >6 时, sigmoid 激活函数图像的 导数接近为 0 ,此时网络参数 更新 极其 缓慢 ,或者 无法更新
        一般来说, sigmoid 网络在 5 层之内  就会产生 梯度消失 现象。而且,该激活函数并不是以 0 为中心的,所以在实践中这种激活函数使用的很少。sigmoid 函数一般只用于 二分类 输出层
        2、tanh 激活函数

                公式:

                求导公式:

                函数图像:

        Tanh 函数将 输入 映射到 (-1, 1) 之间 ,图像以 0 为中心,在 0 点对称,当输入 大概<-3 或者
>3 时将被映射为 -1 或者 1。 导数值 范围 (0, 1) ,当输入的值大概 <-3 或者 > 3 时,其导数
近似 0。
        与 Sigmoid 相比,它是 以 0 为中心 的,且梯度相对于sigmoid大,使得其收敛速度要比
Sigmoid ,减少迭代次数。然而,从图中可以看出,Tanh 两侧的导数也为 0,同样会造成
梯度消失。
        若使用时可在 隐藏层 使用 tanh函数 ,在 输出层使用sigmoid函数
        3、ReLU 激活函数

                公式:                f (x) = max (0,x)

                求导公式:         f '(x) = 0 或 1

                函数图像:

        ReLU 激活函数将小于 0 的值映射为 0,而大于 0 的值则保持不变,它更加重视正信号,而忽略负信号,这种激活函数运算更为简单,能够提高模型的训练效率

        当x<0时,ReLU导数为0,而当x>0时,则不存在饱和问题。所以,ReLU 能够在x>0时保持梯度不衰减,从而缓解梯度消失问题。然而,随着训练的推进,部分输入会落入小于0区域,导致对应权重无法更新。这种现象被称为“神经元死亡

        ReLU是目前最常用的激活函数。与sigmoid相比,ReLU的优势是:采用sigmoid函数,计算量大(指数运算),反向传播求误差梯度时,计算量相对大,而采用Relu激活函数,整个过程的计算量节省很多。 sigmoid函数反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练。 Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。

        4、SoftMax 激活函数

        softmax用于多分类过程中,它是二分类函数sigmoid在多分类上的推广,目的是将多分类的结果以概率的形式展现出来,公式如下:

       Softmax 就是将网络输出的 logits 通过 softmax 函数,就映射成为(0,1)的值,而这些值的累和 为1(满足概率的性质),那么我们将它理解成概率,选取概率最大(也就是值对应最大的)节,作为我们的预测目标类别

scores = torch.tensor([0.2, 0.02, 0.15, 0.15, 1.3, 0.5, 0.06, 1.1, 0.05, 3.75])
probabilities = torch.softmax(scores,dim=0)
print(probabilities)

输出结果: 

        5、其他激活函数

        6、选择方法

        对于 隐藏层

        1. 优先选择 ReLU激活函数

        2. 如果ReLu效果不好,那么尝试其他激活,如Leaky ReLu等。

        3. 如果使用了ReLU, 需要注意Dead ReLU问题, 避免出现大的梯度从而导致过多的神经元死亡。

        4. 少用sigmoid激活函数,可以尝试使用tanh激活函数

        对于 输出层

        1. 二分类 问题选择 sigmoid激活函数
        2. 多分类 问题选择 softmax激活函数
        3. 回归 问题选择 identity 激活函数

三、参数初始化

        1、均匀分布 初始化

        权重参数初始化从区间均匀随机取值,即在(\frac{-1}{\sqrt{d}}\frac{1}{\sqrt{d}})均匀分布中生成当前神经元的权重(d为每个神经元的输入数量)

import torch
import torch.nn.functional as F
import torch.nn as nn
# 均匀分布 随机初始化
def test01():
    linear = nn.Linear(5, 3)
    # 从 0 ~ 1 均匀分布产生参数
    nn.init.uniform_(linear.weight)
    print(linear.weight.data)
        2、正态分布 初始化

       随机初始化从均值为0标准差为1的高斯分布中取样,使用一些很小的值对参数W进行初始化

# 正态分布随机初始化
def test05():
    linear = nn.Linear(5, 3)
    nn.init.normal_(linear.weight, mean=0, std=1)
    print(linear.weight.data)
        3、全0 初始化

        将神经网络中的所有权重参数初始化为 0

# 全0初始化
def test03():
    linear = nn.Linear(5, 3)
    nn.init.zeros_(linear.weight)
    print(linear.weight.data)
        4、全1 初始化

        将神经网络中的所有权重参数初始化为 1

# 全1初始化
def test04():
    linear = nn.Linear(5, 3)
    nn.init.ones_(linear.weight)
    print(linear.weight.data)
        5、固定值初始化

        将神经网络中的所有权重参数初始化为 某个固定值

# 固定初始化
def test02():
    linear = nn.Linear(5, 3)
    nn.init.constant_(linear.weight, 5)
    print(linear.weight.data)
        6、kaiming 初始化

        正态化HE初始化:均值为0,stddev(方差)=  \sqrt{\frac{2}{input}}

        均匀分布HE初始化:从 [ -limit,limit ] 的均匀分布中抽取样本,limit =  \sqrt{\frac{6}{input}}

        input:输入神经元的个数

# kaiming 初始化
def test06():
    # kaiming 正态分布初始化
    linear = nn.Linear(5, 3)
    nn.init.kaiming_normal_(linear.weight)
    print(linear.weight.data)
    # kaiming 均匀分布初始化
    linear = nn.Linear(5, 3)
    nn.init.kaiming_uniform_(linear.weight)
    print(linear.weight.data)
        7、xavier 初始化

        正态化Xavier初始化:均值为0,stddev(方差)=  \sqrt{\frac{2}{input+output}}

        均匀分布Xavier初始化:从 [ -limit,limit ] 的均匀分布中抽取样本,limit =  \sqrt{\frac{6}{input+output}}

        input:输入神经元的个数,output:输出神经元的个数

# xavier 初始化
def test07():
    # xavier 正态分布初始化
    linear = nn.Linear(5, 3)
    nn.init.xavier_normal_(linear.weight)
    print(linear.weight.data)
    # xavier 均匀分布初始化
    linear = nn.Linear(5, 3)
    nn.init.xavier_uniform_(linear.weight)
    print(linear.weight.data)
一般我们在使用 PyTorch 构建网络模型时,每个网络层的参数都有默认的初始化方法,优先选择
kaming 的初始化、xavier 初始化方式。

相关推荐

  1. 激活函数神经网络生命之花

    2024-02-21 12:16:02       31 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-21 12:16:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-21 12:16:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-21 12:16:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-21 12:16:02       18 阅读

热门阅读

  1. git 创建远程分支和本地分支,并将分支关联

    2024-02-21 12:16:02       28 阅读
  2. 正则表达式的一些高级用法

    2024-02-21 12:16:02       31 阅读
  3. 基于单片机的智能交通控制系统研究

    2024-02-21 12:16:02       28 阅读
  4. ASP.NET Core 6 (.NET 6) 快速开发简单登陆和登出功能

    2024-02-21 12:16:02       22 阅读
  5. ARP攻击原理

    2024-02-21 12:16:02       27 阅读
  6. MYSQL 根据条件假删除多余的重复数据

    2024-02-21 12:16:02       27 阅读
  7. 面试浏览器框架八股文十问十答第三期

    2024-02-21 12:16:02       32 阅读
  8. package.json文件详解

    2024-02-21 12:16:02       35 阅读
  9. 纯css实现文字左右循环滚动播放效果

    2024-02-21 12:16:02       28 阅读
  10. 有哪几种行为会导致服务器被入侵

    2024-02-21 12:16:02       28 阅读