文章内容

  • 感知机(Perceptron)
  • 反向传播算法(Back Propagation algorithm)
  • RBF(Radial Basis Function,径向基函数) 网络:单一层前馈网络,它使用径向基作为隐层神经元激活函数
  • ART(Adaptive Resonance Theory,自适应谐振理论) 网络:竞争型学习无监督学习策略
  • SOM(Self Organizing Map,自组织映射) 网络:竞争性学习型的无监督神经网络
  • 级联相关(Cascade-Correlation) 网络:结构自适应网络
  • Elman网络:递归网络
  • Boltzmann机

一、 感知机(Perceptron)

1. 含义

一个感知器有如下组成部分:

  • 输入权值:一个感知器可以接收多个输入x,每个输入上有一个权值w,此外还有一个偏置项b,就是上图中的。
  • 激活函数:如阶跃函数(Step function),sigmoid函数
  • 输出:y= f(wx+b)
  • 权重更新:,其中,η为学习率

单层感知机只能解决线性可分的问题。而多层感知器可以拟合任何的线性函数,任何线性分类线性回归问题都可以用感知器来解决。

2. 更新方法

3. 代码

class Perceptron(object):def __init__(self, input_num, activator):'''初始化感知器,设置输入参数的个数,以及激活函数。激活函数的类型为double -> double'''self.activator = activator# 权重向量初始化为0self.weights = [0.0 for _ in range(input_num)]# 偏置项初始化为0self.bias = 0.0def __str__(self):'''打印学习到的权重、偏置项'''return 'weights\t:%s\nbias\t:%f\n' % (self.weights, self.bias)def predict(self, input_vec):'''输入向量,输出感知器的计算结果'''# 把input_vec[x1,x2,x3...]和weights[w1,w2,w3,...]打包在一起# 变成[(x1,w1),(x2,w2),(x3,w3),...]# 然后利用map函数计算[x1*w1, x2*w2, x3*w3]# 最后利用reduce求和return self.activator(reduce(lambda a, b: a + b,map(lambda (x, w): x * w,  zip(input_vec, self.weights)), 0.0) + self.bias)def train(self, input_vecs, labels, iteration, rate):'''输入训练数据:一组向量、与每个向量对应的label;以及训练轮数、学习率'''for i in range(iteration):self._one_iteration(input_vecs, labels, rate)def _one_iteration(self, input_vecs, labels, rate):'''一次迭代,把所有的训练数据过一遍'''# 把输入和输出打包在一起,成为样本的列表[(input_vec, label), ...]# 而每个训练样本是(input_vec, label)samples = zip(input_vecs, labels)# 对每个样本,按照感知器规则更新权重for (input_vec, label) in samples:# 计算感知器在当前权重下的输出output = self.predict(input_vec)# 更新权重self._update_weights(input_vec, output, label, rate)def _update_weights(self, input_vec, output, label, rate):'''按照感知器规则更新权重'''# 把input_vec[x1,x2,x3,...]和weights[w1,w2,w3,...]打包在一起# 变成[(x1,w1),(x2,w2),(x3,w3),...]# 然后利用感知器规则更新权重delta = label - outputself.weights = map(lambda (x, w): w + rate * delta * x,zip(input_vec, self.weights))# 更新biasself.bias += rate * delta

训练和预测:

def f(x):'''定义激活函数f'''return 1 if x > 0 else 0
def get_training_dataset():'''基于and真值表构建训练数据'''# 构建训练数据# 输入向量列表input_vecs = [[1,1], [0,0], [1,0], [0,1]]# 期望的输出列表,注意要与输入一一对应# [1,1] -> 1, [0,0] -> 0, [1,0] -> 0, [0,1] -> 0labels = [1, 0, 0, 0]return input_vecs, labels
def train_and_perceptron():'''使用and真值表训练感知器'''# 创建感知器,输入参数个数为2(因为and是二元函数),激活函数为fp = Perceptron(2, f)# 训练,迭代10轮, 学习速率为0.1input_vecs, labels = get_training_dataset()p.train(input_vecs, labels, 10, 0.1)#返回训练好的感知器return p
if __name__ == '__main__': # 训练and感知器and_perception = train_and_perceptron()# 打印训练获得的权重print and_perception# 测试print '1 and 1 = %d' % and_perception.predict([1, 1])print '0 and 0 = %d' % and_perception.predict([0, 0])print '1 and 0 = %d' % and_perception.predict([1, 0])print '0 and 1 = %d' % and_perception.predict([0, 1])

