Tensorflow2.x学习——3.张量与相关操作

本系列为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))
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值