Neural-Networks-Programming-comments

学习总结

感知机学习算法

  • 误分类驱动:通过错误点修正权值和偏置
  • 梯度:损失函数对参数的导数
  • 梯度下降:误差函数求最小值的修正过程,在梯度方向上函数变化最大,通过梯度方向探索求取损失函数最小值
  • 学习率: 误分类点每次修正权值和偏差的程度,即误分类点的权值更新的改变程度
  • 随机梯度下降之随机:误分类点中随机选择一个错误点修正权值和偏差参数,求出该点的梯度向量,然后以负梯度方向为搜索方向,以一定的步长学习率进行搜索,从而确定下一个迭代点。持续迭代到收敛
  • 收敛 : 误分类次数小于允许错误门限值(上界)

感知机模型(激活函数)


其中x1, x2为输入,w为权值(即输入对输出的影响程度),b为偏差,整个神经元(感知机)输出为y, 
函数f可以认为是神经元输出表达式,在神经网络中被命名为激活函数

  • 常见的激活函数及其特征
    • Sigmoid(S 型激活函数)
      • 特征:输入一个实值,输出一个 0 至 1 间的值
      • 表达式:σ(x) = 1 / (1 + exp(−x))
    • tanh(双曲正切函数)
      • 特征:输入一个实值,输出一个 [-1,1] 间的值
      • 表达式: tanh(x) = 2σ(2x) − 1
    • ReLU
      • 特征:输出一个实值,并设定 0 的阈值(函数会将负值变为零)
      • 表达式:f(x) = max(0, x)
  • 基本激活函数函数图像
  • 激活函数的直观作用:对神经元多输入的结果进行函数化处理,按照一定映射规则获得输出(本质:函数映射)

神经网络与反向传播

  • 前向传播过程
    • 根据激活函数迭代计算下一层神经元状态
  • 反向传播过程
    • 根据偏差反向修正上一层节点的权值,修正方法为链式求导
    • 反向传播和权重更新: 计算输出节点的总误差,并将误差用反向传播算法传播回网络计算梯度。
    • 使用类似梯度下降之类的算法来「调整」网络节点的权重,以减少输出层的误差
      反向传播参考
      反向传播参考

      神经网络学习算法基本概念

      损失函数

  • 损失函数在数据集上的得到的损失值越小,模型的学习效果就越好,误差越小

    经验损失

  • 在训练数据足够大时经验损失接近期望损失,学习算法的目标是选择期望损失最小的参数模型

    结构损失

  • 结构风险(结构损失)在经验损失最小化基础上加入调整参数,实现正则化
  • 训练误差:训练数据集的平均损失
  • 测试误差:测试数据集的平均损失
  • 过拟合: 模型过度过度学习,太贴近训练数据集的特征,但不能准确反映整体数据的一般特征
    • 即:训练误差小,但是测试误差明显大于训练误差
  • 结构风险最小化: 加入正则影响因子,避免过度靠近训练数据
  • 交叉验证
    • 简单交叉验证: 数据集一部分用于训练,一部分用于测试,选择测试误差最小模型
    • S折交叉验证: 数据集分为s个独立子集,利用S-1个数据集训练,剩余一个做测试,对选择S中选择数据集训练,选择平均测试误差最小模型
    • 留一交叉验证:选择一个数据作为测试,适用于数据不足情况

      算法分析

  • ws: weight 矩阵随机初始化 tf.Variable(tf.random_normal([in_size,out_size]))
  • bs: bias 偏差矩阵随机化,全部置为0.5 tf.Variable(tf.zeros([1,out_size])+0.5)
  • wxpb : 节点状态计算 tf.matmul(inputs,Ws) + bs
  • 每层激活函数sigmoid传入
  • 均方误差学习速率
  • 交叉熵学习速率
  • 交叉熵与均方差的比较

交叉熵参考说明

  • 根据误差方向学习修正参数,交叉熵最小化保证学习速率稳定,避免一般激活函数导致的学习趋近于0的情况

朴素贝叶斯

支持向量机

  • 线性可分
  • 支持向量
  • 函数间隔
  • 几何间隔:w为L2 范数(多维空间距离)

  • 线性可分:使用几何间隔最大化:分离点到分离平面距离之和最大
  • 线性不可分:软间隔最大化,误分距离最小化
  • 核方法:多维空间转化

