前面说了那么多都是理论的东西,太空洞了。从今天开始就着手编程了,并在编程的过程中,会对前面提到的理论一一的实现一遍,以加深对理论的理解,闲话少说,这就开始。
1.Tensorflow编程模型
关键要素:
1.图:它包含训练模型的参数、语句、操作,它是Tensorflow 的核心,例如:上面提到的WX + B 就是放到图中的,图是运行到内存中的,所以在运行的过程中是特别的吃内存的。
2.张量:在线性代数中叫向量,在程序中一般叫多维数组,也就是上个文档中提到的样本(X)和标签(Y),在tensorflow 中使用placeholder表示方式。
3.OP:全称,operate。做的就是把输入的张量组合按WX + B起来。
4.Variable:W、B就是Variable的表现形式之一。
图的执行流程就是:张量 (输入) -> op (组合成 W*X + B) -> 运算资源(CPU/GPU)-> 输出结果,而整个图则是要放到session中运行的,也就是只有运行了session,图才能运行。
2.Tensorflow编程示例
示例1:
import tensorflow as tf
hello = tf.constant("Hello Tensorflow!") #定义一个常量
sess = tf.Session() #建立一个Session()
print(sess.run(hello)) #通过Session中的run来运行结果
sess.close() #关闭Session()
运行结果:
图2
注意:1.constant() 是定义一个常量。2.Session创建了以后需要关闭,不然会造成内存泄漏。
示例2
a = tf.constant(3) #定义一个常量3
b = tf.constant(4) #定义一个常量4
with tf.Session() as sess: #建立Session
print("相加:%i" % sess.run(a+b)) #运行a+b 也就是上面提到的OP
print("相乘:%i" % sess.run(a*b))
运行结果:
图3
注意:1.使用with创建的Session() ,是不需要调用sess.close()的,它会在使用完了自动的调用close(),释放掉内存。
示例3
c = tf.placeholder(tf.int16)
d = tf.placeholder(tf.int16)
add = tf.add(c, d)
mul = tf.multiply(c, d)
with tf.Session() as sess2:
print("相加:%i" % sess2.run(add, feed_dict={c: 3, d: 4}))
print("相乘:%i" % sess2.run(mul, feed_dict={c: 3, d: 4}))
print(sess2.run([add, mul], feed_dict={c: 3, d: 4}))
运行结果:
图4
注意:1.这是使用placeholder注入的方式声明变量。
3.Tensorflow 变量的操作
1.variable 和 get_variable 的区别
使用tf.Variable时,如果检测到命名冲突,系统会自己处理。使用tf.get_variable()时,系统不会处理冲突,而会报错。但是,Variable 与get_variable 首次重名可以自动生成。本质就是:tf.Variable() 每次都在创建新对象,而tf.get_variable则不是。
with tf.Session() as sess2:
var1 = tf.Variable(1, name="var1")
var2 = tf.Variable(2, name="var1")
sess2.run(tf.global_variables_initializer())
print(var1.name)
print(var1.eval())
print(var2.name)
print(var2.eval())
print(var1 is var2)
#输出
var1:0
1
var1_1:0
2
False
get_var1 = tf.get_variable(name="var1", initializer=1)
print(get_var1.name)
get_var2 = tf.get_variable(name="var1", initializer=2)
print(get_var2.name)
#输出
var1_2:0
#错误信息
#ValueError: Variable w_1 already exists, disallowed. Did
#you mean to set reuse=True in VarScope?
2.variable_scope 与共享变量
加上作用域以后get_variable可以定义同样的变量名称,系统会自动的生成加作用域的变量。如果在作用域声明的过程中,加入reuse=True,表示可以重复使用,定义了共享部分,如果已经创建的变量对象,就把那个对象返回。
with tf.variable_scope("test1", ""):
var1 = tf.get_variable(name="var1", shape=[2],dtype=float) #定义1行2列的var1变量
with tf.variable_scope("test2"):
var2 = tf.get_variable(name="var1",shape=[2],dtype=float)
print(var1.name)
print(var2.name)
#输出
test1/var1:0
test1/test2/var1:0
with tf.variable_scope("test1", reuse=True):
var3 = tf.get_variable(name="var1", shape=[2], dtype=float)
with tf.variable_scope("test2"):
var4 = tf.get_variable(name="var1", shape=[2], dtype=float)
print(var3.name)
print(var4.name)
#输出
test1/var1:0
test1/test2/var1:0
3.variable_scope 与name_scope的区别
variable_scope :是作用域,
name_scope:是操作符,针对上面提到的OP。如:下面的x = var2 + 0.1,就是一个操作。
示例:
with tf.variable_scope("scope3"):
var1 = tf.get_variable("var1", [1])
with tf.name_scope("scope_name"): # 针对操作而言的
var2 = tf.get_variable("var2", [1])
x = var2 + 0.1
with tf.variable_scope(""):
with tf.name_scope(""):
var3 = tf.get_variable("var3", [1])
y = var2 + 0.2
print(var1.name)
print(var2.name)
print(x.op.name)
print(var3.name)
print(y.op.name)
# 输出
scope3/var1:0
scope3/var2:0
scope3/scope_name/add
scope3//var3:0
add_2
注意:
1.如果tf.name_scope(""),则提到顶层。
2.tf.variable_scope(""),则相当于增加了“”的域。
3.name_scope对变量的作用域variable_scope是没有任何影响的,但是variable_scope对name_scope是有影响的。
3.Tensorflow 图的操作
1.建立图
import tensorflow as tf
# 定义在全局默认图上的常量
c = tf.constant(0.0)
# 重新的定义一个图
g = tf.Graph()
with g.as_default():
c1 = tf.constant(0.0)
# 获取c1所在的图的地址
print(c1.graph)
# 获取创建图的地址
print(g)
# 获取c所在图的地址,也就是全局图的地址
print(c.graph)
# 获取全局图的地址
g2 = tf.get_default_graph()
print(g2)
# 重新生成全局图,并把旧的图销毁
tf.reset_default_graph()
# 获取全局图的地址
g3 = tf.get_default_graph()
print("g3:", g3)
#输出
<tensorflow.python.framework.ops.Graph object at 0x000001CD50C4AB70>
<tensorflow.python.framework.ops.Graph object at 0x000001CD50C4AB70>
<tensorflow.python.framework.ops.Graph object at 0x000001CD4BDA9EF0>
<tensorflow.python.framework.ops.Graph object at 0x000001CD4BDA9EF0>
g3: <tensorflow.python.framework.ops.Graph object at 0x000001CD50C4AE10>
注意:
1.如果在局部图的作用域中获取全局的默认图是不成功的,它只能得到局部的图。
2.重新设置全局图的方法tf.reset_default_graph()
with g.as_default():
c1 = tf.constant(0.0)
print(c1.graph)
print(g)
print(c.graph)
g3 = tf.get_default_graph()
print(g3)
# 输出
<tensorflow.python.framework.ops.Graph object at 0x000002138838BCF8>
<tensorflow.python.framework.ops.Graph object at 0x000002138838BCF8>
<tensorflow.python.framework.ops.Graph object at 0x00000213FF0CB0B8>
<tensorflow.python.framework.ops.Graph object at 0x000002138838BCF8>
2.获取张量
print(c1.name)
# 通过名字,使用所在的图获取张量
t = g.get_tensor_by_name(name="Const:0")
# 打印张量的属性
print(t)
#输出
Const:0
Tensor("Const:0", shape=(), dtype=float32)
3.获取节点操作OP
# 定义一行两列的数组
a = tf.constant([[1.0, 2.0]])
print(a.shape)
# 定义两行一列的数组
b = tf.constant([[1.0], [2.0]])
print(b.shape)
# 定义矩阵的乘法,操作的名字为:exampleop
tensor1 = tf.matmul(a, b, name="exampleop")
# 打印张量的名字、属性
print(tensor1.name, tensor1)
# 打印张量的名字、属性
test = g3.get_tensor_by_name("exampleop:0")
# 打印张量的属性
print(test)
# 输出
(1, 2)
(2, 1)
exampleop:0 Tensor("exampleop:0", shape=(1, 1), dtype=float32)
Tensor("exampleop:0", shape=(1, 1), dtype=float32)
print("获取操作的属性")
print('tensor1.op.name', tensor1.op.name)
# 通过名称使用所在的图得到操作OP的属性
testop = g3.get_operation_by_name("exampleop")
# 打印操作OP的属性
print(testop)
# 输出
tensor1.op.name 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
}
}
4.获取元素列表
# 返回图中的操作节点列表
tt2 = g.get_operations()
print(tt2)
# 输出 由上面可以看出在g图中只有c1 定义
[<tf.Operation 'Const' type=Const>]
5.获取对象
print("获取对象")
tt3 = g.as_graph_element(c1)
print(tt3)
# 输出
Tensor("Const:0", shape=(), dtype=float32)
4.深度学习训练模型简介
深度学习的基本开发流程为:
1.准备数据
2.搭建模型
3.训练模型
4.保存模型
5.测试模型
6.查看模型
下面以线性回归拟合为例(Y=2X)说明:
说明:1.numpy .random.randn(d0,d1,…,dn):randn函数返回一个或一组样本,具有标准正态分布 ,dn表格每个维度。2.tf.random.normal([1]):从正太分布中随机输出一个值。3.tf.zeros([1]):创建一个所有元素都设置为零的张量,例如:tf.zeros([2]) ,其中的值就是[0. 0.]。
import tensorflow as tf
# 生成数据时使用
import numpy as np
# 图形化生成数据
import matplotlib.pyplot as plt
# 生成字典记录训练批次和loss值
plotdata = {"batchsize": [], "loss": []}
# 1.准备数据
t_X = np.linspace(-1, 1, 100)
t_Y = 2 * t_X + np.random.randn(100) * 0.3
# 显示模拟数据
plt.plot(t_X, t_Y, "ro", label="original data")
plt.legend()
plt.show()
# 重新初始化图
tf.reset_default_graph();
# 2.搭建模型
# 占位符
X = tf.placeholder("float")
Y = tf.placeholder("float")
# 2.1模型参数
W = tf.Variable(tf.random.normal([1]), name="weight")
b = tf.Variable(tf.zeros([1]), name="bias")
# 2.2向前结构
z = tf.multiply(X, W) + b
# 2.3反向优化(均方差)
cost = tf.reduce_mean(tf.square(Y-z))
learning_rate = 0.01
# 2.4使用tf的梯度下降优化器设定的学利率不断优化W和b使的loss最小化,最终使z于Y的误差最小
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
# 3.训练模型
# 3.1初始化变量
init = tf.global_variables_initializer()
# 3.2训练参数
training_epochs = 20
display_step = 2
# 4.保存模型
saver = tf.train.Saver()
savedir = "Model/"
# 3.4启动Session
with tf.Session() as sess:
sess.run(init)
for epoch in range(training_epochs):
for (x, y) in zip(t_X, t_Y):
sess.run(optimizer, feed_dict={X: x, Y: y})
# 显示训练中详细信息
if epoch % display_step == 0:
loss = sess.run(cost, feed_dict={X: t_X, Y: t_Y})
print("测试cost:", cost)
print("测试loss:", loss)
print("Epoch:", epoch+1, "loss=", loss, "W=", sess.run(W), "b=", sess.run(b))
if not (loss == "NA"):
plotdata["batchsize"].append(epoch)
plotdata["loss"].append(loss)
print(" Finsohed!")
print("loss=", sess.run(cost, feed_dict={X: t_X, Y: t_Y}), "")
# 4-1保存模型
saver.save(sess, savedir+"linermodel.cpkt")
# 图形显示
plt.plot(t_X, t_Y, "go", label="original data")
plt.plot(t_X, sess.run(W)*t_X+sess.run(b), label="Fitted")
plt.legend()
plt.show()
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)]
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()
# 5.测试模型-1
print("方式1:", "x= 0.2,z=", sess.run(z, feed_dict={X: 0.2}))
# 测试模型-2
with tf.Session() as sess2:
# 从新初始一下变量
sess2.run(tf.global_variables_initializer())
saver.restore(sess2, savedir+"linermodel.cpkt")
print("方式2:", "x= 0.2,z=", sess2.run(z, feed_dict={X: 0.2}))
# 输出
方式1: x= 0.2,z= [0.41271693]
方式2: x= 0.2,z= [0.41271693]
图5
图6
图7
查看模型:
import tensorflow as tf
# 从tensorflow.python.tools.inspect_checkpoint 引入 方法 print_tensors_in_checkpoint_file
from tensorflow.python.tools.inspect_checkpoint import print_tensors_in_checkpoint_file
savedir = "Model/"
# 打印参数
print_tensors_in_checkpoint_file(savedir + "linermodel.cpkt",, tensor_name=None, all_tensors=True)
从新的修改参数:
import tensorflow as tf
# 从tensorflow.python.tools.inspect_checkpoint 引入 方法 print_tensors_in_checkpoint_file
from tensorflow.python.tools.inspect_checkpoint import print_tensors_in_checkpoint_file
savedir = "Model/"
# 修改参数
W = tf.Variable(1.0, name="weight")
b = tf.Variable(2.0, name="bias")
saver = tf.train.Saver({'weight': b, 'bias': W})
with tf.Session() as see:
# 调用方式和以前的不一样
tf.global_variables_initializer().run()
# 保存参数
saver.save(see, savedir + "linermodel.cpkt")
# 打印参数
print_tensors_in_checkpoint_file(savedir + "linermodel.cpkt", , tensor_name=None, all_tensors=True)
保存模型注意:
1.保存模型。由于训练的时间较长,且对内存要求过高,所以在训练的过程中,难免会出现异常,那么怎么样才能,不用多次重复的训练了呢。解决的最简单的办法就是训练几轮后对训练的结果进行保存,所以上面的演示代码是有问题的。修改的结果如下:
# 每次保存一次的检测点
saver = tf.train.Saver(max_to_keep=1)
savedir = "Model/"
if not (loss == "NA"):
plotdata["batchsize"].append(epoch)
plotdata["loss"].append(loss)
# 加上保存的第几次循环
saver.save(sess, savedir + "linermodel.cpkt", global_step=epoch)
2.使用模型的其他方式
with tf.Session() as sess2:
# 从新初始一下变量
sess2.run(tf.global_variables_initializer())
saver.restore(sess2, savedir+"linermodel.cpkt")
print("方式2:", "x= 0.2,z=", sess2.run(z, feed_dict={X: 0.2}))
with tf.Session() as sess3:
sess3.run(tf.global_variables_initializer())
ckpt = tf.train.get_checkpoint_state(savedir)
# 判断ckpt 存在
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess3, ckpt.model_checkpoint_path)
print("方式3:", "x= 0.2,z=", sess3.run(z, feed_dict={X: 0.2}))
with tf.Session() as sess4:
sess4.run(tf.global_variables_initializer())
# 检测最后一个文件
ckpt = tf.train.latest_checkpoint(savedir)
if ckpt != None:
saver.restore(sess4, ckpt)
print("方式4:", "x= 0.2,z=", sess4.run(z, feed_dict={X: 0.2}))
网友评论