如果你喜欢我的文章,欢迎来我的博客与我讨论饭饭的TensorFlow笔记——科学计算
科学运算
在正式开始神经网络的构建之前,我们可以把TensorFlow看做一个科学计算库,它内置了很多能帮助我们快速进行科学计算的函数
张量
在TensorFlow中,所有数据都是以张量(Tensor)形式表示,我们可以简单理解张量为多维数组,下面是一些实例
# 定义一个随机数(标量)
random_float = tf.random.uniform(shape=())
# 定义一个有2个元素的零向量
zero_vector = tf.zeros(shape=(2))
# 定义两个2×2的常量矩阵
A = tf.constant([[1., 2.], [3., 4.]])
B = tf.constant([[5., 6.], [7., 8.]])
Tensor像numpy中array一样有很多属性
# 查看矩阵A的形状、类型和值
print(A.shape) # 输出(2, 2),即矩阵的长和宽均为2
print(A.dtype) # 输出<dtype: 'float32'>
print(A.numpy()) # 输出[[1. 2.]
# [3. 4.]]
操作
对于张量有以下常用操作
C = tf.add(A, B) # 计算矩阵A和B的和
D = tf.matmul(A, B) # 计算矩阵A和B的乘积
自动求导
自动求导是TensorFlow能够方便的进行机器学习的重要原因之一,接下来我们会通过一个简单的例子来演示TensorFlow自动求导机制
x = tf.Variable(3.)
with tf.GradientTape() as type:
y = tf.square(x)
y_grad = type.gradient(y, x)
print(y, y_grad)
这里 x
是一个初始化为 3 的 变量 (Variable),使用 tf.Variable()
声明。与普通张量一样,变量同样具有形状、类型和值三种属性。使用变量需要有一个初始化过程,这里将变量 x
初始化为 3.
。变量与普通张量的一个重要区别是其默认能够被 TensorFlow 的自动求导机制所求导,因此往往被用于定义机器学习模型的参数。
tf.GradientTape()
是一个自动求导的记录器。只要进入了 with tf.GradientTape() as tape
的上下文环境,则在该环境中计算步骤都会被自动记录。比如在上面的示例中,计算步骤 y = tf.square(x)
即被自动记录。离开上下文环境后,记录将停止,但记录器 tape
依然可用,因此可以通过 y_grad = tape.gradient(y, x)
求张量 y
对变量 x
的导数。
实例:线性回归
接下来我们通过TensorFlow实现一个线性回归来演示TensorFlow实际模型是如何工作的
import numpy as np
import tensorflow as tf
X_raw = np.array([2013, 2014, 2015, 2016, 2017], dtype=np.float32)
y_raw = np.array([12000, 14000, 15000, 16500, 17500], dtype=np.float32)
X = (X_raw - X_raw.min()) / (X_raw.max() - X_raw.min())
y = (y_raw - y_raw.min()) / (y_raw.max() - y_raw.min())
X = tf.constant(X)
y = tf.constant(y)
a = tf.Variable(initial_value=0.)
b = tf.Variable(initial_value=0.)
variables = [a, b]
# 定义常量和变量
num_epoch = 10000
optimizer = tf.keras.optimizers.SGD(learning_rate=5e-4)
for e in range(num_epoch):
# 使用tf.GradientTape()记录损失函数的梯度信息
with tf.GradientTape() as tape:
y_pred = a * X + b
loss = tf.reduce_sum(tf.square(y_pred - y))
# TensorFlow自动计算损失函数关于自变量(模型参数)的梯度
grads = tape.gradient(loss, variables)
# TensorFlow自动根据梯度更新参数
optimizer.apply_gradients(grads_and_vars=zip(grads, variables))
print(a.numpy, b.numpy)