二、反向传播(BP)算法

1. 内容

  • 权重和偏差
  • 代价函数(cost function):均方误差
  • 权重更新:梯度下降(gradient descent)策略
  • 更多优化方法:"正则化",在误差目标函数中添加一个用于描述网络复杂度的部分(如w²)

2. 参数计算与更新

2.1 总误差

2.2 误差在隐藏层反向传播(输出层->隐藏层)

权重参数w5为例,如果我们想知道w5对整体误差产生了多少影响,可以用整体误差对w5求偏导求出:(链式法则)

求三项偏导值

所以,我们得到:

可以取符号δ简化公式(可选):

最后更新权重w:

2.3 误差反向传播(隐藏层->隐藏层)

方法差不多,但要计算误差基于传递过来的之前的误差:

该图中δ含义不一样,只代表(target-out)的误差

out(h1)会接受E(o1)和E(o2)两个地方传来的误差,所以这个地方两个都要计算。

最后,更新权重w1:

总结,前向传播和反向传播顺序说明图:

3. 随机梯度更新和批量更新

批量(batch)更新时,计算完一批样本后Δw再更新:

批量梯度下降随机梯度下降(stochastic gradient descent)对比:

Mini-Batch 梯度下降算法是介于批量梯度下降算法和随机梯度下降算法之间的算法,每计算常数 次训练实例,便更新一次参数。

在批量梯度下降算法中每次迭代我们都要使用到所有的m个样本,在随机梯度下降中我们每次迭代只需要一个样本。Mini-batch算法具体来说就是每次迭代,会使用b个样本,这个b我们称为mini-batch大小的参数

3. 代码

