文章目录
- 概要
- 基础概念
- 简单的神经网络图
- 神经元模型
- 权重
- 求和
- 激活函数
- 输出
- 多层感知机
- 前向传播:
- 激活函数:
- 误差计算(损失函数):
- 反向传播:
- 1. **激活函数(Activation Function)**
- 2. **非线性模型(Non-linear Models)**
- 3. **堆叠多个隐藏层(Stack Multiple Hidden Layers)**
- 4. **超参数(Hyperparameters)**
- 总结:
- 全连接过渡到卷积层
- 1. **局部性(Locality)**
- 2. **平移不变性(Translation Invariance)**
- 3. **参数数量(# Model Params)**
- 4. **卷积核(Kernel)**
- 5. **图示解读**
- 总结:
- 循环神经网络
- 1. **传统神经网络的问题**
- 2. **RNN 的结构**
- 3. **RNN 的优点**
- 4. **RNN 的缺点**
- 5. **改进版本:LSTM 和 GRU**
- 6. **RNN 的应用**
- Python 实现一个简单的 RNN
- 代码解释:
概要
基础概念
从基础概念开始:
神经网络是一种模仿人脑神经元工作方式的计算模型。
它由多个层次组成,包括输入层、隐藏层和输出层。
每一层包含多个神经元,通过权重和激活函数相互连接。
对,很像上图这样的情形。如果结合生活实际呢,你可以这样思考:
输入层:想象你要估计一栋房子的价格,你需要一些信息,比如房子的面积、卧室数量、位置等。这些信息就是输入层的特征。
隐藏层:在这个过程中,神经网络会对这些信息进行处理。隐藏层就像是一个复杂的计算过程,比如分析市场趋势、周边设施等。每个神经元在这里负责处理特定的信息。
输出层:最后,经过处理后,网络会给出一个估计的房价。这就是输出层的作用。
此外还有的概念是连接权重和激活函数
连接权重:层与层之间的连接强度,训练过程中会不断调整。
激活函数:用于决定神经元是否激活,常见的有ReLU、Sigmoid和Tanh等
简单的神经网络图
这是一个简单的神经网络图。现在我们来逐层解释:
输入层(Input Layer):红色的节点代表输入特征,每个节点对应一个输入数据,比如房子的面积或房间数量。
隐藏层(Hidden Layer):紫色节点表示隐藏层,它们负责处理输入数据。每个节点将输入数据通过一系列复杂的计算转化为更高层次的信息。
输出层(Output Layer):绿色节点代表输出结果,这里可能是预测的房价或者分类的结果。
箭头表示信息从输入层流入隐藏层,再流向输出层。整个过程就是神经网络处理和学习的过程。
神经元模型
输入(输入1, 输入2, 输入3):神经元接收到多个输入信号,每个输入代表一个特征或数据点,比如房子的面积、卧室数量等。
权重(权值1, 权值2, 权值3):每个输入信号与一个权重相乘。权重表示每个输入的重要性,网络在训练时通过调整这些权重来优化预测结果。如果一个特征对预测更重要,它的权重会更大。
求和:将所有输入信号乘以各自的权重后进行加和。这是一个线性组合,类似于计算一个加权平均值。
非线性函数:加和后的结果通过一个非线性激活函数,如ReLU、Sigmoid等。这一步使网络可以处理复杂的、非线性的问题。如果没有这个步骤,神经网络只能解决线性问题,学习能力会大大降低。
输出:激活函数处理后的值就是这个神经元的输出,它将作为下一层神经元的输入,或者直接作为最终的输出。
现在我们深入探讨里面的关键点
权重
权重决定了每个输入在计算中的重要性。比如,假设我们在预测房价,房子的面积可能比房间数量更重要,因此面积的权重可能会更高。训练过程中,网络会通过反向传播算法不断调整这些权重,使得模型预测更准确。
求和
激活函数
ReLU(修正线性单元):如果求和结果是正数,它就保持不变;如果是负数,它就变成0。这个函数帮助网络更好地处理复杂的任务。
import numpy as np
# ReLU函数
def relu(x):
return np.maximum(0, x)
# 示例
inputs = np.array([-2, -1, 0, 1, 2])
output = relu(inputs)
print("ReLU输出:", output)
Sigmoid:将结果压缩到0到1之间,常用于分类任务,尤其是在输出二分类问题时,比如是否买房。机器学习中的数学——激活函数(一):Sigmoid函数
import numpy as np
# Sigmoid函数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# 示例
inputs = np.array([-2, -1, 0, 1, 2])
output = sigmoid(inputs)
print("Sigmoid输出:", output)
Tanh:类似Sigmoid,但将结果压缩到-1到1之间,适合需要处理负数的任务。
import numpy as np
# Tanh函数
def tanh(x):
return np.tanh(x)
# 示例
inputs = np.array([-2, -1, 0, 1, 2])
output = tanh(inputs)
print("Tanh输出:", output)
输出
激活函数处理后的结果被传递到下一层或者直接输出。如果是分类任务,输出会是某个类别的概率;如果是回归任务,输出会是一个连续值,比如预测房价。
多层感知机
多层感知机(MLP,Multilayer Perceptron)是神经网络中最基础的架构之一,它包含多个层次的神经元,每一层的神经元都与下一层的神经元完全连接。MLP也是最常见的前馈神经网络的一种,它的特点是信息从输入层一直向前传递到输出层,没有循环。
MLP的工作过程可以总结为以下几个步骤:
前向传播:
输入层接收到数据,并传递到第一个隐藏层。
每个隐藏层的神经元对输入进行加权求和,再通过激活函数进行非线性变换。
处理结果依次传递到下一层,直到输出层。
激活函数:
每层神经元都通过激活函数来引入非线性,常见的激活函数有ReLU、Sigmoid和Tanh。没有激活函数的网络只能解决线性问题,无法处理复杂的数据关系。
误差计算(损失函数):
输出层得到的预测结果会与真实结果进行比较,计算误差(损失)。常见的损失函数有:
对于回归问题:均方误差(MSE)
对于分类问题:交叉熵(Cross-Entropy)
反向传播:
反向传播是MLP的学习过程,通过计算误差的梯度,网络会调整权重,使得下次预测更接近真实值。梯度下降算法是常用的优化方法之一。
这个图展示了多层感知机(MLP)的几个关键概念和结构。逐一解释各个部分:
1. 激活函数(Activation Function)
图中提到了两种常见的激活函数:
- Sigmoid 函数:
公式为 ( \text{sigmoid}(x) = \frac{1}{1 + \exp(-x)} ),它将输入压缩到 0 到 1 之间,适合用于二分类任务。 - ReLU 函数:
公式为 ( \text{ReLU}(x) = \max(0, x) ),即如果输入是负数,它会返回 0,若是正数,则返回该值。ReLU 是当前最常用的激活函数之一,因为它在深层神经网络中表现良好。
激活函数的作用是引入非线性,从而使神经网络能够学习复杂的、非线性的关系。
2. 非线性模型(Non-linear Models)
图中提到,通过激活函数,神经网络从线性模型变为非线性模型。这是因为没有激活函数的网络只能解决线性问题(如简单的线性回归),而引入激活函数后,网络能够捕捉数据中的复杂模式。
3. 堆叠多个隐藏层(Stack Multiple Hidden Layers)
右侧的结构图展示了一个典型的 MLP 结构:
- 输入层通过多个“Dense”层(全连接层)传递数据,每个 Dense 层后面跟着一个激活函数。
- 每一层输出都会成为下一层的输入,逐步提取数据中的特征。
- 这种逐层的架构,随着隐藏层的增加,模型会变得更加“深”(deeper),也能捕获更复杂的模式。
4. 超参数(Hyperparameters)
最后,图中提到了超参数(Hyperparameters),它们是控制模型训练和结构的关键参数。包括:
- 层数(Number of layers):表示网络有多少层。
- 每层的神经元数量(Number of units in each layer):决定了每层神经元的数量,通常根据问题的复杂度来调整。
总结:
- 左侧的公式:展示了激活函数如何将输入数据变为非线性,从而增强网络的学习能力。
- 右侧的结构图:显示了 MLP 的典型结构,数据从输入层流入隐藏层,每层经过一个激活函数后,再输出到下一层,最终给出预测结果。
全连接过渡到卷积层
这张图介绍的是**卷积层(Convolution Layer)**的概念,主要用于卷积神经网络(CNNs),尤其在图像处理和计算机视觉领域。我们逐条解释各个部分:
1. 局部性(Locality)
- 图中提到 “局部性”,意思是卷积层的每个输出只依赖于输入图像的一个小区域,而不是整个输入。这些小区域通常是 ( k \times k ) 的矩形窗口(如 3x3 或 5x5 的矩阵)。这种局部感知特性让卷积层可以提取局部特征,如边缘、角点等。
- 例如,在图像识别任务中,卷积操作可能会识别图像中的某个特定小区域。
2. 平移不变性(Translation Invariance)
- 平移不变性 意味着卷积操作可以识别图像中的某些模式,即使它们在图像中的位置发生变化。图中的输出会使用相同的 ( k \times k ) 权重(即卷积核,也称为 kernel)。通过平移卷积核,网络能够在不同位置检测相同的模式。
- 例如,一个检测到的边缘或物体特征无论在图像的哪部分,它的表现都是一致的。
3. 参数数量(# Model Params)
- 卷积层的参数数量不依赖于输入或输出的大小,因为卷积层的参数是卷积核的权重(kernel weights)。例如,使用一个 3x3 的卷积核,卷积层的参数数目就固定为 9(3x3=9),而不管输入图片是大是小。
- 这让卷积层比全连接层更高效,特别是处理大尺寸的图像时,卷积层的参数量远少于传统的全连接层。
4. 卷积核(Kernel)
- 图中提到卷积核(kernel),这是卷积操作的核心,它通过学习图片中的某种模式或特征,如边缘、纹理等。通过反复训练,卷积核会自动学会识别这些模式。
- 图中的例子展示了不同的卷积核提取的模式,如边缘、角落或复杂纹理等。
5. 图示解读
- 图示中展示了几个不同的卷积核,以及它们可以提取的不同图像模式(如模糊的、线条状的或梯度变化的模式)。这些模式帮助网络识别图像中的特定特征。
总结:
- 局部性 让卷积层能够关注图像的局部区域,而不是整个图像。
- 平移不变性 使卷积层能够识别图像中相同的特征,不论它们在何处。
- 参数数量小,因为卷积层只需要学习卷积核的权重,而不是所有输入数据的连接权重。
- 卷积核学习模式:通过训练,卷积核可以自动学会识别图像中的不同特征。
可以把卷积层理解为一种智能“滤镜”,它通过扫描图片的一部分一部分来提取重要的视觉特征。这种机制大大提高了神经网络在图像识别任务中的表现。
循环神经网络
当然可以!**循环神经网络(RNN, Recurrent Neural Network)**是一种专门用于处理序列数据的神经网络,常用于自然语言处理、时间序列预测等任务。让我们一步步来了解RNN的工作原理。
1. 传统神经网络的问题
在处理像文本、时间序列等顺序数据时,传统的前馈神经网络(如多层感知机MLP)只能处理固定大小的输入数据,并且无法考虑数据之间的顺序关系。比如,如果我们要分析一段文字,前面的单词可能会影响后面的意思,传统网络无法捕捉这种上下文依赖性。
2. RNN 的结构
RNN 的特点是具有“记忆”能力,能够将之前的输入信息保留在“记忆”中,作为处理当前输入的参考。
- 在RNN中,隐藏层的输出不仅依赖于当前输入,还依赖于上一个时间步的隐藏状态。这意味着它可以将之前的状态与当前输入结合起来,形成新的状态。
- RNN中的每个神经元都会连接到它自己,形成一个循环结构,从而将信息从一个时间步传播到下一个时间步。
公式化表示:
3. RNN 的优点
- 捕捉序列依赖性:由于RNN的循环结构,它能够记住前面的输入,因此特别适合处理有顺序依赖的任务,比如语音识别、文本生成等。
- 动态输入长度:RNN能够处理不同长度的输入数据,比如长短不一的文本句子。
4. RNN 的缺点
- 梯度消失和爆炸问题:RNN在训练长序列数据时,梯度随着反向传播逐渐减小(梯度消失)或增大(梯度爆炸),导致训练变得困难。
- 短期记忆问题:标准的RNN只能捕捉短期的依赖关系,无法处理很长时间跨度的数据依赖。
5. 改进版本:LSTM 和 GRU
为了克服RNN的这些问题,人们提出了两种常用的改进版RNN模型:长短期记忆网络(LSTM) 和 门控循环单元(GRU)。
-
LSTM(Long Short-Term Memory):通过引入遗忘门、输入门和输出门,LSTM可以控制哪些信息需要记住、哪些需要遗忘,从而缓解梯度消失问题,能够更好地捕捉长时依赖。
-
GRU(Gated Recurrent Unit):与LSTM类似,但结构稍微简单一些,只使用两个门来控制信息流。它在很多情况下与LSTM表现相当,但训练速度更快。
6. RNN 的应用
- 自然语言处理(NLP):RNN可以应用在文本分类、机器翻译、情感分析、语音识别等领域。比如,RNN可以通过记住前面词汇的上下文,来预测下一个单词或生成新的句子。
- 时间序列预测:RNN在处理股票价格、气象数据等时间序列数据时非常有效,因为它能够捕捉时间之间的依赖关系。
Python 实现一个简单的 RNN
可以使用 Keras
和 TensorFlow
来快速构建一个 RNN 模型:
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import SimpleRNN, Dense
# 创建一个简单的RNN模型
model = Sequential([
SimpleRNN(50, activation='tanh', input_shape=(10, 1)), # 50个隐藏单元,输入形状为 (时间步数, 特征数)
Dense(1) # 输出层,回归任务
])
# 编译模型
model.compile(optimizer='adam', loss='mse')
# 查看模型结构
model.summary()
代码解释:
- SimpleRNN(50):这是一个简单的RNN层,包含50个隐藏单元,使用tanh作为激活函数。
- input_shape=(10, 1):RNN接受形状为 (时间步数, 特征数) 的输入,比如一条有10个时间步的时间序列,每个时间步有1个特征。
- Dense(1):这是输出层,用于回归任务,可以调整为分类任务。