TensorFlow: 静态图

译者:@yongjay13@speedmancs

校对者:@bringtree

本例中的全连接神经网络有一个隐藏层, 后接ReLU激活层, 并且不带偏置参数. 训练时通过最小化欧式距离的平方, 来学习从x到y的映射.

在实现中, 我们会用基本的TensorFlow操作来建立一个计算图, 随后多次执行这个图来训练网络.

TensorFlow和PyTorch有一个很大的区别, 就是TensorFlow用的是静态计算图, 而PyTorch则用动态计算图.

用TensorFlow我们先建立计算图, 然后在多次执行过程中, 计算图固定不变.

  1. import tensorflow as tf
  2. import numpy as np
  3. # 首先我们设置计算图:
  4. # N 批量大小; D_in是输入尺寸;
  5. # H是隐藏尺寸; D_out是输出尺寸.
  6. N, D_in, H, D_out = 64, 1000, 100, 10
  7. # 为输入数据和目标数据创建占位符;
  8. # 当我们执行图时,这些将被填充真实的数据.
  9. x = tf.placeholder(tf.float32, shape=(None, D_in))
  10. y = tf.placeholder(tf.float32, shape=(None, D_out))
  11. # 为权重创建变量并用随机数据初始化它们.
  12. # 一个TensorFlow变量在图的执行中保持其值.
  13. w1 = tf.Variable(tf.random_normal((D_in, H)))
  14. w2 = tf.Variable(tf.random_normal((H, D_out)))
  15. # 正向传递:使用TensorFlow Tensors上的运算来计算预测的y.
  16. # 请注意此代码实际上并未执行任何数字操作;
  17. # 它只是设置我们稍后将执行的计算图.
  18. h = tf.matmul(x, w1)
  19. h_relu = tf.maximum(h, tf.zeros(1))
  20. y_pred = tf.matmul(h_relu, w2)
  21. # 使用TensorFlow张量上的操作计算损失
  22. loss = tf.reduce_sum((y - y_pred) ** 2.0)
  23. # 计算相对于w1和w2的损失梯度.
  24. grad_w1, grad_w2 = tf.gradients(loss, [w1, w2])
  25. # 使用梯度下降更新权重.
  26. # 要实际更新权重,我们需要在执行图时评估new_w1和new_w2.
  27. # 请注意,在TensorFlow中,更新权值的行为是计算图的一部分
  28. # 在PyTorch中,这发生在计算图之外.
  29. learning_rate = 1e-6
  30. new_w1 = w1.assign(w1 - learning_rate * grad_w1)
  31. new_w2 = w2.assign(w2 - learning_rate * grad_w2)
  32. # 现在我们已经构建了计算图,所以我们输入一个TensorFlow会话来实际执行图.
  33. with tf.Session() as sess:
  34. # 运行一次图形初始化变量w1和w2.
  35. sess.run(tf.global_variables_initializer())
  36. # 创建包含输入x和目标y的实际数据的numpy数组
  37. x_value = np.random.randn(N, D_in)
  38. y_value = np.random.randn(N, D_out)
  39. for _ in range(500):
  40. # 多次执行图. 每次执行时,
  41. # 我们都想将x_value绑定到x,将y_value绑定到y,用feed_dict参数指定.
  42. # 每次我们执行图时,我们都想计算损失值new_w1 和 new_w2;
  43. # 这些张量的值作为numpy数组返回.
  44. loss_value, _, _ = sess.run([loss, new_w1, new_w2],
  45. feed_dict={x: x_value, y: y_value})
  46. print(loss_value)