神经网络NN简单理解以及算法

1.什么是神经网络

1.1 背景 :

  • 以人脑中的神经网络为启发,历史上出现过很多不同版本
  • 最著名的算法是1980年的 backpropagation

1.2 多层向前神经网络(Multilayer Feed-Forward Neural Network)

  • Backpropagation被使用在多层向前神经网络上
  • 多层向前神经网络由以下部分组成:
    输入层(input layer), 隐藏层 (hidden layers), 输入层 (output layers)

    神经网络NN简单理解以及算法_第1张图片

    • 每层由单元Unit组成
    • 连接Unit之间有权重weights
    • 输入层用来输入数据
    • 隐藏层数量可以是任意的
    • 理论上有足够多的数据以及足够多的隐藏层,该网络可以模拟出任何方程
    • 需要进行非线性的转换
    • 以上构成2层的神经网络 输入层不作为一层

2. 主要算法介绍

2.1 关于非线性转化方程(non-linear transformation function)

代码中叫做 sigmoid / sigmoidDer (命名不当,理解就好)
- 双曲函数(tanh) 以及 导数
numpy库提供了tanh函数 : numpy.tanh(x)
导数为 : 1.0tanh(x)2
- 逻辑函数(logistic function) 以及 导数
函数为 : logistic(x)=11+ex
导数为 : logistic(x)(1logistic(x))

2.2 BackPropagation 算法

简单的说就是通过迭代性的来处理训练集中的实例,经过神经网络后输入层预测值(predicted value)与真实值(target value)之间的误差不断调整权重weight来使其更加准确,最后反向计算误差来更新连接之间的权重weight

算法大致流程 :

  1. 建立神经网络
  2. 算法输入数据集 学习率(步长alpha)
  3. 初始化权重(weights)和偏向(bias): 随机初始化在-1到1之间,或者-0.5到0.5之间,每个单元有一个偏向
  4. 向前更新传送
  5. 根据误差反向更新(weights)
  6. 终止条件

2.3 基于算法的几个公式

       神经网络NN简单理解以及算法_第2张图片             神经网络NN简单理解以及算法_第3张图片

向前更新传送过程

  • 公式1: Oj=iOiwij+θj
  • 按照上图就是 Oj=y1w1j+y2w2j+...+ynwnj+θj

根据误差(error)反向传送过程

  • 公式2 : 对于输出层 Errj=Oj(1Oj)(TjOj) 其中T为target,就是实际结果, Oj(1Oj) 正好是logistic函数的导数,眼熟不…
  • 公式3 : 对于隐藏层 Errj=Oj(1Oj)kwjkErrk 由于计算的时候是从后向前计算的 最后需要逆置一下
  • 公式4 : 对于weights wij=alphaErrjOi

3. 简单算法实现

注意:本简单实现算法迭代过程使用了随机化,可以更改其条件达到更好的精确性

# coding:utf-8

from numpy import *

def tan(x):
    return tanh(x)

def tanDer(x):  # tanh的导数
    return 1.0 - tanh(x) * tanh(x)

def logistic(x):
    return 1 / (1 + exp(-x))

def logisticDer(x):  # logistic的导数
    return logistic(x) * (1 - logistic(x))

class NN(object):
    def __init__(self, layer, sigmoid=tan, sigmoidD=tanDer):  # layer是个列表 分别存着每一层的元素个数
        self.weights = []
        self.sigmoid = sigmoid
        self.sigmoid_der = sigmoidD
        for i in range(1, len(layer) - 1):  # 随机 生成weight 和  bias
            self.weights.append((2 * random.random((layer[i - 1] + 1, layer[i] + 1)) - 1) * 0.25)
            self.weights.append((2 * random.random((layer[i] + 1, layer[i + 1])) - 1) * 0.25)

    def fit(self, x, y, alpha=0.02, loopNum=10000):  # 步长与循环次数 默认0.02 / 10000
        x = atleast_2d(x)  # 至少2维
        tempx = ones([x.shape[0], x.shape[1] + 1])  # 多加一列
        tempx[:, 0:-1] = x  # 最后一列的1是常数
        x = tempx
        y = array(y)
        for k in range(loopNum):  # 随机选择下标
            index = random.randint(x.shape[0])
            units = [x[index]]  # 当前单元(Unit)格的数值
            for i in range(len(self.weights)):  # 进过两次运算后计算出输出层(预测值) -- 公式 1
                units.append(self.sigmoid(dot(units[i], self.weights[i])))  # dot all a1b1+a2b2.....

            error = y[index] - units[-1]  # Tj - Oj
            deltas = [error * self.sigmoid_der(units[-1])]  # 反向 输出层误差 -- 公式 2
            for i in range(len(units) - 2, 0, -1):
                # 隐藏层误差 -- 公式 3
                deltas.append(deltas[-1].dot(self.weights[i].T) * self.sigmoid_der(units[i])) 
            deltas.reverse()  # 从后往前更新 所以逆转一下
            for i in range(len(self.weights)):
                unit = atleast_2d(units[i])
                delta = atleast_2d(deltas[i])
                self.weights[i] += alpha * unit.T.dot(delta)  # 根据公式不断更新weights -- 公式 4

    def predict(self, x):
        x = array(x)
        temp = ones(x.shape[0] + 1)
        temp[0:-1] = x
        unit = temp
        for i in range(0, len(self.weights)): # 不用保留之前层的数值,只保留最后一层数值,并且放入到sigmoid函数中
            unit = self.sigmoid(dot(unit, self.weights[i]))  # 数值*weight参数
        return unit


