吃瓜教程-Task04

目录

神经网络

神经元模型

感知机与多层网络

感知机

感知机学习规则

功能神经元

线性可分问题

 非线性可分问题

多层前馈神经网络

误差逆传播算法(反向传播算法)-BP算法

实例 

 相关解释


神经网络

神经元模型

经网络是由具 有适应 性的 简单单元组成的广泛并行互连的网络,它的组织能够模拟生物 神经系统对真实 世界体所作出的交 互反应。
吃瓜教程-Task04_第1张图片 M-P神经元模型

输入信号通过 带权重 的连 接( connection) 进行传递 ,神经 接收 到的总输 入值将与 神经元 的阀值进 行比 较,然后通过"激活函数" (a ctivation function 处理以 产生神经元 的输出。
吃瓜教程-Task04_第2张图片 典型的神经元激活函数

阶跃函数具有不连续、不光滑等不太好的性质。sigmoid函数也叫挤压函数。

许多的神经元按照一定的层次连接起来就得到了神经网络。

Example:20个神经元每层10个,则有 100个连接权和 10 个阈值

吃瓜教程-Task04_第3张图片

 

感知机与多层网络

感知机

感知机由两层神经元组成。

吃瓜教程-Task04_第4张图片 两个输入神经元的感知机网络结构示意图

 输出层是M-P神经元

感知机能够实现与或非操作。

  •  
阈值可看作一个固定输入为- 1 的"哑结点" (dummy node) 所对应的连接权重 。
output = activation_function(sum(weight_i * input_i) - bias)

例如,我们有一个节点,其输入是 [0.5, 0.6],权重是 [0.1, 0.2],阈值是 0.3。按照公式,输出为 activation_function(0.5*0.1 + 0.6*0.2 - 0.3)

如果将阈值视为权重,我们将输入增加一个常数项 -1,权重增加一项(即阈值)。输入变为 [0.5, 0.6, -1],权重变为 [0.1, 0.2, 0.3]。计算变为 activation_function(0.5*0.1 + 0.6*0.2 + -1*0.3),得到的结果与之前相同。这样阈值的学习和权重的学习就相统一了。

感知机学习规则

对于训练样例(X,y),若当前感知机的输出是 ,则感知机的权重的调整如下

吃瓜教程-Task04_第5张图片

 称为学习率,将根据错误的程度进行调整权重。

功能神经元

功能神经元(functional neuron)是指在神经网络中执行特定计算功能的单元,包括接收输入、通过激活函数处理,并输出结果。每个神经元都与其他神经元相连,通过权重调整这些连接的强度。功能神经元可以用于实现神经网络的各种功能,包括分类、回归、聚类等。

线性可分问题

线性可分问题是指一个分类问题,其中两个类别可以通过一个直线(在二维空间)、平面(在三维空间)或一个超平面(在更高维度空间)完全分隔开。例如,如果你有两类点在二维平面上,且你可以画一条直线将这两类点完全分开,那么这个分类问题就是线性可分的。

 与、或、非问题都是线性可分的。

若两类模式是线性可分的,即存在一个线性超平面能将它们分开,则感知机的 学习过程一定会收敛 (converge) 而求得适当的权向量; 否则感知机学习过程将会发生震荡 (fluctuation)难以稳定下来,不能求得合适解。
吃瓜教程-Task04_第6张图片 a,b,c线性可分而d非线性可分

 非线性可分问题

要解决此类问题需要使用多层功能神经元。

输出 层与输入居之间的神经元 ,被称为 隐层或隐含层 (h id den la yer)  ,隐含层 输出层神经元都是拥
有激活函数 的功 能神经元。
吃瓜教程-Task04_第7张图片 解决异或问题的两层感知机

多层前馈神经网络

每层神 经元 与下层神 经元全互相连接,神经元之 间不存在同 层连接, 也不存 在跨层连接。
吃瓜教程-Task04_第8张图片 多层前馈神经网络结构示意图
"前馈"并不意味着网络中信号不能向后传!而是指网络拓扑结构中不存在环或回路
只需包含隐层,即可称为多层网络。神经网络的学习过程,就是根据训练数据来调整神经元之间的
"连接权" (connection weight) 以及每个功能神经元的阈值;换言之,神经网络"学"到的东西,蕴涵在连接权与阈值中。

误差逆传播算法(反向传播算法)-BP算法

吃瓜教程-Task04_第9张图片

吃瓜教程-Task04_第10张图片

下面以输入层第i个神经元与隐层第h个神经元之间的连接权为例推导一下: 

吃瓜教程-Task04_第11张图片

吃瓜教程-Task04_第12张图片

吃瓜教程-Task04_第13张图片

或者基本步骤:

  1. 随机初始化神经网络的权重。

  2. 前向传播:输入样本,通过计算每一层的输出,最终得到预测值。

  3. 计算误差:预测值与实际值之间的差距。

  4. 反向传播:从输出层开始,逐层向后计算误差的梯度,并更新每一层的权重。

  5. 迭代:反复执行步骤2-4,直至达到预设的迭代次数,或者误差满足设定的阈值。

实例 

import numpy as np

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def sigmoid_derivative(x):
    return x * (1 - x)

# 输入数据
training_inputs = np.array([[0,0,1],
                            [1,1,1],
                            [1,0,1],
                            [0,1,1]])

# 输出数据
training_outputs = np.array([[0,1,1,0]]).T

np.random.seed(1)

synaptic_weights = 2 * np.random.random((3, 1)) - 1

print('随机初始化的权重: ')
print(synaptic_weights)

for iteration in range(20000):

    input_layer = training_inputs

    outputs = sigmoid(np.dot(input_layer, synaptic_weights))

    # 计算误差
    error = training_outputs - outputs

    # 进行权值调整
    adjustments = error * sigmoid_derivative(outputs)

    synaptic_weights += np.dot(input_layer.T, adjustments)

print('权重更新后:')
print(synaptic_weights)

print("训练后的输出 : ")
print(outputs)

输出: 

吃瓜教程-Task04_第14张图片

 相关解释

synaptic_weights = 2 * np.random.random((3, 1)) - 1

这是在对神经网络中的权重进行随机初始化。

  • np.random.random((3, 1)):生成一个3行1列的数组,数组中的元素是[0, 1)之间的随机数。
  • 2 * np.random.random((3, 1)):将这个数组中的所有元素乘以2,得到的新数组中的元素位于[0, 2)之间。
  • 2 * np.random.random((3, 1)) - 1:从这个新数组中的所有元素中减去1,得到的最终数组中的元素位于[-1, 1)之间。

神经网络的权重通常需要进行随机初始化,以打破对称性并确保每个神经元学习不同的特性。这行代码使用了在[-1, 1)范围内的随机数进行权重初始化。

np.random()

np.random是numpy库中的一个模块,主要用于生成各种类型的随机数。

常用的函数:

  • np.random.rand生成均匀分布的随机数。
  • np.random.randn生成标准正态分布(均值为0,标准差为1)的随机数。
  • np.random.randint生成指定范围内的随机整数。
  • np.random.choice从指定的一维数组中生成随机数。
  • np.random.shuffle:对数组进行随机排列。
  • np.random.random:用于生成介于0(包括)到1(不包括)之间的随机浮点数。
adjustments = error * sigmoid_derivative(outputs)

实际上是利用链式法则进行微分,计算出误差函数关于权重的梯度。这是因为,权重的微小变化会导致网络输出的微小变化,进而导致误差的变化。链式法则允许我们将这些效应相乘,得到权重变化对误差的最终影响,也就是误差函数关于权重的梯度。

梯度在数学上代表了函数值变化最快的方向。在神经网络中,误差函数关于权重的负梯度,就代表了调整权重能够最快减小误差的方向。因此,按照误差的梯度进行权重的更新,就可以在每次迭代中,尽可能快地减小误差,优化神经网络的性能。

synaptic_weights += np.dot(input_layer.T, adjustments)

在这个特定的实现中,已经考虑了调整方向的问题。在adjustments = error * sigmoid_derivative(outputs) 这一行。这里的 error 已经是实际值与预测值之间的差值,所以它已经包含了方向性如果预测值小于实际值,误差是正的,我们需要增加权重;如果预测值大于实际值,误差是负的,我们需要减小权重。

在深度学习中,通常的表述是权重更新的规则是 weights = weights - learning_rate * gradient,这里的 gradient 是损失函数关于权重的梯度,learning_rate 是一个正数,所以 - learning_rate * gradient 表明我们在向损失函数减小的方向更新权重。但在这个例子中,由于已经在 adjustments 中考虑了方向性,所以直接使用加法操作。

你可能感兴趣的:(西瓜书,机器学习)