4、张量的结构和操作


 

(1)张量的阶和数据类型

  • 数组:numpy:ndarray类型,有0维,1维,2维等
  • 矩阵:2维
  • 张量:一个类型化(tensor类型)的N维数组

①基本数据类型 

 由三部分组成:名字(即op的类型,后面的0没有什么意义),张量的形状,类型

    Tensor("Placeholder:0", shape=(2, 2), dtype=float32)

 

②张量的阶

 ③张量的类型,每个类型的精度是不一样的

④张量的属性

 ●graph      张量所属的默认图

 ●op   张量的操作名.

 ●name   张量的字符串描述

 ●shape  张量形状

 1 import tensorflow as tf
 2 import os
 3 os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' #去掉警告,将警告级别提升
 4 
 5 a = tf.constant([2,2])   #定义一个常量
 6 b = tf.constant([4,4])
 7 sum1 = tf.add(a,b)    #加法操作
 8 
 9 #a,b,sum都是张量
10 print("a: \n",a)
11 print("_"*50)
12 print("b:\n ",b)
13 print("_"*50)
14 print("sum1\n: ",sum1)
15 print("_"*50)
16 print("a.graph:\n ",a.graph)
17 print("_"*50)
18 print("a.op: \n",a.op)
19 print("_"*50)
20 print("a.name: \n",a.name)
21 print("_"*50)
22 print("a.shape: \n",a.shape)

输出:

a: 
 Tensor("Const:0", shape=(2,), dtype=int32)
__________________________________________________
b:
  Tensor("Const_1:0", shape=(2,), dtype=int32)
__________________________________________________
sum1
:  Tensor("Add:0", shape=(2,), dtype=int32)
__________________________________________________
a.graph:
  <tensorflow.python.framework.ops.Graph object at 0x0000021A13005F60>
__________________________________________________
a.op: 
 name: "Const"
op: "Const"
attr {
  key: "dtype"
  value {
    type: DT_INT32
  }
}
attr {
  key: "value"
  value {
    tensor {
      dtype: DT_INT32
      tensor_shape {
        dim {
          size: 2
        }
      }
      tensor_content: "\002\000\000\000\002\000\000\000"
    }
  }
}

__________________________________________________
a.name: 
 Const:0
__________________________________________________
a.shape: 
 (2,)

⑤形状 (在深度学习中,形状的改变是经常见到的)

  • TensorFlow打印出来的形状表示

   0维:()

   1维:(2)

   2维:(2,3)

   3维:(2,3,4),表示2张3维4列的表

  •  张量的动态形状与静态形状

    TensorFlow中, 张量具有静态形状和动态形状

    (1)静态形状:创建一个张量,初始状态的形状

      tf.Tensor.get_shape:获取静态形状

      tf.Tensor.set_shape():更新Tensor对象的静态形状,通常用于在不能直接推断的情况下

#设置静态形状
1
plt = tf.placeholder(tf.float32,[None, 2]) #用[ ]不用() 2 print(plt) # Tensor("Placeholder:0", shape=(?, 2), dtype=float32) 3 plt.set_shape([3,2]) 4 print(plt)

输出:

Tensor("Placeholder:0", shape=(?, 2), dtype=float32)
Tensor("Placeholder:0", shape=(3, 2), dtype=float32)

 


 

Φ 对于静态形状来说,一旦张量的形状固定了,那么便不能再次设置静态形状,如果想要需改形状,可以通过动态形状,重新生成一个新的张量。

再次设置形状
1
plt = tf.placeholder(tf.float32,[None, 2]) #用[ ]不用() 2 print(plt) # Tensor("Placeholder:0", shape=(?, 2), dtype=float32) 3 plt.set_shape([3,2]) 4 print(plt) 5 plt.set_shape([6,2]) #静态形状不能再次修改 6 print(plt)

输出:

ValueError: Dimension 0 in both shapes must be equal, but are 3 and 6. Shapes are [3,2] and [6,2].

   (2)动态形状:一种描述原始张量在执行过程中的一种形状(动态变化)

           tf.reshape:创建一个具有不同动态形状的新张量(numpy中的reshape是将原来的数据进行直接修改)

 注意:通过静态形状设置维[3,2]

通过reshape可以再次修改张量的形状,但是受限于张量中元素的个数,新的动态张量的元素必须和原张量的元素个数一致,这里首先使用静态形状方法改变形状,再使用动态形状改变
1
plt = tf.placeholder(tf之后.float32,[None, 2]) #用[ ]不用() 2 print(plt) # Tensor("Placeholder:0", shape=(?, 2), dtype=float32) 3 plt.set_shape([3,2]) 4 print(plt) 5 6 # plt_reshpe = tf.reshape(plt,[3,4]) #形状固定了之后也只能在固定的元素中调整 7 # print(plt_reshpe) 8 9 plt_reshpe = tf.reshape(plt,[2,3]) 10 print(plt_reshpe)

