Tensorflow学习笔记day02+张量(常量+变量+占位符)

一、张量

我们知道, 计算图中的一个节点可以表示一个张量或者一个操作符

那么张量是什么?

张量,可理解为一个 n 维数值阵列

每个张量的维度单位用阶来描述,零阶张量是一个标量,一阶张量是一个向量,二阶张量是一个矩阵

所以标量、向量(矢量)和矩阵等都是特殊类型的张量

图片

TensorFlow 支持以下三种类型的张量:

1、常量:常量是其值不能改变的张量。

2、变量:当一个量在会话中的值需要更新时,使用变量来表示。例如,在神经网络中,权重需要在训练期间更新,可以通过将权重声明为变量来实现。变量在使用前需要被显示初始化

3、占位符:用于将值输入 TensorFlow 图中。它们可以和 feed_dict 一起使用来输入数据。在训练神经网络时,它们通常用于提供新的训练样本。在会话中运行计算图时,可以为占位符赋值。这样在构建一个计算图时不需要真正地输入数据。需要注意的是,占位符不包含任何数据,因此不需要初始化它们

二、TF常量型张量

import tensorflow as tf

“常规操作”

1、声明一个标量常量:
t_1 = tf.constant(4)
with tf.Session() as sess:
    print(sess.run(t_1))
4
2、声明一个向量常量:
t_2 = tf.constant([1,3])
with tf.Session() as sess:
    print(sess.run(t_2))
[1 3]
t_2 = tf.constant([4,3,2])
with tf.Session() as sess:
    print(sess.run(t_2))
[4 3 2]
3、创建一个所有元素为零的张量,可以使用 tf.zeros() 函数。这个语句可以创建一个形如 [M,N] 的零元素矩阵,数据类型(dtype)可以是 int32、float32 等:

tf.zeros([M,N],tf.dtype)

例如 :

zero_t = tf.zeros([2,3],tf.int32)
with tf.Session() as sess:
    print(sess.run(zero_t))
[[0 0 0]
 [0 0 0]]
4、创建一个所有元素都设为 1 的张量。下面的语句即创建一个形如 [M,N]、元素均为 1 的矩阵:

tf.ones([M,N],tf,dtype)

ones_t = tf.ones([2,3],tf.int32)
with tf.Session() as sess:
    print(sess.run(ones_t))
[[1 1 1]
 [1 1 1]]
5、还可以创建与现有 Numpy 数组或张量常量具有相同形状的张量常量,如下所示:
tf.zeros_like(t_2)
<tf.Tensor 'zeros_like:0' shape=(3,) dtype=int32>
tf.ones_like(t_2)
<tf.Tensor 'ones_like:0' shape=(3,) dtype=int32>
6、在一定范围内生成一个从初值到终值等差排布的序列:

tf.linspace(start,stop,num)

相应的值为 (stop-start)/(num-1)。例如:

range_t = tf.linspace(2.0,5.0,5) #从2到5 切成5份
with tf.Session() as sess:
    print(sess.run(range_t))
[2.   2.75 3.5  4.25 5.  ]
7、从开始(默认值=0)生成一个数字序列,增量为 delta(默认值=1),直到终值(但不包括终值):

tf.range(start,limit,delta)

下面给出实例:

range_t = tf.range(10)
with tf.Session() as sess:
    print(sess.run(range_t))
#Result:[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4 5 6 7 8 9]
range_t = tf.range(0,10,1)
with tf.Session() as sess:
    print(sess.run(range_t))
[0 1 2 3 4 5 6 7 8 9]

“随机操作”

TensorFlow 允许创建具有不同分布的随机张量

1、使用以下语句创建一个具有一定均值(默认值=0.0)和标准差(默认值=1.0)、形状为 [M,N] 的正态分布随机数组:
t_random = tf.random_normal([2,3], mean=2.0, stddev=4,seed=12)
with tf.Session() as sess:
    print(sess.run(t_random))
[[ 0.25347447  5.37991     1.9527606 ]
 [-1.5376031   1.2588985   2.8478067 ]]
2、创建一个具有一定均值(默认值=0.0)和标准差(默认值=1.0)、形状为 [M,N] 的截尾正态分布随机数组:
t_random = tf.truncated_normal([1,5], stddev=2,seed=12)
with tf.Session() as sess:
    print(sess.run(t_random))
[[-0.87326276  1.689955   -0.02361972 -1.7688016  -3.87749   ]]
3、要在种子的 [minval(default=0),maxval] 范围内创建形状为 [M,N] 的给定伽马分布随机数组,请执行如下语句:
t_random = tf.random_uniform([2,3], maxval=4,seed=12)
with tf.Session() as sess:
    print(sess.run(t_random))
[[2.54461   3.6963658 2.7051091]
 [2.0085006 3.8445983 3.5426888]]
