Tensorflow使用记录

2 篇文章 0 订阅
1 篇文章 0 订阅

这个文档作为日常我使用tensorflow的一些小笔记。

学习资源

莫凡的python教学视频

使用tensorboard进行网络结构可视化

sess = tf.Session()
writer = tf.summary.FileWriter("logs/", sess.graph)  
writer.close()

在logs的上一个目录打开powershell,运行:
tensorboard --logdir=logs --host=0.0.0.0
这样就可以在浏览器中打开0.0.0.0进行网络结构的查看了。–host也可以不加,我的chrome浏览器用不了默认的地址,所以这样解决了。
如果shell端显示了地址但是浏览器打不开,就换一个地址,经测试这个比较容易打开:
tensorboard --logdir=logs --host=127.0.0.1

tensor flow中的name_scope的理解与使用:

程序的运行过程中,可能训练集与测试集会稍微改一下(不重要的)参数,那么又希望测试集能复用训练集的模型参数,就可以使用reuse方法,这与name_scope紧密相关。
看这段代码,取自GANs网络的一部分。

with tf.variable_scope('discriminator'):
    
	# 对抗网络将真实数据与生成数据进行鉴别,这里需要复用其参数
    D_00 = tf.layers.dense(input, 256, tf.nn.elu,name = 'latent')
    D_01 =  tf.layers.dense(D_00, 128, tf.nn.elu,name = 'latent_1')
    D_02 =  tf.layers.dense(D_01, 64, tf.nn.elu,name = 'latent_2')
    prob_real = tf.layers.dense(D_02, 1, tf.nn.sigmoid, name = 'out')
    
    # reuse the layers for generator
    D_l1 = tf.layers.dense(gen,256,tf.nn.elu,name='latent',reuse=True) #gen为生成的数据,D_l1与D_00名字相同,并在同一个name_scope下reuse,那么D_l1与D_l0完全相同
    D_l2 = tf.layers.dense(D_l1,128,tf.nn.elu,name='latent_1',reuse=True)
    D_l3 = tf.layers.dense(D_l2,64,tf.nn.elu,name='latent_2',reuse=True)
    prob_false = tf.layers.dense(D_l3,1,tf.nn.sigmoid,name= 'out', reuse = True)
#注,可以通过 var.name()打印查看变量的名字

LSTM的使用

看例子,单层lstm网络

rnn_cell = tf.contrib.rnn.BasicLSTMCell(num_units=batch_size)
# 
outputs, final_state = tf.nn.dynamic_rnn(
        cell = rnn_cell,  # 选择传入的cell
        inputs = image,   # 传入的数据,维度为[time_step, input_size]
        initial_state = None, #初始化状态
        dtype = tf.float32, #数据类型
        time_major = False,
        )
output = tf.layers.dense(inputs=outputs[:, -1, :], units=n_classes, activation=tf.nn.sigmoid)   # 取最后一个step的数据

output输出的纬度为[batch_size, time_step, num_units]。
也就是说它为最后一层(如果为多层神经网络)一个step的输出结果。我们想拿它输出的最后一个step的数据,就通过output[:,-1,:]的方式。
而state是每一次最后那个step的输出,那么其维度为[batch_size, num_units]。

MultiRNNCell

看下面这个例子

# 写法一
# cell = tf.nn.rnn_cell.BasicLSTMCell(hidden_size, forget_bias=0.0, state_is_tuple=True)
# cell2 = tf.nn.rnn_cell.BasicLSTMCell(hidden_size2, forget_bias=0.0, state_is_tuple=True)
# mlstm_rnn = tf.contrib.rnn.MultiRNNCell([cell,cell2], state_is_tuple=True)
#写法二
# 为了简便,导入rnn.
from tensorflow.contrib import rnn
mber_units = [128,64,128] #例如我要堆叠三层的lstm网络
rnn_cell = [rnn.BasicLSTMCell(num_units=n) for n in number_units]
mlstm_rnn = rnn.MultiRNNCell(rnn_cell)
#
outputs, final_state = tf.nn.dynamic_rnn(
        cell = mlstm_rnn,  # 选择传入的cell
        inputs = image,   # 传入的数据
        initial_state = None, #初始化状态
        dtype = tf.float32, #数据类型
        time_major = False,
        )

out_put = tf.layers.dense(inputs=outputs[:, -1, :], units=n_classes, activation=tf.nn.sigmoid)   #

# 查看输出的final_state,这里final_state是一个元祖,其与网络的层数有关.
print(final_state[0].h.shape)  #第一层的state的h state
print(final_state[1].h.shape) #第一层的state的c state
print(final_state[1].h.shape)

