【TensorFlow-windows】学习笔记一——基础理解

前言

因为Theano已经停止更新了,所以在前面学完Theano搭建RBM,CNN,RNN相关结构以后,还是得选择一个主流框架的,由于我自身的学习最终是向强化学习靠近,可能用到的仿真环境是openai gym,所以选择了继续学习TensorFlow,而非pyTorch,CNTK之类的深度学习框架。

还是按照Theano的学习方法来,先学习一下入门基础,比如基本存储容器,变量运算,函数执行与取值等操作,然后学一下手写数字识别什么的。

国际惯例,参考博客:

一脸懵逼的官方教程

清晰易懂的中文社区

机器学习速成课程中的TensorFlow

TensorFlow官方文档中文译

简介

在使用入门中提到了TensorFlow分为Eager ExecutionGraph 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=3x+2y=3x+2y=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_outputsreturn 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=3x+2y=3x+2y=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=3x+2y=3x+2y=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=3x+2y=3x+2y=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的内置函数assignassign_addassign_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:如果是实数,就直接取绝对值;如果是复数,就取实部和虚部的平方和的根a2+b2\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+bja+bja+bj,输出是atan2(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/xy/xy/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−yx-yxy

  • cumprod:累乘

    tf.cumprod(x,axis=0,exclusive=False,reverse=False,name=None
    )
    

    有两个比较重要参数:exclusivereverse

    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=exy=e^xy=ex

  • fftfft2dfft3d:快速傅里叶变换

  • ifft,ifft2d,ifft3d:逆傅里叶变换

  • ceil:不小于xxx的最大整数

  • floor:小于xxx的最大整数

  • floordiv:除法,整数的时候等价于tf.div(x,y),浮点的时候等价于tf.floor(tf.div(x,y))

  • floormod:返回余数x=floor(x/y)∗y+mod(x,y)x=floor(x/y)*y+mod(x,y)x=floor(x/y)y+mod(x,y)

  • greater:如果x&gt;yx&gt;yx>y返回真值

  • greater_equal:如果x&gt;=yx&gt;=yx>=y,返回真值

  • less:如果x&lt;yx&lt;yx<y,返回真值

  • less_equal:如果x&lt;=yx&lt;=yx<=y,返回真值

  • log:返回y=log⁡exy=\log_exy=logex

  • log1p:返回y=log⁡e(1+x)y=\log_e(1+x)y=loge(1+x)

  • log_sigmoid:返回y=log⁡(11+e−x)y=\log (\frac{1}{1+e^{-x}})y=log(1+ex1)

  • matrix_inverse:计算方阵的逆或其共轭转置

    tf.matrix_inverse(input,adjoint=False,name=None
    )
    
  • maximum:逐元素返回x&gt;y?x:yx&gt;y?x:yx>y?x:y

    tf.maximum(x,y,name=None
    )
    
  • minimum:逐元素返回x&lt;y?x:yx&lt;y?x:yx<y?x:y

  • negative:逐元素计算负值y=−xy=-xy=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:逐元素计算xyx^yxy

    x = 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=1xy=\frac{1}{\sqrt{x}}y=x1

  • sqrt:逐元素y=xy=\sqrt{x}y=x

  • square:逐元素y=x2y=x^2y=x2

  • squared_difference:逐元素(x−y)2(x-y)^2(xy)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&gt;yx&gt;yx>y

  • assert_greater_equal:判断不小于x&gt;=yx&gt;=yx>=y

  • assert_integer:判断是否为整数

  • assert_same_float_dtype:判断是否为相同的浮点型

  • assert_scalar:判断是否为标量

  • assert_type:判断与给定类型是否相同

  • assert_less:判断是否小于x&lt;yx&lt;yx<y

  • assert_less_equal:判断是否不大于x&lt;=yx&lt;=yx<=y

  • assert_negative:判断是否为负,x&lt;0x&lt;0x<0

  • assert_none_equal:判断是否不等于x≠yx\neq yx̸=y

  • assert_non_negative:判断是否非负x&gt;=0x&gt;=0x>=0

  • assert_non_positive:判断是否为非正数x&lt;=0x&lt;=0x<=0

  • assert_positive:判断是否为正数x&gt;0x&gt;0x>0

  • assert_proper_iterable:判断是否可迭代,张量、ndarraybyte / text类型都是 iterables 本身,所以是有用的

  • assert_rank:判断xxx的秩是否等于给定值

    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:判断xxx与给定秩是否相等或者更大

  • 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 pltimage=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、10、101编码

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【TensorFlow-windows】学习笔记二——低级API

前言 上一篇博客初步了解了tensorflow中建立机器学习模型的方法&#xff1a;可以使用eager execution和graph execution两种模式&#xff0c;可以使用高级API estimator中已经封装好的模型&#xff0c;也可以自己创建estimator&#xff0c;更重要的是我们也可以使用低级API自行…

【TensorFlow-windows】学习笔记五——自编码器

前言 上一篇博客介绍的是构建简单的CNN去识别手写数字&#xff0c;这一篇博客折腾一下自编码&#xff0c;理论很简单&#xff0c;就是实现对输入数据的重构&#xff0c;具体理论可以看我前面的【theano-windows】学习笔记十三——去噪自编码器 国际惯例&#xff0c;参考博客&…

【TensorFlow-windows】学习笔记六——变分自编码器

#前言 对理论没兴趣的直接看代码吧&#xff0c;理论一堆&#xff0c;而且还有点复杂&#xff0c;我自己的描述也不一定准确&#xff0c;但是代码就两三句话搞定了。 国际惯例&#xff0c;参考博文 论文&#xff1a;Tutorial on Variational Autoencoders 【干货】一文读懂…

【TensorFlow-windows】学习笔记七——生成对抗网络

前言 既然学习了变分自编码(VAE)&#xff0c;那也必须来一波生成对抗网络(GAN)。 国际惯例&#xff0c;参考网址&#xff1a; 论文: Generative Adversarial Nets PPT:Generative Adversarial Networks (GANs) Generative Adversarial Nets in TensorFlow GAN原理学习笔记…

Openpose——windows编译(炒鸡简单)

前言 最近准备看看rtpose的代码&#xff0c;发现已经由openpose这个项目维护着了&#xff0c;由于经常在windows下调试代码&#xff0c;所以尝试了一下如何在windows下编译openpose源码&#xff0c;整体来说非常简单的。 国际惯例&#xff0c;参考博客&#xff1a; [OpenPos…

强化学习——Qlearning

前言 在控制决策领域里面强化学习还是占很重比例的&#xff0c;最近出了几篇角色控制的论文需要研究&#xff0c;其中部分涉及到强化学习&#xff0c;都有开源&#xff0c;有兴趣可以点开看看&#xff1a; A Deep Learning Framework For Character Motion Synthesis and Edit…

【TensorFlow-windows】keras接口学习——线性回归与简单的分类

前言 之前有写过几篇TensorFlow相关文章&#xff0c;但是用的比较底层的写法&#xff0c;比如tf.nn和tf.layers&#xff0c;也写了部分基本模型如自编码和对抗网络等&#xff0c;感觉写起来不太舒服&#xff0c;最近看官方文档发现它的教程基本都使用的keras API&#xff0c;这…

【TensorFlow-windows】keras接口——卷积手写数字识别,模型保存和调用

前言 上一节学习了以TensorFlow为底端的keras接口最简单的使用&#xff0c;这里就继续学习怎么写卷积分类模型和各种保存方法(仅保存权重、权重和网络结构同时保存) 国际惯例&#xff0c;参考博客&#xff1a; 官方教程 【注】其实不用看博客&#xff0c;直接翻到文末看我的c…

【TensorFlow-windows】keras接口——BatchNorm和ResNet

前言 之前学习利用Keras简单地堆叠卷积网络去构建分类模型的方法&#xff0c;但是对于很深的网络结构很难保证梯度在各层能够正常传播&#xff0c;经常发生梯度消失、梯度爆炸或者其它奇奇怪怪的问题。为了解决这类问题&#xff0c;大佬们想了各种办法&#xff0c;比如最原始的…

【TensorFlow-windows】keras接口——卷积核可视化

前言 在机器之心上看到了关于卷积核可视化相关理论&#xff0c;但是作者的源代码是基于fastai写的&#xff0c;而fastai的底层是pytorch&#xff0c;本来准备自己用Keras复现一遍的&#xff0c;但是尴尬地发现Keras还没玩熟练&#xff0c;随后发现了一个keras-vis包可以用于做…

【TensorFlow-windows】投影变换

前言 没什么重要的&#xff0c;就是想测试一下tensorflow的投影变换函数tf.contrib.image.transform中每个参数的含义 国际惯例&#xff0c;参考文档 官方文档 描述 调用方法与默认参数&#xff1a; tf.contrib.image.transform(images,transforms,interpolationNEAREST,…

【TensorFlow-windows】扩展层之STN

前言 读TensorFlow相关代码看到了STN的应用&#xff0c;搜索以后发现可替代池化&#xff0c;增强网络对图像变换(旋转、缩放、偏移等)的抗干扰能力&#xff0c;简单说就是提高卷积神经网络的空间不变性。 国际惯例&#xff0c;参考博客&#xff1a; 理解Spatial Transformer…

【TensorFlow-windows】MobileNet理论概览与实现

前言 轻量级神经网络中&#xff0c;比较重要的有MobileNet和ShuffleNet&#xff0c;其实还有其它的&#xff0c;比如SqueezeNet、Xception等。 本博客为MobileNet的前两个版本的理论简介与Keras中封装好的模块的对应实现方案。 国际惯例&#xff0c;参考博客&#xff1a; 纵…

【TensorFlow-windows】keras接口——ImageDataGenerator裁剪

前言 Keras中有一个图像数据处理器ImageDataGenerator&#xff0c;能够很方便地进行数据增强&#xff0c;并且从文件中批量加载图片&#xff0c;避免数据集过大时&#xff0c;一下子加载进内存会崩掉。但是从官方文档发现&#xff0c;并没有一个比较重要的图像增强方式&#x…

【TensorFlow-windows】TensorBoard可视化

前言 紧接上一篇博客&#xff0c;学习tensorboard可视化训练过程。 国际惯例&#xff0c;参考博客&#xff1a; MNIST机器学习入门 Tensorboard 详解&#xff08;上篇&#xff09; Tensorboard 可视化好帮手 2 tf-dev-summit-tensorboard-tutorial tensorflow官方mnist_…

深度学习特征归一化方法——BN、LN、IN、GN

前言 最近看到Group Normalization的论文&#xff0c;主要提到了四个特征归一化方法&#xff1a;Batch Norm、Layer Norm、Instance Norm、Group Norm。此外&#xff0c;论文还提到了Local Response Normalization(LRN)、Weight Normalization(WN)、Batch Renormalization(BR)…

【TensorFlow-windows】keras接口——利用tensorflow的方法加载数据

前言 之前使用tensorflow和keras的时候&#xff0c;都各自有一套数据读取方法&#xff0c;但是遇到一个问题就是&#xff0c;在训练的时候&#xff0c;GPU的利用率忽高忽低&#xff0c;极大可能是由于训练过程中读取每个batch数据造成的&#xff0c;所以又看了tensorflow官方的…

骨骼动画——论文与代码精读《Phase-Functioned Neural Networks for Character Control》

前言 最近一直玩CV&#xff0c;对之前学的动捕知识都忘得差不多了&#xff0c;最近要好好总结一下一直以来学习的内容&#xff0c;不能学了忘。对2017年的SIGGRAPH论文《Phase-Functioned Neural Networks for Character Control》进行一波深入剖析吧&#xff0c;结合源码。 额…

颜色协调模型Color Harmoniztion

前言 最近做换脸&#xff0c;在肤色调整的那一块&#xff0c;看到一个有意思的文章&#xff0c;复现一波玩玩。不过最后一步掉链子了&#xff0c;有兴趣的可以一起讨论把链子补上。 主要是github上大佬的那个复现代码和原文有点差异&#xff0c;而且代码复杂度过高&#xff0…

Openpose推断阶段原理

前言 之前出过一个关于openpose配置的博客&#xff0c;不过那个代码虽然写的很好&#xff0c;而且是官方的&#xff0c;但是分析起来很困难&#xff0c;然后再opencv相关博客中找到了比较清晰的实现&#xff0c;这里分析一波openpose的推断过程。 国际惯例&#xff0c;参考博…