决策树

  • 决策方法: 在任一节点选择条件概率作为特征空间的一个划分,任一节点做二分类将条件概率大的归为一类
  • 每个层级节点选择最有特征,基于该特征分割数据集,直到数据集全部被分到一个确定叶节点(即一个类)
  • 当叶节点划分过细时(过拟合)需要剪枝,将叶子分类归结到父节点,合并唯一类
  • 特征选择

    • 条件熵
    • 信息增益
    • 信息增益比
  • ID3算法:从根节点开始选择信息增益醉的特征作为节点分割的特征
  • C45算法:用信息增益比选择节点分裂特征
  • CART算法:每个节点二分类,利用平方误差最小化尽可能生产复杂的决策树,然后通过最小化损失值向上回缩,两颗子树的损失之和大于归并到父节点之后的损失值
  • 基尼指数
  • 基尼系数表明集合在特征A上分类不确定性,系数越大表明数据集的分类弹性变化越大,稳定性越差

项目地址

戳here

A1手写字符识别

  • 学习验证原理

运行环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 安装numpy,
sudo apt-get install python-numpy # http://www.numpy.org/
# 安装opencv
sudo apt-get install python-opencv # http://opencv.org/
##安装OCR和预处理相关依赖
sudo apt-get install tesseract-ocr
sudo pip install pytesseract
sudo apt-get install python-tk
sudo pip install pillow
# 安装Flask框架、mongo
sudo pip install Flask
sudo apt-get install mongodb # 如果找不到可以先sudo apt-get update
sudo service mongodb started
sudo pip install pymongo

运行

1
2
cd BloodTestReportOCR
python view.py # upload图像,在浏览器打开http://yourip:8080
  • 核心训练代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    def train(self, training_data_array):
    for data in training_data_array:
    # 前向传播得到结果向量
    y1 = np.dot(np.mat(self.theta1), np.mat(data.y0).T)
    sum1 = y1 + np.mat(self.input_layer_bias)
    y1 = self.sigmoid(sum1)
    y2 = np.dot(np.array(self.theta2), y1)
    y2 = np.add(y2, self.hidden_layer_bias)
    y2 = self.sigmoid(y2)
    # 后向传播得到误差向量
    actual_vals = [0] * 10
    actual_vals[data.label] = 1
    output_errors = np.mat(actual_vals).T - np.mat(y2)
    hidden_errors = np.multiply(np.dot(np.mat(self.theta2).T, output_errors), self.sigmoid_prime(sum1))
    # 更新权重矩阵与偏置向量
    self.theta1 += self.LEARNING_RATE * np.dot(np.mat(hidden_errors), np.mat(data.y0))
    self.theta2 += self.LEARNING_RATE * np.dot(np.mat(output_errors), np.mat(y1).T)
    self.hidden_layer_bias += self.LEARNING_RATE * output_errors
    self.input_layer_bias += self.LEARNING_RATE * hidden_errors
  • 运行截图

  • 加载服务器
  • 预测和训练
  • 可视化图示

A23 OCR识别预测

运行环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 安装numpy,
sudo apt-get install python-numpy # http://www.numpy.org/
# 安装opencv
sudo apt-get install python-opencv # http://opencv.org/
##安装OCR和预处理相关依赖
sudo apt-get install tesseract-ocr
sudo pip install pytesseract
sudo apt-get install python-tk
sudo pip install pillo
# 安装Flask框架、mongo
sudo pip install Flask
sudo apt-get install mongodb # 如果找不到可以先sudo apt-get update
sudo service mongodb started
sudo pip install pymongo

运行

