version==2.3.0
参考资料:《简单粗暴TensorFlow》
在Colab上运行
在Colab中使用TensorFlow,免费在线交互Python运行环境,且提供GPU支持。
网址:https://colab.research.google.com
新建笔记本运行python程序
在菜单 “代码执行程序 - 更改运行时类型”可选择GPU加速
ctrl+enter
执行代码 tab
弹出代码提示
1+1
属性
TensorFlow数据基本单位是张量,概念上等同于多维数组。
张量的属性有:
- 形状
shape
- 类型
dtype
- 值
numpy()
将张量值转化为数组
示例:
# 定义一个随机数(标量)
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.]])
# 查看矩阵A的形状、类型和值
print(A.shape) # 输出(2, 2),即矩阵的长和宽均为2
print(A.dtype) # 输出<dtype: 'float32'>
print(A.numpy()) # 输出[[1. 2.]
# [3. 4.]]
自定义
自定矩阵大小、类型以及值:
A = tf.constant([[1., 2.], [3., 4.]],shape=(2,2),dtype=tf.float32)
操作
C = tf.add(A, B) # 计算矩阵A和B的和
D = tf.matmul(A, B) # 计算矩阵A和B的乘积
C、D矩阵的计算结果为:
tf.Tensor( [[ 6. 8.] [10. 12.]], shape=(2, 2), dtype=float32)
tf.Tensor( [[19. 22.] [43. 50.]], shape=(2, 2), dtype=float32)
自动求导
基本
使用tf.GradientTape()
实现自动求导
示例:
求
y
=
f
(
x
)
=
x
2
在
x
=
3
时
的
导
数
求y=f(x)=x^2 在 x=3 时的导数
求y=f(x)=x2在x=3时的导数
x = tf.Variable(initial_value=3.) # x是变量,同样具有形状、类型和值三个属性。使用initial_value进行变量初始化
with tf.GradientTape() as tape: # 在 tf.GradientTape() 的上下文内,所有计算步骤都会被记录以用于求导
y = tf.square(x)
y_grad = tape.gradient(y, x) # 计算y关于x的导数。在上下文环境之外,记录停止,但记录器tape依然可用
print(y, y_grad)
变量默认能够被自动求导机制所求导,往往被用于定义机器学习模型的参数
输出结果:
tf.Tensor(9.0, shape=(), dtype=float32) tf.Tensor(6.0, shape=(), dtype=float32)
多元函数求偏导(向量 矩阵)
示例:
计
算
L
(
w
,
b
)
=
∣
∣
X
w
+
b
−
y
∣
∣
2
在
w
=
(
1
,
2
)
T
,
b
=
1
时
分
别
对
w
,
b
的
偏
导
数
X
=
[
1
2
3
4
]
,
y
=
[
1
2
]
计算L(w,b)=||Xw+b-y||^2在w=(1,2)^T,b=1时分别对w,b的偏导数 \\X=\begin{bmatrix} 1 & 2\\ 3 & 4\end{bmatrix},y=\begin{bmatrix} 1\\ 2\\ \end{bmatrix}
计算L(w,b)=∣∣Xw+b−y∣∣2在w=(1,2)T,b=1时分别对w,b的偏导数X=[1324],y=[12]
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 = tf.reduce_sum(tf.square(tf.matmul(X, w) + b - y))# square()是对张量的每一个元素求平方;reduce_sum()是对张量所有元素求和
w_grad, b_grad = tape.gradient(L, [w, b]) # 计算L(w, b)关于w, b的偏导数
print(L, w_grad, b_grad)
输出结果:
tf.Tensor(125.0, shape=(), dtype=float32) tf.Tensor(
[[ 70.]
[100.]], shape=(2, 1), dtype=float32) tf.Tensor(30.0, shape=(), dtype=float32)
数学表示为:
L
(
(
1
,
2
)
T
,
1
)
=
125
∂
L
(
w
,
b
)
∂
w
∣
w
=
(
1
,
2
)
T
,
b
=
1
=
[
70
100
]
∂
L
(
w
,
b
)
∂
b
∣
w
=
(
1
,
2
)
T
,
b
=
1
=
30
L((1,2)^T,1)=125\\\frac{\partial L(w,b)}{\partial w}|_{w=(1,2)^T,b=1}=\begin{bmatrix}70\\100\end{bmatrix}\\\frac{\partial L(w,b)}{\partial b}|_{w=(1,2)^T,b=1}=30\\
L((1,2)T,1)=125∂w∂L(w,b)∣w=(1,2)T,b=1=[70100]∂b∂L(w,b)∣w=(1,2)T,b=1=30
线性回归
使用Tensorflow利用梯度下降法计算线性回归的解
tf.keras.optimizers.SGD(learning_rate=...)
声明梯度下降优化器,并定义学习率(梯度下降一次迈出步子的大小)
优化器的apply_gradients()
方法自动根据求导结果更新模型参数,并且需要提供参数grads_and_vars=[(变量的偏导数,变量)]
,每次迭代计算参数的偏导,然后用python的zip()
方法将偏导与参数包裹在一起交给迭代器即可
Python的zip()方法:将对应元素打包成元组,返回元组组成的列表,如
a=[1,2],b=[3,4],zip(a,b)=[(1,3),(2,4)]
在Python3中,zip()方法返回的是zip对象,需要调用list()将生成器转化为列表
示例:
用线性模型y=ax+b
拟合以下数据:
y | 2013 | 2014 | 2015 | 2016 | 2017 |
---|---|---|---|---|---|
x | 12000 | 14000 | 15000 | 16500 | 17500 |
先用numpy定义数据,归一
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):
with tf.GradientTape() as tape:
y_pred = a * X + b
# 计算损失函数
loss = tf.reduce_sum(tf.square(y_pred - y))
# 计算损失函数关于变量的偏导(梯度)
grads = tape.gradient(loss, variables)
# 根据偏导值更新参数
optimizer.apply_gradients(grads_and_vars=zip(grads, variables))
计算结果:
[<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.97637>, <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.057565063>]