关于参数和输出数据维度的理解
这是LSTM的网络结构

  • 在图中,每一个小方框为一个前馈网络层,num_units代表了这个层中隐藏的神经元的个数。那么,h(t)的维度等于num_units, x t x_t xt为 输入向量,若其为28维,则每一个前馈网络层的输入为 h ( t − 1 ) h(t-1) h(t1) x t x_t xt进行拼接,也就是156维。
  • 其实是只有一个前馈网络层(即图中的小方框只有一个)的,不同的time_step共享同一套参数,并通过数据的不断刷新而进行网络参数的更新。12
  • 许多文章中,都是把num_units设置为与batch_size相同的值,实际上这二者并没有直接的联系。就像常规的神经网络层的的维度可以自由设置。
  • state的输出数据,与网络的层数有关。看上面的代码的最后三行。

回到tensorflow,一些基础语法部分

后面打算利用tenorflow实现非负性矩阵填充算法(NMF),这里先准备一些基础的东西。

在使用梯度下降法**更新参数时,可以使用tf.assign()**方法。
看例子

import tensorflow as tf

x = tf.Variable(1)
x_new = tf.assign(x,2)  # x.assign(x+1)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

sess.run(x)  #x 值为1
sess.run(y) # x值更新为2,同时将更新后的值赋予y
print(x.eval())

** tf的强大的求导功能**
以函数关系 y = f ( x 1 , x 2 ) y =f(x_1,x_2) y=f(x1,x2)为例,我们想要求 y y y关于 x 1 , x 2 x_1,x_2 x1,x2的偏导数,那么直接使用函数: ∂ x 1 , ∂ x 2 = t f . g r a d i e n t s ( x s = [ x 1 , x 2 ] , y s = y ) \partial x_1,\partial x_2 = tf.gradients(xs = [x_1,x_2], ys = y) x1,x2=tf.gradients(xs=[x1,x2],ys=y),代码形式为

dx1, dx2 = tf.gradients(xs=[x1,x2], ys=y)

非常的nice。
结合上面两步,我们就可以进行参数更新了:

x1 = x1.assign( x1 - a * dx1)

tensorflow保存模型与重新加载

保存

#模型中会有一些占位符作为输入
X = tf.placeholder(tf.float32, shape=[None, Col])  # 网络输入
Y = tf.placeholder(tf.float32,[None, Col]) # 网络输出
#模型的一些中间值或者输出值

cost = tf.reduce_mean(tf.square(Y - output))  #output为模型的一个返回值

#保存
saver = tf.compat.v1.train.Saver()
tf.add_to_collection('s_cost',cost)
sess = tf.Session()
#当模型完成了训练之后
saver.save(sess,"save/my_model")  #会将模型保存到一个save文件夹下,名字为my_model,实际上会生成四个这前缀的文件

文件二,模型的读取

with tf.compat.v1.Session() as sess:
            saver = tf.compat.v1.train.import_meta_graph("save/model.meta")
            saver.restore(sess, tf.train.latest_checkpoint('save/'))
            mb_data = test[:mb_size,:] # minibatch data
            graph = tf.get_default_graph()
            # tensor_name_list = [tensor.name for tensor in graph.as_graph_def().node]# 得到当前图中所有变量的名称
            X = graph.get_tensor_by_name('Placeholder:0') # 网络输入
            Y = graph.get_tensor_by_name('Placeholder_1:0') # 网络输入
#            real = graph.get_operation_by_name('real')
            s_cost = graph.get_collection('s_cost')[0]
            cost= sess.run([s_cost],feed_dict={X:inputs, Y:mb_mat})

下面总结知识点

  • 保存的时候,非占位符变量需要通过添加,如 tf.add_to_collection(‘s_cost’,cost),其中单引号的内容是它保存后的名字,在读取的时候根据这个名字进行检索
  • 占位符保存的时候没有名字,就通过如X = graph.get_tensor_by_name(‘Placeholder:0’) # 网络输入的方式来获得。这个也是挺坑的,那么,可以根据 tensor_name_list = [tensor.name for tensor in graph.as_graph_def().node] 得到当前图中所有变量的名称,将这个name list打印出来就可以查看一下。
  • 在读取的时候,两步,先通过 tf.compat.v1.train.import_meta_graph(‘模型名字.meta’),然后通过saver.restore(sess, tf.train.latest_checkpoint(‘save/’))读取。
  • 获取非占位符,通过 graph.get_collection(‘s_cost’)[0],其中’s_cost’为对应变量保存时的名字。末尾必须加[0]
  • 加载完需要的输入输出变量之后,就可以通过sess.run来跑模型了。

整体而言还是挺坑的,很多博客上的都不太行,自己搞了两个小时才通。palceholder应该可以命名的,后面再说了。想去使用pytorch了==

将tensorflow的warning取消输出

from warnings import simplefilter

simplefilter(action='ignore', category=FutureWarning)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值