去哪里学习做网站,网页游戏排行榜人物漂亮,asp access网站架设教程,网页开发的基本过程前言
上一篇博客初步了解了tensorflow中建立机器学习模型的方法#xff1a;可以使用eager execution和graph execution两种模式#xff0c;可以使用高级API estimator中已经封装好的模型#xff0c;也可以自己创建estimator#xff0c;更重要的是我们也可以使用低级API自行…前言
上一篇博客初步了解了tensorflow中建立机器学习模型的方法可以使用eager execution和graph execution两种模式可以使用高级API estimator中已经封装好的模型也可以自己创建estimator更重要的是我们也可以使用低级API自行设计模型。这里重点研究研究如何使用低级API
主要内容包含
张量、变量构建计算图及其运行可视化
国际惯例参考博客
tensorflow官方教程
Jupyter Notebooks里的TensorFlow图可视化
张量
**概念**张量是对矢量和矩阵向潜在的更高维度的泛化也就是说将一维二维扩展到N维。
**特点**数据类型和形状(维度)
创建张量 tf.Variable tf.Variable(initial-value, nameoptional-name)#初始值和名称tf.constant tf.constant(value,#初始值dtypeNone,#数据类型shapeNone,#大小nameConst,verify_shapeFalse
)tf.placeholder tf.placeholder(dtype,#类型shapeNone,#大小nameNone
)tf.SparseTensor SparseTensor(indices, values, dense_shape)indices是一个二维整型矩阵[N,ndims][N,ndims][N,ndims]指定了稀疏张量中非零元素的索引 values是一维向量[N][N][N]指定了indices所指定的非零向量的值 dense_shape一维向量[ndims][ndims][ndims]指定了稀疏矩阵的维度
实例
#0阶变量标量
mammal tf.Variable(Elephant, tf.string)
ignition tf.Variable(451, tf.int16)
floating tf.Variable(3.14159265359, tf.float64)
its_complicated tf.Variable(12.3 - 4.85j, tf.complex64)
#1阶变量向量
mystr tf.Variable([Hello], tf.string)
cool_numbers tf.Variable([3.14159, 2.71828], tf.float32)
first_primes tf.Variable([2, 3, 5, 7, 11], tf.int32)
its_very_complicated tf.Variable([12.3 - 4.85j, 7.5 - 6.23j], tf.complex64)
#二阶变量矩阵
mymat tf.Variable([[7],[11]], tf.int16)
myxor tf.Variable([[False, True],[True, False]], tf.bool)
linear_squares tf.Variable([[4], [9], [16], [25]], tf.int32)
squarish_squares tf.Variable([ [4, 9], [16, 25] ], tf.int32)
rank_of_squares tf.rank(squarish_squares)
mymatC tf.Variable([[7],[11]], tf.int32)
#更高阶n维矩阵
my_image tf.zeros([10, 299, 299, 3]) # 批 x 高 x 宽 x 通道张量切片 对于0阶张量(标量)无需索引因为它本身就是一个数字 对于1阶张量(向量)通过单一索引访问 atf.constant([0.1,0.5,0.12,0.6,0.7])
sesstf.Session()
print(sess.run(a[2]))#0.12对于2阶张量(矩阵)两个索引返回标量一个索引返回向量 atf.constant([[0.5,0.6,0.3,0.7],[1,6,7,2]])
print(sess.run(a[1,3]))#2.0
print(sess.run(a[1]))#[1. 6. 7. 2.]
print(sess.run(a[:,1]))#[0.6 6. ]
print(sess.run(a[1,:]))#[1. 6. 7. 2.]获取张量的秩和维度
这里秩和数学上的秩不同这个秩指的是多少维
print(sess.run(tf.rank(a)))#2
print(a.shape)#(2,4)张量形状的改变
在保证元素个数相同的情况下改变张量维度其实跟reshape一样
rank_three_tensor tf.ones([3,4,5])
matrix tf.reshape(rank_three_tensor, [6, 10])
matrixB tf.reshape(matrix, [3, -1])
matrixAlt tf.reshape(matrixB, [4, 3, -1])
# 一定要保证改变维度前后矩阵的元素个数相同
#yet_another tf.reshape(matrixAlt, [13, 2, -1])#出错
print(matrix.shape)#(6, 10)
print(matrixB.shape)#(3, 20)
print(matrixAlt.shape)#(4, 3, 5)张量数据类型的改变
强制类型转换主要使用tf.cast函数
float_tensor tf.cast(tf.constant([1, 2, 3]), dtypetf.float32)张量取值
直接调用eval()方法注意必须在Session启动的时候调用
atf.constant([1,2,3,7])
#print(a.eval())#出错
with tf.Session() as sess:print(a.eval())#[1 2 3 7]但是有时候也无法取值比如变量存在容器placeholder中的时候
btf.placeholder(tf.float32)
with tf.Session() as sess:print(b.eval())#报错print(b.eval(feed_dict{b:3.0}))#3.0有时候最好还是记一下报错内容便于后期调试
InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor Placeholder_2 with dtype float张量赋值
使用上一节提到过的assign方法但是注意要初始化以及赋值要在session中执行。
htf.Variable(10,nameh)
inittf.initialize_all_variables()
with tf.Session() as sess:sess.run(init)print(h.eval()) #10assign_optf.assign(h,5)sess.run(assign_op)print(h.eval()) #5变量
在官方文档中虽然介绍了使用tf.Variable创建变量但是又介绍了另一种方法tf.get_variable从名字上看像是获取变量这就是它的优势所在既能创建变量还能检测变量是否已经创建如果创建过就可以重复使用。看一下两种方法的调用方式
#variable创建方式
tf.Variable(initial-value, nameoptional-name)
#get_variable创建方式
tf.get_variable(name,shapeNone,dtypeNone,initializerNone,regularizerNone,trainableTrue,collectionsNone,caching_deviceNone,partitionerNone,validate_shapeTrue,use_resourceNone,custom_getterNone,constraintNone
)很明显的区别是tf.Variable需要指定初始值但是名字是选填而tf.get_variable无需指定初始值因为它有自己的初始器initializer但是名字是必填的因为涉及到重用问题
##变量创建
使用get_variable定义变量时必须指定变量名称其它副本将使用此名称访问同一变量
#创建名为my_variable的变量大小为[1,2,3]值将通过glorot_uniform_initializer随机赋值
my_variabletf.get_variable(my_vairable,[1,2,3])
#也可以指定类型和初始化方法
my_int_variable tf.get_variable(my_int_variable, [1, 2, 3], dtypetf.int32,initializertf.zeros_initializer)
#也可以用constant赋值此时无需指定形状
other_variable tf.get_variable(other_variable, dtypetf.int32,initializertf.constant([23, 42]))##变量集合
便于以一种方式访问所有变量默认情况下有两种集合
tf.GraphKeys.GLOBAL_VARIABLES可以在多台设备间共享变量tf.GraphKeys.TRAINABLE_VARIABLES将计算梯度的变量
如果不希望变量可训练就放到tf.GraphKeys.LOCAL_VARIABLES中或者指定trainableFalse
my_localtf.get_variable(my_local,shape(),collections[tf.GraphKeys.LOCAL_VARIABLES])
my_non_trainabletf.get_variable(my_none_trainable,shape(),trainableFalse)这是在创建的时候丢进去也可以先创建一个属于自己的集合然后挨个加
tf.add_to_collection(my_collection_name,my_local)
tf.add_to_collection(my_collection_name,my_non_trainable)
tf.get_collection(my_collection_name)[tf.Variable my_local:0 shape() dtypefloat32_ref,tf.Variable my_none_trainable:0 shape() dtypefloat32_ref]##变量初始化
变量初始化作用在于允许你从检查点加载模型的时候无需重新运行潜在资源消耗大的初始化器并允许在分布式设置中共享随机初始化的变量时具有确定性。可以选择一次性初始化或者是单独初始化 如需一次性初始化所有可训练变量调用tf.global_variables_initializer()函数返回一个操作负责初始化tf.GraphKeys.GLOCAL_VARIABLES集合中所有变量 session.run(tf.global_variables_initializer())如果需要自行初始化变量可以使用 session.run(my_variable.initializer)可以查询到哪些变量未初始化
print(session.run(tf.report_uninitialized_variables()))需要注意的一点是tf.global_variables_initializer不会指定变量的初始化顺序因此如果变量的初始值取决于另一变量的值那么很有可能会出现错误。如果在初始化某个变量时使用了另一个变量值最好使用variable.initialized_value()而非variable:
v tf.get_variable(v, shape(), initializertf.zeros_initializer())
w tf.get_variable(w, initializerv.initialized_value() 1)##变量使用
当成常规变量使用就行了可以使用assign、assign_add等方法
import tensorflow as tf
v tf.get_variable(v, shape(), initializertf.zeros_initializer())
assignment v.assign_add(1)
sesstf.Session()
sess.run(tf.global_variables_initializer())
sess.run(assignment) #1.0在某个事件发生后强制读取某个变量的值
with tf.control_dependencies([assignment]):wv.read_value()
sess.run(w)此程序每运行一次www的值就加1看样子这个tf.control_dependcies是强制运行所指定语句依据执行结果进入内部操作这个可以看上一篇博客的Assert条件语句部分。
##共享变量
终于还是到这里了在theano中是直接使用theano.shared创建共享变量。为了理解tensorflow中的共享变量使用方法直接看官网的实例
编写一个函数创建卷积/relu层
def conv_relu(input,kernel_shape,bias_shape):#创建权重weightstf.get_variable(weights,kernel_shape,initializertf.random_normal_initializer())#创建偏置biasestf.get_variable(biases,bias_shape,initializertf.constant_initializer(0.0))convtf.nn.conv2d(input,weights,strides[1,1,1,1],paddingSAME)return tf.nn.relu(convbiases)如果在多次卷积操作中如果多次调用次函数就会出现不清晰的操作因为第一次执行此函数的时候已经创建了权重和偏置那么下一次是重复利用还是创建新变量呢这就导致程序报错
input1 tf.random_normal([1,10,10,32])
input2 tf.random_normal([1,20,20,32])
x conv_relu(input1, kernel_shape[5, 5, 32, 32], bias_shape[32])
x conv_relu(x, kernel_shape[5, 5, 32, 32], bias_shape [32]) # This fails.错误内容
ValueError: Variable weights already exists, disallowed. Did you mean to set reuseTrue or reusetf.AUTO_REUSE in VarScope? Originally defined at:如果是想创建新变量可以为每个操作添加不同的作用域
def my_image_filter(input_images):with tf.variable_scope(conv1):#conv1/weights, conv1/biasesrelu1conv_relu(input_images,[5,5,32,32],[32])with tf.variable_scope(conv2):#conv2/weights, conv2/biasesreturn conv_relu(relu1,[5,5,32,32],[32])如果是共享变量有两种方法一种是resuseTrue创建相同名称的作用域
#第一种写法
with tf.variable_scope(model):output1my_image_filter(input1)
with tf.variable_scope(model,reuseTrue):output2my_image_filter(input2)
#第二种写法
with tf.variable_scope(model) as scope:output1my_image_filter(input1)
with tf.variable_scope(scope,reuseTrue):output2my_image_filter(input2)或者直接调用scope.reuse_variables()触发重用
with tf.variable_scope(model) as scope:output1my_image_filter(input1)scope.reuse_variables()output2my_image_filter(input2)计算图的构建与运行
tf.Graph包含两类信息
图结构包括节点和边缘表示各个操作组合在一起图集合在图中存储元数据集合的通用机制。与变量集合用到的方法一样tf.add_to_collection
构建图的时候通过tf.Operation构建图节点tf.Tensor构建图边缘
运行图的时候用tf.Session即可
x tf.constant([[37.0, -23.0], [1.0, 4.0]])
w tf.Variable(tf.random_uniform([2, 2]))
y tf.matmul(x, w)
output tf.nn.softmax(y)
init_op w.initializerwith tf.Session() as sess:sess.run(init_op)print(sess.run(output))y_val, output_val sess.run([y, output])比较方便的一点是tf.Session.run支持喂数据在执行时使用Feed字典替换张量值
x tf.placeholder(tf.float32, shape[3])
y tf.square(x)
with tf.Session() as sess:print(sess.run(y, {x: [1.0, 2.0, 3.0]})) # [1.0, 4.0, 9.0]print(sess.run(y, {x: [0.0, 0.0, 5.0]})) # [0.0, 0.0, 25.0]sess.run(y)#报错必须喂数据sess.run(y, {x: 37.0})其实还可以多个图进行编程但是为了便于消化先不做了解了做个备注以后戳这里学习
图的可视化
使用graphviz可视化
创建一个函数接收的是tensorflow创建的图模型然后分别将节点和边存储到dot中
def tf_to_dot(graph):dotDigraph()for n in g.as_graph_def().node:dot.node(n.name,labelsn.name)for i in n.input:dot.edge(i,n.name)return dot添加一个实例调用上面的函数
gtf.Graph()
with g.as_default():Xtf.placeholder(tf.float32,nameX)W1tf.placeholder(tf.float32,nameW1)b1tf.placeholder(tf.float32,nameb1) a1tf.nn.relu(tf.matmul(X,W1)b1)W2tf.placeholder(tf.float32,nameW2)b2tf.placeholder(tf.float32,nameb2)a2tf.nn.relu(tf.matmul(a1,W2)b2)W3tf.placeholder(tf.float32,nameW3)b3tf.placeholder(tf.float32,nameb3)y_hattf.matmul(a2,W3)b3
tf_to_dot(g)结果 使用tensorboard可视化
只需要将第一种方法的可视化算法换成如下即可
import tensorflow as tf
gtf.Graph()
with g.as_default():Xtf.placeholder(tf.float32,nameX)W1tf.placeholder(tf.float32,nameW1)b1tf.placeholder(tf.float32,nameb1) a1tf.nn.relu(tf.matmul(X,W1)b1)W2tf.placeholder(tf.float32,nameW2)b2tf.placeholder(tf.float32,nameb2)a2tf.nn.relu(tf.matmul(a1,W2)b2)W3tf.placeholder(tf.float32,nameW3)b3tf.placeholder(tf.float32,nameb3)y_hattf.matmul(a2,W3)b3tf.summary.FileWriter(logs,g).close()#换成这个检查一下logs文件夹中是否有events文件最后我们就可以去logs的上级目录打开cmd窗口输入
tensorboard --logdirlogs赋值网址在浏览器中打开便可以看到模型 有时候网络结构太大了我们可以把每层的具体运算用scope封装起来命个名比如第一层第二层啥的
import tensorflow as tf
gtf.Graph()
with g.as_default():Xtf.placeholder(tf.float32,nameX)with tf.name_scope(Layer1):W1tf.placeholder(tf.float32,nameW1)b1tf.placeholder(tf.float32,nameb1) a1tf.nn.relu(tf.matmul(X,W1)b1)with tf.name_scope(Layer2):W2tf.placeholder(tf.float32,nameW2)b2tf.placeholder(tf.float32,nameb2)a2tf.nn.relu(tf.matmul(a1,W2)b2)with tf.name_scope(Layer3):W3tf.placeholder(tf.float32,nameW3)b3tf.placeholder(tf.float32,nameb3)y_hattf.matmul(a2,W3)b3tf.summary.FileWriter(logs,g).close()重复上述操作粘贴网址到浏览器得到 #后记
这篇博客感觉学的有点杂乱打算大体印象还是重复学习和进一步探索了变量的操作、运算图的构建和Session运行最有用的是学了tensorboard可视化网络结构而且很容易就是一句话tf.summary.FileWriter(logs,g).close()即可。
还有关于使用GPU和TPU的相关内容没看感觉初步入门的话先把运算搞清楚再说内存什么的以后遇到问题再折腾有兴趣的可以去官网看看下面有链接这部分内容主要包含
变量的设备放置方式如果不小心将变量放在工作器而不是参数服务器上可能会严重减慢训练速度最坏的情况下可能会让每个工作器不断复制各个变量。运算或张量的设备分配自动分配手动分配多GPU