4、(不起作用好像)要将给定的张量随机裁剪为指定的大小,使用以下语句:

图像分类中,在深度学习的训练时将图片的随机剪裁(random crop)已经成为很普遍的数据扩充(data augmentation)方法,随机剪裁(缩写为:IRC)不但提高了模型精度,也增强了模型稳定性

tf.random_crop(t_random,[2,5],seed=12)

<tf.Tensor 'random_crop:0' shape=(2, 5) dtype=float32>

这里,t_random 是一个已经定义好的张量。这将导致随机从张量 t_random 中裁剪出一个大小为 [2,5] 的张量。

5、随机重新排序

很多时候需要以随机的顺序来呈现训练样本,可以使用 tf.random_shuffle() 来沿着它的第一维随机排列张量。如果 t_random 是想要重新排序的张量,使用下面的代码:

with tf.Session() as sess:
    print(sess.run(t_random))
print("随机重新排序后")
t = tf.random_shuffle(t_random)
with tf.Session() as sess:
    print(sess.run(t))
[[2.54461   3.6963658 2.7051091]
 [2.0085006 3.8445983 3.5426888]]
随机重新排序后
[[2.0085006 3.8445983 3.5426888]
 [2.54461   3.6963658 2.7051091]]
6、随机生成的张量受初始种子值的影响

要在多次运行或会话中获得相同的随机数,应该将种子设置为一个常数值。当使用大量的随机张量时,可以使用 tf.set_random_seed() 来为所有随机产生的张量设置种子。以下命令将所有会话的随机张量的种子设置为 54:

tf.set_random_seed(54)

种子只能有整数值

三、TF变量型张量

tensorflow中的变量是承载和更新参数的对象

变量通常在神经网络中表示权重和偏置

此外还可以保存或恢复变量

变量是由tf.Variable()语句创建的

它必须初始化, 可以用常量来初始化变量,也可以用一个变量来初始化另一个变量

常量初始化变量

下面的代码中创建了两个不同的张量变量 t_a 和 t_b。两者将被初始化为形状为 [50,50] 的随机均匀分布,最小值=0,最大值=10:

rand_t = tf.random_uniform([50,50],0,10,seed=0)
t_a = tf.Variable(rand_t)
t_b = tf.Variable(rand_t)

注意:变量通常在神经网络中表示权重和偏置。

下面的代码中定义了两个变量,分别是权重和偏置。权重变量使用正态分布随机初始化,均值为 0,标准差为 2,权重大小为 100×100。偏置由 100 个元素组成,每个元素初始化为 0。在这里也使用了可选参数名以给计算图中定义的变量命名:

weights = tf.Variable(tf.random_normal([100,100],stddev=2))
bias = tf.Variable(tf.zeros([100]), name = 'biases')

变量初始化变量

下面的语句将利用前面定义的权重变量来初始化 weight2:

weights2 = tf.Variable(weights.initial_value, name='w2')

赋予变量实际的意义

上面两种方式的初始化, 并不代表计算图中的变量已经被赋值了

我们之前说过, 计算图像是一张蓝图, 在此之前张量只被抽象定义,只有在会话时候, 才将张量赋予实际的意义

在会话时, 赋予常量实际的意义,是自动的; 而赋予变量实际的意义,还需要再加些东西

具体需要通过声明初始化操作对象来实现:

intial_op = tf.global_variables_initializer()

举个栗子, 希望程序实现从1数到10 :

import tensorflow as tf

#创建计算图
value = tf.Variable(0, name="value")#创建一个变量,并将其初始化为标量0:
one = tf.constant(1)
new_value = tf.add(value, one)#add和assign操作符仅仅是计算图中的节点,所以在会话运行前,它们不会执行
update_value = tf.assign(value, new_value)


#运行会话,完成计算图中定义的操作
initialize_var = tf.global_variables_initializer() #声明初始化操作对象, 用于计算图中变量的赋值
with tf.Session() as sess:
    sess.run(initialize_var)
    print(sess.run(value))
    for _ in range(10):
        sess.run(update_value)
        print(sess.run(value))
0
1
2
3
4
5
6
7
8
9
10

程序解读: 这个栗子的计算图有四个节点,分别是value变量、one常量、add加法操作符以及assign赋值操作符.这个计算图要实现的功能是value和one通过add相加,得到的值流到assign操作符,让它再赋值回value. 运行会话时,由于变量需要显式初始化,所以需要声明初始化操作对象,然后让它run下来完成初始化

此外, 每个变量也可以在运行图中单独使用 tf.Variable.initializer 来初始化

import tensorflow as tf