1
2
cd BloodTestReportOCR
python view.py # upload图像,在浏览器打开http://yourip:8080
  • 训练预测核心代码(以tensorflow为例)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    def add_layer(inputs,in_size,out_size,n_layer,activation_function=None):
    layer_name='layer%s'%n_layer
    with tf.name_scope('layer'):
    with tf.name_scope('weights'):
    Ws = tf.Variable(tf.random_normal([in_size,out_size]))
    tf.histogram_summary(layer_name+'/weights',Ws)
    with tf.name_scope('baises'):
    bs = tf.Variable(tf.zeros([1,out_size])+0.5)
    tf.histogram_summary(layer_name+'/baises',bs)
    with tf.name_scope('Wx_plus_b'):
    Wxpb = tf.matmul(inputs,Ws) + bs
    if activation_function is None:
    outputs = Wxpb
    else:
    outputs = activation_function(Wxpb)
    tf.histogram_summary(layer_name+'/outputs',outputs)
    return outputs
    # 定义占位符
    with tf.name_scope('inputs'):
    x = tf.placeholder(tf.float32, shape=[None, 26])
    y_ = tf.placeholder(tf.float32, shape=[None, 2])
    #2个隐藏层
    l1 = add_layer(tf.reshape(x, [-1, 26]),26,64,n_layer=1,activation_function=tf.nn.relu)
    l2 = add_layer(l1,64,512,n_layer=2,activation_function=tf.nn.relu)
    # add output layer
    y_result = add_layer(l2,512,2,n_layer=3)
    # 定义损失函数 交叉熵
    with tf.name_scope('loss'):
    cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_result, y_))
    tf.scalar_summary('loss',cross_entropy)
    # 定义训练op
    with tf.name_scope('train'):
    train_step = tf.train.AdamOptimizer(0.0001).minimize(cross_entropy)
    # 定义正确预测
    # correct_prediction = tf.less_equal(tf.abs(tf.sub(tf.argmax(y_result, 1), tf.argmax(y_, 1))), 5)
    correct_prediction = tf.equal(tf.argmax(y_result, 1), tf.argmax(y_, 1))
    # 定义正确率
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
  • 中间两层隐藏层,使用relu作为激活函数

  • 学习目标是交叉熵最小化
  • 优化函数时tensorflow自带的AdamOptimizer,一种逻辑回归优化算法在多维空间的变种

    运行效果

  • 提交报告单

  • OCR识别
  • 预测

Summary

学习内容: 

  • 统计学习方法:这书凝练到想做笔记基本等于抄书
  • Python 基础教程:推荐
  • numpy and Scipy:Python 玩出花来。。。
  • tensorflow: tensorlearn、tensorlaywer可能会更好(傻)

    学习心得体会

  • 项目A1学习过程接触到tensorflow,当时认为是一个很成熟的机器学习框架,参考了官网教程和部分博客,意识到机器学习的基础和困境在于数学,所以把学习的重点放在了数学和算法上,算法部分直接看的<统计学习方法>,有种大呼过瘾的感觉,通俗易懂深入浅出,基本覆盖机器学习的基本领域,明白了算法的数学本质,为什么能够学习道数据内在规律,之后自己琢磨工具学习了Python 和tensorflow, 可能因为代码基础差吧,一直跟在大神后边跑,看着大神们的代码溜到飞起,明白自己的差距还是代码量的问题,同时页说明我最初的方向或者方法出了点问题,或许直接上代码比绕了大圈去看算法更容易出成果吧,站在前人基础上才能看的更远吧,毕竟源码面前了无秘密嚯嚯。
    最大遗憾: talk is cheap, show me the code
  • 感受总结为以下几点:
    1. 机器学习所需数学基础主要时:求导、概率、分布,没有想象中对数学要求那么高,少数涉及拉格朗日,马尔科夫的内容边看边学时完全可以的理解的
    2. 机器学习本质的时大数据量的统计分析,编程的需求或者要求没有想象中高,更多需要的是对数据本身意义的理解即其所代表的现实意义(可以理解为特征工程)
    3. 机器学习适合的人群: 科研->码农->业务数据分析(发现抽象规律) 
    4. 学习算法的本质:
      - 大规模数据的特征的拟合:即找出从定义域到值域的映射关系,学习目标即:(偏差最小)
      
         - 表象: 映射关系不同,多特征的导致的多维计算量的拟合,偏差标识方式和最小化的方式
      • 数学本质:某种程度上是传统统计规律的现代封装
    5. Python、tensorflow 、Keras、tensorlearn、Caffe、tensorlaywer等工具封装底层数学算法,供工程目标研究者使用学习
    6. 机器学习、数据挖掘工程师的核心竞争力: 数据代表的现实意义和将要探究的目标之间的联系
    7. 正确的学习过程: 数据 和 目标 -> 找出又用数据(特征)-> 数据的现实意义(统计目标的意义基础)-> 数据处理  -> 筛选学习泛化 -> 隐藏的规律(已知数据域未知数据的联系)

Reference

统计学习方法pdf by 李航
台大机器学习入门ppt by 李宏毅
知乎问答:关于感知机与神经网络