Tensorflow编程基础笔记之二——图的基本操作和编程模型

Tensorflow编程基础笔记之二——图的基本操作和编程模型

  • 图的基本操作
  • 编程模型

2.1 图的基本操作

  • 图的基本操作包括建立图、获取张量、获取节点操作、获取元素列表和获取对象
import numpy as np
import tensorflow as tf
import os
#张量c是在刚开始默认图中建立的,获得图的第一种方法
c=tf.constant(0.0)
print("查看程序初始默认图的内存地址:",c.graph)
g1=tf.get_default_graph()
print("将程序初始默认图命名为g1,查看g1的内存地址:",g1)

#获得图的第二种方法
g2=tf.Graph()
#with语句表示下面的所有操作如果没有指定图,那么都是在g图中的操作
with g2.as_default():
    c1=tf.constant(0.0)
    print("g2图中建立的张量c1:",c1.graph)
    print("查看g2图的内存地址:",g2)

#获得图的第三种方法
#tf.resset_default_graph函数相当于重新建立了一张图来代替原来的默认图
#在使用tf.reset_default_graph函数时必须保证当前图的资源已经全部释放,否则会报错。
tf.reset_default_graph()
g3=tf.get_default_graph()
print("查看新建默认图g3的内存地址:",g3)
查看程序初始默认图的内存地址: <tensorflow.python.framework.ops.Graph object at 0x0000019B2A7AC390>
将程序初始默认图命名为g1,查看g1的内存地址: <tensorflow.python.framework.ops.Graph object at 0x0000019B2A7AC390>
g2图中建立的张量c1: <tensorflow.python.framework.ops.Graph object at 0x0000019B2A7ACB70>
查看g2图的内存地址: <tensorflow.python.framework.ops.Graph object at 0x0000019B2A7ACB70>
查看新建默认图g3的内存地址: <tensorflow.python.framework.ops.Graph object at 0x0000019B2A7ACC88>

2.2 获取张量

  • 在图里面可以通过名字得到其对应的元素,如,get_tensor_by_name可以获得图里面的张量
  • **注意:**不必花太多精力去关注TensorFlow中默认的命名规则。一般在需要使用名字时都会在定义的同时为它指定好固定的名字。
print(c1.name)
t=g2.get_tensor_by_name(name="Const:0")
print(t)
Const:0
Tensor("Const:0", shape=(), dtype=float32)

2.3 获取节点操作

  • 获取节点操作OP的方法和获取张量的方法非常类似,使用的方法是get_operation_by_name。
  • 计算图中每一个运算操作将作为一个节点(node,又称为operation,缩写成op),节点与节点之间的连接成为边(edge),而在计算图的边中流动(flow)的数据被称为张量(tensor)
  • **注意:**节点操作OP和张量在定义节点时很容易被混淆。tensor1=tf.matmul()并不是OP,而是张量。OP其实是描述张量中的运算关系,是通过访问张量的op属性找到的
a=tf.constant([[1.0,2.0]])
b=tf.constant([[1.0],[3.0]])

tensor1=tf.matmul(a,b,name='exampleop')
print('·计算图中的默认张量名tensor1.name=',tensor1.name,'·图中定义的张量tensor1=',tensor1,sep='\n')
test=g3.get_tensor_by_name('exampleop:0')
print('·通过图中默认张量名[exampleop:0]获得结果张量:',test,sep='\n')

print('输出张量tensor1的节点操作名tensor1.op.name=',tensor1.op.name)
testop=g3.get_operation_by_name('exampleop')
print('·通过图中自定义节点操作名[exampleop]获得结果张量:',testop,sep='\n')

with tf.Session() as sess:
    test=sess.run(test)
    print('·通过图中自定义节点操作名[exampleop]输出结果张量:',test,sep='\n')
    test=tf.get_default_graph().get_tensor_by_name('exampleop:0')
    print('·通过图中默认张量名[exampleop:0]输出结果张量:',test,sep='\n')
·计算图中的默认张量名tensor1.name=
exampleop:0
·图中定义的张量tensor1=
Tensor("exampleop:0", shape=(1, 1), dtype=float32)
·通过图中默认张量名[exampleop:0]获得结果张量:
Tensor("exampleop:0", shape=(1, 1), dtype=float32)
输出张量tensor1的节点操作名tensor1.op.name= exampleop
·通过图中自定义节点操作名[exampleop]获得结果张量:
name: "exampleop"
op: "MatMul"
input: "Const"
input: "Const_1"
attr {
  key: "T"
  value {
    type: DT_FLOAT
  }
}
attr {
  key: "transpose_a"
  value {
    b: false
  }
}
attr {
  key: "transpose_b"
  value {
    b: false
  }
}

·通过图中自定义节点操作名[exampleop]输出结果张量:
[[ 7.]]
·通过图中默认张量名[exampleop:0]输出结果张量:
Tensor("exampleop:0", shape=(1, 1), dtype=float32)

2.4 获取元素列表

  • 使用get_operations函数实现
  • 由于运算多遍,导致输出的元素列表中有很多重复的元素。
