BP神经网络——一个两层神经网络

内容:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以下是一个两层神经网络的代码

import numpy as np
import pickle

# 非线性部分,“sigmoid”的函数,可以将任何值都映射到一个位于0到1范围内的值,
# 通过它,可以将实数转换为概率值,对于神经网络训练,Signomid 函数也有其非常不错的特性
# 通过“online”函数还能得到sigmod函数的导数(当形参derive 为 True 时)。
# Sigmoid 函数优异特性之一,在于只用它的输出值便可以得到其倒数值(即曲线在定点上的斜率)。若Sigmoid 的输出值用变量out表示,
# 则其倒数值可简单通过式子 out * (1 - out) 得到,这是非常高效的。
def nonlin(x, deriv=False):
    if (deriv==True):
        return x * (1 - x)#S函数的导数
    else:
        return 1 / (1 + np.exp(-x))

def load_data():
    fr = open('F:\python学习\代码\神经网络\BP神经网络\data_pickle.txt', 'rb')
    x = pickle.load(fr)
    fr.close()
    return (x)

# 将输入的数据集初始化为 numpy 中的矩阵。每一行为一个“训练实例”,每一列的对应着一个输入节点。
# 这样,我们的神经网络便有 3 个输入节点,4 个训练实例。
x = np.array([[0, 0, 1],
              [0, 1, 1],
              [1, 0, 1],
              [1, 1, 1]])

# 这行代码对输出数据集进行初始化。在本例中,为了节省空间,我们以格式水平(1行4列)定义成了数据集。
# “.T” 为转置函数。经转置后,该 y 矩阵便包含 4 行 1 列。 同我们的输入一致,每一行是一个训练实例,
# 而每一列(仅有一列)对应一个输出节点。因此,我们的网络含有3个输入,1个输出。
y = np.array([[0, 0, 1, 1]]).T

# 你的随机数设定产生种子是一个良好的习惯。这样一来,你得到的权重初始化集仍是随机分布的,但每次训练开始时,
# 得到的权重初始集分布都是完全一致的。这便于观察你的策略变动是如何影响网络训练的。
np.random.seed(1)

# 这行代码实现了该神经网络权重矩阵的初始化操作。用“sny0”来代指“零号突触”(即“输入层-第一层隐层”间权重矩阵)。
# 由于我们的神经网络只有两层(输入层与输出层),因此,想要将10层的每个神经元节点与11层的每个神经元节点相连,
# 就需要一个维度大小为(3,1)的连接矩阵。
# 关于权重的1初始化,有许多学问,这里只是练习,随机初始化的权重矩阵均值为0。
# 所谓的“神经网络”实际上就是这个权值矩阵。虽然有“层”10 和 11 ,但它们都是基于数据集的瞬间值,即层的输入输出
# 状态随不同输入数据而不同,这些状态是不需要保存的。在学习训练过程中,只需存储syno权值矩阵。
syn0 = 2 * np.random.random((3, 1)) - 1

# 本行开始就是神经网络训练代码了。本for循环迭代式地多次执行训练代码,使得我们的网络能够更好地拟合训练集。
for i in range(10000):

    # 网络第一层就是我们的输入数据,X 包含4个训练实例(行),该部分实现中将同时对所有的实现进行处理,这种训练方式
    # 称作“整批”训练。因此,虽然我们有 4 个不同的10行,但你可以将其整体视为单个训练实例,这样做并没有什么差别。
    # (我们可以在不改动一行代码的前提下,一次性装入1000个甚至10000个实例)。
    l0 = x

    # 这是神经网络的前向预测阶段。基本上,首先让网络基于给定输入“试着”去预测输出。
    # 接着,我们研究效果如何,以至于作出一些调整,使得在每次迭代过程中网络能够表现的更好一点。
    # ( 4 x 3 ) dot ( 3 x 1 ) = ( 4 x 1 )
    # 首先,将 10 与 syn0 进行矩阵相乘。然后,将计算结果传递给 sigmoid 函数。具体考虑到各个矩阵的维度。
    # ( 4 x 3 ) dot ( 3 x 1 ) = ( 4 x 1 )
    # 矩阵相乘是有约束的,比如等式靠中间的两个维度必须一致。而最终产生的矩阵。其行数为第一矩阵的行数,
    # 列数则为第二个矩阵的列数
    # 由于装入 4 个训练实例,因此最终得到了4个猜测结果,即一个( 4 x 1 )的矩阵。
    # 每一个输出都对应,给定输入下网络对正确结果的一个猜测。也许这也能直观解释:
    # 为什么可以“载入”任意数目的训练实例,它可以反映出网络的误差多大。
    l1 = nonlin(np.dot(l0, syn0))


    if (i == 1):
        print(l1)
        print(syn0)
    #(4*1)的矩阵。每一个输出都对应,给定输入下网络对正确结果的一个猜测。

    # 对应每一输入,可知 11 都对应的一个“猜测”结果。那么通过将真实的结果(y)与猜测结果(11)作减,就可以
    # 对比得到网络预测的效果怎么样。11_error是一个有正数和负数组成的向量,它可以反映出网络的误差有多大。
    l1_error = y - l1
    print(i, l1_error, '\n')

    # 这部分很复杂,单独说明。
    l1_delta = l1_error * nonlin(l1, True)

    syn0 += np.dot(l0.T, l1_delta)

print('over!\n', l1)
print(syn0)

在这里插入图片描述
此处省略很多组结果
在这里插入图片描述
第77行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第79行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发布了149 篇原创文章 · 获赞 52 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/weixin_43442290/article/details/90048153