TensorFlow系列 #003

TensorFlow入门——神经网络结构、前向传播算法实现

一、神经网络的实现

1、TensorFlow Playground


数据点
  • 二维平面的数据集中,每一个小点代表一个样例,点的颜色代表了样例的标签,点的颜色有两种,因此构成一个二分类的问题。
  • 黄色的点表示合格的零件,蓝色的点表示不合格的零件。判断一个零件是否合格的问题就转变成区分点的颜色的问题。
  • 零件的特征提取:用零件的长度和质量来描述一个零件,,将一个物理意义上的零件转化成长度和质量两个数字。
  • 在机器学习中,所有用于描述实体的数字的组合就是一个实体的特征向量(feature vector)。通过特征提取,可以将实际问题中的实体转化为空间中的点。
  • 举例:FEATURES对应特征向量,x1代表零件的长度,x2代表零件的质量。

输入输出
  • 特征向量是神经网络的输入
  • 第一层是输入层,代表特征向量中每一个特征的取值,如x1 = 0.5表示一个零件的长度为0.5。
  • 在二分类问题中,如判断零件是否合格,神经网络的输出层往往只包含一个节点,这个节点输出一个实数值,通过这个输出值和一个事先设定的阈值,可以得到最后的分类结果。
  • 举例:判断零件是否合格时,当输出的数值大于0时,给出的判断结果是零件合格,反之零件不合格,一般认为当输出值离阈值越远时得到的答案越可靠。

隐藏层
  • 输入和输出层之间的神经网络叫做隐藏层,一个神经网络的隐藏层越多,这个神经网络越深,深度学习中的深度和神经网络的深度密切相关。
  • 支持修改的参数:
    • 隐藏层的数量 hidden layer
    • 学习率 learning rate
    • 激活函数 activation
    • 正则化 regularization

训练结果
  • 一个小格子代表神经网络中的一个节点!
  • 边代表节点之间的连接,每一条边代表盛景网络中的一个参数,可以是任意实数。
  • 神经网络通过对参数的合理设置来解决分类或者回归问题。边上的颜色体现了这个参数的取值,边的颜色越深,这个参数取值的绝对值越大;边的颜色接近白色时,参数的取值接近于0.
  • 每一个节点上的颜色代表了这个节点的区分平面。如果把这个平面当成一个笛卡尔坐标系,这个平面上的每一个点就代表了(x1,x2)的一种取值。点的颜色就体现了x1,x2在这种取值下这个节点的输出值。节点的输出值的绝对值越大时,颜色越深。
  • 举例:**输入层x1代表的节点的区分平面就是y轴。(理解?)**因为这个节点的输出就是x1本身的值,所以当x1小于零时,这个节点的输出就是负数,而x1大于0时,输出的就是正数。于是y轴的左侧都为黄色,右侧都为蓝色

总结:使用神经网络解决分类问题的步骤
  1. 提取问题中实体的特征向量作为神经网络的输入。不同的实体可以提取不同的特征向量。
  2. 定义神经网络的结构,并定义如何从神经网络的输入得到输出。这个过程就是神经网络的钱箱传播算法。
  3. 通过训练数据来调整神经网络中参数的取值,这就是训练神经网络的过程。
  4. 使用训练好的神经网络来预测未知的数据。

二、前向传播算法——全连接网络

1、神经元结构

  • 神经元是构成一个神经网络的最小单元
  • 一个神经元有多个输入和一个输出。每个神经元的输入既可以是其他神经元的输出,也可以是整个神经网络的输入。神经网络的结构就是指不同神经元之间的连接结构。
  • 一个最简单的神经元结构的输出就是所有输入的加权和,不同输入的权重就是神经元的参数。
  • 神经网络的优化过程就是优化神经元中参数取值的过程。
  • 举例:一个简单的判断零件是否合格的三层全连接网络。全连接神经网络是指相邻两层之间任意两个节点之间都有连接。
  • 全连接神经网络结构与卷积层,LSTM结构相区别。

2、前向传播过程

  • 前向传播过程解析[BOOK]
  • 计算神经网络的前向传播需要三部分信息:
    1. 神经网络的输入
    2. 神经网络的连接结构
    3. 每个神经元的参数
  • 用矩阵乘法表示前向传播算法中的加权和
  • 举例:xW(1)a(1)W(2)y
    • a(1) = x*W(1)
    • y = a(1)*W(2)
  • Tensorflow实现:
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)
  • 总结tf.matmul可以实现矩阵乘法的功能
  • 其他支持的神经网络:
    • 更加复杂的神经元结构:偏置(bias)、激活函数(activation function)
    • 更加复杂的神经网络:卷积神经网络、LSTM结构

3、神经网络参数与TensorFlow变量

  • 变量(tf.Variable)的作用是保存和更新神经网络中的参数
  • 使用随机数给TensorFlow中的变量初始化:
    weights = tf.Variable(tf.random_normal([2,3],stddev=2))
    # tf.random_normal[2,3],stddev=2)产生一个2×3矩阵,元素是均值为0,标准差为2的随机数
    # tf.random_normal函数可以通过参数mean来指定平均值,在没有指定时默认为0
    
  • 总结:通过满足正态分布的随机数来初始化神经网络中的参数是一个非常常用的方法
  • 其他随机数生成器:
