这两天一直在学习tensorfow学到迷糊了,是时候总结一下了。
记得刚来实验室的时候墙上写着上一届的一个要求还是啥,说熟练使用tensorflow语言,当时我还有一些困惑:tensorflow不就是一个框架吗,怎么独立成一个语言了。现在我理解了,tensorflow的确有很多语言特征值得深究。
首先下载tensorflow框架,可以下载cpu和gpu版本,现阶段学习的话我用的cpu版本,不过的确有很多局限性,运行很简单的程序都要很久的感觉。当然往gpu版本的过渡不过是一行代码的事情不用过度担心。
先说一些基本概念:
图
图是默认已经注册了的,他是一组表示tf.operation计算单位的对象和tf.tensor操作之间流动数据的对象
一些常用操作
API | 功能 |
---|---|
tf.get_default_graph | 获取默认图,返回graph |
tf.Graph() | 创建一张图,返回图名 |
tf.constant() | 创建一个张量 |
tf.placeholder(tf.float32, [None, 3]) | 样本不固定,特征值有三个 |
sess.run(plt, feed_dict={plt: [[1, 2, 3], [4, 5, 6], [7864, 2514, 1]]})) | placehodlder和feed_dict是结合在一块去使用的,实时的去提供数据训练 |
import tensorflow as tf
# 关闭警告,回顾的时候可以把这句删掉试试
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# 自己创建一张图,上下文环境 图是包含了一组op和tensor
# op:只要是用tensorflow的API定义的函数都是op
# 张量:tensor就指代的数据
g = tf.Graph()
# print(g)
with g.as_default(): # 相当于是一段申明内存的语句
c = tf.constant(11.0)
# print(c.graph)
# 当创建一张新的图的时候,系统就会创建一块新的空间去计算
# 实现一个加法运算
a = tf.constant(5.0) # 在tensorflow中a不叫作变量
b = tf.constant(6.0)
# print(a)
# print(b)
sum1 = tf.add(a, b)
# print(sum1)天
# 运算符重载
val1 = 2.0
sum2 = a + val1 # 这是神奇的地方,如果两个变量都是int类型是不能放到run方法里运行的,也是不能直接相加的,
# 但是如果一个变量是tensor类型就可以了
# 获取图,打印,默认的这张图相当于给程序分配内存
# graph = tf.get_default_graph()
# print(graph)
# 只能运行一个图结构,可以在绘画当中指定图去运行用graph参数,如果不指定就用默认图
# 只要有会话的上下文环境就可以使用方便的eval了
# plt=tf.placeholder(tf.float32,[2,3]) #placehloder是占位符
plt = tf.placeholder(tf.float32, [None, 3]) # 样本不固定,特征值有三个
with tf.Session(graph=g, config=tf.ConfigProto(log_device_placement=True)) as sess: # 打开会话
print(sess.run([a, b, sum1, sum2])) # 普通的python里面的类型是不能运行的,必须是tensor或者op类型的才可以
print(sess.run(plt, feed_dict={
plt: [[1, 2, 3], [4, 5, 6], [7864, 2514, 1]]})) # placehodlder和feed_dict是结合在一块去使用的,实时的去提供数据训练
# # print(c.eval()) # session就是启动子和张图,其实我的理解就是开始在这段内存运行
# print(a.graph)
# print(sum1.graph)
# print(sess.graph) # 可以看得出图的地址在一个地方
print(a.graph) # a的图
print(11111111111)
print(a.shape) # 形状
print(1111111111)
print(plt.shape)
print(11111111)
print(a.name) # 名字
print(111111111)
print(a.op) # 属性
张量
tendorflow依赖于numpy,其实张量就是numpy.array的tensor类型
张量的阶和数据类型:
tensorfolw的基本数据格式
一个类型化的N维度数组
三个部分,名字、形状、数据类型
形状的改变
在深度学习中因为要进行矩阵运算所以经常要改变数据矩阵的形状
tensor的形状分为动态形状和静态形状,他们的区别在于有没有生成一张新的张量数据。
静态形状:
创建一个张量初始状态的形状
tf.tensor tf.get_shape获取静态形状
tf.Tensor.set_shapr()更新张量对象静态形状
动态形状:
一种描述原始张量在执行过程中的一种形状
tf.reshape()创建一个不同动态形状的新张量
静态形状修改之后不能再修改形状了,如果想要修改,只能修改动态形状,具体请看demo,动态形状修改的时候元素要匹配上,也就是说原来是3*3的,修改完之后还是要是9个元素
API | 功能 |
---|---|
tf.zeros(shape,dtype=tf.float32,name=None) | 创建一个全0张量 |
tf.ones(shape,dtype=tf.float32,name=None) | 创建一个全1张量 |
tf.constant(value) | 创建一个常数张量 |
tf.random_normal(shape,mean,stddev=1.0) | 创建一个随机分布的张量 |
tf.cast(x,tf.int32) | 改变张量类型 |
tf.concat([a,b],axis=0) | a和b张量按行进行拼接 |
import tensorflow as tf
import numpy as py
import os
# 静态形状和动态形状
plt = tf.placeholder(tf.float32, [None, 2])
print(plt.shape)
plt.set_shape([3, 2]) # 现在固定了形状
print(plt.shape)
# plt.set_shape([2,2]) 这句话就报错了,对于静态形状来说,一旦形状固定之后就不能修改了
# 那么就通过动态形状来修改
plt_reshape = tf.reshape(tensor=plt, shape=[2, 3], name=None) # 动态形状改变的时候元素的数量要匹配,如果shape是[2,2]会出错
print(plt_reshape)
a = tf.cast(plt, tf.int32) # 改变张量类型
print(a.dtype)
变量
变量其实也是一种op,是一种特殊的张量。能够进行存储持久化,它的值就是张量,默认被训练
var = tf.Variable(tf.random_normal([3,3],mean=0.0))
如果想要在上下文环境中显示变量还要进行变量初始化
init_op=tf.global_varial_initializer()
在上下文环境中去run
with tf.Session() as sess:
sess.run(init_op)
sess.run(var)
import tensorflow as tf
import pandas as pd
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# 变量op
a = tf.constant([1, 2, 3, 4, 5])
var = tf.Variable(tf.random_normal([3, 3], mean=0.0, stddev=1.0))
print(a, var)
# 必须做一步显示的初始化
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
# 必须运行初始化op
sess.run(init_op)
print(sess.run([a, var]))
模型的保存于加载
以tensorflow实现线性回归为例
模型的保存:tf.train.Saver(var_list=None,max_to_keep=5),var_list是将要保存于加载的会话,它作为一个dict或者一个列表传递。
max_to_keep:保存要保留的的最近检查点的最大数量
import tensorflow as tf
import os
# 添加权重参数,损失值等变量值的变化
def myregression():
"""
自实现一个线性回归预测
:return: None
"""
with tf.variable_scope("data"): # bian
# 准备数据
x = tf.random_normal([100, 1], mean=1.75, stddev=0.5, name="x_data")
# 矩阵相乘必须是二维的
y_true = tf.matmul(x, [[0.7]]) + 0.8
with tf.variable_scope("model"):
# 建立线性回归模型 1个特征一个权重 一个偏置y=wx+b
# 随机初始化,随机给一个权重和偏执的值,让他计算损失,在当前状态下优化
weight = tf.Variable(tf.random_normal([1, 1], mean=0.0, stddev=1.0), name="w")
# 用变量定义才能优化
bias = tf.Variable(0.0, name="b")
# 初始的计算
y_perdict = tf.matmul(x, weight) + bias
with tf.variable_scope("loss"):
# 建立损失函数,损失是均方误差
loss = tf.reduce_mean(tf.square(y_true - y_perdict))
with tf.variable_scope("optimizer"):
# 梯度下降优化损失,去不用的学习率对结果有影响,刚设置成1.0,后果很可怕,偏差很大
train_op = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(loss)
# 收集tensor
tf.summary.scalar("loss", loss)
#tf.summary.scalar("weight", weight)
# 合并变量写入事件文件
merge = tf.summary.merge_all()
# 定义一个初始化变量的op
init_op = tf.global_variables_initializer()
#定义一个保存模型的实例
saver=tf.train.Saver()
# 通过会话运行程序
with tf.Session() as sess:
# 初始化变量
sess.run(init_op)
# 打印最先随机初始化的值
print("随机初始化的参数权重为:%f ,偏执为:%f" % (weight.eval(), bias.eval()))
# 建立事件文件
file_wirte = tf.summary.FileWriter("./txt", graph=sess.graph)
# 加载模型,覆盖模型中随机 定义的参数,从上次训练的参数结果开始
if os.path.exists("./temp/model"):
saver.restore(sess, "./temp/model")
# 循环训练优化
# 运行优化op
for i in range(100):
sess.run(train_op)
# 运行合并的tensor
summary = sess.run(merge)
file_wirte.add_summary(summary, i)
print("第%d次参数权重为:%f ,偏执为:%f" % (i, weight.eval(), bias.eval()))
saver.save(sess,"./tmp/model")
return None
if __name__ == '__main__':
myregression()
authoe: specyue@mail.ustc.edu.cn 欢迎交流