TensorFlow中的常量与变量

TensorFlow中的常量与变量

变量是指在程序运行过程中,存储可以变化的数据;而常量是指在程序运行过程中,值不能改变的量。常量因其不变性,编译器可以直接将其编译成目标代码,有利于提升程序的性能。

constant 常量

基于 python 数据构建常量

在 TensorFlow 中,可以利用 tf.constant() 方法来生成常量,例如用 Python 列表来生成常量:

import tensorflow as tf

a_list = [1, 2, 3, 4, 5]
b = tf.constant(a_list)
print(b)

上述代码运行结果为:

tf.Tensor([1 2 3 4 5], shape=(5,), dtype=int32)

基于 numpy 数据构建常量

也可以利用 Numpy 数组来生成常量:

import numpy as np
import tensorflow as tf

np_arr = np.array([[1, 2, 3], [4, 5, 6]])
c = tf.constant(np_arr)
print(c)

上述代码运行结果为:

tf.Tensor(
[[1 2 3]
 [4 5 6]], shape=(2, 3), dtype=int64)

利用数据扩展构建常量

若提供的数据不完整,可以设置 shape 参数,利用数据扩展来构建常量:

import tensorflow as tf

const_float_tensor = tf.constant(10.0, shape=[2, 3, 4], dtype=tf.float32)
print(const_float_tensor)

上述代码运行结果为:

tf.Tensor(
[[[10. 10. 10. 10.]
  [10. 10. 10. 10.]
  [10. 10. 10. 10.]]

 [[10. 10. 10. 10.]
  [10. 10. 10. 10.]
  [10. 10. 10. 10.]]], shape=(2, 3, 4), dtype=float32)

Variable 变量

在机器学习中,某些参数(如模型参数)可能需要长期保存,且值会不断发生更迭,这时就需要用变量(Variable)来保存。

tf.Variable 对象是一个常驻内存,不会被轻易回收的张量。在神经网络中,由于梯度运算会消耗大量计算资源,因此对于那些不需要进行优化的张量(例如神经网络的输入层 X),无需利用 tf.Variable 进行构建。

对于需要进行梯度运算和优化的张量,如神经网络中的权值 w 和偏置 b,它们的值在不断变化,同时在更新值的时候,还要用到上一次的值,因此需要利用 tf.Variable 来构建,便于 TensorFlow 跟踪梯度相关信息。

我们可以利用 tf.Variable() 方法来创建变量,如下:

import tensorflow as tf

my_state = tf.Variable(1.0)  # 定义变量
one = tf.constant(1.0)  # 定义常量

read_and_increment = tf.function(lambda: my_state.assign_add(one))  # 自定义 TensorFlow 函数

print(my_state)
for _ in range(3):
    read_and_increment()  # 调用 read_and_increment 函数
    print(my_state.numpy())  # 将张量转换为 numpy 数据类型并输出

上述代码运行结果为:

<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=1.0>
2.0
3.0
4.0

上述代码中 read_and_increment = tf.function(lambda: my_state.assign_add(one)) 中利用 tf.function() 方法创建了一个名称为 read_and_increment 的 TensorFlow 函数,该函数通过 lamda 表达式方法实现了 my_state 变量的自增操作,类似于 i++assign_add() 方法是每个 tf.Variable 对象都拥有的方法,可以实现求和与自我赋值操作。

tf.Variable 详解

name 和 trainable 属性

我们注意到一个问题,在 tf 作为前缀名时,有时后面的成员是小写(tf.constant),有时又是大写(例如 tf.Variable),这是什么原因呢?这是 TensorFlow 中的编程约定,若成员首字母小写,表明其是一级方法成员;若成员首字母大写,表明其是class)。

tf.Variable 有两个属性:nametrainable。不指定 name 属性的话,TensorFlow 会自动维护命名体系;trainable 表明是否参与梯度运算,默认值为 True(表明参与梯度运算,TensorFlow 会对其进行优化)。

我们通过代码来查看下 tf.Variable 对象的两个属性:

import tensorflow as tf

my_state = tf.Variable(1.0)  # 定义变量

print(my_state.name)
print(my_state.trainable)

上述代码运行结果为:

Variable:0
True

注意

trainable 是只读属性,在 tf.Variable 对象初始化之后,trainable 属性就无法改变了。

计算图

TensorFlow 1.x 版本中的计算图使用起来非常麻烦,因此 TensorFlow 2.0 版本推荐使用即时执行模式,但也带来了执行效率低下的问题,因为在即时执行模式中,需要依赖 Python 解释器进行计算,无法对数据流和计算图进行优化,为了解决该问题, TensorFlow 2.0 引入了 tf.function 概念来构建计算图。

在之前 read_and_increment = tf.function(lambda: my_state.assign_add(one...[^1] 中我们使用了 tf.function 方法来构建一个简单的计算图,我们还可以通过装饰器 @tf.function 来构建一个计算图,如下所示:

import tensorflow as tf


@tf.function
def func1(x):
    if tf.reduce_sum(x) > 0:
        return x * x
    else:
        return -x // 2


my_var = tf.Variable([3, -2, 4])
tf.print(func1(my_var).numpy())

上述代码运行结果为:

array([ 9,  4, 16], dtype=int32)

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://cangmang.xyz/articles/tensorflow-constant-and-variable