tensorflow训练的模型好的模型,怎么调用

对于机器学习,尤其是深度学习DL的算法,模型训练可能很耗时,几个小时或者几天,所以如果是测试模块出了问题,每次都要重新运行就显得很浪费时间,所以如果训练部分没有问题,那么可以直接将训练的模型保存起来,然后下次运行直接加载模型,然后进行测试很方便。
在tensorflow中保存(save)和加载(restore)模型的类是tf.train.Saver(),其中变量保存的是key-value,不传参数默认是全部变量。
保存模型使用的是save函数,先创建一个saver对象,
保存模型如下:
import tensorflow as tf
声明variable和op
初始化op声明
#创建saver对象,它添加了一些op用来save和restore模型参数
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(init_op)
#训练模型过程
#使用saver提供的简便方法去调用 save op
saver.save(sess, "save_path/file_name.ckpt")
加载模型使用的是restore函数,先创建一个saver对象,
恢复模型如下:
import tensorflow as tf
声明variable和op
初始化op声明
#创建saver 对象
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(init_op)#可以执行或不执行,restore的值会override初始值
saver.restore(sess, "save_path/file_name.ckpt")
本文已收录于以下专栏:
相关文章推荐
  猫狗大战,tensorflow实现,超详细讲解
保存与读取模型在使用tf来训练模型的时候,难免会出现中断的情况。这时候自然就希望能够将辛辛苦苦得到的中间参数保留下来,不然下次又要重新开始。好在tf官方提供了保存和读取模型的方法。保存模型的方法:# ...
前言本人最近正在学习深度学习以及tensorflow,在此记录一些学习过程中看到的有价值的参考资料,并且写下一点我自己的初步理解。
环境win10 64+anaconda3(python3.5)+te...
测试一张图片获取一张图片函数:def get_one_image(train):
输入参数:train,训练图片的路径
返回参数:image,从训练图片中随机抽取一张图片
n = len(train)...
实现回归模型
为了用python实现高效的数值计算,我们通常会使用函数库,比如NumPy,会把类似矩阵乘法这样的复杂运算使用其他外部语言实现。不幸的是,从外部计算切换回Python的每一个操作,仍...
之前的笔记里实现了softmax回归分类、简单的含有一个隐层的神经网络、卷积神经网络等等,但是这些代码在训练完成之后就直接退出了,并没有将训练得到的模型保存下来方便下次直接使用。为了让训练结果可以复用...
一、TensorFlow模型保存和提取方法
1. TensorFlow通过tf.train.Saver类实现神经网络模型的保存和提取。tf.train.Saver对象saver的save方法将Ten...
背景之前已经写过TensorFlow图与模型的加载与存储了,写的很详细,但是或闻有人没看懂,所以在附上一个关于模型加载与存储的例子,.其中模型很巧妙,比之前numpy写一大堆简单多了,这样有利于把主要...
tensorflow中有operation和tensor,前者表示 操作 ,后者表示 容器 ,每个operation都是有一个tensor来存放值的,比如y=f(x), operation是f...
他的最新文章
讲师:汪剑
讲师:刘道宽
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)tensorflow将训练好的模型freeze,即将权重固化到图里面,并使用该模型进行预测
我的图书馆
tensorflow将训练好的模型freeze,即将权重固化到图里面,并使用该模型进行预测
ML主要分为训练和预测两个阶段,此教程就是将训练好的模型freeze并保存下来.freeze的含义就是将该模型的图结构和该模型的权重固化到一起了.也即加载freeze的模型之后,立刻能够使用了。
下面使用一个简单的demo来详细解释该过程,
一、首先运行脚本tiny_model.py
#-*-&coding:utf-8&-*-&&import&tensorflow&as&tf&&import&numpy&as&np&&&&&&with&tf.variable_scope('Placeholder'):&&&&&&inputs_placeholder&=&tf.placeholder(tf.float32,&name='inputs_placeholder',&shape=[None,&10])&&&&&&labels_placeholder&=&tf.placeholder(tf.float32,&name='labels_placeholder',&shape=[None,&1])&&&&with&tf.variable_scope('NN'):&&&&&&W1&=&tf.get_variable('W1',&shape=[10,&1],&initializer=tf.random_normal_initializer(stddev=1e-1))&&&&&&b1&=&tf.get_variable('b1',&shape=[1],&initializer=tf.constant_initializer(0.1))&&&&&&W2&=&tf.get_variable('W2',&shape=[10,&1],&initializer=tf.random_normal_initializer(stddev=1e-1))&&&&&&b2&=&tf.get_variable('b2',&shape=[1],&initializer=tf.constant_initializer(0.1))&&&&&&&&a&=&tf.nn.relu(tf.matmul(inputs_placeholder,&W1)&+&b1)&&&&&&a2&=&tf.nn.relu(tf.matmul(inputs_placeholder,&W2)&+&b2)&&&&&&&&y&=&tf.div(tf.add(a,&a2),&2)&&&&with&tf.variable_scope('Loss'):&&&&&&loss&=&tf.reduce_sum(tf.square(y&-&labels_placeholder)&/&2)&&&&with&tf.variable_scope('Accuracy'):&&&&&&predictions&=&tf.greater(y,&0.5,&name="predictions")&&&&&&correct_predictions&=&tf.equal(predictions,&tf.cast(labels_placeholder,&tf.bool),&name="correct_predictions")&&&&&&accuracy&=&tf.reduce_mean(tf.cast(correct_predictions,&tf.float32))&&&&&&adam&=&tf.train.AdamOptimizer(learning_rate=1e-3)&&train_op&=&adam.minimize(loss)&&&&#&generate_data&&inputs&=&np.random.choice(10,&size=[10000,&10])&&labels&=&(np.sum(inputs,&axis=1)&&&45).reshape(-1,&1).astype(np.float32)&&print('inputs.shape:',&inputs.shape)&&print('labels.shape:',&labels.shape)&&&&&&test_inputs&=&np.random.choice(10,&size=[100,&10])&&test_labels&=&(np.sum(test_inputs,&axis=1)&&&45).reshape(-1,&1).astype(np.float32)&&print('test_inputs.shape:',&test_inputs.shape)&&print('test_labels.shape:',&test_labels.shape)&&&&batch_size&=&32&&epochs&=&10&&&&batches&=&[]&&print("%d&items&in&batch&of&%d&gives&us&%d&full&batches&and&%d&batches&of&%d&items"&%&(&&&&&&len(inputs),&&&&&&batch_size,&&&&&&len(inputs)&//&batch_size,&&&&&&batch_size&-&len(inputs)&//&batch_size,&&&&&&len(inputs)&-&(len(inputs)&//&batch_size)&*&32)&&)&&for&i&in&range(len(inputs)&//&batch_size):&&&&&&batch&=&[&inputs[batch_size*i:batch_size*i+batch_size],&labels[batch_size*i:batch_size*i+batch_size]&]&&&&&&batches.append(list(batch))&&if&(i&+&1)&*&batch_size&&&len(inputs):&&&&&&batch&=&[&inputs[batch_size*(i&+&1):],labels[batch_size*(i&+&1):]&]&&&&&&batches.append(list(batch))&&print("Number&of&batches:&%d"&%&len(batches))&&print("Size&of&full&batch:&%d"&%&len(batches[0]))&&print("Size&if&final&batch:&%d"&%&len(batches[-1]))&&&&global_count&=&0&&&&with&tf.Session()&as&sess:&&#sv&=&tf.train.Supervisor()&&#with&sv.managed_session()&as&sess:&&&&&&sess.run(tf.initialize_all_variables())&&&&&&for&i&in&range(epochs):&&&&&&&&&&for&batch&in&batches:&&&&&&&&&&&&&&#&print(batch[0].shape,&batch[1].shape)&&&&&&&&&&&&&&train_loss&,&_=&sess.run([loss,&train_op],&feed_dict={&&&&&&&&&&&&&&&&&&inputs_placeholder:&batch[0],&&&&&&&&&&&&&&&&&&labels_placeholder:&batch[1]&&&&&&&&&&&&&&})&&&&&&&&&&&&&&#&print('train_loss:&%d'&%&train_loss)&&&&&&&&&&&&&&&&if&global_count&%&100&==&0:&&&&&&&&&&&&&&&&&&acc&=&sess.run(accuracy,&feed_dict={&&&&&&&&&&&&&&&&&&&&&&inputs_placeholder:&test_inputs,&&&&&&&&&&&&&&&&&&&&&&labels_placeholder:&test_labels&&&&&&&&&&&&&&&&&&})&&&&&&&&&&&&&&&&&&print('accuracy:&%f'&%&acc)&&&&&&&&&&&&&&global_count&+=&1&&&&&&&&acc&=&sess.run(accuracy,&feed_dict={&&&&&&&&&&inputs_placeholder:&test_inputs,&&&&&&&&&&labels_placeholder:&test_labels&&&&&&})&&&&&&print("final&accuracy:&%f"&%&acc)&&&&&&#在session当中就要将模型进行保存&&&&&&saver&=&tf.train.Saver()&&&&&&last_chkp&=&saver.save(sess,&'results/graph.chkp')&&&&&&#sv.saver.save(sess,&'results/graph.chkp')&&&&for&op&in&tf.get_default_graph().get_operations():&&&&&&print(op.name)&&说明:saver.save必须在session里面,因为在session里面,整个图才是激活的,才能够将参数存进来,使用save之后能够得到如下的文件:
.data:存放的是权重参数
.meta:存放的是图和metadata,metadata是其他配置的数据
如果想将我们的模型固化,让别人能够使用,我们仅仅需要的是图和参数,metadata是不需要的
二、综合上述几个文件,生成可以使用的模型的步骤如下:
1、恢复我们保存的图
2、开启一个Session,然后载入该图要求的权重
3、删除对预测无关的metadata
4、将处理好的模型序列化之后保存
运行freeze.py
#-*-&coding:utf-8&-*-&&import&os,&argparse&&import&tensorflow&as&tf&&from&tensorflow.python.framework&import&graph_util&&&&dir&=&os.path.dirname(os.path.realpath(__file__))&&&&def&freeze_graph(model_folder):&&&&&&#&We&retrieve&our&checkpoint&fullpath&&&&&&checkpoint&=&tf.train.get_checkpoint_state(model_folder)&&&&&&input_checkpoint&=&checkpoint.model_checkpoint_path&&&&&&&&&&&&#&We&precise&the&file&fullname&of&our&freezed&graph&&&&&&absolute_model_folder&=&"/".join(input_checkpoint.split('/')[:-1])&&&&&&output_graph&=&absolute_model_folder&+&"/frozen_model.pb"&&&&&&&&#&Before&exporting&our&graph,&we&need&to&precise&what&is&our&output&node&&&&&&#&this&variables&is&plural,&because&you&can&have&multiple&output&nodes&&&&&&#freeze之前必须明确哪个是输出结点,也就是我们要得到推论结果的结点&&&&&&#输出结点可以看我们模型的定义&&&&&&#只有定义了输出结点,freeze才会把得到输出结点所必要的结点都保存下来,或者哪些结点可以丢弃&&&&&&#所以,output_node_names必须根据不同的网络进行修改&&&&&&output_node_names&=&"Accuracy/predictions"&&&&&&&&#&We&clear&the&devices,&to&allow&TensorFlow&to&control&on&the&loading&where&it&wants&operations&to&be&calculated&&&&&&clear_devices&=&True&&&&&&&&&&&&#&We&import&the&meta&graph&and&retrive&a&Saver&&&&&&saver&=&tf.train.import_meta_graph(input_checkpoint&+&'.meta',&clear_devices=clear_devices)&&&&&&&&#&We&retrieve&the&protobuf&graph&definition&&&&&&graph&=&tf.get_default_graph()&&&&&&input_graph_def&=&graph.as_graph_def()&&&&&&&&#We&start&a&session&and&restore&the&graph&weights&&&&&&#这边已经将训练好的参数加载进来,也即最后保存的模型是有图,并且图里面已经有参数了,所以才叫做是frozen&&&&&&#相当于将参数已经固化在了图当中&&&&&&&with&tf.Session()&as&sess:&&&&&&&&&&saver.restore(sess,&input_checkpoint)&&&&&&&&&&&&#&We&use&a&built-in&TF&helper&to&export&variables&to&constant&&&&&&&&&&output_graph_def&=&graph_util.convert_variables_to_constants(&&&&&&&&&&&&&&sess,&&&&&&&&&&&&&&&input_graph_def,&&&&&&&&&&&&&&&output_node_names.split(",")&#&We&split&on&comma&for&convenience&&&&&&&&&&)&&&&&&&&&&&&&#&Finally&we&serialize&and&dump&the&output&graph&to&the&filesystem&&&&&&&&&&with&tf.gfile.GFile(output_graph,&"wb")&as&f:&&&&&&&&&&&&&&f.write(output_graph_def.SerializeToString())&&&&&&&&&&print("%d&ops&in&the&final&graph."&%&len(output_graph_def.node))&&&&&&if&__name__&==&'__main__':&&&&&&parser&=&argparse.ArgumentParser()&&&&&&parser.add_argument("--model_folder",&type=str,&help="Model&folder&to&export")&&&&&&args&=&parser.parse_args()&&&&&&&&freeze_graph(args.model_folder)&&
说明:对于freeze操作,我们需要定义输出结点的名字.因为网络其实是比较复杂的,定义了输出结点的名字,那么freeze的时候就只把输出该结点所需要的子图都固化下来,其他无关的就舍弃掉.因为我们freeze模型的目的是接下来做预测.所以,一般情况下,output_node_names就是我们预测的目标.
三、加载freeze后的模型,注意该模型已经是包含图和相应的参数了.所以,我们不需要再加载参数进来.也即该模型加载进来已经是可以使用了.
#-*-&coding:utf-8&-*-&&import&argparse&&&import&tensorflow&as&tf&&&&def&load_graph(frozen_graph_filename):&&&&&&#&We&parse&the&graph_def&file&&&&&&with&tf.gfile.GFile(frozen_graph_filename,&"rb")&as&f:&&&&&&&&&&graph_def&=&tf.GraphDef()&&&&&&&&&&graph_def.ParseFromString(f.read())&&&&&&&&#&We&load&the&graph_def&in&the&default&graph&&&&&&with&tf.Graph().as_default()&as&graph:&&&&&&&&&&tf.import_graph_def(&&&&&&&&&&&&&&graph_def,&&&&&&&&&&&&&&&input_map=None,&&&&&&&&&&&&&&&return_elements=None,&&&&&&&&&&&&&&&name="prefix",&&&&&&&&&&&&&&&op_dict=None,&&&&&&&&&&&&&&&producer_op_list=None&&&&&&&&&&)&&&&&&return&graph&&&&if&__name__&==&'__main__':&&&&&&parser&=&argparse.ArgumentParser()&&&&&&parser.add_argument("--frozen_model_filename",&default="results/frozen_model.pb",&type=str,&help="Frozen&model&file&to&import")&&&&&&args&=&parser.parse_args()&&&&&&#加载已经将参数固化后的图&&&&&&graph&=&load_graph(args.frozen_model_filename)&&&&&&&&#&We&can&list&operations&&&&&&#op.values()&gives&you&a&list&of&tensors&it&produces&&&&&&#op.name&gives&you&the&name&&&&&&#输入,输出结点也是operation,所以,我们可以得到operation的名字&&&&&&for&op&in&graph.get_operations():&&&&&&&&&&print(op.name,op.values())&&&&&&&&&&#&prefix/Placeholder/inputs_placeholder&&&&&&&&&&#&...&&&&&&&&&&#&prefix/Accuracy/predictions&&&&&&#操作有:prefix/Placeholder/inputs_placeholder&&&&&&#操作有:prefix/Accuracy/predictions&&&&&&#为了预测,我们需要找到我们需要feed的tensor,那么就需要该tensor的名字&&&&&&#注意prefix/Placeholder/inputs_placeholder仅仅是操作的名字,prefix/Placeholder/inputs_placeholder:0才是tensor的名字&&&&&&x&=&graph.get_tensor_by_name('prefix/Placeholder/inputs_placeholder:0')&&&&&&y&=&graph.get_tensor_by_name('prefix/Accuracy/predictions:0')&&&&&&&&&&&&&&&&with&tf.Session(graph=graph)&as&sess:&&&&&&&&&&y_out&=&sess.run(y,&feed_dict={&&&&&&&&&&&&&&x:&[[3,&5,&7,&4,&5,&1,&1,&1,&1,&1]]&#&&&45&&&&&&&&&&})&&&&&&&&&&print(y_out)&#&[[&0.]]&Yay!&&&&&&print&("finish")&&说明:
1、在预测的过程中,当把freeze后的模型加载进来后,我们只需要定义好输入的tensor和目标tensor即可
2、在这里要注意一下tensor_name和ops_name,
注意prefix/Placeholder/inputs_placeholder仅仅是操作的名字,prefix/Placeholder/inputs_placeholder:0才是tensor的名字
x = graph.get_tensor_by_name('prefix/Placeholder/inputs_placeholder:0')一定要使用tensor的名字
3、要获取图中ops的名字和对应的tensor的名字,可用如下的代码:
#&We&can&list&operations&&#op.values()&gives&you&a&list&of&tensors&it&produces&&#op.name&gives&you&the&name&&#输入,输出结点也是operation,所以,我们可以得到operation的名字&&for&op&in&graph.get_operations():&&&&&&print(op.name,op.values())&&
=============================================================================================================================
上面是使用了Saver()来保存模型,也可以使用sv = tf.train.Supervisor()来保存模型
#-*-&coding:utf-8&-*-&&import&tensorflow&as&tf&&import&numpy&as&np&&&&&&with&tf.variable_scope('Placeholder'):&&&&&&inputs_placeholder&=&tf.placeholder(tf.float32,&name='inputs_placeholder',&shape=[None,&10])&&&&&&labels_placeholder&=&tf.placeholder(tf.float32,&name='labels_placeholder',&shape=[None,&1])&&&&with&tf.variable_scope('NN'):&&&&&&W1&=&tf.get_variable('W1',&shape=[10,&1],&initializer=tf.random_normal_initializer(stddev=1e-1))&&&&&&b1&=&tf.get_variable('b1',&shape=[1],&initializer=tf.constant_initializer(0.1))&&&&&&W2&=&tf.get_variable('W2',&shape=[10,&1],&initializer=tf.random_normal_initializer(stddev=1e-1))&&&&&&b2&=&tf.get_variable('b2',&shape=[1],&initializer=tf.constant_initializer(0.1))&&&&&&&&a&=&tf.nn.relu(tf.matmul(inputs_placeholder,&W1)&+&b1)&&&&&&a2&=&tf.nn.relu(tf.matmul(inputs_placeholder,&W2)&+&b2)&&&&&&&&y&=&tf.div(tf.add(a,&a2),&2)&&&&with&tf.variable_scope('Loss'):&&&&&&loss&=&tf.reduce_sum(tf.square(y&-&labels_placeholder)&/&2)&&&&with&tf.variable_scope('Accuracy'):&&&&&&predictions&=&tf.greater(y,&0.5,&name="predictions")&&&&&&correct_predictions&=&tf.equal(predictions,&tf.cast(labels_placeholder,&tf.bool),&name="correct_predictions")&&&&&&accuracy&=&tf.reduce_mean(tf.cast(correct_predictions,&tf.float32))&&&&&&adam&=&tf.train.AdamOptimizer(learning_rate=1e-3)&&train_op&=&adam.minimize(loss)&&&&#&generate_data&&inputs&=&np.random.choice(10,&size=[10000,&10])&&labels&=&(np.sum(inputs,&axis=1)&&&45).reshape(-1,&1).astype(np.float32)&&print('inputs.shape:',&inputs.shape)&&print('labels.shape:',&labels.shape)&&&&&&test_inputs&=&np.random.choice(10,&size=[100,&10])&&test_labels&=&(np.sum(test_inputs,&axis=1)&&&45).reshape(-1,&1).astype(np.float32)&&print('test_inputs.shape:',&test_inputs.shape)&&print('test_labels.shape:',&test_labels.shape)&&&&batch_size&=&32&&epochs&=&10&&&&batches&=&[]&&print("%d&items&in&batch&of&%d&gives&us&%d&full&batches&and&%d&batches&of&%d&items"&%&(&&&&&&len(inputs),&&&&&&batch_size,&&&&&&len(inputs)&//&batch_size,&&&&&&batch_size&-&len(inputs)&//&batch_size,&&&&&&len(inputs)&-&(len(inputs)&//&batch_size)&*&32)&&)&&for&i&in&range(len(inputs)&//&batch_size):&&&&&&batch&=&[&inputs[batch_size*i:batch_size*i+batch_size],&labels[batch_size*i:batch_size*i+batch_size]&]&&&&&&batches.append(list(batch))&&if&(i&+&1)&*&batch_size&&&len(inputs):&&&&&&batch&=&[&inputs[batch_size*(i&+&1):],labels[batch_size*(i&+&1):]&]&&&&&&batches.append(list(batch))&&print("Number&of&batches:&%d"&%&len(batches))&&print("Size&of&full&batch:&%d"&%&len(batches[0]))&&print("Size&if&final&batch:&%d"&%&len(batches[-1]))&&&&global_count&=&0&&&&#with&tf.Session()&as&sess:&&sv&=&tf.train.Supervisor()&&with&sv.managed_session()&as&sess:&&&&&&#sess.run(tf.initialize_all_variables())&&&&&&for&i&in&range(epochs):&&&&&&&&&&for&batch&in&batches:&&&&&&&&&&&&&&#&print(batch[0].shape,&batch[1].shape)&&&&&&&&&&&&&&train_loss&,&_=&sess.run([loss,&train_op],&feed_dict={&&&&&&&&&&&&&&&&&&inputs_placeholder:&batch[0],&&&&&&&&&&&&&&&&&&labels_placeholder:&batch[1]&&&&&&&&&&&&&&})&&&&&&&&&&&&&&#&print('train_loss:&%d'&%&train_loss)&&&&&&&&&&&&&&&&if&global_count&%&100&==&0:&&&&&&&&&&&&&&&&&&acc&=&sess.run(accuracy,&feed_dict={&&&&&&&&&&&&&&&&&&&&&&inputs_placeholder:&test_inputs,&&&&&&&&&&&&&&&&&&&&&&labels_placeholder:&test_labels&&&&&&&&&&&&&&&&&&})&&&&&&&&&&&&&&&&&&print('accuracy:&%f'&%&acc)&&&&&&&&&&&&&&global_count&+=&1&&&&&&&&acc&=&sess.run(accuracy,&feed_dict={&&&&&&&&&&inputs_placeholder:&test_inputs,&&&&&&&&&&labels_placeholder:&test_labels&&&&&&})&&&&&&print("final&accuracy:&%f"&%&acc)&&&&&&#在session当中就要将模型进行保存&&&&&&#saver&=&tf.train.Saver()&&&&&&#last_chkp&=&saver.save(sess,&'results/graph.chkp')&&&&&&sv.saver.save(sess,&'results/graph.chkp')&&&&for&op&in&tf.get_default_graph().get_operations():&&&&&&print(op.name)&&
注意:使用了sv = tf.train.Supervisor(),就不需要再初始化了,将sess.run(tf.initialize_all_variables())注释掉,否则会报错.
TA的最新馆藏[转]&
喜欢该文的人也喜欢深度学习利器:TensorFlow与NLP模型_Linux教程_Linux公社-Linux系统门户网站
你好,游客
深度学习利器:TensorFlow与NLP模型
作者:武维
自然语言处理(简称NLP),是研究计算机处理人类语言的一门技术,NLP技术让计算机可以基于一组技术和理论,分析、理解人类的沟通内容。传统的自然语言处理方法涉及到了很多语言学本身的知识,而深度学习,是表征学习(representation learning)的一种方法,在机器翻译、自动问答、文本分类、情感分析、信息抽取、序列标注、语法解析等领域都有广泛的应用。
2013年末谷歌发布的word2vec工具,将一个词表示为词向量,将文字数字化,有效地应用于文本分析。2016年谷歌开源自动生成文本摘要模型及相关TensorFlow代码。年,谷歌发布/升级语言处理框架SyntaxNet,识别率提高25%,为40种语言带来文本分割和词态分析功能。2017年谷歌官方开源tf-seq2seq,一种通用编码器/解码器框架,实现自动翻译。本文主要结合TensorFlow平台,讲解TensorFlow词向量生成模型(Vector Representations of Words);使用RNN、LSTM模型进行语言预测;以及TensorFlow自动翻译模型。
Word2Vec数学原理简介
我们将自然语言交给机器学习来处理,但机器无法直接理解人类语言。那么首先要做的事情就是要将语言数学化,Hinton于1986年提出Distributed Representation方法,通过训练将语言中的每一个词映射成一个固定长度的向量。所有这些向量构成词向量空间,每个向量可视为空间中的一个点,这样就可以根据词之间的距离来判断它们之间的相似性,并且可以把其应用扩展到句子、文档及中文分词。
Word2Vec中用到两个模型,CBOW模型(Continuous Bag-of-Words model)和Skip-gram模型(Continuous Skip-gram Model)。模型示例如下,是三层结构的神经网络模型,包括输入层,投影层和输出层。
(点击放大图像)
(点击放大图像)
其中score(wt, h),表示在的上下文环境下,预测结果是的概率得分。上述目标函数,可以转换为极大化似然函数,如下所示:
(点击放大图像)
求解上述概率模型的计算成本是非常高昂的,需要在神经网络的每一次训练过程中,计算每个词在他的上下文环境中出现的概率得分,如下所示:
(点击放大图像)
然而在使用word2vec方法进行特性学习的时候,并不需要计算全概率模型。在CBOW模型和skip-gram模型中,使用了逻辑回归(logistic regression)二分类方法进行的预测。如下图CBOW模型所示,为了提高模型的训练速度和改善词向量的质量,通常采用随机负采样(Negative Sampling)的方法,噪音样本w1,w2,w3,wk&为选中的负采样。
(点击放大图像)
TensorFlow近义词模型
本章讲解使用TensorFlow word2vec模型寻找近义词,输入数据是一大段英文文章,输出是相应词的近义词。比如,通过学习文章可以得到和five意思相近的词有: four, three, seven, eight, six, two, zero, nine。通过对大段英文文章的训练,当神经网络训练到10万次迭代,网络Loss值减小到4.6左右的时候,学习得到的相关近似词,如下图所示:
(点击放大图像)
下面为TensorFlow word2vec API 使用说明:
构建词向量变量,vocabulary_size为字典大小,embedding_size为词向量大小
embeddings = tf.Variable(tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))
定义负采样中逻辑回归的权重和偏置
nce_weights = tf.Variable(tf.truncated_normal
([vocabulary_size, embedding_size], stddev=1.0 / math.sqrt(embedding_size)))
nce_biases = tf.Variable(tf.zeros([vocabulary_size]))
定义训练数据的接入
train_inputs = tf.placeholder(tf.int32, shape=[batch_size])
train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])
定义根据训练数据输入,并寻找对应的词向量
embed = tf.nn.embedding_lookup(embeddings, train_inputs)
基于负采样方法计算Loss值
loss = tf.reduce_mean( tf.nn.nce_loss
(weights=nce_weights, biases=nce_biases, labels=train_labels,
inputs=embed, num_sampled=num_sampled, num_classes=vocabulary_size))
定义使用随机梯度下降法执行优化操作,最小化loss值
optimizer = tf.train.GradientDescentOptimizer(learning_rate=1.0).minimize(loss)
通过TensorFlow Session Run的方法执行模型训练
for inputs, labels in generate_batch(...):
feed_dict = {train_inputs: inputs, train_labels: labels}
_, cur_loss = session.run([optimizer, loss], feed_dict=feed_dict)
TensorFlow语言预测模型
本章主要回顾RNN、LSTM技术原理,并基于RNN/LSTM技术训练语言模型。也就是给定一个单词序列,预测最有可能出现的下一个单词。例如,给定[had, a, general] 3个单词的LSTM输入序列,预测下一个单词是什么?如下图所示:
(点击放大图像)
RNN技术原理
循环神经网络(Recurrent Neural Network, RNN)是一类用于处理序列数据的神经网络。和卷积神经网络的区别在于,卷积网络是适用于处理网格化数据(如图像数据)的神经网络,而循环神经网络是适用于处理序列化数据的神经网络。例如,你要预测句子的下一个单词是什么,一般需要用到前面的单词,因为一个句子中前后单词并不是独立的。RNN之所以称为循环神经网路,即一个序列当前的输出与前面的输出也有关。具体的表现形式为网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐藏层之间的节点不再无连接而是有连接的,并且隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。如下图所示:
(点击放大图像)
LSTM技术原理
RNN有一问题,反向传播时,梯度也会呈指数倍数的衰减,导致经过许多阶段传播后的梯度倾向于消失,不能处理长期依赖的问题。虽然RNN理论上可以处理任意长度的序列,但实习应用中,RNN很难处理长度超过10的序列。为了解决RNN梯度消失的问题,提出了Long Short-Term Memory模块,通过门的开关实现序列上的记忆功能,当误差从输出层反向传播回来时,可以使用模块的记忆元记下来。所以 LSTM 可以记住比较长时间内的信息。常见的LSTM模块如下图所示:
(点击放大图像)
(点击放大图像)
output gate类似于input gate同样会产生一个0-1向量来控制Memory Cell到输出层的输出,如下公式所示:
(点击放大图像)
三个门协作使得 LSTM 存储块可以存取长期信息,比如说只要输入门保持关闭,记忆单元的信息就不会被后面时刻的输入所覆盖。
使用TensorFlow构建单词预测模型
首先,该数据集大概包含10000个不同的单词,并对不常用的单词进行了标注。
首先需要对样本数据集进行预处理,把每个单词用整数标注,即构建词典索引,如下所示:
读取训练数据
data = _read_words(filename)
#按照单词出现频率,进行排序
counter = collections.Counter(data)
count_pairs = sorted(counter.items(), key=lambda x: (-x1, x[0]))
#构建词典及词典索引
words, _ = list(zip(*count_pairs))
word_to_id = dict(zip(words, range(len(words))))
接着读取训练数据文本,把单词序列转换为单词索引序列,生成训练数据,如下所示:
读取训练数据单词,并转换为单词索引序列
data = _read_words(filename) data = [word_to_id[word] for word in data if word in word_to_id]
生成训练数据的data和label,其中epoch_size为该epoch的训练迭代次数,num_steps为LSTM的序列长度
i = tf.train.range_input_producer(epoch_size, shuffle=False).dequeue()
x = tf.strided_slice(data, [0, i * num_steps], [batch_size, (i + 1) * num_steps])
x.set_shape([batch_size, num_steps])
y = tf.strided_slice(data, [0, i * num_steps + 1], [batch_size, (i + 1) * num_steps + 1])
y.set_shape([batch_size, num_steps])
构建LSTM Cell,其中size为隐藏神经元的数量
lstm_cell = tf.contrib.rnn.BasicLSTMCell(size,
forget_bias=0.0, state_is_tuple=True)
如果为训练模式,为保证训练鲁棒性,定义dropout操作
attn_cell = tf.contrib.rnn.DropoutWrapper(lstm_cell,
output_keep_prob=config.keep_prob)
根据层数配置,定义多层RNN神经网络
cell = tf.contrib.rnn.MultiRNNCell( [ attn_cell for _ in range(config.num_layers)],
state_is_tuple=True)
根据词典大小,定义词向量
embedding = tf.get_variable("embedding",
[vocab_size, size], dtype=data_type())
根据单词索引,查找词向量,如下图所示。从单词索引找到对应的One-hot encoding,然后红色的weight就直接对应了输出节点的值,也就是对应的embedding向量。
inputs = tf.nn.embedding_lookup(embedding, input_.input_data)
(点击放大图像)
定义RNN网络,其中state为LSTM Cell的状态,cell_output为LSTM Cell的输出
for time_step in range(num_steps):
if time_step & 0: tf.get_variable_scope().reuse_variables()
(cell_output, state) = cell(inputs[:, time_step, :], state)
outputs.append(cell_output)
定义训练的loss值就,如下公式所示。
(点击放大图像)
softmax_w = tf.get_variable("softmax_w", [size, vocab_size], dtype=data_type())
softmax_b = tf.get_variable("softmax_b", [vocab_size], dtype=data_type())
logits = tf.matmul(output, softmax_w) + softmax_b
loss = tf.contrib.legacy_seq2seq.sequence_loss_by_example([logits],
[tf.reshape(input_.targets, [-1])], [tf.ones([batch_size * num_steps], dtype=data_type())])
定义梯度及优化操作
cost = tf.reduce_sum(loss) / batch_size
tvars = tf.trainable_variables()
grads, _ = tf.clip_by_global_norm(tf.gradients(cost, tvars), config.max_grad_norm)
optimizer = tf.train.GradientDescentOptimizer(self._lr)
单词困惑度eloss
perplexity = np.exp(costs / iters)
TensorFlow语言翻译模型
本节主要讲解使用TensorFlow实现RNN、LSTM的语言翻译模型。基础的sequence-to-sequence模型主要包含两个RNN网络,一个RNN网络用于编码Sequence的输入,另一个RNN网络用于产生Sequence的输出。基础架构如下图所示
(点击放大图像)
上图中的每个方框表示RNN中的一个Cell。在上图的模型中,每个输入会被编码成固定长度的状态向量,然后传递给解码器。2014年,Bahdanau在论文&Neural Machine Translation by Jointly Learning to Align and Translate&中引入了Attention机制。Attention机制允许解码器在每一步输出时参与到原文的不同部分,让模型根据输入的句子以及已经产生的内容来影响翻译结果。一个加入attention机制的多层LSTM sequence-to-sequence网络结构如下图所示:
(点击放大图像)
针对上述sequence-to-sequence模型,TensorFlow封装成了可以直接调用的函数API,只需要几百行的代码就能实现一个初级的翻译模型。tf.nn.seq2seq文件共实现了5个seq2seq函数:
basic_rnn_seq2seq:输入和输出都是embedding的形式;encoder和decoder用相同的RNN cell,但不共享权值参数;
tied_rnn_seq2seq:同basic_rnn_seq2seq,但encoder和decoder共享权值参数;
embedding_rnn_seq2seq:同basic_rnn_seq2seq,但输入和输出改为id的形式,函数会在内部创建分别用于encoder和decoder的embedding矩阵;
embedding_tied_rnn_seq2seq:同tied_rnn_seq2seq,但输入和输出改为id形式,函数会在内部创建分别用于encoder和decoder的embedding矩阵;
embedding_attention_seq2seq:同embedding_rnn_seq2seq,但多了attention机制;
embedding_rnn_seq2seq函数接口使用说明如下:
encoder_inputs:encoder的输入
decoder_inputs:decoder的输入
cell:RNN_Cell的实例
num_encoder_symbols,num_decoder_symbols:分别是编码和解码的大小
embedding_size:词向量的维度
output_projection:decoder的output向量投影到词表空间时,用到的投影矩阵和偏置项
feed_previous:若为True, 只有第一个decoder的输入符号有用,所有的decoder输入都依赖于上一步的输出;
outputs, states = embedding_rnn_seq2seq(
encoder_inputs, decoder_inputs, cell,
num_encoder_symbols, num_decoder_symbols,
embedding_size, output_projection=None,
feed_previous=False)
,采用的是网站提供的语料数据,主要包含:giga-fren.release2.fixed.en(英文语料,3.6G)和giga-fren.release2.fixed.fr(法文语料,4.3G)。该示例的代码结构如下所示:
seq2seq_model.py:seq2seq的TensorFlow模型
采用了embedding_attention_seq2seq用于创建seq2seq模型。
data_utils.py:对语料数据进行数据预处理,根据语料数据生成词典库;并基于词典库把要翻译的语句转换成用用词ID表示的训练序列。如下图所示:
(点击放大图像)
translate.py:主函数入口,执行翻译模型的训练
执行模型训练
python translate.py
--data_dir [your_data_directory] --train_dir [checkpoints_directory]
--en_vocab_size=40000 --fr_vocab_size=40000
随着TensorFlow新版本的不断发布以及新模型的不断增加,TensorFlow已成为主流的深度学习平台。本文主要介绍了TensorFlow在自然语言处理领域的相关模型和应用。首先介绍了Word2Vec数学原理,以及如何使用TensorFlow学习词向量;接着回顾了RNN、LSTM的技术原理,讲解了TensorFlow的语言预测模型;最后实例分析了TensorFlow sequence-to-sequence的机器翻译 API及官方示例。
深度学习利器:分布式TensorFlow及实例分析
深度学习利器:TensorFlow使用实战
深度学习利器:TensorFlow系统架构与高性能程序设计
深度学习利器:TensorFlow与深度卷积神经网络
武维:IBM Spectrum Computing 研发工程师,博士,系统架构师,主要从事大数据,深度学习,云计算等领域的研发工作。
本文永久更新链接地址:
相关资讯 & & &
& (09月29日)
& (09月28日)
& (昨 06:33)
& (09月29日)
& (09月05日)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款}

我要回帖

更多关于 tensorflow预训练模型 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信