#coding:utf-8
import random
import math#
#   参数解释:
#   "pd_" :偏导的前缀
#   "d_" :导数的前缀
#   "w_ho" :隐含层到输出层的权重系数索引
#   "w_ih" :输入层到隐含层的权重系数的索引class NeuralNetwork:LEARNING_RATE = 0.5def __init__(self, num_inputs, num_hidden, num_outputs, hidden_layer_weights = None, hidden_layer_bias = None, output_layer_weights = None, output_layer_bias = None):self.num_inputs = num_inputsself.hidden_layer = NeuronLayer(num_hidden, hidden_layer_bias)self.output_layer = NeuronLayer(num_outputs, output_layer_bias)self.init_weights_from_inputs_to_hidden_layer_neurons(hidden_layer_weights)self.init_weights_from_hidden_layer_neurons_to_output_layer_neurons(output_layer_weights)def init_weights_from_inputs_to_hidden_layer_neurons(self, hidden_layer_weights):weight_num = 0for h in range(len(self.hidden_layer.neurons)):for i in range(self.num_inputs):if not hidden_layer_weights:self.hidden_layer.neurons[h].weights.append(random.random())else:self.hidden_layer.neurons[h].weights.append(hidden_layer_weights[weight_num])weight_num += 1def init_weights_from_hidden_layer_neurons_to_output_layer_neurons(self, output_layer_weights):weight_num = 0for o in range(len(self.output_layer.neurons)):for h in range(len(self.hidden_layer.neurons)):if not output_layer_weights:self.output_layer.neurons[o].weights.append(random.random())else:self.output_layer.neurons[o].weights.append(output_layer_weights[weight_num])weight_num += 1def inspect(self):print('------')print('* Inputs: {}'.format(self.num_inputs))print('------')print('Hidden Layer')self.hidden_layer.inspect()print('------')print('* Output Layer')self.output_layer.inspect()print('------')def feed_forward(self, inputs):hidden_layer_outputs = self.hidden_layer.feed_forward(inputs)return self.output_layer.feed_forward(hidden_layer_outputs)def train(self, training_inputs, training_outputs):self.feed_forward(training_inputs)# 1. 输出神经元的值pd_errors_wrt_output_neuron_total_net_input = [0] * len(self.output_layer.neurons)for o in range(len(self.output_layer.neurons)):# ∂E/∂zⱼpd_errors_wrt_output_neuron_total_net_input[o] = self.output_layer.neurons[o].calculate_pd_error_wrt_total_net_input(training_outputs[o])# 2. 隐含层神经元的值pd_errors_wrt_hidden_neuron_total_net_input = [0] * len(self.hidden_layer.neurons)for h in range(len(self.hidden_layer.neurons)):# dE/dyⱼ = Σ ∂E/∂zⱼ * ∂z/∂yⱼ = Σ ∂E/∂zⱼ * wᵢⱼd_error_wrt_hidden_neuron_output = 0for o in range(len(self.output_layer.neurons)):d_error_wrt_hidden_neuron_output += pd_errors_wrt_output_neuron_total_net_input[o] * self.output_layer.neurons[o].weights[h]# ∂E/∂zⱼ = dE/dyⱼ * ∂zⱼ/∂pd_errors_wrt_hidden_neuron_total_net_input[h] = d_error_wrt_hidden_neuron_output * self.hidden_layer.neurons[h].calculate_pd_total_net_input_wrt_input()# 3. 更新输出层权重系数for o in range(len(self.output_layer.neurons)):for w_ho in range(len(self.output_layer.neurons[o].weights)):# ∂Eⱼ/∂wᵢⱼ = ∂E/∂zⱼ * ∂zⱼ/∂wᵢⱼpd_error_wrt_weight = pd_errors_wrt_output_neuron_total_net_input[o] * self.output_layer.neurons[o].calculate_pd_total_net_input_wrt_weight(w_ho)# Δw = α * ∂Eⱼ/∂wᵢself.output_layer.neurons[o].weights[w_ho] -= self.LEARNING_RATE * pd_error_wrt_weight# 4. 更新隐含层的权重系数for h in range(len(self.hidden_layer.neurons)):for w_ih in range(len(self.hidden_layer.neurons[h].weights)):# ∂Eⱼ/∂wᵢ = ∂E/∂zⱼ * ∂zⱼ/∂wᵢpd_error_wrt_weight = pd_errors_wrt_hidden_neuron_total_net_input[h] * self.hidden_layer.neurons[h].calculate_pd_total_net_input_wrt_weight(w_ih)# Δw = α * ∂Eⱼ/∂wᵢself.hidden_layer.neurons[h].weights[w_ih] -= self.LEARNING_RATE * pd_error_wrt_weightdef calculate_total_error(self, training_sets):total_error = 0for t in range(len(training_sets)):training_inputs, training_outputs = training_sets[t]self.feed_forward(training_inputs)for o in range(len(training_outputs)):total_error += self.output_layer.neurons[o].calculate_error(training_outputs[o])return total_errorclass NeuronLayer:def __init__(self, num_neurons, bias):# 同一层的神经元共享一个截距项bself.bias = bias if bias else random.random()self.neurons = []for i in range(num_neurons):self.neurons.append(Neuron(self.bias))def inspect(self):print('Neurons:', len(self.neurons))for n in range(len(self.neurons)):print(' Neuron', n)for w in range(len(self.neurons[n].weights)):print('  Weight:', self.neurons[n].weights[w])print('  Bias:', self.bias)def feed_forward(self, inputs):outputs = []for neuron in self.neurons:outputs.append(neuron.calculate_output(inputs))return outputsdef get_outputs(self):outputs = []for neuron in self.neurons:outputs.append(neuron.output)return outputsclass Neuron:def __init__(self, bias):self.bias = biasself.weights = []def calculate_output(self, inputs):self.inputs = inputsself.output = self.squash(self.calculate_total_net_input())return self.outputdef calculate_total_net_input(self):total = 0for i in range(len(self.inputs)):total += self.inputs[i] * self.weights[i]return total + self.bias# 激活函数sigmoiddef squash(self, total_net_input):return 1 / (1 + math.exp(-total_net_input))def calculate_pd_error_wrt_total_net_input(self, target_output):return self.calculate_pd_error_wrt_output(target_output) * self.calculate_pd_total_net_input_wrt_input();# 每一个神经元的误差是由平方差公式计算的def calculate_error(self, target_output):return 0.5 * (target_output - self.output) ** 2def calculate_pd_error_wrt_output(self, target_output):return -(target_output - self.output)def calculate_pd_total_net_input_wrt_input(self):return self.output * (1 - self.output)def calculate_pd_total_net_input_wrt_weight(self, index):return self.inputs[index]# 文中的例子:nn = NeuralNetwork(2, 2, 2, hidden_layer_weights=[0.15, 0.2, 0.25, 0.3], hidden_layer_bias=0.35, output_layer_weights=[0.4, 0.45, 0.5, 0.55], output_layer_bias=0.6)
for i in range(10000):nn.train([0.05, 0.1], [0.01, 0.09])print(i, round(nn.calculate_total_error([[[0.05, 0.1], [0.01, 0.09]]]), 9))#另外一个例子,可以把上面的例子注释掉再运行一下:# training_sets = [
#     [[0, 0], [0]],
#     [[0, 1], [1]],
#     [[1, 0], [1]],
#     [[1, 1], [0]]
# ]# nn = NeuralNetwork(len(training_sets[0][0]), 5, len(training_sets[0][1]))
# for i in range(10000):
#     training_inputs, training_outputs = random.choice(training_sets)
#     nn.train(training_inputs, training_outputs)
#     print(i, nn.calculate_total_error(training_sets))

