第二章
import tensorflow as tf
print(tf.__version__)
查看TF的版本
2.2数据操作
2.2.1 创建tensor
- 创建tensor
x = tf.constant(range(12))#constant 代表是常量的tensor
print(x.shape)
x
print(x)
len(x)#可以用len函数获取长度
(12,)
<tf.Tensor: id=0, shape=(12,), dtype=int32, numpy=array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])>
12
- 使用reshape函数
使用reshape函数把行向量x的形状改为(3, 4),也就是一个3行4列的矩阵,并记作X
X = tf.reshape(x,(3,4))#第一个参数为tensor,第二个参数为()元组
上面x.reshape((3, 4))也可写成x.reshape((-1, 4))或x.reshape((3, -1))。由于x的元素个数是已知的,这里的-1是能够通过元素个数和其他维度的大小推断出来的。
- 创建一个各元素为0,形状为(2, 3, 4)的张量
tf.zeros((2,3,4))
- 创建各元素为1的张量
tf.ones((3,4))
- 通过Python的列表(list)指定需要创建的tensor中每个元素的值
Y = tf.constant([[2,1,4,3],[1,2,3,4],[4,3,2,1]])
Y
<tf.Tensor: id=9, shape=(3, 4), dtype=int32, numpy=
array([[2, 1, 4, 3],
[1, 2, 3, 4],
[4, 3, 2, 1]])>
- 我们需要随机生成tensor中每个元素的值。下面我们创建一个形状为(3, 4)的tensor。它的每个元素都随机采样于均值为0、标准差为1的正态分布。
x=tf.random.normal(shape=[3,4], mean=0, stddev=1)
print(x)
tf.Tensor(
[[-1.153268 0.6116716 0.9703915 -2.7604232 ]
[ 0.48349026 -0.14327626 2.940394 0.98280823]
[ 0.11714476 -1.9485139 -0.46181852 -0.23992358]],
shape=(3, 4), dtype=float32)
2.2.2运算
- 乘除
X + Y #这里的X,Y有相同的形状,对应元素可以相加
X * Y#对应的元素相乘
X / Y
- 指数运算
Y = tf.cast(Y, tf.float32)#这里先转换tensor的类型
x=tf.reshape(tf.constant(range(12)),(3,4))
print(x)
x = tf.cast(x, tf.float32)
print(tf.exp(x))
tf.Tensor(
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]], shape=(3, 4), dtype=int32)
tf.Tensor(
[[1.0000000e+00 2.7182817e+00 7.3890562e+00 2.0085537e+01]
[5.4598152e+01 1.4841316e+02 4.0342880e+02 1.0966332e+03]
[2.9809580e+03 8.1030840e+03 2.2026467e+04 5.9874145e+04]], shape=(3, 4), dtype=float32)
这里注意,这里必须要cast 类型转换
- 矩阵的乘法,matmul函数做矩阵乘法
Y = tf.cast(Y, tf.int32)
tf.matmul(X, tf.transpose(Y))
- 矩阵 的转置
tf.transpose(Y)
- tensor 的拼接
tf.concat([X,Y],axis = 0)#行为axis=0,结果shape (6,4)
tf.concat([X,Y],axis = 1)#列为axis=1,结果shape (3,8)
- 判断值相等,以X == Y为例,如果X和Y在相同位置的条件判断为真(值相等),那么新的tensor在相同位置的值为1;反之为0。
tf.equal(X,Y)
<tf.Tensor: id=31, shape=(3, 4), dtype=bool, numpy=
array([[False, True, False, True],
[False, False, False, False],
[False, False, False, False]])>
- 求和
tf.reduce_sum(X)
2.2.3广播机制
对两个形状相同的tensor做按元素运算。当对两个形状不同的tensor按元素运算时,可能会触发广播(broadcasting)机制:先适当复制元素使这两个tensor形状相同后再按元素运算。
2.2.4索引
在tensor中,索引(index)代表了元素的位置。tensor的索引从0开始逐一递增。例如,一个3行2列的矩阵的行索引分别为0、1和2,列索引分别为0和1。
X[1:3]
#X为3行4列,这句话等于X[1:3,:],依据左闭右开指定范围的惯例,它截取了矩阵X中行索引为1和2的两行。
<tf.Tensor: id=50, shape=(2, 4), dtype=float32, numpy=
array([[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]], dtype=float32)>
- 赋值
指定tensor中需要访问的单个元素的位置,如矩阵中行和列的索引,并为该元素重新赋值。
X = tf.Variable(X)#从常量转换为变量
X[1,2].assign(9)
<tf.Variable 'UnreadVariable' shape=(3, 4) dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 9., 7.],
[ 8., 9., 10., 11.]], dtype=float32)>
2.2.5 运算的内存开销
tensor 和 NumPy 相互变换
import numpy as np
P = np.ones((2,3))
D = tf.constant(P)
下面为TF 的tensor
<tf.Tensor: id=115, shape=(2, 3), dtype=float64, numpy=
array([[1., 1., 1.],
[1., 1., 1.]])>
在转换回来
下面为np的tensor
np.array(D)
2.3自动求梯度
对函数 求关于列向量 xx 的梯度。
x = tf.reshape(tf.Variable(range(4), dtype=tf.float32),(4,1))
with tf.GradientTape() as t:
t.watch(x)
y = 2 * tf.matmul(tf.transpose(x), x)
dy_dx = t.gradient(y, x)
dy_dx
<tf.Tensor: id=30, shape=(4, 1), dtype=float32, numpy=
array([[ 0.],
[ 4.],
[ 8.],
[12.]], dtype=float32)>
with tf.GradientTape(persistent=True) as g:
g.watch(x)
y = x * x
z = y * y
dz_dx = g.gradient(z, x) # 108.0 (4*x^3 at x = 3)
dy_dx = g.gradient(y, x) # 6.0
dz_dx,dy_dx
WARNING:tensorflow:Calling GradientTape.gradient on a persistent tape inside its context is significantly less efficient than calling it outside the context (it causes the gradient ops to be recorded on the tape, leading to increased CPU and memory usage). Only call GradientTape.gradient inside the context if you actually want to trace the gradient in order to compute higher order derivatives.
WARNING:tensorflow:Calling GradientTape.gradient on a persistent tape inside its context is significantly less efficient than calling it outside the context (it causes the gradient ops to be recorded on the tape, leading to increased CPU and memory usage). Only call GradientTape.gradient inside the context if you actually want to trace the gradient in order to compute higher order derivatives.
(<tf.Tensor: id=41, shape=(4, 1), dtype=float32, numpy=
array([[ 0.],
[ 4.],
[ 32.],
[108.]], dtype=float32)>,
<tf.Tensor: id=47, shape=(4, 1), dtype=float32, numpy=
array([[0.],
[2.],
[4.],
[6.]], dtype=float32)>)
with tf.GradientTape(persistent=True) as g:
g.watch(x)
y = x * x
z = y * y
dz_dx = g.gradient(z, x) # 108.0 (4*x^3 at x = 3)
dy_dx = g.gradient(y, x) # 6.0
dz_dx,dy_dx
WARNING:tensorflow:Calling GradientTape.gradient on a persistent tape inside its context is significantly less efficient than calling it outside the context (it causes the gradient ops to be recorded on the tape, leading to increased CPU and memory usage). Only call GradientTape.gradient inside the context if you actually want to trace the gradient in order to compute higher order derivatives.
WARNING:tensorflow:Calling GradientTape.gradient on a persistent tape inside its context is significantly less efficient than calling it outside the context (it causes the gradient ops to be recorded on the tape, leading to increased CPU and memory usage). Only call GradientTape.gradient inside the context if you actually want to trace the gradient in order to compute higher order derivatives.
(<tf.Tensor: id=41, shape=(4, 1), dtype=float32, numpy=
array([[ 0.],
[ 4.],
[ 32.],
[108.]], dtype=float32)>,
<tf.Tensor: id=47, shape=(4, 1), dtype=float32, numpy=
array([[0.],
[2.],
[4.],
[6.]], dtype=float32)>)
2.4
想了解某个函数或者类的具体用法时,可以使用help函数。让我们以ones函数为例,查阅它的用法。更详细的信息,可以通过Tensorflow的API文档版本选择页,选择与自己环境中的 tensorflow 版本一致的 API 版本进行查询。
help(tf.ones)
当我们想知道一个模块里面提供了哪些可以调用的函数和类的时候,可以使用dir函数。下面我们打印dtypes和random模块中所有的成员或属性。
当我们想知道一个模块里面提供了哪些可以调用的函数和类的时候,可以使用dir函数。下面我们打印dtypes和random模块中所有的成员或属性。
dir(tf.dtypes)
['DType',
'QUANTIZED_DTYPES',
'__builtins__',
'__cached__',
'__doc__',
'__file__',
'__loader__',
'__name__',
'__package__',
'__path__',
'__spec__',
'_sys',
'as_dtype',
'bfloat16',
'bool',
'cast',
'complex',
'complex128',
'complex64',
'double',
'float16',
'float32',
'float64',
'half',
'int16',
'int32',
'int64',
'int8',
'qint16',
'qint32',
'qint8',
'quint16',
'quint8',
'resource',
'saturate_cast',
'string',
'uint16',
'uint32',
'uint64',
'uint8',
'variant']