机器学习实战四(神经网络)

image * NumPy 是Python语言的一个扩充程序库。支持高级大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

二、单层神经元

1. 问题描述

问题

  • 假设在一群人中,我们只能获得每个人的三个特征:
  1. 特征1:长发(1)还是短发(0)
  2. 特征2:衣服颜色是红色(1)还是不是红色(0)
  3. 特征3:身高大于178cm(1)还是不超过178(0)
  • 假设我们只知道其中四个人的性别(男:0,女:1),我们需要依据这四个人的三个特征以及性别训练一个神经网络,用于预测一个人的性别。
  • 因此该问题有三个输入,一个输出。

样本信息如下:

头发 衣服 身高 性别
0 0 1 0
1 1 1 1
1 0 1 1
0 1 1 0

2. 简单的单层神经网络

  1. 用X表示输入的特征向量,由于每个样本有三个特征,一共有四个样本,所以我们定义一个4X3的矩阵,每一行代表一个样本

    1
    2
    3
    4
    5
    6
    7
    #import numpy
    import numpy as np
    # input dataset
    X = np.array([[0, 0, 1],
    [0, 1, 1],
    [1, 0, 1],
    [1, 1, 1]])

  2. 而四个样本对应输出(分类结果)我们用一个1X4的矩阵表示。.T为转置函数,转置后变成了4X1的矩阵。
  • 同我们的输入一致,每一行是一个训练实例,而每一列(仅有一列)对应一个输出节点。
    1
    y = np.array([[0, 0, 1, 1]]).T
  1. 初始化神经网络的权重
  • 由于输入层有三个神经元,而输出结果只有一个神经元,所以权重矩阵为3x1。
  • 由于一般初始化权重是随机选择的,因此要为随机数设定产生的种子(如下代码所示)
  • 这样可以使每次训练开始时,得到的训练随机数都是一致的。这样便于观察策略变动是如何影响网络训练的,消除初始权重的影响。
1
np.random.seed(1)
  • 由于我们要将随机初始化的权重矩阵均值设定为0,因此要计算syn0(第一层网络间的权重矩阵)
1
syn0 = 2*np.random.random((3,1)) - 1
  1. sigmoid函数
  • 定义为:
    image
  • 特点:其导数可以用其自身表示出来,在计算的时候,我们只需要计算出其函数值,就可以计算出其导数值,从而可以减少浮点运算次数,提高效率
  • 导数为: image
  • python中代码实现

    1
    2
    3
    4
    5
    # sigmoid function
    def nonlin(x,deriv=False):
    if(deriv==True):
    return x*(1-x)
    return 1/(1+np.exp(-x))

  • 其中,deriv参数表示是否计算的是其导数值:

3. 开始训练神经网络

  • 迭代10000次,每一次迭代可描述如下
  1. 计算输入层的加权和,即用输入矩阵L0乘以权重矩阵syn0,并通过sigmid函数进行归一化。得到输出结果l1;
  2. 计算输出结果L1与真实结果y之间的误差L1_error;
  3. 计算权重矩阵的修正L1_delta,即用误差乘以sigmoid在L处的导数;(阶梯下降法
  4. 用L1_delta更新权重矩阵syn0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    for iter in range(10000):
    # forward propagation
    l0 = X
    l1 = nonlin(np.dot(l0,syn0))

    # how much did we miss?
    l1_error = y - l1

    # multiply how much we missed by the
    # slope of the sigmoid at the values in l1
    l1_delta = l1_error * nonlin(l1,True)

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

4. 一次训练过程的参数更新如下图所示:

  • image

    image

  • 批量循环训练 image

5.结果

1
2
3
4
Output syn0 After Training:
[[ 9.67299303]
[-0.2078435 ]
[-4.62963669]]
  1. 从syn0迭代后的输出可看出
  • yn0的第一个元素,也就是第一个输入特征(长发)的权重最大,而第二个和第三个特征都很小
  • 所以神经网络学习的结果是加重第一个特征的权重,而其他两个特征对于是女性这个推测的贡献较小,所以减小其权重。
  1. 为了验证训练结果,我们加入两组新数据,(短头发,红衣服,矮个子),(长头发,不是红衣服,矮个子),并用神经网络来进行分类:
1
2
3
X_new = np.array([[0,1,0],
[1,0,0]])
y_new = np.dot(X_new,syn0)
  • 计算结果如下:
    1
    2
    3
    Predicte With syn0:
    [[-0.2078435 ]
    [ 9.67299303]]

完整代码

三、二层神经网络