三、SOM自组织映射网络

SOM网络又称Kohonen网络,是自组织竞争型神经网络的一种,该网络为无监督学习网络,能够识别环境特征并自动聚类。它通过自动寻找样本中的内在规律和本质属性,自组织、自适应地改变网络参数与结构。

1. SOM网络拓扑结构

  • 网络包含两层,即一个输入层和一个输出层,输出层也称竞争层,不包括隐层。
  • 输入层中的每个输入节点都与输出节点完全相连。
  • 输出节点呈二维结构分布,且节点之间具有侧向连接。于是,对某个输出节点来说,在一定邻域范围内会有一定数量的“邻近细胞”,即邻接节点

2. 原理

  1. 分类与输入模式的相似性:分类是在类别知识等导师信号的指导下,将待识别的输入模式分配到各自的模式类中,无导师指导的分类称为聚类,聚类的目的是将相似的模式样本划归一类,而将不相似的分离开来,实现模式样本的类内相似性和类间分离性。由于无导师学习的训练样本中不含期望输出,因此对于某一输入模式样本应属于哪一类并没有任何先验知识。对于一组输入模式,只能根据它们之间的相似程度来分为若干类,因此,相似性是输入模式的聚类依据
  2. 相似性测量:神经网络的输入模式向量的相似性测量可用向量之间的距离来衡量。常用的方法有欧氏距离法和余弦法两种。
  3. 竞争学习原理:竞争学习规则的生理学基础是神经细胞的侧抑制现象:当一个神经细胞兴奋后,会对其周围的神经细胞产生抑制作用。最强的抑制作用是竞争获胜的“唯我独兴”,这种做法称为“胜者为王”(Winner-Take-All)。竞争学习规则就是从神经细胞的侧抑制现象获得的。它的学习步骤为:A、向量归一化;B、寻找获胜神经元;C、网络输出与权调整;D、重新归一化处理

SOM网络的竞争调节策略,优胜节点及邻接节点的更新

3. 具体算法

网络学习过程中,当样本输入网络时, 竞争层上的神经元计算 输入样本与 竞争层神经元权值之间的 欧几里德距离,距离最小的神经元为获胜神经元。调整获胜神经元和相邻神经元权值,使获得神经元及周边权值靠近该输入样本。通过反复训练,最终各神经元的连接权值具有一定的分布,该分布把数据之间的相似性组织到代表各类的神经元上,使同类神经元具有相近的权系数,不同类的神经元权系数差别明显。需要注意的是,在学习的过程中,权值修改学习速率和神经元领域均在不断较少,从而使同类神经元逐渐集中。

总的来说,SOM网络包含初始化、竞争、迭代三块内容

