1. TensorFlow 基本操作
在 TensorFlow 中,其基本的数据类型为“张量”(tensor),用来表示n维数组。
一个 tf.Tensor 对象,包含以下属性:
a data type (float32, int32, or string, for example)
a shape
其中,要求该 Tensor 中的每一个元素,拥有相同的数据类型,且数据类型已知。
1.1 创建/变换
1)查看 tensorflow 版本
import tensorflow as tf
print(tf.__version__)
2.0.0
2)创建 常数张量
x = tf.constant(range(12))
x
<tf.Tensor: id=17, shape=(12,), dtype=int32, numpy=array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], dtype=int32)>
x.shape
TensorShape([12])
x.dtype
tf.int32
x.numpy()
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], dtype=int32)
3)更改 shape
x_1 = tf.reshape(x, (3, 4))
# 或 x_1 = tf.reshape(x, (-1, 4))
# 或 x_1 = tf.reshape(x, (3, -1))
x_1
<tf.Tensor: id=19, shape=(3, 4), dtype=int32, numpy=
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]], dtype=int32)>
4)更改 数据类型
tf.cast(x_1, tf.float32)
<tf.Tensor: id=15, shape=(3, 4), dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]], dtype=float32)>
5)转置
tf.transpose(x_1)
<tf.Tensor: id=9, shape=(4, 3), dtype=int32, numpy=
array([[ 0, 4, 8],
[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11]], dtype=int32)>
6)创建 各元素为1(或0)的张量
tf.zeros((2,3,4))
<tf.Tensor: id=33, shape=(2, 3, 4), dtype=float32, numpy=
array([[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]]], dtype=float32)>
tf.ones((3, 4))
<tf.Tensor: id=30, shape=(3, 4), dtype=float32, numpy=
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]], dtype=float32)>
7)创建 各元素为随机值的张量
# 标准正态分布
tf.random.normal(shape=[3,4], mean=0, stddev=1)
<tf.Tensor: id=39, shape=(3, 4), dtype=float32, numpy=
array([[-0.7968009 , -0.23385778, 0.17272884, 0.40618992],
[ 1.179755 , 1.4119581 , 0.16764395, 1.9177414 ],
[ 0.8029417 , -0.4669095 , -0.7361532 , -1.0058894 ]],
dtype=float32)>
1.2 运算
a = tf.constant([[1., 3., 2.], [-2., 1., 1.]])
b = tf.ones((2, 3))
c = tf.zeros((2, 3))
1)按元素 加/减/乘/除
多个 shape 相同的 tensor,按元素进行 加/减/乘/除,结果 shape 不变。
a+b*c
<tf.Tensor: id=75, shape=(2, 3), dtype=float32, numpy=
array([[ 1., 3., 2.],
[-2., 1., 1.]], dtype=float32)>
2)按元素 指数运算
tf.exp(c)
<tf.Tensor: id=26, shape=(2, 3), dtype=float32, numpy=
array([[1., 1., 1.],
[1., 1., 1.]], dtype=float32)>
3)矩阵乘法
# a.shape=(2, 3)
tf.matmul(a, tf.transpose(a))
<tf.Tensor: id=29, shape=(2, 2), dtype=float32, numpy=
array([[14., 3.],
[ 3., 6.]], dtype=float32)>
4)连接
a.shape=(2, 3)
# 按行
tf.concat([a, a], axis=0)
<tf.Tensor: id=31, shape=(4, 3), dtype=float32, numpy=
array([[ 1., 3., 2.],
[-2., 1., 1.],
[ 1., 3., 2.],
[-2., 1., 1.]], dtype=float32)>
# 按列
tf.concat([a, a], axis=1)
<tf.Tensor: id=33, shape=(2, 6), dtype=float32, numpy=
array([[ 1., 3., 2., 1., 3., 2.],
[-2., 1., 1., -2., 1., 1.]], dtype=float32)>
5)条件判断
tf.equal(a, b)
<tf.Tensor: id=34, shape=(2, 3), dtype=bool, numpy=
array([[ True, False, False],
[False, True, True]])>
6)对所有元素求和
tf.reduce_sum(a)
<tf.Tensor: id=53, shape=(), dtype=float32, numpy=6.0>
1.3 广播
两个 shape 不同的 tensor,按元素进行运算,触发广播(broadcasting)机制:先复制元素使 tensor 形状相同,再按元素运算。
A = tf.reshape(tf.constant(range(3)), (3,1))
B = tf.reshape(tf.constant(range(2)), (1,2))
A, B
(<tf.Tensor: id=73, shape=(3, 1), dtype=int32, numpy=
array([[0],
[1],
[2]], dtype=int32)>,
<tf.Tensor: id=76, shape=(1, 2), dtype=int32, numpy=array([[0, 1]], dtype=int32)>)
A * B
<tf.Tensor: id=87, shape=(3, 2), dtype=int32, numpy=
array([[0, 0],
[0, 1],
[0, 2]], dtype=int32)>
A + A * B
<tf.Tensor: id=86, shape=(3, 2), dtype=int32, numpy=
array([[0, 0],
[1, 2],
[2, 4]], dtype=int32)>
1.4 索引
1)选取指定 行/列
与python切片用法一致。
# x_1
<tf.Tensor: id=7, shape=(3, 4), dtype=int32, numpy=
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]], dtype=int32)>
x_1[1,2]
<tf.Tensor: id=107, shape=(), dtype=int32, numpy=6>
x_1[1:,:2]
<tf.Tensor: id=127, shape=(2, 2), dtype=int32, numpy=
array([[4, 5],
[8, 9]], dtype=int32)>
2)选取并赋值
先转为 tf.Variable,再赋值。
x_3 = tf.Variable(x_1)
x_3[1,2].assign(9)
x_3
<tf.Variable 'Variable:0' shape=(3, 4) dtype=int32, numpy=
array([[ 0, 1, 2, 3],
[ 4, 5, 9, 7],
[ 8, 9, 10, 11]], dtype=int32)>
否则,报如下错:
x_1[1,2].assign(9)
x_1
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-82-1755a38d8d5c> in <module>
----> 1 x_1[1,2].assign(9)
2 x_1
AttributeError: 'tensorflow.python.framework.ops.EagerTensor' object has no attribute 'assign'
1.5 减少内存开销
对于不会复用的结构,为减少内存开销,可以写为:
X[:] = X + Y ,或, X += Y。
1.6 tensor 和 numpy array 相互转换
1)numpy array 转 tensor
import numpy as np
m = np.ones((2,3))
n = tf.constant(m)
m, n
<tf.Tensor: id=115, shape=(2, 3), dtype=float64, numpy=
array([[1., 1., 1.],
[1., 1., 1.]])>
2)tensor 转 numpy array
np.array(m)
array([[1., 1., 1.],
[1., 1., 1.]])
1.7 对比
1.7.1 constant vs variable 指定 shape
1)constant 支持 配置shape参数
x = tf.constant(np.arange(12.), shape=(3, 4))
x
<tf.Tensor: id=104, shape=(3, 4), dtype=float64, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])>
2)variable 需要 tf.reshape 变换
配置shape参数 报错
import numpy as np
x = tf.Variable(np.arange(12.), shape=(3, 4))
x
ValueError: The initial value's shape ((12,)) is not compatible with the explicitly supplied `shape` argument ((3, 4)).
tf.reshape 变换
x = tf.Variable(np.arange(12.))
tf.reshape(x, (3, -1))
<tf.Tensor: id=124, shape=(3, 4), dtype=float64, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])>
1.7.3 tensor 按元素相加 多种实现
1)tf.add
tf.add(x, 3)
<tf.Tensor: id=75, shape=(3, 4), dtype=int32, numpy=
array([[ 3, 4, 5, 6],
[ 7, 8, 9, 10],
[11, 12, 13, 14]], dtype=int32)>
2)tensor 相加
x+tf.constant([3])
<tf.Tensor: id=77, shape=(3, 4), dtype=int32, numpy=
array([[ 3, 4, 5, 6],
[ 7, 8, 9, 10],
[11, 12, 13, 14]], dtype=int32)>