函数名称随机数分布主要参数
tf.random_normal正态分布平均值、标准差、取值类型
if.truncted_normal正态分布,但如果随机出来的值偏离平均值超过2个标准差,那么这个数将会被重新随机平均值、标准差、取值类型
tf.random_uniform平均分布最小、最大取值,取值类型
tf.random_gammaGamma分布形状参数alpha、尺寸参数beta、取值类型
  • 常量声明方法
函数名称功能样例
tf.zeros产生全0的数组tf.zeros([2,3],int32)->[[0,0,0],[0,0,0]]
tf.ones产生全1的数组tf.omes([2,3],int32)->[[1,1,1],[1,1,1]]
tf.fill产生一个全部为给定数字的数组tf.fill([2,3],9)->[[9,9,9],[9,9,9]
tf.constant产生一个给定值的常量if.comstant([1,2,3])->[1,2,3]
  • 偏置项通常会使用常数来设置初始值
biases = tf.Variable(tf.zeros([3]))
# 生成一个初始值全部为0且长度为3的变量
  • 使用其他变量的初始值来初始化新的变量
w2 = tf.Variable(weights.initialized_value())
w3 = tf.Variable(weights.initialized_value()*2.0)
# w2的初始值设置成与weights变量相同,w3的初始值设置成wieghts初始值的两倍
  • 实现神经网络前向传播过程【重要案例】
import tensorflow as tf
# 声明w1、w2两个变量。通过seed参数设定随机种子(伪随机数)
# 这样可以保证每次运行得到的结果是一样的。
w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2 = tf.Variale(tf.random_normal([3,1],stddev=1,seed=1))
# 暂时将输入的特征向量定义为一个常量。注意这里x是一个1*2的矩阵。
x = tf.constant([[0.7,0.9]]) # ??? 为什么有两层括号
# 构建前向传播算法的神经网络全连接结构
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)

sess = tf.Session()
# 这里不能直接通过sess.run(y)来获取y的取值,
# 因为w1和w2都还没有运行初始化过程。下面的两行分别初始化了w1和w2两个变量。
sess.run(w1.initializer) # 初始化w1
sess.run(w2.initializer) # 初始化w2
# 输出[[3.95757794]]
print(sess.run(y))
sess.close()
  • 分析:以上程序直接调用每个变量的初始化过程是一个可行的方案,但是当变量数目增多,或者变量之间存在依赖关系时,单个调用的方案就比较麻烦。TensorFlow提供了一种更加快捷的方式俩完成变量初始化过程。 tf.initialize_all_variavles函数实现所有变量的初始化。
init_op = tf.initialize_all_variables()
sess.run(init_op)
  • 变量和张量的关系:
    TensorFlow的核心概念是张量(tensor),所有的数据都是通过张量的形式来组织的。变量声明函数tf.Variable是一个运算,则个运算的输出结果就是一个张量,这个张量就是之前提到的变量。所以变量只是一种特殊的张量。

  • tf.Variable操作在TF中的底层实现,总结

    • w1是一个Variable运算
    • 初始化变量w1的操作是通过Assign操作完成的
    • Assign节点的输入为随机数生成函数的输出,输出赋值给了变量w1
    • w1通过一个read操作将值提供给了一个MatMul乘法运算tf.matmul(x,w1)
  • TensorFlow中所有的变量会被自动的加入GraphKeys.VARIAVLES集合。通过tf.all_variables函数可以拿到当前计算图上所有的变量。拿到计算图上所有的变量有助于持久化整个计算图的运行状态**(不理解!…)**。

  • 构建机器学习模型时,比如神经网络,可以通过变量声明函数中的trainable参数来区分需要优化的参数(比如神经网中的参数)和其他参数(比如迭代的轮数)。如果声明变量时参数trainable为True,那么这个变量将会被加入GraphKeys.TRAINABLE_VARIABLES集合。

  • 通过tf.trainable_variables函数得到所有需要优化的参数。TensorFlow中提供的神经网络优化算法会将GraphKeys.TRAINABLE_VARIABLES集合中的变量作为默认的优化对象。

  • 类似张量,维度(shape)和类型也是变量最重要的两个属性。一个变量在构建之后,变量的类型是不可改变的。两个不同类型的变量赋值会报出类型不匹配的错误。

  • 示例代码:

w1 = tf.Variable(tf.random_normal([2,3],stddev=1),name = 'w1')
w2 = tf.Variable(tf.random_normal([2,3],dtype=tf.float64,stddev=1),name="w1")
w1.assign(w2)

# 程序报错: 
# TypeError:Input 'value' of 'Assign' Op has type float64 that does not match type float32 of argument 'ref'.
  • TensorFlow支持更改变量的维度,通过设置参数validete_shape=False,但该用法在实践中比较罕见
  • 示例代码:
w1 = tf.Varialble(tf.random_normal([2,3],stddev=1),name="w1")
w2 = tf.Varialble(tf.random_normal([2,2],stddev=1),name="w2")
# tf.assign(w1,w2)
# 维度不匹配报错,ValueError:Shapes(2,3)and (2,2) are not compatible
# 应改为下面的语句
tf.assign(w1,w2,validate_shape=False)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值