tt2=g3.get_operations()
print(tt2)
[<tf.Operation 'Const' type=Const>, <tf.Operation 'Const_1' type=Const>, <tf.Operation 'exampleop' type=MatMul>]

2.5 获取对象

  • 可以根据名字来获取元素,还可以根据对象来获取元素。使用tf.Graph.as_graph_element()函数,即传入一个对象,返回一个张量或是一个OP
  • 该函数具有验证和转换功能,在多线程方面会偶尔用到。
tt3=g3.as_graph_element(a)
print(tt3)
Tensor("Const:0", shape=(1, 2), dtype=float32)

**注意:**张量本质上也是一个对象。

3.1 编程模型

  • TensorFlow的命名来源于本身的运行原理。Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算。TensorFlow是张量从图像的一端流动到另一端的计算过程,这也是TensorFlow的编程模型。
  • TensorFlow的运行机制属于“定义”与“运行”相分离。从操作层面可以抽象成两种:模型构建和模型运行。
  • 模型构建中的概念
类型 描述 用途
Session 会话 图必须在称之为“会话”的上下文中执行。会话将图的OP分发到诸如CPU或GPU上计算
Graph(计算图) 描述结算过程 必须在Session中启动
tensor(张量) 数据 数据类型之一,代表多维数组
图中的节点操作(operation,op) 操作 图中的节点称之为op,一个op获得0或者多个Tensor,执行计算,产生0或者多个Tensor
Variable(变量) 变量 数据类型之一,运行过程中可以被改变,用于维护状态,常用于定义模型中的参数
placeholder(占位符) 占位符 输入变量的载体。可理解成定义函数时的参数
feed(注入机制) 赋值 为op的Tensor赋值,通过占位符向模型中传入数据
fetch(取回机制) 取值 从op的Tensor中取值,从模型中得到结果
Constant(常量) 常量 数据类型之一,不可变
  • session将图的OP分发到如CPU或GPU之类的设备上,同时提供执行OP的方法,这些方法执行后,将产生的tensor返回。
  • 在Python语言中,返回的tensor是numpy ndarray对象。
  • 在模型中,实参就是输入的样本,形参就是占位符,运算过程就相当于函数体,得到的结果相当于返回值。

3.2 模型注入机制

使用注入机制,将具体的实参注入到相应的placeholder中。feed只在调用它的方法内有效,方法结束后feed就会消失。

import tensorflow as tf
a=tf.placeholder(tf.int16)
b=tf.placeholder(tf.int16)
add=tf.add(a,b)
mul=tf.multiply(a,b)
with tf.Session() as sess:
    print("相加:%i"% sess.run(add,feed_dict={a:3,b:4}))
    print("相乘:%i"% sess.run(mul,feed_dict={a:3,b:4}))
    #一次将多个节点取出来
    print(sess.run([mul,add],feed_dict={a:3,b:4}))
相加:7
相乘:12
[12, 7]

3.3 保存和载入模型

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#确保生成的图片插入文档中
%matplotlib inline
#定义生成loss可视化的函数
plotdata={"batchsize":[],"loss":[]}
def moving_average(a,w=10):
    if len(a)<w:
        return a[:]
    return [val if idx <w else sum(a[(idx-w):idx])/w for idx,val in enumerate(a)]
#生成模拟数据
train_X=np.linspace(-1,1,100)
train_Y=2 * train_X +np.random.randn(*train_X.shape) *0.3
#图形显示
plt.plot(train_X,train_Y,'ro',label='Original data')
plt.legend()
plt.show()

png

#创建模型
#占位符
X=tf.placeholder("float")
Y=tf.placeholder("float")
#模型参数,参数后面的name可用于保存模型时使用
W=tf.Variable(tf.random_normal([1]),name='weight')
b=tf.Variable(tf.zeros([1]),name='bias')
#前向结构
z=tf.multiply(X,W)+b
#TensorBoard可视化第一步
tf.summary.histogram('z',z)   #将预测值以直方图形式显示,给直方图命名z
<tf.Tensor 'z:0' shape=() dtype=string>
#反向优化
cost=tf.reduce_mean(tf.square(Y-z))
learning_rate=0.01
optimizer=tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)  #梯度下降

