精华内容
下载资源
问答
  • BP神经网络Python代码实现,短短的代码,实现大大的功能。附加详细注释。
  • 人工神经网络是一种经典的机器学习模型,随着深度学习的发展神经网络模型日益完善.联想大家熟悉的回归问题, 神经网络模型实际上是根据训练样本创造出一个多维输入多维输出的函数, 并使用该函数进行预测, 网络的...

    人工神经网络是一种经典的机器学习模型,随着深度学习的发展神经网络模型日益完善.

    联想大家熟悉的回归问题, 神经网络模型实际上是根据训练样本创造出一个多维输入多维输出的函数, 并使用该函数进行预测, 网络的训练过程即为调节该函数参数提高预测精度的过程.神经网络要解决的问题与最小二乘法回归解决的问题并无根本性区别.

    回归和分类是常用神经网络处理的两类问题, 如果你已经了解了神经网络的工作原理可以在http://playground.tensorflow.org/上体验一个浅层神经网络的工作过程.

    感知机(Perceptron)是一个简单的线性二分类器, 它保存着输入权重, 根据输入和内置的函数计算输出.人工神经网络中的单个神经元即是感知机.

    在前馈神经网络的预测过程中, 数据流从输入到输出单向流动, 不存在循环和返回的通道.

    目前大多数神经网络模型都属于前馈神经网络, 在下文中我们将详细讨论前馈过程.

    多层感知机(Multi Layer Perceptron, MLP)是由多个感知机层全连接组成的前馈神经网络, 这种模型在非线性问题中表现出色.

    所谓全连接是指层A上任一神经元与临近层B上的任意神经元之间都存在连接.

    反向传播(Back Propagation,BP)是误差反向传播的简称,这是一种用来训练人工神经网络的常见算法, 通常与最优化方法(如梯度下降法)结合使用.

    本文介绍的神经网络模型在结构上属于MLP, 因为采用BP算法进行训练, 人们也称其为BP神经网络.

    BP神经网络原理

    经典的BP神经网络通常由三层组成: 输入层, 隐含层与输出层.通常输入层神经元的个数与特征数相关,输出层的个数与类别数相同, 隐含层的层数与神经元数均可以自定义.

    793413-20161010152810539-341221931.png

    每个神经元代表对数据的一次处理:

    793413-20161010152655274-1512072099.png

    每个隐含层和输出层神经元输出与输入的函数关系为:

    \[I_j=\sum_iW_{ij}O_i

    \]

    \[O_j= sigmod(I_l) =\frac{1}{1+e^{-I_l}}

    \]

    其中\(W_{ij}\)表示神经元i与神经元j之间连接的权重,\(O_j\)代表神经元j的输出, sigmod是一个特殊的函数用于将任意实数映射到(0,1)区间.

    上文中的sigmod函数称为神经元的激励函数(activation function), 除了sigmod函数\(\frac{1}{1+e^{-I_l}}\)外, 常用还有tanh和ReLU函数.

    我们用一个完成训练的神经网络处理回归问题, 每个样本拥有n个输入.相应地,神经网络拥有n个输入神经元和1个输出神经元.

    实际应用中我们通常在输入层额外增加一个偏置神经元, 提供一个可控的输入修正;或者为每个隐含层神经元设置一个偏置参数.

    我们将n个特征依次送入输入神经元, 隐含层神经元获得输入层的输出并计算自己输出值, 输出层的神经元根据隐含层输出计算出回归值.

    上述过程一般称为前馈(Feed-Forward)过程, 该过程中神经网络的输入输出与多维函数无异.

    现在我们的问题是如何训练这个神经网络.

    作为监督学习算法,BP神经网络的训练过程即是根据前馈得到的预测值和参考值比较, 根据误差调整连接权重\(W_{ij}\)的过程.

    训练过程称为反向传播过程(BackPropagation), 数据流正好与前馈过程相反.

    首先我们随机初始化连接权重\(W_{ij}\), 对某一训练样本进行一次前馈过程得到各神经元的输出.

    首先计算输出层的误差:

    \[E_j= sigmod'(O_j)*(T_j-O_j) =O_j(1-O_j)(T_j-O_j)

    \]

    其中\(E_j\)代表神经元j的误差,\(O_j\)表示神经元j的输出, \(T_j\)表示当前训练样本的参考输出, \(sigmod'(x)\)是上文sigmod函数的一阶导数.

    793413-20170106165524300-795195019.jpg

    计算隐含层误差:

    \[E_j= sigmod'(O_j)*\sum_kE_kW_{jk} =O_j(1-O_j)\sum_kE_kW_{jk}

    \]

    隐含层输出不存在参考值, 使用下一层误差的加权和代替\((T_j-O_j)\).

    计算完误差后就可以更新\(W_{ij}\)和\(\theta_j\):

    \[W_{ij}=W_{ij}+\lambda E_jO_i

    \]

    其中\(\lambda\)是一个称为学习率的参数,一般在(0,0.1)区间上取值.

    实际上为了加快学习的效率我们引入称为矫正矩阵的机制, 矫正矩阵记录上一次反向传播过程中的\(E_jO_i\)值, 这样\(W_j\)更新公式变为:

    \[W_{ij}=W_{ij}+\lambda E_jO_i + \mu C_{ij}

    \]

    \(\mu\)是一个称为矫正率的参数.随后更新矫正矩阵:

    \[C_{ij} = E_jO_i

    \]

    每一个训练样本都会更新一次整个网络的参数.我们需要额外设置训练终止的条件.

    最简单的训练终止条件为设置最大迭代次数, 如将数据集迭代1000次后终止训练.

    单纯的设置最大迭代次数不能保证训练结果的精确度, 更好的办法是使用损失函数(loss function)作为终止训练的依据.

    损失函数可以选用输出层各节点的方差:

    \[L = \sum_j(T_j-O_j)^2

    \]

    为了避免神经网络进行无意义的迭代, 我们通常在训练数据集中抽出一部分用作校验.当预测误差高于阈值时提前终止训练.

    Python实现BP神经网络

    首先实现几个工具函数:

    def rand(a, b):

    return (b - a) * random.random() + a

    def make_matrix(m, n, fill=0.0): # 创造一个指定大小的矩阵

    mat = []

    for i in range(m):

    mat.append([fill] * n)

    return mat

    定义sigmod函数和它的导数:

    def sigmoid(x):

    return 1.0 / (1.0 + math.exp(-x))

    def sigmod_derivate(x):

    return x * (1 - x)

    定义BPNeuralNetwork类, 使用三个列表维护输入层,隐含层和输出层神经元, 列表中的元素代表对应神经元当前的输出值.使用两个二维列表以邻接矩阵的形式维护输入层与隐含层, 隐含层与输出层之间的连接权值, 通过同样的形式保存矫正矩阵.

    定义setup方法初始化神经网络:

    def setup(self, ni, nh, no):

    self.input_n = ni + 1

    self.hidden_n = nh

    self.output_n = no

    # init cells

    self.input_cells = [1.0] * self.input_n

    self.hidden_cells = [1.0] * self.hidden_n

    self.output_cells = [1.0] * self.output_n

    # init weights

    self.input_weights = make_matrix(self.input_n, self.hidden_n)

    self.output_weights = make_matrix(self.hidden_n, self.output_n)

    # random activate

    for i in range(self.input_n):

    for h in range(self.hidden_n):

    self.input_weights[i][h] = rand(-0.2, 0.2)

    for h in range(self.hidden_n):

    for o in range(self.output_n):

    self.output_weights[h][o] = rand(-2.0, 2.0)

    # init correction matrix

    self.input_correction = make_matrix(self.input_n, self.hidden_n)

    self.output_correction = make_matrix(self.hidden_n, self.output_n)

    定义predict方法进行一次前馈, 并返回输出:

    def predict(self, inputs):

    # activate input layer

    for i in range(self.input_n - 1):

    self.input_cells[i] = inputs[i]

    # activate hidden layer

    for j in range(self.hidden_n):

    total = 0.0

    for i in range(self.input_n):

    total += self.input_cells[i] * self.input_weights[i][j]

    self.hidden_cells[j] = sigmoid(total)

    # activate output layer

    for k in range(self.output_n):

    total = 0.0

    for j in range(self.hidden_n):

    total += self.hidden_cells[j] * self.output_weights[j][k]

    self.output_cells[k] = sigmoid(total)

    return self.output_cells[:]

    定义back_propagate方法定义一次反向传播和更新权值的过程, 并返回最终预测误差:

    def back_propagate(self, case, label, learn, correct):

    # feed forward

    self.predict(case)

    # get output layer error

    output_deltas = [0.0] * self.output_n

    for o in range(self.output_n):

    error = label[o] - self.output_cells[o]

    output_deltas[o] = sigmod_derivate(self.output_cells[o]) * error

    # get hidden layer error

    hidden_deltas = [0.0] * self.hidden_n

    for h in range(self.hidden_n):

    error = 0.0

    for o in range(self.output_n):

    error += output_deltas[o] * self.output_weights[h][o]

    hidden_deltas[h] = sigmod_derivate(self.hidden_cells[h]) * error

    # update output weights

    for h in range(self.hidden_n):

    for o in range(self.output_n):

    change = output_deltas[o] * self.hidden_cells[h]

    self.output_weights[h][o] += learn * change + correct * self.output_correction[h][o]

    self.output_correction[h][o] = change

    # update input weights

    for i in range(self.input_n):

    for h in range(self.hidden_n):

    change = hidden_deltas[h] * self.input_cells[i]

    self.input_weights[i][h] += learn * change + correct * self.input_correction[i][h]

    self.input_correction[i][h] = change

    # get global error

    error = 0.0

    for o in range(len(label)):

    error += 0.5 * (label[o] - self.output_cells[o]) ** 2

    return error

    定义train方法控制迭代, 该方法可以修改最大迭代次数, 学习率\(\lambda\), 矫正率\(\mu\)三个参数.

    def train(self, cases, labels, limit=10000, learn=0.05, correct=0.1):

    for i in range(limit):

    error = 0.0

    for i in range(len(cases)):

    label = labels[i]

    case = cases[i]

    error += self.back_propagate(case, label, learn, correct)

    编写test方法,演示如何使用神经网络学习异或逻辑:

    def test(self):

    cases = [

    [0, 0],

    [0, 1],

    [1, 0],

    [1, 1],

    ]

    labels = [[0], [1], [1], [0]]

    self.setup(2, 5, 1)

    self.train(cases, labels, 10000, 0.05, 0.1)

    for case in cases:

    print(self.predict(case))

    完整源代码参见bpnn.py

    使用tensorflow实现一个神经网络可能是更简单高效的方法, 可以参见tensorflow入门指南中的第二节:实现一个简单神经网络.

    展开全文
  • import numpy as np#科学计算的基础 # 定义sigmoid函数及其求导,deriv=False时进行前向传播的运算,deriv=True进行反向传播的运算 # 即当derive为假时,不计算导数,反之计算,控制传播方向。 def sigmoid(x, ...

     注释为当前行的注释或者是下一行的注释。

    import numpy as np#科学计算的基础包
    
    # 定义sigmoid函数及其求导,deriv=False时进行前向传播的运算,deriv=True进行反向传播的运算
    # 即当derive为假时,不计算导数,反之计算,控制传播方向。
    def sigmoid(x, deriv=False):
        if (deriv == True):# 求导
            return x * (1 - x)#这里x=1/(1+exp(-x)),是sigmoid函数求导后的结果根据前向传播,x=sigmoid(x),求导需要(sigmoid(x)',e,而这里的return语句中的x替换为sigmoid(x)与求导等价
        return 1 / (1 + np.exp(-x)) #前向传播
    
    
    #输入4个样本,每个样本三个特征值
    X = np.array([[0, 0, 1],
                  [0, 1, 1],
                  [1, 0, 1],
                  [1, 1, 1]])
    print(X.shape)
    
    #每一行对应的类用0,1表示
    y = np.array([[0, 1, 1, 0]]).T
    print(y.shape)
    
    # 初始化权重weight01的维数与样本特征与神经元的个数有关,random初始化的值在(0,1)的半开区间内,乘2减1后控制w0的值在(-1.+1)区间上
    weight01 = 2 * np.random.random((3, 4)) - 1#生成生成3行 4列的随机浮点数,w01左边连3个特征,右边连4个神经元,浮点数范围:(0,1)
    weight12 = 2 * np.random.random((4, 2)) - 1#生成生成4行 2列的随机浮点数,w12左边连4个神经元,右边连2个神经元,浮点数范围:(0,1)
    weight23 = 2 * np.random.random((2, 1)) - 1#生成生成2行 1列的随机浮点数,w23左边连两个神经元,右边连一个输出值,浮点数范围:(0,1)
    
    # 初始化偏倚
    b1 = 2 * np.random.random((1, 4)) - 1#第一个隐层四个神经元
    b2 = 2 * np.random.random((1, 2)) - 1#第二个隐层两个神经元
    b3 = 2 * np.random.random((1, 1)) - 1#输出层一个神经元
    bias1 = np.array([b1[0], b1[0], b1[0], b1[0]])#array是数组函数
    print(bias1)
    bias2 = np.array([b2[0], b2[0], b2[0], b2[0]])
    bias3 = np.array([b3[0], b3[0], b3[0], b3[0]])
    
    # 开始训练
    for j in range(60000):#迭代六万次
        I0 = X#将x的值给l0,l0为输入层
        O0 = I0#4行3列
        I1 = np.dot(O0, weight01) + bias1# 默认False,是进行前向传播
        O1 = sigmoid(I1)#中间层经过第一层后的值,4行4列
        I2 = np.dot(O1, weight12) + bias2# 默认False,是进行前向传播
        O2 = sigmoid(I2)#中间层经过第二层后的值,4行2列
        I3 = np.dot(O2, weight23) + bias3# 默认False,是进行前向传播
        O3 = sigmoid(I3) #输出层的值,4行1列
    
        f3_error = y - O3#输出层的值与期望的值的差异
    
        if (j % 10000) == 0:
            print("Error:" + str(np.mean(f3_error)))#每经过一万次迭代输出一次差异值的平均值,以便观察差异值是否减小
    
        f3_delta = f3_error * sigmoid(O3, deriv=True)#w23对错误的贡献,反向传播,误差作为一个权重,误差越大权重越大
        #print(f3_delta.shape),(4行1列)
    
        f2_error = f3_delta.dot(weight23.T)#反向传播根据f3_delta得出,矩阵f3_delta乘w23的转置
    
        f2_delta = f2_error * sigmoid(O2, deriv=True)#w12对错误的贡献,反向传播,误差作为一个权重,误差越大权重越大
        #print(f2_delta.shape),(4行2列)
    
        f1_error = f2_delta.dot(weight12.T)#反向传播根据f2_delta得出,矩阵f2_delta乘w12的转置
    
        f1_delta = f1_error * sigmoid(O1, deriv=True)#w01对错误的贡献,反向传播,误差作为一个权重,误差越大权重越大
        #print(f1_delta.shape),(4行4列)
        weight23 += O2.T.dot(f3_delta)# 调整权重,根据反馈过来的结果对w23进行调节 , 因为从后往前,所以先更新w23
        weight12 += O1.T.dot(f2_delta)# 调整权重,根据反馈过来的结果对w12进行调节
        weight01 += O0.T.dot(f1_delta)# 调整权重,根据反馈过来的结果对w01进行调节
    
        bias3 += f3_delta  # 调整偏倚
        bias2 += f2_delta
        bias1 += f1_delta
    
    print("outout after Training:")
    print(O3)

     

    展开全文
  • BP神经网络的实现+python

    千次阅读 2020-04-06 14:42:33
    什么是神经网络(Neural Network) 计算机处理数字计算十分简单,然而处理图像数据却十分困难。通过利用生物学的设计构建一个使计算机能处理高维数据的模型,从而产生了神经网络这样的技术。 假设有这样一台机器,接受...

    本科生毕业设计想出来一个题目,用CNN来手写体识别。出了题目之后,发现对NN的知识都忘光了,现在重新手写NN来再学一次。

    什么是神经网络(Neural Network)

    计算机处理数字计算十分简单,然而处理图像数据却十分困难。通过利用生物学的设计构建一个使计算机能处理高维数据的模型,从而产生了神经网络这样的技术。
    假设有这样一台机器,接受一个问题进行思考,然后得出答案。对于人类而言就是这样一个过程,对于计算机来说。这样的过程变成了:输入->计算->输出。但是从流程上看起来他们是相似的。
    {% asset_img 1.png 预测机 %}
    {% asset_img 2.png 神经元 %}
    生物大脑的基本单元是神经元,虽然有各种形式,但是他们的本质就是将电信号从一端传递到另一端,从一个神经元传递到另一个神经元。然而,每个神经元的输入信号可能是单个,也可能是多个。有时候单个信号的输入并不能很好的解决某些问题(例如异或情况的分类)。
    {% asset_img 3.png 多个信号的输入 %}
    {% asset_img 4.png 异或XOR的分类 %}
    但是与传统函数的输入输出不同,神经元对于微小的噪声信号直接忽略,只有在输入信号高于**阈值(threshold)才会产生输出。因此多个信号输入之后进行累加求和,当求和总量达到某个阈值后,神经元被激活,产生输出结果。这就是神经元。
    {% asset_img 5.png 激活神经元 %}
    关于阈值的判断,需要一个名为
    激活函数(activtion function)**的模型来对信号进行处理。激活函数的种类十分多,普遍比较多的是Sigmoid函数。
    s i g m o i d ( x ) = 1 1 + e − x sigmoid(x)=\frac{1}{1+e^{-x}} sigmoid(x)=1+ex1
    这个函数相比较于阶跃函数比较平滑。
    通过多个神经元之间的连接,构造一种名为神经网络的模型方法,对于计算机识别高维度的数据而言具有良好的适用性。
    {% asset_img 6.png 生物神经网络 %}

    神经网络的工作原理

    {% asset_img 7.png 神经网络模型 %}
    传统的神经网络分为三层,输入层(input layer)隐藏层(hidden layer)输出层(output layer)。隐藏层可以有多层网络构建,每层之间依靠连接权值进行连接。

    正向传值

    现在开始考虑正向传值计算,即从输入->输入层->隐藏层->输出层的过程。从单个神经元开始分析,从输入层开始,当输入值进入输入层时,输入值就只是单纯赋值给输入层节点,即输入值=输入单元,无需进行计算。
    从输入层进入隐藏层开始,引入了权值的概念。即输入*权值的过程。
    {% asset_img 8.png 隐藏层神经元 %}
    再将得到的值经过激活函数进行调节,这样就能得到隐藏层每个节点的输入结果。将得到的结果放入输出层再次进行计算,这样子我们就得到了一个完整的正向传播过程。
    为了计算方便,引入矩阵来进行计算。令输入层数据为 I I I,输入层权值矩阵为 W i h W_{ih} Wih。则进入隐藏层的和值为:
    X h i d d e n = W i h I X_{hidden}=W_{ih}I Xhidden=WihI
    再将这个和值通过对应的激活函数进行激活得到隐藏层的输出,在这里我们使用Sigmoid函数作为激活函数(此时计算出来的 X X X为值向量,长度为隐藏层神经元的个数),输出值为:
    O h i d d e n = S i g m o i d ( X h i d d e n ) O_{hidden}=Sigmoid(X_{hidden}) Ohidden=Sigmoid(Xhidden)
    然后将隐藏层输出值 O h i d d e n O_{hidden} Ohidden放入到输出层重复以上步骤输出,得到输出矩阵 O o u t p u t O_{output} Ooutput

    反向传播(BackPropagation)

    单次的正向传播得出的结果和实际结果相差可能会很大,现在需要做的就是使用这个误差来调整神经网络本身,进而改进输出值。
    误差值的修正,是通过权值来进行实现的。当我们得到正向计算矩阵 O o u t p u t O_{output} Ooutput之后,可以求得输出误差 E o u t p u t = T − O o u t p u t E_{output}=T-O_{output} Eoutput=TOoutput,通过来自多个节点的权重进行反馈传播,这里还是要用到矩阵的计算,首先将隐藏输出系数矩阵 W h o W_{ho} Who进行转置,然后和输出误差点乘,公式如下:
    E h i d d e n = W h o T E o u t p u t E_{hidden}=W_{ho}^{T}E_{output} Ehidden=WhoTEoutput
    使用这样的方式是将误差分割,按照权值的比例进行分配给不同的神经元。虽然也有其他的分配方式(如均匀分配),但是按权分配是比较合理的做法。
    {% asset_img 9.png 误差反馈 %}

    更新权重

    虽然得到了每个神经元的误差值,但是还是没有解决如何更新权值的问题。在这里我们使用最简明且有效的方法:梯度下降(Gradient Descent)。关于梯度下降的过程,在手写线性回归的实现那章当中我有写,这里就不再描述了。
    我们的目标是求得 ∂ E ∂ w i j \frac{\partial E}{\partial w_{ij}} wijE的极小值。这里使用链式法则并将每个项展开。
    ∂ E ∂ w i j = ∂ E ∂ o k × ∂ o k ∂ w i j \frac{\partial E}{\partial w_{ij}}=\frac{\partial E}{\partial o_{k}}\times\frac{\partial o_{k}}{\partial w_{ij}} \\ wijE=okE×wijok
    E = ∑ n ( t n − o n ) 2 E=\sum _{n}(t_{n}-o_{n})^{2} \\ E=n(tnon)2
    o k = s i g m o i d ( ∑ j w j k o j ) o_{k}=sigmoid(\sum_{j} w_{jk} o_{j}) ok=sigmoid(jwjkoj)
    sigmoid函数求导过程十分复杂,这里不赘述。将上式化简得:
    ∂ E ∂ w i j = − ( e j ) × s i g m o i d ( ∑ i w i j o i ) × ( 1 − s i g m o i d ( ∑ i w i j o i ) ) × o i \frac{\partial E}{\partial w_{ij}}=-(e_{j}) \times sigmoid(\sum_{i} w_{ij} o_{i})\times(1-sigmoid(\sum_{i} w_{ij} o_{i}))\times o_{i} wijE=(ej)×sigmoid(iwijoi)×(1sigmoid(iwijoi))×oi
    这里将公式化为了输入-隐藏层的下标,隐藏-输出层权值更新同理。
    {% asset_img 10.png 权重更新表示 %}
    得到了修正值之后,设定学习率 α \alpha α,然后得到更新权值如下:
    w j k = w j k − α ∂ E ∂ w j k w_{jk}=w_{jk}-\alpha\frac{\partial E}{\partial w_{jk}} wjk=wjkαwjkE
    虽然一次更新的量十分微小,但是训练集量足够预测效果将十分优秀。
    以上基本就是BP神经网络的工作原理,接下来我们使用python手写一个BP神经网络,并使用mnist手写体训练集来测试效果。

    编码实现

    class NeuralN:
        def __init__(self,input_nodes,hidden_nodes,output_nodes,learning_rate):
            self.inodes = input_nodes
            self.hnodes = hidden_nodes
            self.onodes = output_nodes
            
            self.lr = learning_rate
        
            self.wih = np.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.inodes))
            self.who = np.random.normal(0.0,pow(self.onodes,-0.5),(self.onodes,self.hnodes))
            
            self.activtion_fun = lambda x: special.expit(x)
            
        def train(self,inputs_list,targets_list):
            inputs = np.array(inputs_list, ndmin=2).T
            targets = np.array(targets_list,ndmin=2).T
            
            hidden_inputs = np.dot(self.wih,inputs)
            hidden_outputs = self.activtion_fun(hidden_inputs)
    #         print(hidden_outputs.shape)
            final_inputs = np.dot(self.who,hidden_outputs)
            final_outputs = self.activtion_fun(final_inputs)
            
            outputs_error = targets - final_outputs
            
            hidden_error = np.dot(self.who.T,outputs_error)
            
    #         print(hidden_error.shape)
            print((hidden_error * hidden_outputs * (1 - hidden_outputs)).shape)
    #         print('+++++++++++++++++')
            print(np.transpose(inputs).shape)
            print('+++++++++++++++++')
    #         print(np.dot((outputs_error * final_outputs * (1 - final_outputs)),np.transpose(hidden_outputs)))
            
            self.who += self.lr * np.dot((outputs_error * final_outputs * (1.0 - final_outputs)), \
                                         np.transpose(hidden_outputs))
            
            self.wih += self.lr * np.dot((hidden_error * hidden_outputs * (1.0 - hidden_outputs)), \
                                         np.transpose(inputs))
            pass
        
        def query(self,inputs_list):
            inputs = np.array(inputs_list, ndmin=2).T
            
            hidden_inputs = np.dot(self.wih,inputs)
            
            hidden_outputs = self.activtion_fun(hidden_inputs)
            
            final_inputs = np.dot(self.who,hidden_outputs)
            
            final_outputs = self.activtion_fun(final_inputs)
            
            return final_outputs
    
    

    这里是BP神经网络的基本框架。读取的数据是手写数据集,每个图像都是28x28的矩阵,训练集包含了70000个手写体数据。这里的不能使用有序的数据进行训练,不然就会取值趋于最后一个特定值。(之前使用了sklearn自带的数据集,调了一下午QAQ)下面我们开始加载数据,调用框架。

    input_nodes = 784
    hidden_nodes = 100
    output_nodes = 10
    learning_rate = 0.3
    
    n = NeuralN(input_nodes,hidden_nodes,output_nodes,learning_rate)
    
    training_data_file = open("./mnist_train.csv",'r')
    training_data_list = training_data_file.readlines()
    training_data_file.close()
    
    for record in training_data_list:
        all_values = record.split(',')
        inputs = (np.asfarray(all_values[1:])/255*0.99)+0.01
        targets = np.zeros(output_nodes) + 0.01
        targets[int(all_values[0])] = 0.99
        n.train(inputs,targets)
    
    # train_list = X[:10000,:]
    # target_list = Y[:10000]
    # i = 0
    # for record in train_list:
    # #     print(record.shape)
    #     inputs_list = (np.asfarray(record[:]/255*0.99)+0.01)
    # #     print(inputs_list.shape)
    #     targets = np.zeros(output_nodes) + 0.01
    #     print(target_list[i])
    #     targets[int(target_list[i])] = 0.99
    #     i += 1
    #     print(i)
    #     print(targets)
    #     n.train(inputs_list,targets)
    #     print()
    

    训练完成之后我们开始预测。读取测试集,使用计分表进行积分,输出正确率。

    test_data_file = open("./mnist_test.csv",'r')
    test_data_list = test_data_file.readlines()
    test_data_file.close()
    
    scorecard =[]
    
    for record in test_data_list:
        all_values = record.split(',')
        correct_label = int(all_values[0])
        print(correct_label,'correct label')
        inputs = (np.asfarray(all_values[1:])/255*0.99)+0.01
        outputs = n.query(inputs)
        label = np.argmax(outputs)
        print(label,'net answer')
        if label == correct_label:
            scorecard.append(1)
        else:
            scorecard.append(0)
    
    scorecard_arr = np.array(scorecard)
    print(scorecard_arr.sum()/scorecard_arr.size)
    

    最后正确率在93左右。

    总结

    整个手写基本参考《python神经网络编程》。这本书基本上详细讲明了BP神经网络和python基本开发方法,这篇博客是在这本书的基础上加上自身的学习经验所作的一个简单总结。因为时间有限,书中很多内容都没有好好总结(公式推导,预测问题,矩阵计算,权重初始随机等)。还有很多可以优化的地方,如学习率优化,隐藏层节点数优化等等。在这之后,卷积神经网络(Convolutional Neural Networks, CNN)是对于BP神经网络而言,在手写体识别具有更好的效果。毕业设计的题目也是使用CNN来进行手写体识别,所以说下一步就开始手写CNN试试。

    参考链接

    原文
    《python神经网络编程》

    展开全文
  • BP神经网络Python实现

    2018-10-13 17:54:18
    class BPNeuralNetwork: def __init__(self): self.input_n = 0 self.hidden_n = 0 self.output_n = 0 self.input_cells = [] self.hidden_cells = [] self.output_cells = [] self.input_weights = [] ...
    # encoding:utf-8
    import numpy as np
    import math
    import random
    def rand(a, b):
        return (b-a)*random.random() + a
    
    def make_matrix(m, n, fill=0.0):
        mat = []
        for i in range(m):
            mat.append([fill]*n)
        return mat
    
    def sigmoid(x):
        return 1.0 / (1.0+math.exp(-x))
    
    def sigmoid_derivate(x):
        return x*(1-x)
    
    class BPNeuralNetwork:
        def __init__(self):
            self.input_n = 0
            self.hidden_n = 0
            self.output_n = 0
            self.input_cells = []
            self.hidden_cells = []
            self.output_cells = []
            self.input_weights = []
            self.output_weights = []
    
        def setup(self, ni, nh, no):
            self.input_n = ni +1
            self.hidden_n = nh
            self.output_n = no
    
            self.input_cells = [1.0] * self.input_n
            self.hidden_cells = [1.0] * self.hidden_n
            self.output_cells = [1.0] * self.output_n
    
            self.input_weights = make_matrix(self.input_n, self.hidden_n)
            self.output_weights = make_matrix(self.hidden_n, self.output_n)
    
            #random active
            for i in range(self.input_n):
                for h in range(self.hidden_n):
                    self.input_weights[i][h] = rand(-0.2, 0.2)
            for h in range(self.hidden_n):
                for o in range(self.output_n):
                    self.output_weights[h][o] = rand(-2.0, 2.0)
    
        def predict(self, inputs):
            for i in range(self.input_n - 1):
                self.input_cells[i] = inputs[i]
    
            for j in range(self.hidden_n):
                total = 0.0
                for i in range(self.input_n):
                    total += self.input_cells[i] * self.input_weights[i][j]
                self.hidden_cells[j] = sigmoid(total)
    
            for k in range(self.output_n):
                total = 0.0
                for j in range(self.hidden_n):
                    total += self.hidden_cells[j] * self.output_weights[j][k]
                self.output_cells[k] = sigmoid(total)
    
            return self.output_cells[:]
    
        def back_propagate(self, case, label, learn):
            self.predict(case)
            #计算输出层的误差
            output_deltas = [0.0] * self.output_n
            for k in range(self.output_n):
                error = label[k] - self.output_cells[k]
    
                output_deltas[k] = sigmoid_derivate(self.output_cells[k])*error
    
            hidden_deltas = [0.0] * self.hidden_n
            for j in range(self.hidden_n):
                error = 0.0
                for k in range(self.output_n):
                    error += output_deltas[k] * self.output_weights[j][k]
                    hidden_deltas[j] = sigmoid_derivate(self.hidden_cells[j]) * error
            #更新输出层权重
            for j in range(self.hidden_n):
                for k in range(self.output_n):
                    self.output_weights[j][k] += learn * output_deltas[k] * self.hidden_cells[j]
            #更新隐藏层权重
            for i in range(self.input_n):
                for j in range(self.hidden_n):
                    self.input_weights[i][j] += learn*hidden_deltas[j]*self.input_cells[i]
    
            error = 0
            for o in range(len(label)):
                error += 0.5 * (label[o] - self.output_cells[o]) ** 2
                return error
    
        def train(self, cases, labels, limit=100, learn=0.05):
            for i in range(len(cases)):
                error = 0
                label = labels[i]
                case = cases[i]
                error += self.back_propagate(case, label, learn)
            pass
        def test(self):
            cases = [
                [0,0],
                [0,1],
                [1,0],
                [1,1],
            ]
            labels = [[0],[1],[1],[0]]
            self.setup(2,5,1)
            self.train(cases,labels,10000,0.05)
            for case in cases:
                print(self.predict(case))
    
    if __name__=="__main__":
        nn = BPNeuralNetwork()
        nn.test()
    [0.8011297025491382]
    [0.8150046347993829]
    [0.8064371429753873]
    [0.8200696997295588]
    

     

    展开全文
  • bp神经网络python实现

    千次阅读 2017-04-18 23:28:00
    最近在看深度学习的东西,一开始看的吴恩达的UFLDL教程,有中文版就直接看了,后来发现有些地方总是不是很明确,又去看英文版,然后又找了些资料看,才发现,中文版的...反向传播法其实是神经网络的基础了,但是
  • 一、BP神经网络结构模型   BP算法的基本思想是,学习过程由信号的正向传播和误差的反向传播俩个过程组成,输入从输入层输入,经隐层处理以后,传向输出层。如果输出层的实际输出和期望输出不符合,就进入误差的...
  • 1) 局部极小化问题:从数学角度看,传统的 BP神经网络为一种局部搜索的优化方法,它要解决的是一个复杂非线性化问题,网络的权值是通过沿局部改善的方向逐渐进行调整的,这样会使算法陷入局部极值,权值收敛到局部极...
  • BP神经网络理解原理——用Python编程实现识别手写数字    备注,这里可以用这个方法在csdn中编辑公式: https://www.zybuluo.com/codeep/note/163962 一、前言   本文主要根据一片英文书籍进行学习,并且...
  • BP神经网络的原理及Python实现

    千次阅读 2017-09-02 10:35:53
    网络结构 层数:2 输入个数:3 隐藏层节点数:10 输出层节点数:1 数据结构 用一个dict表示整个网络: {’input_layer’ : 输入节点列表 , ‘hidden_layer’ : 隐藏层节点列表 , ‘output_layer’ :...
  • 在这篇教程中,我会给大家介绍一些神经网络概念,实现代码和数据推导,可以帮助你更好的理解和构建一个神经网络。网上的一些教程要不侧重于数学推导,要不侧重于代码实现,这些都是非常不利于理解神经网络的。在这篇...
  • BP神经网络源码.rar

    2020-12-07 22:53:10
    python代码实现,可以调整网络结构,适用分类与回归问题,包含随机梯度下降、动量梯度下降,RMSProp、Adam优化算法。通过hyperopt优化参,另外补充了一些测试demo
  • 实验要求: 实现一个手写数字识别程序, 如下图所示, 要求神经网络包含一个隐层, 隐层的神经元个数为 15。 整体思路:主要参考西瓜书第五章神经网络部分的介绍,使用批量梯度下降对神经网络进行训练。 Tip: 整体...
  • 人工神经网络(Artificial Neural Networks,ANN)系统是 20 世纪 40 年代后出现的。它是由众多的神经元可调的连接权值连接而成,具有大规模并行处理、分布式信 息存储、良好的自组织自学习能力等特点。
  • 盲区行者:深度学习之BP神经网络--Stata和R同步实现(附R数据和代码)​zhuanlan.zhihu.com原公众号推文标题:深度学习之BP神经网络-Stata和R同步实现(附数据和代码)神经网络(Neural Network,或Artif...
  • Ref: 1、https://blog.csdn.net/luanpeng825485697/article/details/79009223 2、
  • 虽然说在python中通过tensorflow、pytorch等工具库构建神经网络模型真的很方便,但是通过编写自己动手编写代码来实现能够更好地理解整个神经网络模型,今天就以最简单的bp神经网络为例,来给大家展示一下如何...
  • 搭建BP神经网络(准确率较低) from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelBinarizer, StandardScaler from sklearn.metrics import confusion_matrix, ...
  • python的神经网络实现之BP神经网络

    千次阅读 2018-10-14 14:20:37
    直接上代码BP神经网络的一般形式: -- coding: utf-8 -- “”" Created on Sun Oct 14 10:41:33 2018 @author: fang “”" -- coding:utf-8 -- #! python2 import numpy as np 定义...
  • 给出深度神经网络BP算法代码实现(文末)及结果.1 激活函数的位置上文最后小节(3.3)介绍了结合Softmax和Cross Entropy Loss Function的神经网络反向传播输出层梯度计算. 在该网络中,输出层(第...
  • BP网络(Back-Propagation Network)是1986年由Rumelhart 和 McCelland 为首的科学教小组提出的,是一种按误差逆向传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一,用于函数逼近、模型识别分类、...
  • 竞争型学习神经网络 简述 最近对神经网络比较感兴趣,因此花了两三天时间对整个领域进行了简单的调研,梳理和学习。其中深度学习,尤其以我们熟悉的如今大火的深度网络模型,如CNN, RNN, GAN和AE及它们的子类等;是在...
  • bp神经网络 python初探

    2016-08-04 16:32:15
    最近抽空学习了一下bp神经网络,并且用python实现了一下。 加入了动量项和自调节步长,都是为了拟合的更快一些(这里指定了次数) python的numpy里的矩阵乘法有些坑人,行列不分;被坑了很久,只好看了一下网上大神...
  • BP神经网络对鸢尾花进行分类

    千次阅读 多人点赞 2020-05-15 21:51:42
    题目:BP神经网络分类器 一、实验项目: BP神经网络对鸢尾花进行分类 二、实验目的: 掌握BP神经网络学习算法,利用BP神经网络进行数据分类 三、实验内容: 1、编程实现BP神经网络算法 2、建立三层BP神经网络,节点...
  • 基于keras库训练BP神经网络的实例

    千次阅读 2020-07-15 19:59:38
    学习了BP神经网络的原理后,我使用python的keras库来训练一个BP神经网络的实例 1.数据集准备 下表由雇员数据库的训练数据组成。数据已泛化,例如,age “31–35"表示年龄在31~ 35之间。对于给定的行,count表示...
  • 一文详解神经网络 BP 算法原理及 Python 实现 | 雷峰网关于反向传播。https://www.leiphone.com/category/yanxishe/TMsNCqjpOIfN3Bjr.html 这篇博客写的非常的好。本文为了珍藏,复制了一份。 什么是梯度下降和...
  • 详细BP神经网络预测算法及实现过程实例

    万次阅读 多人点赞 2019-09-13 21:47:37
    BP神经网络通常采用Sigmoid可微函数和线性函数作为网络的激励函数。本文选择S型正切函数tansig作为隐层神经元的激励函数。而由于网络的输出归一到[ -1, 1]范围内, 因此预测模型选取S 型对数函数tansig作为输出层...
  • python编写自己的RBF径向基神经网络

    千次阅读 2020-12-19 13:18:18
    目录 前言 一、RBF神经网络 1.代码 ...径向基函数神经网络是一种前馈式神经网络,包含输入层、隐含层和输出层,其多...RBF神经网络在电网故障中的应用,RBF神经网络改善了BP神经网络的各层之间权值和阈值的复杂运...
  • 脑机接口研习社公众号即将开通机器学习专栏,从本篇文章开始,将介绍如何利用Bindsnet-Python包模拟脉冲神经网络(SNN)。 一、脉冲神经网络(SNN)简介 首先,我们来看什么是人工神经网络。 人工神经网络...
  • CNN卷积神经网络案例程序源代码合集matlab/Python等 1、深入理解CNN(包括CNN的过程显示和前向后向推倒,以及CNN的应用举例。) 2、kerasttensorflow CNN(CNN_python程序集.rar) 3、CNN-Tensorflow交通标志识别 4、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,313
精华内容 525
关键字:

bp神经网络python代码调包

python 订阅