创建张量

创建张量1

TensorFlow中的Tensor表示张量,其实就是多维数组。在此之前,我们还学习过

  • python中的列表list

  • Numpy中的数组对象ndarray
    它们也都可以作为数据的载体,那么它们有何区别呢?

  • Python列表(list)

    • 元素可以使用不同的数据类型,可以嵌套
    • 在内存中不连续存放,是一个动态的指针数据
    • 读写效率低,占用内存空间大
    • 不适合做数值计算
  • Numpy数组(ndarray)

    • 元素数据类型相同
    • 每个元素在内存中占用的空间相同,存储在一个连续的内存区域中
    • 存储空间小,读取和写入速度快
    • 在CPU中运算,不能够主动检测、利用GPU进行计算
  • TensorFlow张量(Tensor)

    • 可以高速运行于GPU和TPI之上
    • 支持CPU、嵌入式、单机多卡和多机多卡等多种计算环境
    • 高速的实现神经网络和深度学习中的复杂算法

TensorFlow的基本运算、参数命名、运算规则、API的设计与Numpy非常相近。

创建Tensor对象

张量由Tensor类实现,每个张量都是一个Tensor对象,可以使用tf.constant()的函数来创建张量。

tf.constant(value, dtype, shape)

其中参数
value:可以是一个数,一个Python列表也可以是一个Numpy数组参数
dtype:元素的数据类型,可以省略
shape:张量的形状,可以省略

参数为python列表

首先是用python列表来创建张量。这里将value参数指定为一个二维列表,其他参数省略。
这是运行结果

tf.constant([[1, 2], [3, 4]])
"""
<tf.Tensor: id=0, shape=(2, 2), dtype=int32, numpy=
array([[1, 2],
       [3, 4]])>
"""

这个尖括号表示这是tensorflow返回的提示信息, tf.tensor表示这是tenseflow中的张量对象,id是张量的序号由系统自动按顺序给出,shape是张量的形状,这是一个二维张量,形状是(2, 2),我们没有给出数据类型,默认为32位整型,最后是这个张量的值,以Numpy数组的形式给出

张量的.numpy()方法

tensorflow中的张量是对Numpy数组的封装,在tensorflow2.0中所有的张量都可以通过numpy方法得到它对应的数组,例如

a = tf.constant([[1, 2], [3, 4]])
a.numpy()
"""
array([[1, 2],
       [3, 4]])
"""

type(a)

"""
<class 'tensorflow.python.framework.ops.EagerTensor'>
"""
print(a)
"""
tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32)
"""

参数为数字

张量也可以是一个数字

tf.constant(1.0)
# <tf.Tensor: id=3, shape=(), dtype=float32, numpy=1.0>

这里形状是一个空括号,表示0维张量,tensorflow创建浮点数张量时,默认是float32类型。

tf.constant(1.)
# <tf.Tensor: id=4, shape=(), dtype=float32, numpy=1.0>

为了方便,这里也可以将小数点后的0省略。

tf.constant(1.0, dtype=tf.float64)
# <tf.Tensor: id=5, shape=(), dtype=float64, numpy=1.0>

张量元素的数据类型

数据类型描述
tf.int88位有符号整数
tf.int1616位有符号整数
tf.int3232位有符号整数
tf.int6464位有符号整数
tf.uint88位无符号整数
tf.float3232位浮点数
tf.float6464位浮点数
tf.string字符串
tf.bool布尔型
tf.complex64复数,实部和虚部分别为32位浮点数

也可以在常见张量时,指定张量的数据类型。

tf.constant(1.0, dtype=tf.float64)
# <tf.Tensor: id=5, shape=(), dtype=float64, numpy=1.0>
tf.constant(1.0, dtype=float64)
"""
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'float64' is not defined
"""

是因为在python中是找不到这个数据类型的。

参数为numpy数组

import numpy as np
tf.constant(np.array([1, 2]))
# <tf.Tensor: id=6, shape=(2,), dtype=int32, numpy=array([1, 2])>

