正文
y_val = 5 * np.square(x_val) + 3
return x_val, y_val
sess = tf.Session()
# 因为我们要使用这些变量,所以我们需要先将它们初始化
sess.run(tf.global_variables_initializer())
for _ in range(1000):
x_val, y_val = generate_data()
_, loss_val = sess.run([train_op, loss], {x: x_val, y: y_val})
print(loss_val)
print(sess.run([w]))
运行完这段代码之后,我得到的参数结果是:
[4.98605919,-0.00187828875e-04,3.8395009]
上面是编辑运行完之后的结果,它对应的损失值是 17.6175. 每一次的具体结果都会不同,但是最终结果都很接近期望的函数值。下面
是原文作者提供的值。
[4.9924135,0.00040895029, 3.4504161]
这是与期望参数相当接近的近似。
这只是 TensorFlow 能够做到的事情的冰山一角而已。很多类似于优化具有上百万个参数的大型神经网络的问题都能够用 TensorFlow 以很少量的代码来高效地实现。与此同时,TensorFlow 的开发团队还致力于在多种设备、多线程以及支持多平台等问题上更进一步。
简单起见,在绝大多数例子中我们都手动地创建了会话,我们并没有保存和加载 checkpoint,但是这却是我们在实战中经常需要做的事情。你很可能想着使用估计 API 来进行会话管理以及做日志。我们在 code/framework 路径下提供了一个简单的可扩展架构,作为使用 TensorFlow 来训练神经网络的一个实际架构的例子。
理解静态维度和动态维度
TensorFlow 中的张量具有静态维度的属性,它在构建图的时候就被确定好了。静态维度也有可能是不确定的。举个例子,我们也许会定义一个维度为 [None,128] 的张量。
import tensorflow as tf
a = tf.placeholder([None, 128])
这意味着第一个维度可以是任意大小,会在 Session.run() 的过程中被动态地决定。在表现静态张量的时候,TensorFlow 有着相当丑的 API:
static_shape = a.get_shape().as_list() # returns [None, 128]
(这个应该写成 a,shape() 的形式,但是这里有人把它定义得太不方便了。)
为获得张量的动态形式,你可以调用 tf.shape 功能,它会返回一个表示给定张量的形状的张量:
dynamic_shape = tf.shape(a)
一个张量的静态维度可以使用 Tensor.set_shape() 函数来进行设置。
a.set_shape([32, 128])
仅当你知道自己在做什么的时候再使用这个函数,事实上使用 tf.reshape() 会更加安全。
a = tf.reshape(a, [32, 128])
如果有一个函数能在方便的时候返回静态维度,在可用的时候返回动态维度,那将会很方便。下面就定义了这样一个函数:
def get_shape(tensor):
static_shape = tensor.get_shape().as_list()
dynamic_shape = tf.unstack(tf.shape(tensor))
dims = [s[1] if s[0] is None else s[0]
for s in zip(static_shape, dynamic_shape)]
return dims
现在设想:我们想通过折叠第二维和第三维来把一个 3 维的矩阵转换成一个 2 维的矩阵。我们可以使用上述的 get_shape() 函数来完成这件事:
b = placeholder([None, 10, 32])
shape = get_shape(tensor)
b = tf.reshape(b, [shape[0], shape[1] * shape[2]])
值得注意的是,这里无论矩阵是不是静态的,这个方法都能奏效。
事实上我们可以写一个更加具有通用目标的函数来折叠任何几个维度:
import tensorflow as tfimport numpy as np
def reshape(tensor, dims_list):
shape = get_shape(tensor)
dims_prod = []
for dims in dims_list:
if