7.系统学习-神经网络基础与激活函数解析

7.系统学习-神经网络基础与激活函数解析

全连接网络

全连接网络(Fully Connected Neural Network,简称FCN)是人工神经网络的一种形式,它的特点是每一层的神经元都与下一层的每一个神经元相连接。为了更容易理解,可以把它想象成一张"网",每一个节点(神经元)都通过"线"(连接权重)与其他节点相连。

以下用一个简单的例子来通俗解释:

  1. 核心概念
    神经元:可以把神经元想象成一个"小计算器",它接收输入数据,做一些简单的运算(加权求和,然后通过激活函数处理),最后输出一个结果。
    权重:权重就像每条"线"上的开关,决定了输入的重要性。例如,如果权重大,输入的影响就更大;如果权重小,输入的影响就小。
    偏置:偏置可以理解为对结果的微调,类似于烹饪中的"调味料",让模型的计算更灵活。
    激活函数:激活函数是一个公式,用来让神经网络更有"非线性",更聪明地处理复杂问题。
  2. 结构特点
    全连接网络由多个**层(layer)**组成:
    输入层:接收原始数据,比如图像中的像素值或文字的数值表示。
    隐藏层:输入经过"计算器"和"线"传递到隐藏层,这里进行复杂的运算。
    输出层:最终的结果,比如分类问题中是预测的类别。
    全连接:每一层的每个神经元都与下一层的每个神经元连接。换句话说,它们之间没有任何遗漏,所有信息都会传递过去。
  3. 简单类比
    想象有一个班级,输入层是学生的成绩单(语文、数学、英语等),每个成绩是一个数字。
    隐藏层是老师们(比如班主任、学科组长),他们根据学生的成绩做综合分析,得出某种评估结果。
    输出层是最后的决定,比如判断这个学生是优秀、中等还是需要改进。
    权重就像老师的"侧重点",有的老师更看重数学,有的更看重语文,最终根据这些权重来综合评估。
  4. 优点
    全连接网络适用于各种各样的数据,尤其是表格型数据。
    模型结构简单,适合作为入门神经网络的学习对象。
  5. 缺点
    参数太多:每一层都与下一层完全连接,这会导致参数数量非常庞大,占用大量计算资源。
    不擅长处理复杂结构化数据,比如图片和语音,这种场景下通常用卷积神经网络(CNN)或循环神经网络(RNN)更合适。

总的来说,全连接网络是神经网络的基础,适合用来学习神经网络的核心概念,但在实际应用中,更高效的网络结构通常会对它进行优化或替代。

代码示例

一个典型的两层全连接网络结构如下:

cpp 复制代码
import torch 
import torch.nn.functional as F 
cpp 复制代码
class Net(torch.nn.Module): 
    def __init__(self, n_feature, n_hidden, n_output): 
        super(Net, self).__init__() 
        self.hidden = torch.nn.Linear(n_feature, n_hidden) 
        self.out = torch.nn.Linear(n_hidden, n_output)    
    def forward(self, x): 
        x = F.relu(self.hidden(x))   # relu为激活函数
        x = self.out(x) 
        return x 
net = Net(n_feature=2, n_hidden=10, n_output=2) 
print(net) 

在创建网络时除了前面介绍的两个全连接层外。还在第一个全连接层后添加了relu激活函数。

激活函数

激活函数(activation function)通过计算加权来确定神经元是否应该被激活, 它们将输入信号转换为输出的可微运算。 大多数激活函数都是非线性的。

为什么激活函数需要非线性函数?

  1. 假若网络中全部是线性部件,那么线性的组合还是线性,与单独一个线性分类器无异。这样就做不到用非线性来逼近任意函数。
  2. 使用非线性激活函数 ,以便使网络更加强大,增加它的能力,使它可以学习复杂的事物,复杂的表单数据,以及表示输入输出之间非线性的复杂的任意函数映射。使用非线性激活函数,能够从输入输出之间生成非线性映射。

激活函数是深度学习的基础,下面介绍一些常见的激活函数。

常见的激活函数及图像

1. sigmoid 激活函数