3.1 初始化

  1. 归一化数据集。
  2. 设计竞争层结构。一般根据预估的聚类簇数进行设置。比如要分成4类,那我可以将竞争层设计为2*2,1*4,4*1。SOM网络不需要预先提供聚类数量,类别的数据由网络自动识别出来。
  3. 预设竞争层神经元的权重节点。一般我们会根据输入数据的维度和竞争层预估的分类数来设置权重节点,若输入为二维数据,最终聚类为4类,则权重矩阵就是2*4。
  4. 初始化邻域半径学习率

3.2 竞争过程

  1. 随机选择样本,根据权重节点计算到竞争层每个神经元节点的距离。一般我们选择欧式距离公式求距离。

    (或者另一种方法:权重w和输入x的点积最大判断优胜节点)

  2. 选择优胜节点。通过竞争,选择距离最小的神经元节点作为优胜节点。

Best Matching Unit(BMU) 优胜节点: The winner node(or weight) which has the shortest distance from itself to the sample vector. There are numerous ways to determine the distance, however, the most commonly used method is the Euclidean Distance, is the most common metric to calculate distance between weights and sample vector.

3.3 迭代过程

1、圈定出优胜邻域(neighborhood)内的所有节点。根据邻域半径,圈定出距离小于邻域半径的节点,形成优胜邻域。

2、对优胜邻域内的节点权重进行迭代更新。更新的思想是越靠近优胜节点,更新幅度越大;越远离优胜节点,更新幅度越小,故我们需要对不同的节点增加一个更新约束,一般可以高斯函数求得。另外我们更新节点的目的是为了使得优胜节点更加逼近样本点,故在节点权重的更新上,我们采用以下公式:

不同neighborhood function:

  • case ’bubble’, H = (Ud<=radius(t));
  • case ’gaussian’, H = exp(-Ud/(2*radius(t)));
  • case ’cutgauss’, H = exp(-Ud/(2radius(t))) . (Ud<=radius(t));
  • case ’ep’, H = (1-Ud/radius(t)) .* (Ud<=radius(t));

3.4 衰减函数 decay func

SOM网络的另一个特点是,学习率和邻域范围随着迭代次数会逐渐衰减

最常用的decay funciton是 1 / (1 + t/T)

sigma(t) = sigma / (1 + t/T)

learning_rate(t) = learning_rate / (1 + t/T)

t 代表当前迭代次数
T = 总迭代次数 / 2

4. 实际例子

初始权重为w1 = (0.45,0.89) , w2 = (0.55,0.83) , w3 = (0.95,0.32) 和 w4 = (0.62,0.78) 。让四个神经元(N=4),N1, N2, N3和N4分别位于直角坐标平面位置(0,0), (1,0), (1,0)和(1,1)的网格中。假设网络接受二维(A=2)输入矢量(x1,x2)。让w_i= (w1_i,w2_i)为神经元i的权重 . neighborhood radius = 0.6。输入向量X=(3,1)。假设学习率=0.5,并且在整个过程中是恒定的。假设初始权重如图中所述。

5. 代码

References

零基础入门深度学习(1) - 感知器 - 作业部落 Cmd Markdown 编辑阅读器

一文弄懂神经网络中的反向传播法——BackPropagation

Backpropagation

神经网络算法总结_晴晴_Amanda的博客-CSDN博客

批量梯度下降,随机梯度下降,mini-batch随机梯度下降对比说明: - 知乎

机器学习算法推导&手写实现07——SOM网络 - 知乎

自组织映射神经网络(SOM)_意念回复的博客-CSDN博客

https://medium.com/analytics-vidhya/how-does-self-organizing-algorithm-works-f0664af9bf04