#TensorBoard可视化第一步
tf.summary.scalar('loss_function',cost)  #将损失值以标量形式显示,命名为loss_function
<tf.Tensor 'loss_function:0' shape=() dtype=string>
#初始化所有变量
init=tf.global_variables_initializer()
#定义学习参数
training_epochs=20
display_step=2
#设置模型保存的参数和路径,生成saver
saver=tf.train.Saver(max_to_keep=1)
savedir="log/"
#print("打印当前目录:",os.getcwd())
#启动图
with tf.Session() as sess:
    sess.run(init)   #先对模型初始化
    plotdata={"batchsize":[],"loss":[]}  #由于在网页中运行会多次存储,因此在这里重新初始化
    #TensorBoard可视化第二步
    merged_summary_op=tf.summary.merge_all()  #合并所有summary
    #创建summary_writer,用于写文件
    summary_writer=tf.summary.FileWriter('log/mnist_with_summaries',sess.graph)
    #向模型中输入数据
    for epoch in range(training_epochs):
        for (x,y) in zip(train_X,train_Y):
            sess.run(optimizer,feed_dict={X:x,Y:y})
            
            #TensorBoard可视化第三步——生成summary
            summary_str=sess.run(merged_summary_op,feed_dict={X:x,Y:y})
            summary_writer.add_summary(summary_str,epoch) #将summary写入文件
        #显示训练中的详细信息
        if epoch % display_step==0:
            loss=sess.run(cost,feed_dict={X:train_X,Y:train_Y})
            print("训练次数:",epoch+1,"cost=",loss,"W=",sess.run(W),"b=",sess.run(b))
            if not(loss=="NA"):
                plotdata["batchsize"].append(epoch)
                plotdata["loss"].append(loss)
            saver.save(sess,savedir+"linermodel.cpkt",global_step=epoch)
    print("Finished!")
    print("cost=",sess.run(cost,feed_dict={X:train_X,Y:train_Y}),"W=",sess.run(W),"b=",sess.run(b))
    
    #显示模型
    plt.plot(train_X,train_Y,'ro',label='Original data')
    plt.plot(train_X,sess.run(W)*train_X+sess.run(b),label='Fitted Wline')
    plt.legend()
    plt.show()
训练次数: 1 cost= 2.06425 W= [-0.17830342] b= [ 0.60749894]
训练次数: 3 cost= 0.237772 W= [ 1.3914659] b= [ 0.18420461]
训练次数: 5 cost= 0.0860665 W= [ 1.81684232] b= [ 0.02398242]
训练次数: 7 cost= 0.0751848 W= [ 1.92715943] b= [-0.01830052]
训练次数: 9 cost= 0.0742996 W= [ 1.95568919] b= [-0.02924783]
训练次数: 11 cost= 0.0741998 W= [ 1.9630661] b= [-0.03207865]
训练次数: 13 cost= 0.0741826 W= [ 1.96497369] b= [-0.03281069]
训练次数: 15 cost= 0.0741787 W= [ 1.9654671] b= [-0.03300003]
训练次数: 17 cost= 0.0741778 W= [ 1.96559441] b= [-0.03304888]
训练次数: 19 cost= 0.0741775 W= [ 1.96562755] b= [-0.03306159]
Finished!
cost= 0.0741775 W= [ 1.96563327] b= [-0.03306378]

png

plotdata["avgloss"]=moving_average(plotdata["loss"])
plt.figure(1)
plt.subplot(211)
plt.plot(plotdata["batchsize"],plotdata["avgloss"],'b--')
plt.xlabel('Minibatch number')
plt.ylabel('Loss')
plt.title('Minibatch run vs Training loss')
plt.show()

png

#重启一个session,载入检查点(通过指定迭代次数获取检查点文件)
load_epoch=18
with tf.Session() as sess2:
    sess2.run(tf.global_variables_initializer())   #先对模型初始化
    #使用restore()方法,参数可以进行初始化,也可以不进行初始化,因为即使初始化了,初始化的值也会被restore的值给覆盖
    saver.restore(sess2,savedir+"linermodel.cpkt-"+str(load_epoch))
    print("x=0.2,z=",sess2.run(z,feed_dict={X:0.2}))
INFO:tensorflow:Restoring parameters from log/linermodel.cpkt-18
x=0.2,z= [ 0.36006391]
#重启一个session,使用其他方法载入检查点(tr.train.get_checkpoint_state(ckpt_dir))
with tf.Session() as sess3:
    sess3.run(tf.global_variables_initializer())
    ckpt=tf.train.get_checkpoint_state(savedir)
    if ckpt and ckpt.model_checkpoint_path:
        saver.restore(sess3,ckpt.model_checkpoint_path)
        print("x=0.2,z=",sess3.run(z,feed_dict={X:0.2}))
INFO:tensorflow:Restoring parameters from log/linermodel.cpkt-18
x=0.2,z= [ 0.36006391]
#重启一个session,使用其他方法载入检查点(tr.train.latest_checkpoint(savedir))
with tf.Session() as sess4:
    sess4.run(tf.global_variables_initializer())
    kpt=tf.train.latest_checkpoint(savedir)
    if kpt!=None:
        saver.restore(sess4,kpt)
        print("x=0.2,z=",sess4.run(z,feed_dict={X:0.2}))
INFO:tensorflow:Restoring parameters from log/linermodel.cpkt-18
x=0.2,z= [ 0.36006391]
#查看模型内容
from tensorflow.python.tools.inspect_checkpoint import print_tensors_in_checkpoint_file
print_tensors_in_checkpoint_file(savedir+"linermodel.cpkt-18",None,True)
tensor_name:  bias
[-0.03306159]
tensor_name:  weight
[ 1.96562755]

**注意:**通过模型内容可以看到,tensor_name:后面跟的就是创建的变量名,接着就是它的数值。

猜你喜欢

转载自blog.csdn.net/peng10263/article/details/83106158