函数的定义为:

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

其值域为 ( 0 , 1 ) (0,1) (0,1)。

函数图像如下:

2. tanh 激活函数

函数的定义为:

f ( x ) = t a n h ( x ) = e x − e − x e x + e − x f(x) = tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} f(x)=tanh(x)=ex+e−xex−e−x

值域为 ( − 1 , 1 ) (-1, 1) (−1,1)。

函数图像如下:

3. ReLU 激活函数

函数的定义为:

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

值域为 [ 0 , + ∞ ) [0, +\infty) [0,+∞)。

函数图像如下:

4. Leak ReLU 激活函数

函数定义为:

f ( x ) = { a x , x < 0 x , x ≥ 0 f(x) = \begin{cases} ax, & x < 0 \\ x, & x \geq 0 \end{cases} f(x)={ax,x,x<0x≥0

值域为 ( − ∞ , + ∞ ) (-\infty, +\infty) (−∞,+∞)。

图像如下( a = 0.5 a = 0.5 a=0.5):

5. SoftPlus 激活函数

函数的定义为:

f ( x ) = ln ⁡ ( 1 + e x ) f(x) = \ln(1 + e^x) f(x)=ln(1+ex)

值域为 ( 0 , + ∞ ) (0, +\infty) (0,+∞)。

函数图像如下:

6. Softmax 函数

函数定义为:

σ ( z ) j = e z j ∑ k = 1 K e z k \sigma(z)j = \frac{e^{z_j}}{\sum{k=1}^K e^{z_k}} σ(z)j=∑k=1Kezkezj

Softmax 多用于多分类神经网络输出。

常见激活函数的导数计算?

对常见激活函数,导数计算如下:

激活函数及其导数

激活函数性质

  1. 非线性

    当激活函数是非线性的,一个两层的神经网络就可以基本上逼近所有的函数。但如果激活函数是恒等激活函数的时候,即 f ( x ) = x f(x) = x f(x)=x,就不满足这个性质,而且如果 MLP 使用的是恒等激活函数,那么其实整个网络跟单层神经网络是等价的。

  2. 可微性

    当优化方法是基于梯度的时候,就体现了该性质。

  3. 单调性

    当激活函数是单调的时候,单层网络能够保证是凸函数。

  4. 近似线性

    当激活函数满足 f ( x ) ≈ x f(x) \approx x f(x)≈x 这个性质的时候,如果参数的初始化是随机的较小值,那么神经网络的训练将会很高效;如果不满足这个性质,那么就需要详细地去设置初始化值。

  5. 输出值的范围

    当激活函数输出值是有限的时候,基于梯度的优化方法会更加稳定,因为特征的表示受有限权值的影响更显著;当激活函数的输出是无限的时候,模型的训练会更加高效,不过在这种情况下,一般需要更小的 Learning Rate。

如何选择激活函数?

选择一个适合的激活函数并不容易,需要考虑很多因素。通常的做法是,如果不确定哪个激活函数效果更好,可以都试试,然后在验证集或者测试集上进行评价。然后看哪一种表现的更好,就去使用它。

以下是常见的选择情况:

  1. 输出是 0 或 1 值(二分类问题)

    如果输出层是 0 和 1 值,则输出层选择 sigmoid 函数,然后其他的所有单元都选择 ReLU 函数。

  2. 隐藏层激活函数的选择

    如果在隐藏层上不确定使用哪个激活函数,那么通常会使用 ReLU 激活函数。有时,也会使用 tanh 激活函数,但 ReLU 的一个优点是:当是负值的时候,导数等于 0。

  3. sigmoid 激活函数

    除了输出层是一个二分类问题,基本不会用它。

  4. tanh 激活函数

    tanh 是非常优秀的,几乎适合所有场合。

  5. ReLU 激活函数

    最常用的默认函数,如果不确定用哪个激活函数,就使用 ReLU 或者 Leaky ReLU,再尝试其他的激活函数。

  6. 解决死神经元问题

    如果遇到了一些死的神经元,我们可以使用 Leaky ReLU 函数。

使用 ReLu 激活函数的优点?

  1. ReLU 在区间变动较大的情况

    在区间变动很大的情况下,ReLU 激活函数的导数或者激活函数的斜率都会远大于 0。在程序实现中,ReLU 激活函数通常是一个简单的 if-else 语句,而 sigmoid 函数需要进行浮点四则运算。在实践中,使用 ReLU 激活函数构建神经网络通常会比使用 sigmoid 或者 tanh 激活函数学习得更快。

  2. 梯度消失问题

    sigmoid 和 tanh 函数的导数在正负饱和区的梯度都接近于 0,这会造成梯度弥散现象。而 ReLU 和 Leaky ReLU 函数在大于 0 部分的梯度为常数,不会产生梯度弥散现象。

  3. ReLU 的死神经元问题

    需要注意,ReLU 进入负半区时,梯度为 0,神经元此时不会训练,产生所谓的稀疏性。而 Leaky ReLU 不会产生这个问题。

代码示例

cpp 复制代码
import torch 
import torch.nn.functional as F 
from torch.autograd import Variable 
import matplotlib.pyplot as plt 
cpp 复制代码
# 生成数据
x = torch.linspace(5, 5, 200)  # x data ﴾tensor﴿, shape=﴾200, 1﴿ 
x_np = x.data.numpy()   # numpy array for plotting 
x_np 
cpp 复制代码
# 使用激活函数对数据进行处理
 
y_relu = F.relu(x).data.numpy() 
y_sigmoid = torch.sigmoid(x).data.numpy() 
y_tanh = torch.tanh(x).data.numpy() 
y_softplus = F.softplus(x).data.numpy() 
cpp 复制代码
# 导入所需库
import matplotlib.pyplot as plt

# 对激活函数结果进行显示
plt.figure(1, figsize=(8, 6))

# ReLU 激活函数
plt.subplot(221)
plt.plot(x_np, y_relu, c='red', label='relu')
plt.ylim((-1, 5))
plt.legend(loc='best')

# Sigmoid 激活函数
plt.subplot(222)
plt.plot(x_np, y_sigmoid, c='red', label='sigmoid')
plt.ylim((-0.2, 1.2))
plt.legend(loc='best')

# Tanh 激活函数
plt.subplot(223)
plt.plot(x_np, y_tanh, c='red', label='tanh')
plt.ylim((-1.2, 1.2))
plt.legend(loc='best')

# Softplus 激活函数
plt.subplot(224)
plt.plot(x_np, y_softplus, c='red', label='softplus')
plt.ylim((-0.2, 6))
plt.legend(loc='best')

# 显示图像
plt.show()
相关推荐
pchmi15 分钟前
C# OpenCV机器视觉:智能水果采摘
人工智能·opencv·c#·机器视觉
呀啊~~32 分钟前
【前端框架与库】「React 全面解析」:从 JSX 语法到高阶组件,深度剖析前端开发中的核心概念与最佳实践
前端·javascript·学习·react.js·前端框架
EterNity_TiMe_34 分钟前
【人工智能】deepseek R1模型在蓝耘智算平台的搭建与机器学习的探索
人工智能·python·机器学习·deepseek
灵魂画师向阳36 分钟前
白嫖RTX 4090?Stable Diffusion:如何给线稿人物快速上色?
java·大数据·人工智能·ai作画·stable diffusion
等什么君!1 小时前
spring 学习(spring-Dl补充(注入不同类型的数据))
java·学习·spring
新加坡内哥谈技术1 小时前
ChunkKV:优化 KV 缓存压缩,让 LLM 长文本推理更高效
人工智能·科技·深度学习·语言模型·机器人
派森先生1 小时前
《麻省理工公开课:线性代数》 中文学习笔记
笔记·学习·线性代数
Narnat1 小时前
opencv打开摄像头出现读取帧错误问题
人工智能·opencv·计算机视觉
珠江上上上1 小时前
支持向量机原理
人工智能·深度学习·算法·机器学习·支持向量机·数据挖掘
pchmi1 小时前
C# OpenCV机器视觉:对位贴合
人工智能·opencv·c#·机器视觉·opencvsharp