基本概念
计算模型(计算图)
// 还没看懂
数据模型(张量)
所有数据都是通过张量的形式来表示, 在张量中并没有真正保存数字, 它保存的是如何得到这些数字的计算过程
对中间结果的引用
# a和b 就是对常量生成这个运算结果的引用 |
获得计算结果
当计算图构造完成之后, 张量可以用来获得计算结果, 也就是得到真实的数字print(tf.Session().run(result))
# [3. 5.]
变量
- 变量与张量的关系
- 在tf中, 变量的声明函数tf.Variable是一个运算, 这个运算的结果就是一个张量
- 变量是特殊的张量
- 所有变量都会被自动加入到GraphKeys.VARIABLES集合
- 如果声明函数时参数trainable为True, 那么这个变量将会被加入GraphKeys.TRAINABLE_VARIABLES
- tf中提供的神经网络优化算法会将GraphKeys.TRAINABLE_VARIABLES集合中的变量作为默认的优化对象
- 类型
- 一个变量在构建之后, 它的类型就不能再改变
- 维度(shape)
- 会话拥有并管理tf程序运行时的所有资源
- 当所有计算完成之后,需要关闭会话来帮助系统回收资源, 否则就可能出现资源泄露的问题
第一种模式
明确调用会话生成函数和关闭会话函数# 创建一个会话
sess = tf.Session()
# 得到运算结果
sess.run(result)
# 关闭会话使得本次运行中的资源可以被释放
sess.close()
实现神经网络
通过对参数的合理设置来解决分类或者回归问题
- 特征向量
- 所有用于描述实体的数字的组合就是一个实体的特征向量, 通过特征提取, 就可以将实际问题中的实体转化为空间中的点
- 神经网络结构
- 不同的神经元之间的连接结构
- 神经网络的优化过程
- 优化神经元中参数的取值过程
- 全连接神经网络
- 相邻两层之间任意两个节点之间都有连接
- 每个神经元的输入既可以是其他神经元的输出, 也可以是整个神经网络的输入
- 一个最简单的神经元结构的输出就是所有输入的加权和, 不同输入的权重就是神经元的参数
神经网络解决分类问题
- 提取问题中实体的特征向量作为输入
- 定义神经网络的结构, 并定义如何从神经网络的输入得到输出(前向传播算法)
- 通过训练数据集来调整神经网络中参数的取值(训练)
- 使用训练好的神经网络来预测未知的数据
前向传播算法
计算神经网络的前向传播结果需要三部分信息
- 神经网络的输入, 就是从实体中提取的特征向量
- 神经网络的连接结构
- 神经网络是由神经元构成的, 神经网络的结构给出不同神经元(节点)之间输入输出的连接关系
- 每个神经元中的参数
监督学习方式
使用监督学习的方式来更合理地设置参数取值, 设置神经网络参数的过程就是神经网络的训练过程, 只有经过有效训练的神经网络模型才可以真正的解决分类或者回归问题
使用监督学习的方式设置神经网络参数需要一个标注好的训练数据集 (eg. 收集的一批合格和不合格的零件)
重要思想: 在已知答案的标注数据集上, 模型给出的预测结果要尽量接近真实答案
通过调整神经网络中的参数对训练数据进行拟合, 可以使得模型对未知的样本提供预测的能力
训练神经网络过程
- 定义神经网络的结构和前向传播的输出结果
- 定义损失函数以及选择反向传播优化的算法
- 生成会话并在训练数据上反复运行反向传播优化算法
深度神经网络
神经网络有两个非常重要的特性 ———— 多层 和 非线性
- 多层
- 感知机
- 感知机可以简单地理解为单层的神经网络
- 将输入进行加权和,通过激活函数,得到输出,没有隐藏层
- 异或问题
- 如果2个输入的符号相同,则输出0,否则输出1
- 感知机无法模拟异或运算的功能
- 深度神经网络实际上有组合特征提取的功能
- 感知机
- 线性模型的局限性
- 线性模型最大的特点就是任意线性模型的组合仍然是线性模型
- 只通过线性变换,任意层的全连接神经网络和单层神经网络模型的表达能力没有任何区别,而且它们都是线性模型
- 线性模型能解决线性可分问题,但在现实世界中,绝大部分问题都是无法线性分割的
- 深度学习定义中,特意强调它的目的是为解决更加复杂的问题,至少是无法通过直线(或者高维空间的平面)划分的
- 激活函数
- 将每个神经元的输出通过一个非线性函数(激活函数),那么整个神经网络的模型也就不再是线性的了
- 常用的激活函数
- ReLu tf.nn.relu
- sigmoid tf.sigmoid
- tanh tf.tanh
损失函数
分类问题
分类问题希望解决的是将不同的样本分到事先定义好的类别中
通过神经网络解决多分类问题最常用的方法是设置n个输出节点,理想情况下,类别所对应的输出节点值为1,其他都是0
- 交叉熵(常用损失函数)
- 两个概率分布之间的距离
- 交叉熵值越小,两个概率分布越接近
- y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0))
- softmax回归处理
- 将神经网络的输出变成一个概率分布
- 因为交叉熵一般会与softmax回归一起使用,所以tf对这两个功能进行了统一封装
- tf.nn.softmax_cross_entyopy_withlogits(y, y)
- y: 输出结果; y_: 标准答案
回归问题
回归问题解决的是对具体数值的预测,不是事先定义好的一个类别,而是一个任意实数(房价预测、销量预测等)
解决回归问题的神经网络一般只有一个输出节点,这个节点的输出值就是预测值
- 均方误差(常用损失函数,同时也是分类问题常用损失函数)
- tf.reducemean(tf.square(y - y))
自定义损失函数
自定义损失函数,使得神经网络优化的结果更加接近实际问题和需求
- 预测商品销量
- 比如在预测商品销量时,假设一个商品的成本是1元,利润是10元。那么少预测一个就少挣10元,多预测一个才少挣1元
- 为了最大化利润,需要将损失函数和利润直接联系起来
- 不同情况下有不同的预测值
- 正确值比预测值大, 10 * (y_ - y)
- 正确值小于等于预测值, 1 * (y - y_)
- loss = tf.reduce_sum(tf.select(tf.greater(v1, v2), a(v1-v2), b(v2-v1)))
神经网络优化算法
反向传播算法
- 反向传播算法给出了一个高效的方式在所有参数上使用梯度下降算法,从而使神经网络模型在训练数据上的损失函数尽可能小
- 反向传播算法是训练神经网络的核心算法
梯度下降算法
主要用于优化单个参数的取值
函数方法
函数
函数名 | 功能 | 使用 |
---|---|---|
get_shape | 获取结果张量的维度信息 | result.get_shape() |
tensorflow 函数
函数名 | 功能 | 使用 |
---|---|---|
all_variables | 获取当前计算图上所有的变量, 有助于持久化整个计算图的运行状态 | tf.all_variables() |
trainable_variables | 得到所有需要优化的参数 | |
initialize_all_variables | 初始化所有变量 | tf.initialize_all_variables() |
clip_by_value | 将一个张量中的数值限制在一个范围内,可以避免一些运算错误(log0),小于min的被换成min,大于max的被换成max | tf.clip_by_value(v, min, max) |
log | 对张量中所有元素依次求对数 | tf.log(v) |
加减乘除 | 元素之间直接相操作 | v1 * v2 |
matmul | 矩阵乘法 | tf.matmul(v1, v2) |
reduce_mean | 整个矩阵取平均 | tf.reduce_mean(v) |
square | 求平方 | tf.square(y_ - y) |
greater | v1是否大于v2, 返回False, True,输入张量维度不一样时,tf会进行类似numpy广播操作的处理s | tf.greater(v1, v2) |
select | true返回v1 false返回v2 | tf.select(True, v1, v2) |