算法工程师修仙之路:TensorFlow(六)

TensorFlow 入门

TensorFlow实现神经网络


神经网络参数与 TensorFlow 变量

  • 在 TensorFlow 中,变量(tf.Variable)的作用就是保存和更新神经网络中的参数。

  • 和其他编程语言类似,TensorFlow中的变量也需要指定初始值。因为在神经网络中,给参数赋予随机初始值最为常见,所以一般也使用随机数给 TensorFlow 中的变量初始化。

    # 声明一个2*3的矩阵变量
    weights = tf.Variable(tf.random_normal([2, 3], stddev=2.0))
    
    • 这段代码调用了 TensorFlow 变量的声明函数 tf.Variable。
    • 在变量声明函数中给出了初始化这个变量的方法。
    • tf.random_normal([2, 3], stddev=2)会产生一个 2 3 2*3 的矩 阵,矩阵中的元素是均值为0,标准差为2的随机数。
    • tf.random_normal 函数可以通过参数 mean 来指定平均值,在没有指定时默认为0。
  • TensorFlow 中变量的初始值可以设置成随机数、常数或者是通过其他变量的初始值计算得到。

  • 通过满足正态分布的随机数来初始化神经网络中的参数是一个非常常用的方法,除了正态分布的随机数,TensorFlow 还提供了一些其他的随机数生成器:
    在这里插入图片描述

  • TensorFlow 也支持通过常数来初始化一个变量:
    在这里插入图片描述

  • 在神经网络中,偏置项(bias)通常会使用常数来设置初始值。

    biases = tf.Variable(tf.zeros([3]))     # 生成一个初始值全部为0且长度为3的变量。
    
  • 除了使用随机数或者常数,TensorFlow 也支持通过其他变量的初始值来初始化新的变量。

    # w2的初始值被设置成了与weights变量相同。
    w2 = tf.Variable(weights.initialized_value())   
    # w3的初始值则是weights初始值的两倍。    
    w3 = tf.Variable(weights.initialized_value() * 2.0)    
    
  • 在 TensorFlow 中,一个变量的值在被使用之前,这个变量的初始化过程需要被明确地调用。

  • 通过变量实现神经网络的参数并实现前向传播:

    import tensorflow as tf 
    
    """ 
    声明wl、w2两个变量。这里还通过seed参数设定了随机种子,
    这样可以保证每次运行得到的结果是一样的。 
    """
    
    """ 
    当声明了变量wl、w2之后,可以通过wl和w2来定义神经网络的前向传播过程并得到中间结果a和最后答案y。
    定义wl、w2, a和y的过程对应了TensorFlow程序的第一步。
    这一步定义了TensorFlow计算图中所有的计算,但这些被定义的计算在这一步中并不真正地运行。
    当需要运行这些计算并得到具体数字时,需要进入TensorFlow程序的第二步。 
    """
    
    w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
    w2 = tf.Variable(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)
    
    """ 
    在TensorFlow程序的第二步会声明一个会话(session),并通过会话计算结果。
    当会话定义完成之后就可以开始真正运行定义好的计算了。
    但在计算y之前,需要将所有用到的变量初始化。
    也就是说,虽然在变量定义时给出了变量初始化的方法,但这个方法并没有被真正运行。
    所以在计算y之前,需要通过运行w1.initializer和w2.initializer来给变量赋值。 
    """
    
    sess = tf.Session()
    
    # 第一种方法,不主张
    """ 
    这里不能直接通过sess.run(y)来获取y的取值,
    因为wl和w2都还没有运行初始化过程。
    以下两行分别初始化了wl和w2两个变量。 
    sess.run(w1.initializer)      # 初始化w1。
    sess.run(w2.initializer)      # 初始化w2。 
    """
    
    # 第二种方法,常用
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    
    # 输出[[ 3.95757794]]。
    print(sess.run(y))
    sess.close()
    
    • 虽然方法一直接调用每个变量的初始化过程是一个可行的方案,但是当变量数目增多,或者变量之间存在依赖关系时,单个调用的方案就比较麻烦了。
    • 为了解决这个问题, TensorFlow 提供了一种更加便捷的方法二来完成变量初始化过程。通过 tf.global_variables_initializer 函数,就不需要将变量一个一个初始化了。这个函数也会自动处理变量之间的依赖关系。
  • 在 TensorFlow 中,变量的声明函数 tf.Variable 是一个运算,这个运算的输出结果就是一个张量,这个张量也就是变量,所以变量只是一种特殊的张量。

  • 通过 tf.global_variables()函数可以拿到当前计算图上所有的变量。

    • 拿到计算图上所有的变量有助于持久化整个计算图的运行状态。
    • 当构建机器学习模型时,比如神经网络,可以通过变量声明函数中的 trainable 参数来区分需要优化的参数(比如神经网络中的参数)和其他参数(比如迭代的轮数)。
    • 如果声明变量时参数 trainable 为 True ,那么这个变量将会被加入到GraphKeys.TRAINABLE_VARJABLES 集合。
    • 在 TensorFlow 中可以通过 tf.trainable_variables函数得到所有需要优化的参数。
    • TensorFlow 中提供的神经网络优化算法会将GraphKeys.TRAINABLE_VARIABLES 集合中的变量作为默认的优化对象。
  • 类似张量,维度(shape)和类型 (type)也是变量最重要的两个属性。和大部分程序语言类似,变量的类型是不可改变的。一个变量在构建之后,它的类型就不能再改变了。维度是变量另一个重要的属性。和类型不大一样的是,维度在程序运行中是有可能改变的,但是需要通过设置参数 validate_shape=False。虽然 TensorFlow 支持更改变量的维度,但是这种用法在实践中比较罕见。

猜你喜欢

转载自blog.csdn.net/faker1895/article/details/86153086