网络程序设计之神经网络

学*总结

感知机学*算法

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

感知机模型(激活函数)


其中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上分类不确定性,系数越大表明数据集的分类弹性变化越大,稳定性越差

Code Review

  1. A1手写字符识别
  • 学*验证原理

运行环境

# 安装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

运行

cd  BloodTestReportOCR
python view.py # upload图像,在浏览器打开http://yourip:8080

  • 核心训练代码
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
  • 运行截图
  • 加载服务器
  • 预测和训练
  • 可视化图示
  1. A23 OCR识别预测

运行环境

# 安装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

运行

cd  BloodTestReportOCR
python view.py # upload图像,在浏览器打开http://yourip:8080

  • 训练预测核心代码(以tensorflow为例)
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
  • tensorflow

学*心得体会

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

Reference

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

posted @ 2017-01-03 19:27  zeroArn  阅读(362)  评论(0编辑  收藏  举报