探索Tensorflow2.2自动求导机制

这个专栏主要对64位mac上的Tensorflow2.2的使用进行探索。在本专栏的第一篇文章中,笔者列举了几个对于Tensorflow使用者而言比较清晰的学习网站,有兴趣的学习者可以去自行探索。不同角度学习Tensorflow的途径还有很多,笔者在此就不一一详述。


  • 引语

在本专栏的上篇文章中,运用Tensorflow对于 ddx(y=x2)|x=2进行求导计算时,

我们得到了以下输出结果:

tf.Tensor(4.0, shape=(), dtype=float32) tf.Tensor(4.0, shape=(), dtype=float32)

其中我们可以看出这串代码中包括了求导的正确答案4.0,但其后面还有两个属性:shape()和dtype。如何运用Tensorflow进行求导计算,以及答案中的这两个属性分别代表了什么含义呢?笔者在之后的篇幅中会对其详述。

  • 深入

1.1张量(Tensor)

TensorFlow 使用张量 (Tensor)作为数据的基本单位,张量的重要属性是其形状(shape)和类型(dtype)。

import tensorflow as tf
A = tf.constant([[1., 2., 3.], [4., 5., 6.]])
print(A)

对于张量进行挖掘之后,我们得到了下列对于张量的属性表达

tf.Tensor(
[[1. 2. 3.]
 [4. 5. 6.]], shape=(2, 3), dtype=float32)

因此,我们可以得出属性shape中的值为(行的数量,列的数量)。所以TensorFlow 的张量在概念上等同于多维数组,我们可以使用它来描述数学中的标量(0 维数组)、向量(1 维数组)、矩阵(2 维数组)等等。

张量的属性Dtype中指的是数据类型,用32位float型表示的张量类型为浮点型数据类型(float32)。

1.2数学运算(Operation)

1) Tensorflow2的加法运算

Addition:
A = tf.constant([[1., 2., 3.], [4., 5., 6.]])
B = tf.constant([[7., 8., 9.], [1., 2., 3.]])
C = tf.add(A, B)    # 计算矩阵A和B的和
print(C)

Conclusion:
tf.Tensor(
[[ 8. 10. 12.]
 [ 5.  7.  9.]], shape=(2, 3), dtype=float32)

2) Tensorflow2的乘法运算

Multiplication:
import tensorflow as tf
A = tf.constant([[1., 2., 3.], [4., 5., 6.]])
B = tf.constant([[7., 8.], [9., 1.], [2., 3.]])
C = tf.matmul(A, B) # 计算矩阵A和B的乘积
print(C)

Conclusion:
tf.Tensor(
[[31. 19.]
 [85. 55.]], shape=(2, 2), dtype=float32)

2.1 自动求导机制

2.1.1 求导机制

在机器学习中,我们经常需要计算函数的导数。TensorFlow 提供了强大的自动求导机制来计算导数。TensorFlow 引入了 tf.GradientTape() 这个 “求导记录器” 来实现自动求导。在使用变量需要有一个初始化过程,所以可以通过在 tf.Variable() 中指定 initial_value 参数来指定初始值。

下代码展示了如何使用tf.GradientTape()计算函数 y=x2 在 x=4 时的导数。

import tensorflow as tf
x = tf.Variable(initial_value=4.)
with tf.GradientTape() as tape:
    y = tf.square(x)
y_grad = tape.gradient(y, x)
print(y, y_grad)

输出:

tf.Tensor(16.0, shape=(), dtype=float32) tf.Tensor(8.0, shape=(), dtype=float32)

2.1偏导数求导机制

对于一些复杂的函数,我们需要计算它们对于单个变量的偏导数。在机器学习中,更加常见的是对多元函数求偏导数,以及对向量或矩阵的求导。所以,在Tensorflow中运用偏导数求导机制也十分重要。

计算函数 L(w,b)=||Xw+b−y||2 在 w=(2,3)T , b=2 时分别对 ,w,b 的偏导数。

其中, x=[1234] , y=[12]

X = tf.constant([[1., 2.], [3., 4.]])
y = tf.constant([[1.], [2.]])
w = tf.Variable(initial_value=[[2.], [3.]])
b = tf.Variable(initial_value=2.)
with tf.GradientTape() as tape:
    L = tf.reduce_sum(tf.square(tf.matmul(X, w) + b - y))
w_grad, b_grad = tape.gradient(L, [w, b])        # 计算L(w, b)关于w, b的偏导数
print(L, w_grad, b_grad)

输出:

tf.Tensor(405.0, shape=(), dtype=float32) tf.Tensor(
[[126.]
 [180.]], shape=(2, 1), dtype=float32) tf.Tensor(54.0, shape=(), dtype=float32)

从输出可见,TensorFlow 帮助我们计算出了

L(w=(2,3)T,2)=405

∂L(w,b)∂w|w=(2,3)T,b=2=[126180]

∂L(w,b)∂b|w=(2,3)T,b=2=54


结语

这篇主要对于对于Tensorflow的自动求导机制进行了介绍,将求导机制从理论表达上转化到代码中的实现。这些简单明了的机制都是之后运用Tensroflow进行线性拟合或者实现其他算法的基础。

PS:鄙人不才,欢迎各位大佬指正!如果觉得本篇本章对您有所帮助,欢迎关注、评论、赞!

猜你喜欢

转载自blog.csdn.net/zhaomengsen/article/details/130874984