tf.constant(np.array([1.0, 2.0]))
# <tf.Tensor: id=7, shape=(2,), dtype=float64, numpy=array([1., 2.])>

tf.constant(np.array([1.0, 2.0]), dtype=tf.float32)
# <tf.Tensor: id=8, shape=(2,), dtype=float32, numpy=array([1., 2.], dtype=float32)>

numpy创建浮点数数组时,默认的浮点型是64位浮点数。当使用Numpy数组创建张量时,TensorFlow会接受数组元素的数据类型,使用64位浮点数保存数据。

在GPU上运行TensorFlow程序处理32位浮点数的速度比处理64位浮点数要快得多,而对于大多数深度学习算法使用32位整数或者32位浮点数就可以满足运算的精度了,因此在使用numpy数组创建张量时,建议指明数据类型为32位浮点数,除非非常确定需要使用64位浮点数的情况。

tf.constant()函数:改变张量中元素的数据类型

在张量创建之后,也可以使用tf.cast()的函数改变张量中元素的数据类型。

tf.cast(x, dtype)

例如

a = tf.constant(np.array([1, 2]))
b = tf.cast(a, dtype=tf.float32)
print(b.dtype)
# tf.float32

a = tf.constant(123456789, dtype=tf.int32)
tf.cast(a, tf.int16)
# <tf.Tensor: id=11, shape=(), dtype=int32, numpy=123456789>

参数为布尔型

0表示False,非0表示True

tf.constant(True)
# <tf.Tensor: id=13, shape=(), dtype=bool, numpy=True>

a = tf.constant([True, False])
tf.cast(a, tf.int32)
# <tf.Tensor: id=16, shape=(2,), dtype=int32, numpy=array([1, 0])>

a = tf.constant([-1, 0, 1, 2])
tf.cast(a, tf.bool)
# <tf.Tensor: id=18, shape=(4,), dtype=bool, numpy=array([ True, False,  True,  True])>

参数为字符串

tf.constant("hello")
# <tf.Tensor: id=19, shape=(), dtype=string, numpy=b'hello'>

可以看到数据类型是string,这里的b表示,这是一个字节串,因为在python3中字符串,默认是unicode的编码,因此要转换成字节串,就要在原先的字符串前面加上一个b

tf.convert_to_tensor()函数

除了constant的函数之外,还可以使用tf.convert_to_tensor()函数来创建张量参数

tf.convert_to_tensor(数组/列表/数字/布尔型/字符串)

例如

na = np.arange(12).reshape(3, 4)
ta = tf.convert_to_tensor(na)

type(na)
# <class 'numpy.ndarray'>
type(ta)
# <class 'tensorflow.python.framework.ops.EagerTensor'>

可以使用is_tensor()函数来判断变量是不是张量。

is_tensor()
tf.is_tensor(ta)
# True

tf.is_tensor(na)
# False

另外,还可以使用python原生的isinstance()函数来验证。

isinstance(ta, tf.Tensor)
# True

isinstance(na, np.ndarray)
# True

创建张量2

类似于numpy,TensorFlow中也可以直接生成一些特殊的张量,例如全0张量,全1张量,所有元素的值都相同的张量,以及元素取值符合某种随机分布的张量。

创建全0张量和全1张量

创建全0张量和全1张量,分别使用tf.zeros()tf.ones()函数

tf.zeros(shape, dtype=tf.float32)
tf.ones(shape, dtype=tf.float32)
  • shape 是张量的形状。
  • dtype 是张量数据的数据类型,默认是32位浮点数

例如

tf.ones(shape=(2, 1))
"""
<tf.Tensor: id=23, shape=(2, 1), dtype=float32, numpy=
array([[1.],
       [1.]], dtype=float32)>
"""

tf.ones([6])
"""
<tf.Tensor: id=26, shape=(6,), dtype=float32, numpy=array([1., 1., 1., 1., 1., 1.], dtype=float32)>
"""