#创建计算图
value = tf.Variable(0, name="value")#创建一个变量,并将其初始化为标量0:
one = tf.constant(1)
new_value = tf.add(value, one)#add和assign操作符仅仅是计算图中的节点,所以在会话运行前,它们不会执行
update_value = tf.assign(value, new_value)


#运行会话,完成计算图中定义的操作
#initialize_var = tf.global_variables_initializer() #声明初始化操作对象, 用于计算图中变量的赋值
with tf.Session() as sess:
    sess.run(value.initializer)#变量在运行图中单独初始化,常量就不用了.
    print(sess.run(value))
    for _ in range(10):
        sess.run(update_value)
        print(sess.run(value))
0
1
2
3
4
5
6
7
8
9
10

保存变量

神经网络训练完后, 一般都需要保存训练好的参数,也就是我们所谓的权重和偏置, 其实际上就是变量, 所以我们要使用 Saver 类来保存变量,定义一个 Saver 操作对象:

saver = tf.train.Saver()

四、TF占位符型张量

介绍完常量和变量之后,我们来讲解最重要的张量——占位符

它是不需要初始化的

在会话中运行计算图时,可以为占位符赋值,通过会话对象中run里feed_dict


它用于将值输入计算图中,它和feed_dict一起来输入数据

run(fetches,feed_dict=None,options=None,run_metadata)

所以在训练神经网络时(会话),它们通常用于提供新的训练样本

如何定义一个占位符:

tf.placeholder(dtype,shape=None,name=None)

dtype 是占位符的数据类型,并且必须在声明占位符时指定

下面示例中, 定义一个占位符型张量x, 并计算 y=2*x,会话时使用 feed_dict 输入一个随机的 4×5 矩阵:

import tensorflow as tf

#计算图
x = tf.placeholder("float")#占位符
y = 2*x
data = tf.random_uniform([4,5], 10)#随机常量

#run时才算进入会话
with tf.Session() as sess:
    print(data) #未进入会话
    x_data = sess.run(data) #会话时才能取出它的值
    print(x_data)#提出来了
    print("\n\n")
    print(sess.run(y, feed_dict = {x:x_data}))
Tensor("random_uniform_2:0", shape=(4, 5), dtype=float32)
[[9.789586  4.122238  2.5008888 2.8134599 2.4266639]
 [3.33526   3.5702267 6.666023  1.2452259 3.4237428]
 [6.941977  8.032328  2.8022385 8.071983  6.399656 ]
 [6.231288  2.589786  1.2040987 8.232471  1.4575834]]



[[19.579172   8.244476   5.0017776  5.6269197  4.8533278]
 [ 6.67052    7.1404533 13.332046   2.4904518  6.8474855]
 [13.883954  16.064655   5.604477  16.143967  12.799312 ]
 [12.462576   5.179572   2.4081974 16.464943   2.9151669]]

代码解释:

计算图一共有4个节点,分别是占位型张量x、常数型张量2、乘法操作符y以及单独的常数型张量data. 会话时取出data的值赋值给x_data,然后放入feed_dict再一次进入会话赋值给占位符x, 提取y的运行结果

run的时候才算进入会话

所以第一次run只是fetch data里的数据, 第二次才开始fetch y进行乘法运算

五、拓展阅读

拓展1

很多时候需要大规模的常量张量对象;在这种情况下,为了优化内存,最好将它们声明为一个可训练标志设置为 False 的变量:

large_array = [1,2,3] #假如时一个很大的数组
t_large = tf.Variable(large_array,trainable=False)
with tf.Session() as sess:
    sess.run(t_large.initializer)
    print(sess.run(t_large))
[1 2 3]

trainable:如果为True,则会默认将变量添加到图形集合GraphKeys.TRAINABLE_VARIABLES中。此集合用于优化器Optimizer类优化的的默认变量列表【可为optimizer指定其他的变量集合】,也就是要训练的变量列表。

拓展2

TensorFlow 被设计成与 Numpy 配合运行,因此所有的 TensorFlow 数据类型都是基于 Numpy 的

使用 tf.convert_to_tensor() 可以将给定的值转换为张量类型,并将其与 TensorFlow 函数和运算符一起使用。该函数接受 Numpy 数组、Python 列表和 Python 标量,并允许与张量对象互操作。

拓展3

下表列出了 TensorFlow 支持的常见的数据类型:

拓展4

for i in range(1,10,1):
    print(i)
1
2
3
4
5
6
7
8
9
import numpy as np
for i in np.arange(1,10,1):
    print(i)

1
2
3
4
5
6
7
8
9

TensorFlow 序列不可迭代。试试下面的代码:

for i in tf.range(10)
  File "<ipython-input-30-83ab65fa2626>", line 1
    for i in tf.range(10)
                         ^
SyntaxError: invalid syntax
发布了52 篇原创文章 · 获赞 40 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_40519315/article/details/104302738
今日推荐