前言
因为Theano已经停止更新了,所以在前面学完Theano搭建RBM,CNN,RNN
相关结构以后,还是得选择一个主流框架的,由于我自身的学习最终是向强化学习靠近,可能用到的仿真环境是openai gym,所以选择了继续学习TensorFlow,而非pyTorch,CNTK之类的深度学习框架。
还是按照Theano的学习方法来,先学习一下入门基础,比如基本存储容器,变量运算,函数执行与取值等操作,然后学一下手写数字识别什么的。
国际惯例,参考博客:
简介
在使用入门中提到了TensorFlow分为Eager Execution和Graph Execution,此外还有一些必须了解的API,包括高阶API、中阶API、低阶API、核。但是像我们这种做算法的,一般只需关注如何使用某类语言搭建网络结构即可。
Eager Execution
它是TensorFlow的一种命令式编程环境,特点是无法构建图,可立即评估操作并输出具体数值:
#Eager Execution
import tensorflow as tf
tf.enable_eager_execution()
print('是否开启eager execution:',tf.executing_eagerly())
x=[[2.]]
m=tf.matmul(x,x)
print('hello,{}'.format(m)
结果:
是否开启eager execution: True
hello,[[4.]]
可以看出,如果我们要使用Eager Execution调试程序,必须先启动它,启动了以后,执行很多操作都无需创建图去执行运算,比如你不启动它,直接运行计算:
import tensorflow as tf
x=[[2.]]
m=tf.matmul(x,x)
print('hello,{}'.format(m))
输出:
hello,Tensor("MatMul:0", shape=(1, 1), dtype=float32)
很容易发现输出的是数据类型和大小
再来个复杂点的例子,建立一个感知器逼近函数 y = 3 x + 2 y=3x+2 y=3x+2
#为3x+2的函数建模
import tensorflow as tf
import tensorflow.contrib.eager as tfe
tf.enable_eager_execution()#启动eager_execution
NUM_EXAMPLES=1000#样本数
training_inputs=tf.random_normal([NUM_EXAMPLES])#随机输入
noise=tf.random_normal([NUM_EXAMPLES])#随机噪声
training_outputs=training_inputs*3+2+noise#函数输出+噪声
def prediction(input,weight,bias):
return input*weight+bias#前向计算
def loss(weights,biases):
error=prediction(training_inputs,weights,biases)-training_outputs
return tf.reduce_mean(tf.square(error))#均方差损失
def grad(weights,biases):
with tf.GradientTape() as tape:
loss_value=loss(weights,biases)
return tape.gradient(loss_value,[weights,biases])#计算梯度
train_steps=200
learning_rate=0.01
W=tfe.Variable(5.)
B=tfe.Variable(10.)
print('Initial Loss:{:.3f}'.format(loss(W,B)))
for i in range(train_steps):
dW,dB=grad(W,B)
W.assign_sub(dW*learning_rate)#每次循环更新权重
B.assign_sub(dB*learning_rate)#每次循环更新偏置
if i%20==0:
print('Loss at step{:03d}:{:.3f}'.format(i,loss(W,B)))
print('Final loss:{:.3f}'.format(loss(W,B)))
print('W={},B={}'.format(W.numpy(),B.numpy()))
输出
Initial Loss:71.285
Loss at step000:68.417
Loss at step020:30.346
Loss at step040:13.806
Loss at step060:6.604
Loss at step080:3.461
Loss at step100:2.086
Loss at step120:1.483
Loss at step140:1.218
Loss at step160:1.101
Loss at step180:1.050
Final loss:1.028
W=3.0146498680114746,B=2.108891725540161
这个例子很容易看出,在eager execution中:
- 无需为输入数据建立容器,如theano中的theano.tensor.scalar
- 无需为运算操作建立图结构,例如theano中的function类似
- 梯度更新使用tf.GradientTape()中的gradient
感觉就是简单的numpy操作,只不过在tensorflow中实现了,外加了一个自动梯度求解。
对于eager execution
暂时了解这么多,印象最深的是:
- 无需为变量建立容器;无需为运算建立计算图**,**
- 自动梯度的函数是gradient
后续要是用到这种方式书写程序再做了解,毕竟深度学习框架比较重要的就是计算图,应该没谁会一直选择使用这种方式编写程序吧,虽然看起来很简洁。
Graph Execution
先看一句话:使用 Graph Execution
时,程序状态(如变量)存储在全局集合中,它们的生命周期由 tf.Session
对象管理。相反,在 Eager Execution
期间,状态对象的生命周期由其对应的 Python 对象的生命周期决定。接下来要介绍的大部分内容基本都属于Graph Execution范围内的知识。
这里使用Graph execution
对上面Eager Execution演示
函数
y
=
3
x
+
2
y=3x+2
y=3x+2进行建模
#生成样本
NUM_EXAMPLES=1000
training_inputs=np.random.rand(NUM_EXAMPLES)
training_outputs=training_inputs*3+2
#定义容器
tf.reset_default_graph()
W=tf.get_variable(name='W',shape=[1])
b=tf.get_variable(name='b',shape=[1])
input_placeholder=tf.placeholder(shape=[1,NUM_EXAMPLES],dtype=tf.float32)
label_placeholder=tf.placeholder(shape=[1,NUM_EXAMPLES],dtype=tf.float32)
loss=tf.reduce_mean(tf.square(input_placeholder*W+b-label_placeholder))
optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.01)
update_op=optimizer.minimize(loss)
init=tf.initialize_all_variables()
#创建计算图
with tf.Session() as sess:
sess.run(init)
for i in range(5000):
_,new_W,new_b=sess.run(
[update_op,W,b],
feed_dict={input_placeholder:[training_inputs],
label_placeholder:[training_outputs]})
print(new_W,new_b)
#[2.999767] [2.0001235]
但是我不知道为什么要这么多迭代次数才能逼近,毕竟Eager Execution
仅需200次迭代就能达到很好效果,这个用了5000次才能逼近。
但是从这个例子可以看出,我们需要学习的有:容器、优化器、迭代优化等相关操作。
高阶API: Estimator
暂时理解是这个Estimator
封装好了很多结构,比如分类器、回归器,具体有哪些,戳这里,同时也封装好了对应的训练、评估、预测方法。
还是用函数
y
=
3
x
+
2
y=3x+2
y=3x+2演示一下Estimator
中的LinearRegressor
做函数逼近
#创建回归器
NUM_EXAMPLES=1000
training_inputs=np.random.rand(NUM_EXAMPLES)
training_outputs=training_inputs*3+2
column=tf.feature_column.numeric_column('x')
classifier = tf.estimator.LinearRegressor(feature_columns=[column])
#训练
train_input=tf.estimator.inputs.numpy_input_fn(\
x={'x':training_inputs},
y=training_outputs,
shuffle=False,
num_epochs=None)
classifier.train(train_input,steps=2500)
如何取出权重,我暂时也不是特别清楚,因为这个classifier
中的参数有点多,可以通过get_variable_names
函数看到分类器都有哪些参数名,然后对应取出来就行:
print(classifier.get_variable_names())
print(classifier.get_variable_value('linear/linear_model/bias_weights'))
print(classifier.get_variable_value('linear/linear_model/x/weights'))
输出:
['global_step', 'linear/linear_model/bias_weights', 'linear/linear_model/bias_weights/part_0/Ftrl', 'linear/linear_model/bias_weights/part_0/Ftrl_1', 'linear/linear_model/x/weights', 'linear/linear_model/x/weights/part_0/Ftrl', 'linear/linear_model/x/weights/part_0/Ftrl_1']
[2.0108593]
[[2.9801264]]
初步估计这个权重和偏置的取出是这样,至于其它参数是什么,还没懂,以后用到再说。
自定义Estimator暂时不看,这个应该属于进阶了,后续需要再学习
总结
上面通过三种方式对函数
y
=
3
x
+
2
y=3x+2
y=3x+2建模,展示了tensorflow
中构建及运行模型的方法,做一个初步了解就行,其实搞科研第二种算法用的比较多,因为它类似于Theano
,只不过封装了更好的函数操作,调试信息感觉也更加清晰。此外,我暂时不打算使用Eager execution
的方法建立模型,感觉和numpy
一样,还有也不打算用Estimator
封装好的各种模型,感觉对理论理解就不够了。
下面就针对Graph execution
构建模型所需了解的入门级知识,按照学Theano
的步骤来吧:首先是变量定义(标量、向量、矩阵)和操作(点乘、叉乘之类的)。
入门级操作
数据类型定义与取值
**常量:**使用tf.constant
,输入参数有
tf.constant(
value,
dtype=None,
shape=None,
name='Const',
verify_shape=False
)
依次代表:常量值,类型,维度,名称,是否在每次验证大小(如果设置成False
,以后还能修改大小)
tensor1=tf.constant([1,2,3,4,5,6,7])#一维常量
tensor2=tf.constant([1],shape=[2,7])#二维常量
如果想取值看看,就必须在Session
中取值,感觉这个是最麻烦的,取值还得去Session
,不过这样就能让我们保持一个良好习惯,写任何东西,把Session
定义出来就行了:
with tf.Session() as sess:
print(tensor1.eval())
print(tensor2.eval())
'''
[1 2 3 4 5 6 7]
[[1 1 1 1 1 1 1]
[1 1 1 1 1 1 1]]
'''
变量: 使用tf.Variable
,输入参数有
tf.Variable(<initial-value>, name=<optional-name>)
包括初始值和名称,比如定义权重和偏置:
weights=tf.Variable(np.random.rand(2,3),name='weights')
bias=tf.Variable(0,name='bias')
但是在使用此变量之前,一定要初始化,才能进行其它操作,比如取值,幸好TensorFlow
提供了统一初始化函数initialize_all_variables
,我们无需一个个初始化了:
weights=tf.Variable(np.random.rand(2,3),name='weights')
bias=tf.Variable(0,name='bias')
init_op=tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init_op)
print(weights.eval())
'''
[[0.6229396 0.42244541 0.47293289]
[0.70087716 0.42179686 0.09062685]]
'''
如果想初始化某个变量,可使用内置函数initializer
。
内置简单的赋值和加减操作:主要是Variable
的内置函数assign
、assign_add
、assign_sub
切记一定要在Session
中进行操作:
with tf.Session() as sess:
sess.run(init_op)
sess.run(bias.assign(bias+10))
print(bias.eval())
#10
占位器:用于存储变量的placeholder,与Variable
的区别在于,占位器无需预先定义数值,它仅仅是一个容器,类似于theano
中的tensor.vector
之类的,可指定维度,后续可以用feed_dict
给它喂数据:
tf.placeholder(
dtype,
shape=None,
name=None
)
举个例子:
x = tf.placeholder(tf.float32, shape=(1024, 1024))
y = tf.matmul(x, x)
with tf.Session() as sess:
print(sess.run(y)) # ERROR: will fail because x was not fed.
rand_array = np.random.rand(1024, 1024)
print(sess.run(y, feed_dict={x: rand_array})) # Will succeed.
再一次说明定义的时候无需指定数值,只需指定大小和类型,那我们设计神经网络的时候可以常用它来为输入数据占位。
基本运算
-
abs:如果是实数,就直接取绝对值;如果是复数,就取实部和虚部的平方和的根 a 2 + b 2 \sqrt{a^2+b^2} a2+b2
x1=tf.constant([-1,2,3,-4,5]) y1=tf.abs(x1) x2=tf.constant([[-3+4j],[-6+8j]]) y2=tf.abs(x2) with tf.Session() as sess: print(y1.eval())#[1 2 3 4 5] print(y2.eval()) ''' [[ 5.] [10.]] '''
-
add:加和操作
x3=tf.constant(2) y3=tf.add(x3,4) with tf.Session() as sess: print(y3.eval())#6
-
angle:角度值,输入被看成复数 a + b j a+bj a+bj,输出是 a t a n 2 ( b , a ) atan2(b,a) atan2(b,a),如果输入是实数,输出就是0
x4=tf.constant([[-2.25+4.75j],[3.25+5.75j]]) y4=tf.angle(x4) with tf.Session() as sess: print(y4.eval()) ''' [[2.01317055] [1.05634501]] '''
-
argmax,argmin:返回最大/最小值的位置索引
indx=tf.argmax(x1) with tf.Session() as sess: print(x1.eval()) print(indx.eval()) ''' [-1 2 3 -4 5] 4 '''
-
assign:赋值
-
assign_add:加
-
assign_sub:减
-
sin:正弦,还有对应的asin
-
sinh:双曲正弦,还有对应的asinh
-
cos:余弦,还有对应的acos
-
cosh:双曲余弦,还有对应的acosh
-
tan:正切
-
tanh:双曲正切
-
atan:对每个元素计算反正切
-
atan2:输入是atan2(y,x),计算 y / x y/x y/x的反正切,范围 [ − π , π ] [-\pi,\pi] [−π,π]
-
complex:将两个实数变换成复数
real = tf.constant([2.25, 3.25]) imag = tf.constant([4.75, 5.75]) tf.complex(real, imag) # [[2.25 + 4.75j], [3.25 + 5.75j]]
-
real:返回复数的实部
-
imag:返回复数的虚部
-
cross:计算两个相同维度向量的叉乘
x5=[1,2,3] y5=[4,5,6] temp5=tf.cross(x5,y5) with tf.Session() as sess: print(temp5.eval())#[-3 6 -3] print(np.cross(x5,y5))#[-3 6 -3]
-
matmul:点乘
a=tf.constant([1,2,3,4,5,6],shape=[2,3]) b=tf.constant([7,8,9,10,11,12],shape=[3,2]) c=tf.matmul(a,b) with tf.Session() as sess: sess.run(c) print(c.eval()) ''' [[ 58 64] [139 154]] '''
-
multiply:逐元素相乘
a=tf.constant([1,2,3,4,5,6],shape=[2,3]) b=tf.constant([7,8,9,10,11,12],shape=[2,3]) c=tf.multiply(a,b) with tf.Session() as sess: sess.run(c) print(c.eval()) ''' [[ 7 16 27] [40 55 72]] '''
-
subtract:逐元素相减 x − y x-y x−y
-
cumprod:累乘
tf.cumprod( x, axis=0, exclusive=False, reverse=False, name=None )
有两个比较重要参数:exclusive和reverse
tf.cumprod([a, b, c]) # [a, a * b, a * b * c] tf.cumprod([a, b, c], exclusive=True) # [1, a, a * b] tf.cumprod([a, b, c], reverse=True) # [a * b * c, b * c, c] tf.cumprod([a, b, c], exclusive=True, reverse=True) # [b * c, c, 1]
-
cumsum:累加
tf.cumsum([a, b, c]) # [a, a + b, a + b + c] tf.cumsum([a, b, c], exclusive=True) # [0, a, a + b] tf.cumsum([a, b, c], reverse=True) # [a + b + c, b + c, c] tf.cumsum([a, b, c], exclusive=True, reverse=True) # [b + c, c, 0]
-
div:逐元素除法
-
equal:对应元素是否相等
-
exp:返回 y = e x y=e^x y=ex
-
fft,fft2d,fft3d:快速傅里叶变换
-
ifft,ifft2d,ifft3d:逆傅里叶变换
-
ceil:不小于 x x x的最大整数
-
floor:小于 x x x的最大整数
-
floordiv:除法,整数的时候等价于tf.div(x,y),浮点的时候等价于tf.floor(tf.div(x,y))
-
floormod:返回余数 x = f l o o r ( x / y ) ∗ y + m o d ( x , y ) x=floor(x/y)*y+mod(x,y) x=floor(x/y)∗y+mod(x,y)
-
greater:如果 x > y x>y x>y返回真值
-
greater_equal:如果 x > = y x>=y x>=y,返回真值
-
less:如果 x < y x<y x<y,返回真值
-
less_equal:如果 x < = y x<=y x<=y,返回真值
-
log:返回 y = log e x y=\log_ex y=logex
-
log1p:返回 y = log e ( 1 + x ) y=\log_e(1+x) y=loge(1+x)
-
log_sigmoid:返回 y = log ( 1 1 + e − x ) y=\log (\frac{1}{1+e^{-x}}) y=log(1+e−x1)
-
matrix_inverse:计算方阵的逆或其共轭转置
tf.matrix_inverse( input, adjoint=False, name=None )
-
maximum:逐元素返回 x > y ? x : y x>y?x:y x>y?x:y
tf.maximum( x, y, name=None )
-
minimum:逐元素返回 x < y ? x : y x<y?x:y x<y?x:y
-
negative:逐元素计算负值 y = − x y=-x y=−x
-
ones:初始化全1矩阵
tf.ones( shape, dtype=tf.float32, name=None ) #example tf.ones([2, 3], tf.int32) # [[1, 1, 1], [1, 1, 1]]
-
zeros:初始化全0矩阵
-
ones_like:初始化与给定矩阵维度相同的全1矩阵
tf.ones_like( tensor, dtype=None, name=None, optimize=True ) #example tensor = tf.constant([[1, 2, 3], [4, 5, 6]]) tf.ones_like(tensor) # [[1, 1, 1], [1, 1, 1]]
-
zeros_like
:初始化与给定矩阵维度相同的全0矩阵 -
pad填充:
tf.pad( tensor, paddings, mode='CONSTANT', name=None, constant_values=0 )
按照
paddings
去填充tensor
,官网解释有点复杂,感觉paddings
是一个二维矩阵,分别指示tensor
的上下左右分别要填充多少。mode
是填充模式,是常量填充CONSTANT
、镜像填充REFLECT
或是对称填充SYMMETRIC
t = tf.constant([[1, 2, 3], [4, 5, 6]]) paddings = tf.constant([[1, 1,], [2, 2]]) # 'constant_values' is 0. # rank of 't' is 2. tf.pad(t, paddings, "CONSTANT") # [[0, 0, 0, 0, 0, 0, 0], # [0, 0, 1, 2, 3, 0, 0], # [0, 0, 4, 5, 6, 0, 0], # [0, 0, 0, 0, 0, 0, 0]] tf.pad(t, paddings, "REFLECT") # [[6, 5, 4, 5, 6, 5, 4], # [3, 2, 1, 2, 3, 2, 1], # [6, 5, 4, 5, 6, 5, 4], # [3, 2, 1, 2, 3, 2, 1]] tf.pad(t, paddings, "SYMMETRIC") # [[2, 1, 1, 2, 3, 3, 2], # [2, 1, 1, 2, 3, 3, 2], # [5, 4, 4, 5, 6, 6, 5], # [5, 4, 4, 5, 6, 6, 5]]
-
pow
:逐元素计算 x y x^y xyx = tf.constant([[2, 2], [3, 3]]) y = tf.constant([[8, 16], [2, 3]]) tf.pow(x, y) # [[256, 65536], [9, 27]]
-
range:创建序列
tf.range(limit, delta=1, dtype=None, name='range') tf.range(start, limit, delta=1, dtype=None, name='range')
其中start是表示开始数字,limit是最后一个数字的最终取值范围,delta是增量
start = 3 limit = 18 delta = 3 tf.range(start, limit, delta) # [3, 6, 9, 12, 15] start = 3 limit = 1 delta = -0.5 tf.range(start, limit, delta) # [3, 2.5, 2, 1.5] limit = 5 tf.range(limit) # [0, 1, 2, 3, 4]
-
reduce_join:合并某些维度
tf.reduce_join( inputs, axis=None, keep_dims=False, separator='', name=None, reduction_indices=None )
# tensor `a` is [["a", "b"], ["c", "d"]] tf.reduce_join(a, 0) ==> ["ac", "bd"] tf.reduce_join(a, 1) ==> ["ab", "cd"] tf.reduce_join(a, -2) = tf.reduce_join(a, 0) ==> ["ac", "bd"] tf.reduce_join(a, -1) = tf.reduce_join(a, 1) ==> ["ab", "cd"] tf.reduce_join(a, 0, keep_dims=True) ==> [["ac", "bd"]] tf.reduce_join(a, 1, keep_dims=True) ==> [["ab"], ["cd"]] tf.reduce_join(a, 0, separator=".") ==> ["a.c", "b.d"] tf.reduce_join(a, [0, 1]) ==> "acbd" tf.reduce_join(a, [1, 0]) ==> "abcd" tf.reduce_join(a, []) ==> [["a", "b"], ["c", "d"]] tf.reduce_join(a) = tf.reduce_join(a, [1, 0]) ==> "abcd"
-
reduce_max
:按照指定维度计算最大值 -
reduce_min
:按照指定维度计算最小值 -
reduce_prob
:按照指定维度计算累加 -
reduce_sum
:按照指定维度计算累乘a=tf.constant([1,2,3,4,5,6],shape=[2,3],dtype=tf.float32) b=tf.reduce_prod(a,0) c=tf.reduce_prod(a,1) with tf.Session() as sess: sess.run(c) print(a.eval()) print(b.eval())#[ 4. 10. 18.] print(c.eval())#[ 6. 120.]
-
reduce_mean
:按照指定维度计算均值a=tf.constant([1,2,3,4,5,6],shape=[2,3],dtype=tf.float32) b=tf.reduce_mean(a,0) c=tf.reduce_mean(a,1) with tf.Session() as sess: sess.run(c) print(a.eval()) print(b.eval())#[2.5 3.5 4.5] print(c.eval())#[2. 5.]
-
reverse
:按照指定维度翻转矩阵# tensor 't' is [[[[ 0, 1, 2, 3], # [ 4, 5, 6, 7], # [ 8, 9, 10, 11]], # [[12, 13, 14, 15], # [16, 17, 18, 19], # [20, 21, 22, 23]]]] # tensor 't' shape is [1, 2, 3, 4] # 'dims' is [3] or 'dims' is [-1] reverse(t, dims) ==> [[[[ 3, 2, 1, 0], [ 7, 6, 5, 4], [ 11, 10, 9, 8]], [[15, 14, 13, 12], [19, 18, 17, 16], [23, 22, 21, 20]]]] # 'dims' is '[1]' (or 'dims' is '[-3]') reverse(t, dims) ==> [[[[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23] [[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]]] # 'dims' is '[2]' (or 'dims' is '[-2]') reverse(t, dims) ==> [[[[8, 9, 10, 11], [4, 5, 6, 7], [0, 1, 2, 3]] [[20, 21, 22, 23], [16, 17, 18, 19], [12, 13, 14, 15]]]]
-
rint:返回与当前元素最接近的整数值,有一半的时候,取最近偶数
x = tf.constant([0.9, 2.5, 2.3, 1.3, -4.5]) y=tf.round(x) with tf.Session() as sess: sess.run(y) print(y.eval())#[ 1. 2. 2. 1. -4.]
-
rsqrt:逐元素 y = 1 x y=\frac{1}{\sqrt{x}} y=x1
-
sqrt:逐元素 y = x y=\sqrt{x} y=x
-
square:逐元素 y = x 2 y=x^2 y=x2
-
squared_difference:逐元素 ( x − y ) 2 (x-y)^2 (x−y)2
-
sign:返回元素符号,大于0返回1,等于0或者非数返回0,小于0返回-1
-
squeeze:默认去除是维度为1的维度,也可指定
# 't' is a tensor of shape [1, 2, 1, 3, 1, 1] tf.shape(tf.squeeze(t)) # [2, 3] # 't' is a tensor of shape [1, 2, 1, 3, 1, 1] tf.shape(tf.squeeze(t, [2, 4])) # [1, 2, 3, 1]
-
stack:堆叠向量或者矩阵
x = tf.constant([1, 4]) y = tf.constant([2, 5]) z = tf.constant([3, 6]) tf.stack([x, y, z]) # [[1, 4], [2, 5], [3, 6]] tf.stack([x, y, z], axis=1) # [[1, 2, 3], [4, 5, 6]]
-
svd:奇异值分解
# a is a tensor. # s is a tensor of singular values. # u is a tensor of left singular vectors. # v is a tensor of right singular vectors. s, u, v = svd(a) s = svd(a, compute_uv=False)#还可以返回u,v
-
unique:去重
# tensor 'x' is [1, 1, 2, 4, 4, 4, 7, 8, 8] y, idx = unique(x) y ==> [1, 2, 4, 7, 8] idx ==> [0, 0, 1, 2, 2, 2, 3, 4, 4]
##条件函数:Assert
tf.Assert(
condition,
data,
summarize=None,
name=None
)
如果条件不成立,就从data
中打印张量列表,summerize
决定了打印多少个条目。
注意应使用此函数的输出,如果条件不满足, 则会记录一个InvalidArgumentError
警告。若要将输出标记为已用, 请调用其. *mark_used()*方法。
但是如果在图模式中,为了保证Assert
能够执行,需要添加一个依赖项:
a=tf.constant([1,2,3,4,5,6],shape=[2,3],dtype=tf.float32)
b=tf.constant([0.1,0.2,0.3,0.4,0.5,0.6],shape=[2,3],dtype=tf.float32)
assert_op=tf.Assert(tf.less(tf.reduce_max(b),1.),[x])
with tf.control_dependencies([assert_op]):
output = tf.reduce_sum(a)
with tf.Session() as sess:
print(output.eval())#21.0
但是如果把上述的less
换成greater
就会报错:
a=tf.constant([1,2,3,4,5,6],shape=[2,3],dtype=tf.float32)
b=tf.constant([0.1,0.2,0.3,0.4,0.5,0.6],shape=[2,3],dtype=tf.float32)
assert_op=tf.Assert(tf.greater(tf.reduce_max(b),1.),[x])
with tf.control_dependencies([assert_op]):
output = tf.reduce_sum(a)
with tf.Session() as sess:
print(output.eval())#报错InvalidArgumentError
当然这个assert_op
也不是必须自己写,TensorFlow
自身提供了一堆:
-
assert_equal:判断相等
-
assert_greater:判断大于 x > y x>y x>y
-
assert_greater_equal:判断不小于 x > = y x>=y x>=y
-
assert_integer:判断是否为整数
-
assert_same_float_dtype:判断是否为相同的浮点型
-
assert_scalar:判断是否为标量
-
assert_type:判断与给定类型是否相同
-
assert_less:判断是否小于 x < y x<y x<y
-
assert_less_equal:判断是否不大于 x < = y x<=y x<=y
-
assert_negative:判断是否为负, x < 0 x<0 x<0
-
assert_none_equal:判断是否不等于 x ≠ y x\neq y x̸=y
-
assert_non_negative:判断是否非负 x > = 0 x>=0 x>=0
-
assert_non_positive:判断是否为非正数 x < = 0 x<=0 x<=0
-
assert_positive:判断是否为正数 x > 0 x>0 x>0
-
assert_proper_iterable:判断是否可迭代,张量、ndarray、byte / text类型都是 iterables 本身,所以是有用的
-
assert_rank:判断 x x x的秩是否等于给定值
assert_rank ( x , rank , data = None , summarize = None , message = None , name = None ) #例子 with tf.control_dependencies ([ tf.assert_rank(X2)]): output = tf.reduce_sum (x)
-
assert_rank_at_least:判断 x x x与给定秩是否相等或者更大
-
assert_variables_initialized:判断是否已初始化
随便举个例子,判断是否大于:
a=tf.constant([1,2,3,4,5,6],shape=[2,3],dtype=tf.float32)
b=tf.constant([0.1,0.2,0.3,0.4,0.5,0.6],shape=[2,3],dtype=tf.float32)
with tf.control_dependencies([tf.assert_greater(a,b)]):
output = tf.reduce_sum(a)
with tf.Session() as sess:
print(output.eval())#21.0
##随机操作
random_crop:随机裁剪
tf.random_crop(
value,
size,
seed=None,
name=None
)
将value
随机裁剪到指定size
,比如裁剪图像的时候用到:
distorted_image = tf.random_crop(image,[height,width,3])
一个使用例子可以戳这里
#随机裁剪
import matplotlib.image as img
import matplotlib.pyplot as plt
image=img.imread('F:/Photo/2.jpg')
reshaped_image=tf.cast(image,dtype=tf.float32)#转换数据类型
with tf.Session() as sess:
size=tf.cast(tf.shape(reshaped_image).eval(),tf.int32)
height=sess.run(size[0]//2)
width=sess.run(size[1]//2)
distored_image=tf.random_crop(reshaped_image,[height,width,3])
with tf.Session() as sess:
#plt.imshow(sess.run(tf.cast(reshaped_image,tf.uint8)))
plt.imshow(sess.run(tf.cast(distored_image,tf.uint8)))
random_shuffle:随机打乱次序
tf.random_shuffle(
value,
seed=None,
name=None
)
实例:
a=tf.constant([[1,2],[3,4],[5,6]])
b=tf.random_shuffle(a)
with tf.Session() as sess:
sess.run(b)
print(b.eval())
'''
[[3 4]
[1 2]
[5 6]]
'''
random_gamma:伽马分布,输入形状参数和逆尺度(倒数?)参数
random_normal:正态分布,输入大小,均值,方差
random_poisson:泊松分布,输入 λ \lambda λ和形状
random_uniform:平均分布,输入形状,最小值,最大值
##单热度编码:one_hot
这个通常用来制作标签,对应位置为指定值,一般用 0 、 1 0、1 0、1编码
tf.one_hot(
indices,
depth,
on_value=None,
off_value=None,
axis=None,
dtype=None,
name=None
)
其中:
- indices:是真实数值标签
- depth:长度,一般代表总类数
- on_value:在编码中激活该种类时,应该放什么值
- off_value:未激活的是什么值
indices = [0, 1, 2]
depth = 3
tf.one_hot(indices, depth) # output: [3 x 3]
# [[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]]
indices = [0, 2, -1, 1]
depth = 3
tf.one_hot(indices, depth,
on_value=5.0, off_value=0.0,
axis=-1) # output: [4 x 3]
# [[5.0, 0.0, 0.0], # one_hot(0)
# [0.0, 0.0, 5.0], # one_hot(2)
# [0.0, 0.0, 0.0], # one_hot(-1)
# [0.0, 5.0, 0.0]] # one_hot(1)
indices = [[0, 2], [1, -1]]
depth = 3
tf.one_hot(indices, depth,
on_value=1.0, off_value=0.0,
axis=-1) # output: [2 x 2 x 3]
# [[[1.0, 0.0, 0.0], # one_hot(0)
# [0.0, 0.0, 1.0]], # one_hot(2)
# [[0.0, 1.0, 0.0], # one_hot(1)
# [0.0, 0.0, 0.0]]] # one_hot(-1)
函数执行方案:Session
正如之前所有的代码演示一样,在Graph execution
中几乎所有的运算都必须放到Session
中通过run
函数才能执行,这应该是tensorflow
的约定,这里我们看看两种Session
标准的tf.Session
这个就不用说了,典型的调用方法:
a=tf.constant([1,2])
b=tf.add(a,2);
with tf.Session() as sess:
sess.run(b)
print(b.eval())#[3 4]
或者
import tensorflow as tf
a=tf.constant([1,2])
b=tf.add(a,2);
sess=tf.Session()
print(sess.run(b))
交互式的InteractiveSession
前面那个标准的Session
每次都要用那个典型的调用方法,感觉很冗余,想办法把当前环境的Session预先初始化好,后面用的时候直接运行或者调用run就好了,这就是InteractiveSession的用途。
举个例子:
#程序1
import tensorflow as tf
a=tf.constant([1,2])
b=tf.add(a,2);
isess=tf.Session()
print(b.eval())
此程序是无法运行的,报错
ValueError: Cannot evaluate tensor using `eval()`: No default session is registered. Use `with sess.as_default()` or pass an explicit session to `eval(session=sess)`
但是如果把Session
换成InteractiveSession()
就能执行了:
#程序2
import tensorflow as tf
a=tf.constant([1,2])
b=tf.add(a,2);
isess=tf.InteractiveSession()
print(b.eval())#[3 4]
记住,只要执行过InteracitveSession()
,那么当前环境的所有操作都无需添加Session
了,比如你先运行了程序2,再去运行程序1,是可以执行的,因为交互式环境已被激活。具体理解可以戳这里
后记
作为入门先了解这么多吧, 多了的更复杂了,消化不了,通过实战了解更多知识比较好。
在本博客中,主要了解了:
- TensorFlow的数据类型、基本运算
- 函数执行方案
本文代码链接:https://pan.baidu.com/s/1NC0QPG6KxSsNq5ndthbdhg 密码:suxw