tf.ones([2, 3], tf.int32)
"""
<tf.Tensor: id=29, shape=(2, 3), dtype=int32, numpy=
array([[1, 1, 1],
       [1, 1, 1]])>
"""

zeros的用法和ones的完全相同。

创建元素都相同的张量–tf.fill()函数

tf.fill(dims, value)

dims 是形状
value 是填充的值

tf.fill([2, 3], 9)
"""
<tf.Tensor: id=32, shape=(2, 3), dtype=int32, numpy=
array([[9, 9, 9],
       [9, 9, 9]])>
"""

tf.fill([2, 3], 9.0)
"""
<tf.Tensor: id=35, shape=(2, 3), dtype=float32, numpy=
array([[9., 9., 9.],
       [9., 9., 9.]], dtype=float32)>
"""

创建元素都相同的张量–tf.constant()函数

tf.constant(value=9, shape=[2, 3])
"""
<tf.Tensor: id=38, shape=(2, 3), dtype=int32, numpy=
array([[9, 9, 9],
       [9, 9, 9]])>
"""

tf.fill(dims=[2, 3], value=9)
"""
<tf.Tensor: id=41, shape=(2, 3), dtype=int32, numpy=
array([[9, 9, 9],
       [9, 9, 9]])>
"""

创建随机数张量–正态分布

tf.random.normal(shape, mean, stddev, dtype)

shape:张量的形状
mean:均值
stddev:标准差
dtype:元素的数据类型,默认是32位浮点数

当均值和标准差省略时,默认是标准正态分布,均值为0,标准差为1。

例:创建一个2*2的张量,其元素服从标准正态分布的张量

tf.random.normal([2, 2])
"""
<tf.Tensor: id=47, shape=(2, 2), dtype=float32, numpy=
array([[-0.07223961,  1.2670088 ],
       [-0.0232278 , -0.44618014]], dtype=float32)>
"""

创建一个三维张量,其元素服从正态分布。

tf.random.normal([3, 3, 3], mean=0.0, stddev=2.0)
"""
<tf.Tensor: id=53, shape=(3, 3, 3), dtype=float32, numpy=
array([[[-2.343591  , -2.5604963 , -3.131829  ],
        [-2.6622703 , -2.3248575 ,  3.6765773 ],
        [-2.0164406 , -0.5749179 , -2.8921757 ]],
       [[-0.8125065 ,  1.0438641 , -0.51730233],
        [ 1.4487618 , -1.4161435 , -1.0760221 ],
        [ 1.8550812 ,  0.32153162, -0.636167  ]],
       [[ 0.84067494, -0.92889154, -2.2943053 ],
        [ 0.8124192 ,  3.7003622 , -1.2836558 ],
        [-2.2072492 ,  0.14961068,  3.3054852 ]]], dtype=float32)>
"""

创建随机数张量–截断正态分布

tf.random.truncated_normal(shape, mean, stddev, dtype)

返回一个截断的正态分布
截断的标准是2倍的标准差,也就是说它不会创建任何偏离均值,标准差的值,从而可以防止张量中个别元素和其他元素有太大的差异。

例如当均值为0,标准差为1时,

  • 使用tf.random.truncated_normal()函数的输出是不可能出现区间[-2, 2]以外的点的
  • 而如果形状足够大的时候,使用tf.random.normal(),却可能会产生区间[-2, 2]之外的输出

设置随机种子–tf.random.set_seed()函数

tf.random.set_seed(8)
tf.random.normal([2, 2])
"""
<tf.Tensor: id=60, shape=(2, 2), dtype=float32, numpy=
array([[ 1.2074401, -0.7452462],
       [ 0.6908678, -0.7635988]], dtype=float32)>
"""

tf.random.set_seed(8)
tf.random.normal([2, 2])
"""
<tf.Tensor: id=60, shape=(2, 2), dtype=float32, numpy=
array([[ 1.2074401, -0.7452462],
       [ 0.6908678, -0.7635988]], dtype=float32)>
"""

创建均匀分布张量–tf.random.uniform()函数