神经网络算法入门和代码相关推荐

  1. 机器学习_神经网络算法入门

    近来迷上机器学习了,特别是神经网络这一段,很有科幻片的味道,这里把神经网络的内容整理成一篇博客,欢迎大家点评. 神经网络是让计算机模仿人的神经网络结构,设计出的一种算法,(简写ANN),有时候也称为连 ...

  2. 神经网络算法入门实例,神经网络算法入门书籍

    想要学习人工神经网络,需要什么样的基础知识? 人工神经网络理论百度网盘下载:链接:   提取码:rxlc简介:本书是人工神经网络理论的入门书籍.全书共分十章. 第一章主要阐述人工神经网络理论的产生及发 ...

  3. AI从入门到放弃:BP神经网络算法推导及代码实现笔记

    作者 | @Aloys (腾讯员工,后台工程师) 本文授权转自腾讯的知乎专栏 ▌一. 前言: 作为AI入门小白,参考了一些文章,想记点笔记加深印象,发出来是给有需求的童鞋学习共勉,大神轻拍! [毒鸡汤 ...

  4. BP神经网络算法推导及代码实现笔记

    文章目录 一.前言 二.科普 三.通往沙漠的入口: 神经元是什么,有什么用: 四.茫茫大漠第一步: 激活函数是什么,有什么用 五.沙漠中心的风暴:BP(Back Propagation)算法 1. 神 ...

  5. BP神经网络算法推导及代码实现笔记zz

    一. 前言: 作为AI入门小白,参考了一些文章,想记点笔记加深印象,发出来是给有需求的童鞋学习共勉,大神轻拍! [毒鸡汤]:算法这东西,读完之后的状态多半是 --> "我是谁,我在哪? ...

  6. 基于标准反向传播算法的改进BP神经网络算法(Matlab代码实现)

  7. BP神经网络算法在MATLAB中的代码

    BP神经网络算法在MATLAB中的代码通常包括以下步骤: 导入所需的库,如nnstart.patternnet和train. 准备训练数据和测试数据.这通常包括读取数据文件.将数据转换为矩阵的形式并分 ...

  8. 4.1 神经网络算法原理

    神经网络算法介绍: https://blog.csdn.net/qq_37406130/article/details/79157025 AI从入门到放弃:BP神经网络算法推导及代码实现笔记: htt ...

  9. 神经网络算法实例说明,简单神经网络算法原理

    神经网络算法实例说明有哪些? 在网络模型与算法研究的基础上,利用人工神经网络组成实际的应用系统,例如,完成某种信号处理或模式识别的功能.构作专家系统.制成机器人.复杂系统控制等等. 纵观当代新兴科学技 ...

最新文章

  1. 使用自变分原理改进正则化核回归:通过变分法推导和推广Nadaraya-Watson估计
  2. 科普丨机器学习和人类学习的区别到底是什么?
  3. 基础知识(三)-网络
  4. 常见的基于node.js的web框架
  5. 原生Get请求和Post请求
  6. SilverLight入门实例(一)
  7. delstr函数python_Python Day26:多态、封装、内置函数:__str__、__del__、反射(反省)、动态导入模块...
  8. MySQL笔记-唯一键的使用
  9. html页面布局代码bootstrap,Bootstrap3.0学习笔记之页面布局
  10. 怎么成为日上会员直邮_放福利啦,免税店现在一件也能直邮,不用出入境、不用出入境、不用找代购...
  11. C#进阶(一)——TXT文件处理:以导线网近似平差为例
  12. svg练习题——抽风路径、高斯模糊、仪表盘、个性签名、loading加载
  13. 金碟旗舰版凭证反记功能在哪_我们希望今年所有旗舰Android手机都能拥有的五个功能...
  14. 【Vijos-P1285】佳佳的魔法药水-Dijkstra思想
  15. 详解windows server 2008服务器的服务
  16. 计算机毕设(附源码)JAVA-SSM敬老院信息管理系统
  17. 手机微信资料打印怎么打,微信接收的文档如何打印
  18. 近段时间的学习碎片整理(6)
  19. 网络编程实现FTP服务器
  20. H5音乐标签实现网页自动播放和隐藏

热门文章

  1. 电脑重装oracle提示,电脑重装系统后怎样恢复ORACLE?
  2. ThinkPad E431 截屏快捷键
  3. simulink永磁同步PMSG一次调频9节点系统VSG虚拟同步机控制超速减载变桨功率备用控制。
  4. simulink永磁直驱风机PMSG联合飞轮储能或者电化学电池储能抑制风速波动导致的频率变化
  5. 第六十四章 SQL函数 INSTR
  6. Nginx HA双机热备
  7. AHP算法(一)----算法介绍
  8. 读书笔记:《人力资源管理》- 2
  9. 染色基础知识(二)——染什么?
  10. mysql 数组查询_MySQL查询使用数组