详解TensorFlow的 tf.placeholder 函数:创建一个占位符张量

  • Post category:Python

当使用 TensorFlow 时,我们可能需要在运行图的时候才能确定某些张量的值,例如神经网络的输入数据或者训练数据的标签。这时,就需要使用 tf.placeholder() 函数来定义一个占位符,协助我们后续在计算图中填充数据。

作用

tf.placeholder() 的功能是创建一个占位符张量。占位符可以看作是一种变量,不过并不会像变量那样直接初始化,它会在后续的计算图中被赋值,从而实现张量的绑定过程,进而参与运算操作。

使用方法

tf.placeholder(dtype, shape=None, name=None)

  • dtype 参数指定了 tensor 的类型,如 tf.float32, tf.float64, tf.int32 等等

  • shape 参数是一个可选参数,指定了占位符张量的形状,如果不指定,则表示张量的形状是不确定的,这种情况可以用 tf.shape() 函数在执行时动态地获取

  • name 参数是可选的,给占位符张量命名

下面给出两个例子:

例1:在 TensorFlow 中定义一个占位符并使用

假设我们希望定义一个占位符 a,它的类型为 tf.float32,形状为 [None, 2] 表示数据是二维的,但行数是不确定的,列数为 2。其中,None 表示该维度大小可以是任意大小。

import tensorflow as tf

# 定义一个占位符,数据类型为 float32,形状为 [None, 2]
a = tf.placeholder(dtype=tf.float32, shape=[None, 2], name='my_placeholder')

# 定义一个操作,将占位符张量加 1
b = a + 1

# 构造一个 feed_dict,往占位符张量 a 中喂入数据
data = [[1, 2], [3, 4], [5, 6]] # 形状为 [3, 2]
with tf.Session() as sess:
    result = sess.run(b, feed_dict={a: data})
    print(result)

注:在 feed_dict 中,我们需要按照定义时的占位符张量名 a 对齐,输入数据 data 的形状为 [3, 2],即三行两列。

例2:在 TensorFlow 中构建一个简单的神经网络

在 TensorFlow 中,我们可以结合占位符张量实现一个简单的神经网络,下面是一个例子:

import tensorflow as tf
import numpy as np

# 定义一个占位符,作为输入层的输入 x
x = tf.placeholder(dtype=tf.float32, shape=[None, 10], name='input')

# 定义一个全连接层,参数为 w 和 b
w1 = tf.Variable(tf.random_normal(shape=[10, 20]), dtype=tf.float32)
b1 = tf.Variable(tf.zeros(shape=[20], dtype=tf.float32))
h1 = tf.nn.relu(tf.matmul(x, w1) + b1)

# 定义一个输出层,输出预测结果 y_hat
w2 = tf.Variable(tf.random_normal(shape=[20, 1]), dtype=tf.float32)
b2 = tf.Variable(tf.zeros(shape=[1], dtype=tf.float32))
y_hat = tf.matmul(h1, w2) + b2

# 定义 placeholder 用于接收训练数据的输入和标签
x_ph = tf.placeholder(dtype=tf.float32, shape=[None, 10], name='x')
y_ph = tf.placeholder(dtype=tf.float32, shape=[None, 1], name='y')

# 定义损失函数和优化算法
loss = tf.reduce_mean(tf.square(y_hat - y_ph)) # 均方误差
optimizer = tf.train.AdamOptimizer(learning_rate=0.01)
train_op = optimizer.minimize(loss)

# 构造数据
x_train = np.random.rand(100, 10)
y_train = np.random.rand(100, 1)

# 开始训练
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for epoch in range(1000):
        _, cur_loss = sess.run([train_op, loss], feed_dict={x_ph: x_train, y_ph: y_train})
        if epoch % 100 == 0:
            print(f'epoch {epoch}, loss={cur_loss}')

上述代码中,我们先定义了一个占位符张量 x,表示输入数据。然后,我们通过定义全连接层和输出层构建了一个简单的神经网络,其输出结果保存在变量 y_hat 中。我们定义了另外两个占位符张量 x_ph 和 y_ph,用于接收训练数据的输入 x_train 和标签 y_train。最后,我们通过定义损失函数和优化算法,迭代地训练出了神经网络中的变量 w1, b1, w2, b2。