if __name__ == '__main__':

    '''简单数学逻辑运算'''
    x = array([[0, 0], [0, 1], [1, 0], [1, 1]])
    y = array([1, 0, 0, 1])
    nn = NN([2, 2, 1], tan, tanDer)
    nn.fit(x, y)
    for i in [[0, 0], [0, 1], [1, 0], [1, 1]]:
        print i,int(nn.predict(i) > 0.5)
    print '01 is over\n'
    '''从numpy库导入数据进行数字识别'''
    from sklearn.datasets import load_digits
    from sklearn.metrics import confusion_matrix, classification_report
    from sklearn.preprocessing import LabelBinarizer
    from sklearn.cross_validation import train_test_split

    digits = load_digits()
    X = digits.data
    y = digits.target
    X -= X.min()
    X /= X.max()  # for X range : 0-1

    nn = NN([64, 500, 10], logistic)
    X_train, X_test, y_train, y_test = train_test_split(X, y)  # 随机切分数据集
    labels_train = LabelBinarizer().fit_transform(y_train)  # 二值化label
    labels_test = LabelBinarizer().fit_transform(y_test)  # 比如1就是 01000000000
    print "start fitting number"
    nn.fit(X_train, labels_train, alpha=0.001, loopNum=50000)
    predictions = []  # 预测值
    for i in range(X_test.shape[0]):
        o = nn.predict(X_test[i])
        predictions.append(argmax(o))  # argmax(o) 返回o数组中最大的元素的下标
    print confusion_matrix(y_test, predictions)  # 对比数值
    print classification_report(y_test, predictions)  # 分类报告
    # print predictions

4. 输出数据 以及 简单分析

'''
[0, 0] 1
[0, 1] 0
[1, 0] 0
[1, 1] 1
01 is over

start fitting number 
[[42  0  0  0  0  0  0  0  0  0]
 [ 0 33  1  0  0  0  0  0  2  7]
 [ 0  0 40  0  0  0  0  0  0  0]
 [ 0  1  0 40  0  3  0  2  3  0]
 [ 0  0  0  0 47  0  0  0  2  0]
 [ 0  0  0  0  0 43  0  0  0  3]
 [ 0  0  0  0  0  0 41  0  0  0]
 [ 0  0  0  0  0  1  0 47  1  1]
 [ 0  3  0  0  0  1  0  1 43  0]
 [ 0  0  0  0  0  2  0  0  1 39]]

             precision    recall  f1-score   support

          0       1.00      1.00      1.00        42
          1       0.89      0.77      0.82        43
          2       0.98      1.00      0.99        40
          3       1.00      0.82      0.90        49
          4       1.00      0.96      0.98        49
          5       0.86      0.93      0.90        46
          6       1.00      1.00      1.00        41
          7       0.94      0.94      0.94        50
          8       0.83      0.90      0.86        48
          9       0.78      0.93      0.85        42

avg / total       0.93      0.92      0.92       450

'''
# 分析
# 关于01的与或运算应该是很准确了 原始数据进行了sigmoid函数计算
# 关于数字识别 第一个矩阵对角线上说明正确的个数
# 第二个矩阵 有正确率以及反向正确率 450张训练正确率93%尚可
# 可以改变参数比如步长,随机循环次数等等.....

    • 什么是神经网络
      • 1 背景
      • 2 多层向前神经网络Multilayer Feed-Forward Neural Network
    • 主要算法介绍
      • 1 关于非线性转化方程non-linear transformation function
      • 2 BackPropagation 算法
      • 3 基于算法的几个公式
    • 简单算法实现
    • 输出数据 以及 简单分析

你可能感兴趣的:(机器学习实战,with,python,机器学习实战)