输出:

Tensor("Placeholder:0", shape=(?, 2), dtype=float32)
Tensor("Placeholder:0", shape=(3, 2), dtype=float32)
Tensor("Reshape:0", shape=(2, 3), dtype=float32)

如果原张量没有指定形状,即[None, 2],那么在使用动态形状改变方式reshape后得到新的张量,还是可以再次使用得到不一样总元素的张量

 1 import tensorflow as tf
 2 import os
 3 os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' #去掉警告,将警告级别提升
 4 
 5 plt = tf.placeholder(tf.float32,[None, 2])  #用[ ]不用()
 6 print(plt)  # Tensor("Placeholder:0", shape=(?, 2), dtype=float32)
 7 
 8 plt_reshpe = tf.reshape(plt,[2,3])
 9 print(plt_reshpe)
10 
11 plt_reshpe = tf.reshape(plt,[6,2])  #动态数组可以再次修改
12 print(plt_reshpe)

输出:

Tensor("Placeholder:0", shape=(?, 2), dtype=float32)
Tensor("Reshape:0", shape=(2, 3), dtype=float32)
Tensor("Reshape_1:0", shape=(6, 2), dtype=float32)

 综上:静态形状和动态形状的区别在于有没有生成一个新的张量数据,静态形状在修改确定后便不能再次进行设置,动态形状的修改受限于原来张量的元素个数,如果原来的张量的元素个数不确定,那么在使用动态形状修改后,仍然可以再次使用动态形状修改,而且不受限于元素的个数,因为动态形状改变就会生成一个新的张量数据,与原来的张量无关,所以再次使用动态形状修改自然也是可以的。

1、转换静态形状的时候,1-D到1-D, 2-D到2-D,不能跨阶数改变形状

2、对于已经固定或者设置静态形状的张量/变量,不能再次设置静态形状

3、tf.reshape()动态 创建新张量时,元素个数不能不匹配


 (2)张量的操作

 ① 生成张量

    1、生成固定值张量

  • tf.zeros(shape, dtype=tf.float32, name=None)  (常见)

    创建所有元素设置为零的张量。此操作返回一个dtype具有形状shape和所有元素设置为零的类型的张量。

  • tf.zeros_like(tensor, dtype=None, name=None)

   给tensor定单张量() ,此操作返回tensor与所有元素设置为零相同的类型和形状的张量。

  • tf.ones(shape, dtype=tf.float32, name=None)    (常见)

  创建一个所有元素设置为1的张量。此操作返回一个类型的张量,dtype形状shape和所有元素设置为1.

  • tf.ones_like(tensor, dtype=None, name=None)

  给tensor定单张量() ,此操作返回tensor与所有元素设置为1相同的类型和形状的张量。

  • tf.fill(dims, value, name=None)

  创建一个填充了标量值的张量。此操作创建一个张 量的形状dims并填充它value.

  • tf.constant(value, dtype=None, shape=None, name='Const')   (常见)

  创建一个常数张量。

例:进入交互式操作,然后可以用eval()提取zeros的数据

   2、生成随机值张量

  一般我们经 常使用的随机数函数Math.random0产生的是服从均匀分布的随机数,能够模拟等概率出现的情况,例如扔一个骰子, 1到6点的概率应该相等,但现实生活中更多的随机现象是符合正态分布的,例如20岁成年人的体重分布等。

  假如我们在制作一个游戏, 要随机设定许许多多NPC的身高,如果还用Math.random(),生成从140到220之间的数字,就会发现每个身高段的人数是一-样多的,这是比较无趣的,这样的世界也与我们习惯不同,现实应该是特别高和特别矮的都很少,处于中间的人数最多,这就要求随机函数符合正态分布。  

  • tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype =tf.float32, seed=None, name=None)   (mean表示平均值,stddev表示标准差)

  从截断的正态分布中输出随机值,和tf.random. normal() 一样,但是所有数字都不超过两个标准差

  • tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)

  从正态分布中输出随机值,由随机正态分布的数字组成的矩阵

 

 

 3、张量的类型转换

提供了如下一些改变张量中数值类型的函数

  • tf.string_ to. number(string_ _tensor, out_ _type=None, name=None)
  • tf.to double(x, name='ToDouble)
  • tf.to_ float(x, name='ToFloat')
  • tf.to_ bfloat16(x, name='ToBFloat16')
  • tf.to_ _int32(x, name='Tolnt32')
  • tf.to_ jint64(x, name= 'Tolnt64')
  • tf.cast(x, dtype, name=None)   (万能转换)

 int32—>float32

 

 

  4、张量的切片与拓展

 tf.concat(values,axis,name='cancat')

 

 

 

 

 

 

 

 

 

 

posted on 2019-11-12 15:11  Luaser  阅读(836)  评论(0编辑  收藏  举报