tf.random.uniform(shape, minval, maxval, dtype)

shape:形状
minval:最小值
maxval:最大值
dtype:元素的数据类型
这个区间是前闭后开的,不包括最大值。

tf.random.uniform(shape=(3, 3), minval=0, maxval=10, dtype='int32')
"""
<tf.Tensor: id=64, shape=(3, 3), dtype=int32, numpy=
array([[6, 8, 3],
       [9, 5, 1],
       [8, 6, 1]])>
"""

随机打乱–tf.random.shuffle()函数

x = tf.constant([[1, 2], [3, 4], [5, 6]])
tf.random.shuffle(x)
"""
<tf.Tensor: id=66, shape=(3, 2), dtype=int32, numpy=
array([[1, 2],
       [5, 6],
       [3, 4]])>
"""
y = [1, 2, 3, 4, 5, 6]
tf.random.shuffle(y)
"""
<tf.Tensor: id=70, shape=(6,), dtype=int32, numpy=array([6, 5, 1, 2, 3, 4])>
"""
z = np.arange(5)
tf.random.shuffle(z)
"""
<tf.Tensor: id=72, shape=(5,), dtype=int32, numpy=array([4, 0, 3, 2, 1])>
"""

随机序列–tf.range()函数

tf.range(start, limit, delta=1, dtype)

start:起始数字
limit:结束数字
delta:步长

tf.range(10)
# <tf.Tensor: id=80, shape=(10,), dtype=int32, numpy=array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>

tf.range(10, delta=2)
# <tf.Tensor: id=84, shape=(5,), dtype=int32, numpy=array([0, 2, 4, 6, 8])>

tf.range(1, 10, delta=2)
# <tf.Tensor: id=88, shape=(5,), dtype=int32, numpy=array([1, 3, 5, 7, 9])>

小结:创建张量

在这里插入图片描述

Tensor对象的属性–ndim、shape、dtype

在创建张量时,就可以在返回结果中看到张量的shape和dtype的属性。

tf.constant([[1, 2], [3, 4]])
"""
<tf.Tensor: id=1, shape=(2, 2), dtype=int32, numpy=
array([[1, 2],
       [3, 4]])>
"""

也可以将所创建的张量复制给一个Python变量,然后通过变量名.属性名的方式来查看它。
例如将张量赋值给变量a,然后分别输出这个张量变量的维度,元素数据类型和形状

a = tf.constant([[1, 2], [3, 4]])
print("ndim", a.ndim)
print("dtype", a.dtype)
print("shape", a.shape)

运行结果

ndim 2
dtype <dtype: 'int32'>
shape (2, 2)

Tensor对象的shape()、size()、rank()方法

在这里插入图片描述

Tensor和Numpy数组

通过前面的学习,我们已经发现张量和Numpy数组互不相同又紧密相关,张量可以看作是在Numpy数组的基础上又做了一层封装,使它可以执行Tensor flow中的API,并且可以运行于GPU和TPU,支持单机多卡,多机多卡等不同的环境。

  • 在Tensor flow中,所有的运算都是在张量之间进行的。
  • Numpy数组仅仅是作为输入和输出来使用。
    例如在运算之前,通过Numpy数组提供数据生成张量对象,在运算的过程中或者运算结束之后,可以使用张量对象的numpy方法获取张量的值,以numpy数组的形式返回给我们,而在Tensor flow的整个计算过程中,numpy数组是不参与运算的。
  • 张量可以运行于CPU,也可以运行于GPU和TPU。
  • numpy数组,只能够在CPU中运行。
    当张量在CPU中运行时,它和numpy数组其实是共享同一段内存的,只是读出和理解它的方式不同而已。因此这种情况下使用张量的numpy方法可以非常快的得到结果。
    而当张量是在GPU上运行时,就把内存中的numpy数组的内容再拷贝一份到GPU的显存中,在GPU中做高速运算,这时如果用numpy方法读取它的值,就需要再从GPU的解存中拷贝到内存中。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值