计算机视觉笔记总目录
1.tf.keras 获取数据集
Keras API 以 tf.keras
的形式包装在 TensorFlow 中。
时装分类Mnist数据集:
60,000张28x28总共10个类别的灰色图片,10,000张用于测试。
from keras.datasets import fashion_mnist
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
- 返回两个元组:
x_train, x_test:uint8 数组表示的灰度图像,尺寸为 (num_samples, 28, 28)。
y_train, y_test:uint8 数组表示的数字标签(范围在 0-9 之间的整数),尺寸为 (num_samples,)。
2.Tensorflow 计算
TensorFlow 视为一个科学计算库。导入TensorFlow
import tensorflow as tf
TensorFlow 使用 张量 (Tensor) 作为数据的基本单位。TensorFlow 的张量在概念上等同于多维数组,我们可以使用它来描述数学中的标量(0 维数组)、向量(1 维数组)、矩阵(2 维数组)等各种量,示例如下:
# 定义一个随机数(标量)
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.]])
张量的重要属性是其形状、类型和值。可以通过张量的 shape 、 dtype 属性和 numpy() 方法获得。例如:
# 查看矩阵A的形状、类型和值
print(A.shape) # 输出(2, 2),即矩阵的长和宽均为2
print(A.dtype) # 输出<dtype: 'float32'>
print(A.numpy()) # 输出[[1. 2.]
# [3. 4.]]
2.1 张量的类型
2.2 张量的阶
形状有0阶、1阶、2阶….
tensor1 = tf.constant(4.0)
tensor2 = tf.constant([1, 2, 3, 4])
linear_squares = tf.constant([[4], [9], [16], [25]], dtype=tf.int32)
print(tensor1.shape)
# 0维:() 1维:(10, ) 2维:(3, 4) 3维:(3, 4, 5)
3.张量操作
固定值张量
随机值张量
张量的变换
- 类型变换
- 张量的数学运算
- 算术运算符
- 基本数学函数
- 矩阵运算
- reduce操作
- 序列索引操作
参考官网链接
4.自动求导机制
在机器学习中,我们经常需要计算函数的导数。TensorFlow 提供了强大的自动求导机制来计算导数。
1、使用 tf.GradientTape()
计算函数
y
(
x
)
=
x
2
y(x)=x^{2}
y(x)=x2 在3时的导数:
import tensorflow as tf
x = tf.Variable(initial_value=3.)
with tf.GradientTape() as tape: # 在 tf.GradientTape() 的上下文内,所有计算步骤都会被记录以用于求导
y = tf.square(x)
y_grad = tape.gradient(y, x) # 计算y关于x的导数
print([y, y_grad])
输出:
[array([9.], dtype=float32), array([6.], dtype=float32)]
-
1、这里x是一个初始化为 3 的 变量 (Variable),使用
tf.Variable()
声明。与普通张量一样,变量同样具有形状、类型和值三种属性。使用变量需要有一个初始化过程,可以通过在 tf.Variable()中指定initial_value
参数来指定初始值。- 变量与普通张量的一个重要区别是其默认能够被 TensorFlow 的自动求导机制所求导,因此往往被用于定义机器学习模型的参数。
-
tf.GradientTape()
是一个自动求导的记录器,在其中的变量和计算步骤都会被自动记录。在上面的示例中,变量 x和计算步骤y = tf.square(x)
被自动记录,因此可以通过y_grad = tape.gradient(y, x)
求张量 y 对变量 x 的导数。
2、多元函数求导
通常我们实际应用中更多的是对多元函数求偏导数,以及对向量或矩阵的求导。如下面例子:
L
=
1
2
∗
∑
(
(
X
∗
w
)
+
b
−
y
)
2
L = \frac{1}{2} * \sum((X*w) + b - y)^2
L=21∗∑((X∗w)+b−y)2
X = tf.constant([[1, 2], [3., 4.]])
y = tf.constant([[1], [2.]])
w = tf.Variable(initial_value=[[1.], [2.]])
b = tf.Variable(initial_value=1.)
with tf.GradientTape() as tape:
L = 0.5 * tf.reduce_sum(tf.square(tf.matmul(X, w) + b - y))
w_grad, b_grad = tape.gradient(L, [w, b])
print([L.numpy(), w_grad.numpy(), b_grad.numpy()])
输出:
[62.5, array([[35.],
[50.]], dtype=float32), 15.0]
求导公式如下:
tf.reduce_sum()
操作代表对输入张量的所有元素求和,输出一个形状为空的纯量张量(可以通过 axis 参数来指定求和的维度,不指定则默认对所有元素求和)
5.案例:线性回归
考虑一个实际问题,某城市在 2013 年 - 2017 年的房价如下表所示:
年份 | 2013 | 2014 | 2015 | 2016 | 2017 |
---|---|---|---|---|---|
房价 | 12000 | 14000 | 15000 | 16500 | 17500 |
现在,我们希望通过对该数据进行线性回归,即使用线性模型 y = a x + b y = ax + b y=ax+b 来拟合上述数据,此处 a a a 和 b b b 是待求的参数。首先,我们定义数据,进行基本的归一化操作。
import numpy as np
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())
TensorFlow 下的线性回归:
TensorFlow 的 Eager Execution(动态图) 模式与 NumPy 的运行方式十分类似,然而提供了更快速的运算(GPU 支持)、自动求导、优化器等一系列对深度学习非常重要的功能。
- 使用
tape.gradient(ys, xs)
自动计算梯度; - m使用
optimizer.apply_gradients(grads_and_vars)
自动更新模型参数。 - 使用
tf.keras.optimizers.SGD(learning_rate=)
进行指定优化器
# 1、定义Tensor类型
X = tf.constant(X)
y = tf.constant(y)
# 2、参数使用变量初始化
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=1e-3)
for e in range(num_epoch):
# 使用tf.GradientTape()记录损失函数的梯度信息
with tf.GradientTape() as tape:
y_pred = a * X + b
loss = 0.5 * 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, b)
tf.keras.optimizers.SGD(learning_rate=1e-3)
声明了一个梯度下降 优化器 (Optimizer),其学习率为 1e-3。优化器可以帮助我们根据计算出的求导结果更新模型参数,从而最小化某个特定的损失函数,具体使用方式是调用其apply_gradients()
方法。- 更新模型参数的方法
optimizer.apply_gradients()
需要提供参数grads_and_vars
,具体而言,这里需要传入一个 Python 列表(List),列表中的每个元素是一个 (变量的偏导数,变量) 对,比如这里是 [(grad_a, a), (grad_b, b)]。
在实际应用中,我们编写的模型往往比这里一行就能写完的线性模型 y = a * x + b 要复杂得多。所以,我们往往会编写并实例化一个模型类model = Model()
,然后使用 y_pred = model(X)
调用模型,使用 model.variables
获取模型参数。