本系列为tensorflow官方教程与文档学习笔记,结合个人理解提取其中的关键内容,便于日后复习。
张量
张量和高维数组是等价的,tensorflow有丰富的API用以生产和消费张量数据。与Numpy类型的数组不同的是,Tensors具备两个特点:
- Tensors可以通过GPU和TPU进行计算加速
- Tensors是不可变的(immutable)
1.1 张量的生成
1.1.1 通过numpy和list生成
通过tf.convert_to_tensor()
实现:
tf.convert_to_tensor(np.ones([3, 3]))
tf.convert_to_tensor([1,2,3])
Tensor与Numpy类型的数据在操作时具备自动转换特性:即numpy中的操作可以运用在Tensor上,tensorflow的操作可以运用在numpy的array上,如:
np.mean(tf.convert_to_tensor([1,2,3]))
tf.add(np.array([1,2]), np.array([1,2]))
想要显式地将Tensor转为numpy类型,使用.numpy()
方法。
1.1.2 通过相关方法生成
-
tf.zeros([2, 2])
:生成全零张量; -
tf.zeros_like([1, 2, 3])
:生成与参数形状相同的全零张量; -
tf.fill([2, 3], 1.5)
:生成填充的张量,第一个参数为张量形状,第二个参数为填充的数值; -
tf.ones([2, 2])
:生成全一张量; -
tf.random.normal([2, 2], mean=1, stddev=1)
:生成指定均值与方差下的随机张量; -
tf.random.uniform([2, 2], minval = 0, maxval = 1)
:生成指定区间的均匀分布张量;
1.2 GPU加速
很多Tensorflow中的操作都可以通过GPU加速,Tensorflow会自动决定使用CPU还是GPU,如:
x = tf.random.uniform([3, 3])
print("Is there a GPU available: "),
print(tf.config.experimental.list_physical_devices("GPU"))
print("Is the Tensor on GPU #0: "),
print(x.device.endswith('GPU:0'))
#Is there a GPU available:
#[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
#Is the Tensor on GPU #0:
#True
然而,通过tf.device
上下文管理器,可以手动决定操作是基于CPU还是GPU:
import time
def matmul(x):
start = time.time()
for loop in range(1000):
tf.matmul(x, x)
result = 1000 * (time.time() - start)
print("1000 loops: {:0.2f}ms".format(result))
# Force execution on CPU
print("On CPU:")
with tf.device("CPU:0"):
x = tf.random.uniform([1000, 1000])
assert x.device.endswith("CPU:0")
matmul(x)
# Force execution on GPU #0 if available
if tf.config.experimental.list_physical_devices("GPU"):
print("On GPU:")
with tf.device("GPU:0"): # Or GPU:1 for the 2nd GPU, GPU:2 for the 3rd etc.
x = tf.random.uniform([1000, 1000])
assert x.device.endswith("GPU:0")
matmul(x)
1.3 张量的索引与切片
- 最基础的索引方式:
a = tf.random.uniform([2, 2], minval = 0, maxval = 1)
a[0][0]
- numpy风格的索引方式:
a = tf.random.uniform([2, 2], minval = 0, maxval = 1)
a[0, 0]
- 使用
:
符号切片:
a = tf.random.uniform([2, 2, 2], minval = 0, maxval = 1)
a[1, :, :] == a[1, :]
- 使用
start:end:step
格式
a = tf.range(10)
a[1:10:2]
#<tf.Tensor: shape=(5,), dtype=int32, numpy=array([1, 3, 5, 7, 9])>
- 使用
tf.gather()
进行灵活切片
a = tf.Variable([[1,2,3,4,5], [6,7,8,9,10], [11,12,13,14,15]])
# 取出第一列和第二列
print(tf.gather(a, axis=1, indices=[0,1]).numpy())
# 取出第三行
print(tf.gather(a, axis=0, indices=[2]).numpy())
1.4 张量的维度变换
- 通过
tf.reshape(tensor, shape, name=None)
改变张量形状
tf.reshape([[1,2,3], [4,5,6]], [6])
# <tf.Tensor: shape=(6,), dtype=int32, numpy=array([1, 2, 3, 4, 5, 6])>
tf.transpose(a, perm=None, conjugate=False, name='transpose')
进行维度的变换(若不加perm
参数即为张量转置)
a = tf.Variable([[1,2,3], [4,5,6]])
tf.transpose(a).numpy()
# array([[1, 4],
# [2, 5],
# [3, 6]])
- 在指定的axis增加维度
tf.expand_dims(input, axis, name=None)
tf.expand_dims([[1,2,3], [4,5,6]], axis=1).shape
# TensorShape([2, 1, 3])
- 使用
tf.squeeze(input, axis=None, name=None)
缩小张量维度(只能作用于shape=1的维度)
a = tf.Variable([[1],[2]])
tf.squeeze(a).numpy()
# array([1, 2])
1.5 张量的合并与分割
- 使用
tf.concat(values, axis, name='concat')
在指定的axis上进行合并(合并后维度不变)
t1 = tf.eye(5)
t2 = tf.eye(5)
tf.concat([tf.expand_dims(t1, axis=0), tf.expand_dims(t2, axis=0)], axis=0)
# <tf.Tensor: shape=(2, 5, 5), dtype=float32, numpy=
# array([[[1., 0., 0., 0., 0.],
# [0., 1., 0., 0., 0.],
# [0., 0., 1., 0., 0.],
# [0., 0., 0., 1., 0.],
# [0., 0., 0., 0., 1.]],
# [[1., 0., 0., 0., 0.],
# [0., 1., 0., 0., 0.],
# [0., 0., 1., 0., 0.],
# [0., 0., 0., 1., 0.],
# [0., 0., 0., 0., 1.]]], dtype=float32)>
- 使用
tf.split(value, num_or_size_splits, axis=0, num=None, name='split')
进行张量的分割(分割后维度不变)
a, b = tf.split(tf.stack([t1, t2], axis=0), num_or_size_splits=2)
# tf.Tensor(
# [[[1. 0. 0. 0. 0.]
# [0. 1. 0. 0. 0.]
# [0. 0. 1. 0. 0.]
# [0. 0. 0. 1. 0.]
# [0. 0. 0. 0. 1.]]], shape=(1, 5, 5), dtype=float32)
- 使用
tf.stack(values, axis=0, name='stack')
在新建维度上合并(合并后维度增加)
# 与上例为同样效果
t1 = tf.eye(5)
t2 = tf.eye(5)
tf.stack([t1, t2], axis=0)
- 通过
tf.unstack(value, num=None, axis=0, name='unstack')
进行张量的分割(分割后维度减少)
# 将合并后的张量重新拆分为t1和t2
t1, t2 = tf.unstack(tf.stack([t1, t2], axis=0))