原始代码来源于github,具体网址为:https://github.com/heshenghuan/LSTM-CRF.git
但读入语料不是用的模板,而是自己写的读取数据的代码
本人对深度学习的理解:
(本人刚接触神经网络不久,一些看法仅代表自己的看法,若是有不同的地方,可以一起交流)
下面对代码进行简单的解释(本人的理解+百度)
程序主要包括:
main.py 主程序
model.py 神经网络模型设置程序
pretreatment.py :数据预处理程序
git上面还有其他的py文件,感兴趣的可以自己下载看一下
(1)相关包的导入
#coding:utf-8
import random
import numpy as np
import codecs as cs
import tensorflow as tf
from pretreatment import process_data,process_test ##数据的处理
import model as tagger ##给model一个别称,即重新取了一个名字
import sys
reload(sys)
sys.setdefaultencoding('utf8') ##选的python2.7,大家懂得。。编码问题。。头疼啊。。
(2)各个参数的默认值设置
执行main函数之前首先进行flags的解析,通过设置flags可以在运行程序时给入参数,也可以选择默认的值,即在程序运行之前初始化各个参数一个默认的值。
在https://blog.csdn.net/weiqi_fan/article/details/72722510的解释为:
执行main函数之前首先进行flags的解析,也就是说Tensorflow通过设置flags来传递tf.app.run()所需要的参数,我们可以直接在程序运行前初始化flags,也可以在运行程序的时候设置命令行参数达到传参的目的
#FLAGS是一个对象,保存了解析后的命令行参数
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string('train_data',DATA_DIR+r'train_data.txt','train data file')
tf.app.flags.DEFINE_string('test_data',DATA_DIR+r'test_data.txt','test data file')
tf.app.flags.DEFINE_string('valid_data',DATA_DIR+r'dev_data.txt','validation data file')
tf.app.flags.DEFINE_string('log_dir',LOG_DIR,'the log dir')
tf.app.flags.DEFINE_string('model_dir',MODEL_DIR,'models dir')
tf.app.flags.DEFINE_string('model','LSTM','model type:LSTM/BLSTM/CNNBLSTM')
tf.app.flags.DEFINE_string('restore_model','None','path of the model to restored')
tf.app.flags.DEFINE_string('emb_file',EMB_DIR+'/data_vec.txt','embeddings file')
tf.app.flags.DEFINE_integer('emb_dim',100,'embedding size')
tf.app.flags.DEFINE_string('output_dir',OUTPUT_DIR,'output dir')
tf.app.flags.DEFINE_float('lr',0.002,'learning rate')
tf.app.flags.DEFINE_float('dropout',0.,'dropout rate of input layer')
tf.app.flags.DEFINE_boolean('fine_tuning',True,'whether fine-tuning the embeddings')
tf.app.flags.DEFINE_boolean('eval_test',True,'whether evaluate the test data')
tf.app.flags.DEFINE_integer("max_len", MAX_LEN,'max num of tokens per query')
tf.app.flags.DEFINE_integer("nb_classes", 7, 'Tagset size')
tf.app.flags.DEFINE_integer("hidden_dim", 80, 'hidden unit number')
tf.app.flags.DEFINE_integer("batch_size", 200, 'num example per mini batch')
tf.app.flags.DEFINE_integer("train_steps", 50, 'trainning steps')
tf.app.flags.DEFINE_integer("display_step", 1, 'number of test display step')
tf.app.flags.DEFINE_float("l2_reg", 0.0001, 'L2 regularization weight')
tf.app.flags.DEFINE_boolean('log', True, 'Whether to record the TensorBoard log.')
例子:
tf.app.flags.DEFINE_string('model','LSTM','model type:LSTM/BLSTM/CNNBLSTM')
参数的名字:model
参数的默认值:LSTM
参数的数据类型:DEFINE_string
参数的注释:model type:LSTM/BLSTM/CNNBLSTM
括号中的三个参数分别对应参数的名字、参数默认的值、参数的注释
在运行main.py文件时,可以有两种运行方式:
python main.py --model BLSTM
python main.py
第一种参数model的值为BLSTM,不再是LSTM,通过命令行参数对其进行了更改
第二种参数model的值仍为默认值LSTM(不传的话,会使用默认值)
tf.app.flags.DEFINE_xxx()就是添加命令行的optional argument(可选参数),而tf.app.flags.FLAGS可以从对应的命令行参数取出参数。
(3)主函数
if __name__ == '__main__':
tf.app.run()
在很多Tensorflow代码中都会存在上述的代码,源代码如下所示:
def run(main=None):
f = flags.FLAGS
f._parse_flags()
main = main or sys.modules['__main__'].main
sys.exit(main(sys.argv))
作用:
先处理flag解析,然后执行main函数
网上搜到各种解释如下所示(不一一粘贴网址了):
1)tensorflow的程序中,在main函数下,都是使用tf.app.run()来启动
2)可以看到源码中的过程是首先加载flags的参数项,然后执行main函数。其中参数是使用tf.app.flags.FLAGS定义的
3)在主程序中执行启动tensorflow
(4)main函数
def main(_):
np.random.seed(1337)
random.seed(1337)##设置随机种子目的是使每一次初始化时给定的初值保持一致
##数据的读取
train,valid,test,dict1,max_len,label= process_data(FLAGS.train_data,FLAGS.valid_data,FLAGS.test_data)
train_x,train_y,train_len = train
valid_x,valid_y,valid_len = valid
test_x,test_y,test_len = test
FLAGS.max_len = max_len
idx2label = {}
for i in range(len(label)):
idx2label[i] = label[i]
nb_classes = len(label) ##标签的总个数
FLAGS.nb_classes = nb_classes
print FLAGS.nb_classes
nb_words = len(dict1) ##字典的大小
FLAGS.nb_words = nb_words
FLAGS.in_dim = FLAGS.nb_words + 1
##读取词向量,词向量的维度为100
emb_mat,idx_map = read_emb_from_file(FLAGS.emb_file,dict1)
FLAGS.emb_dim = max(emb_mat.shape[1],FLAGS.emb_dim)
if FLAGS.model == 'LSTM':
MODEL_type = tagger.LSTM_NER
elif FLAGS.model == 'BLSTM':
MODEL_type = tagger.Bi_LSTM_NER
elif FLAGS.model == 'CNNBLSTM':
MODEL_type = tagger.CNN_Bi_LSTM_NER
num_feature = 5 ##表示的是几列特征
model=MODEL_type(nb_words,FLAGS.emb_dim,emb_mat,FLAGS.hidden_dim,
FLAGS.nb_classes,FLAGS.dropout,FLAGS.batch_size,
FLAGS.max_len,num_feature,FLAGS.l2_reg,FLAGS.fine_tuning)
pred_test,test_loss,test_acc = model.run(
train_x, train_y, train_len,
valid_x, valid_y, valid_len,
test_x, test_y, test_len,FLAGS
)
print "test loss:%f,accuracy:%f"%(test_loss,test_acc)
pred_test = [pred_test[i][:test_len[i]] for i in xrange(len(pred_test))]
pred_test_label = convert_id_to_word(pred_test,idx2label)
问题:
def main(_):
括号中为什么会有一个下划线“_”,知道的小哥哥小姐姐可以留言告诉我一声
batch_size :表示输入的是句子的数量,程序中设置为200,即一次输入200个句子
一个词的词向量(选择的word2vec进行训练得出的):
emb_mat[0]:
[-0.6621169 -0.8313406 0.54108036 0.20365714 -0.10455681 0.3607058
0.4160717 -0.41833383 -0.39466462 0.07336954 -0.49563563 -0.08958961
0.49159595 -0.16177754 -0.06243266 -0.14767128 0.1618933 0.19220804
-0.10710583 0.29073772 0.7336261 -0.7396908 -0.6750916 0.02076059
0.13271192 -0.28970304 0.12586454 0.35763028 0.22733922 -0.09528491
-0.08213616 -0.10439471 0.2566883 -0.08572228 -0.00877656 -0.01470754
0.09599475 0.08488567 -0.22608955 0.29944983 -0.1588087 0.16511342
-0.5654839 0.02626183 -0.00412571 0.08016261 -0.66539353 -0.04139498
0.31533444 0.1254148 -0.05564674 0.42645916 -0.5808047 -0.3405478
0.36155587 0.18621838 -0.05239308 0.10274373 -0.36228842 -0.27298418
0.33608422 -0.2988138 -0.5349861 -0.38662362 0.28941253 0.09757522
-0.28427303 0.0545605 -0.07313918 -0.31062493 0.36393994 0.10052888
0.3193981 -0.16685288 -0.19736792 -0.1944135 0.45230377 0.23940851
0.17697854 0.19814879 -0.19274928 0.6112448 -0.20306586 -0.11211285
-0.48181373 0.4691558 0.14557801 0.25496432 -0.28298065 -0.3830366
-0.6511909 -0.1889271 -0.05878077 -0.20141794 0.32011527 -0.06556274
0.05855491 0.07617607 -0.08813886 -0.20229647]
model=MODEL_type(nb_words,FLAGS.emb_dim,emb_mat,FLAGS.hidden_dim,
FLAGS.nb_classes,FLAGS.dropout,FLAGS.batch_size,
FLAGS.max_len,num_feature,FLAGS.l2_reg,FLAGS.fine_tuning)
参数所对应的值分别为:
4832 100 4835 80 7 0.0 200 150 5 0.0001 True
数据读取过后的样式:
print len(train_x),type(train_x),len(train_y),type(train_y),len(train_len),type(train_len)
print 'train_x[0]',train_x[0]
print 'train_y[0]',train_y[0]
print 'train_len',train_len
46658
train_x[0]
[[4834 4834 1 2 3]
[4834 1 2 3 4]
[ 1 2 3 4 5]
[ 2 3 4 5 6]
[ 3 4 5 6 7]
[ 4 5 6 7 8]
[ 5 6 7 8 9]
[ 6 7 8 9 10]
[ 7 8 9 10 11]
[ 8 9 10 11 12]
[ 9 10 11 12 13]
[ 10 11 12 13 14]
[ 11 12 13 14 15]
[ 12 13 14 15 16]
[ 13 14 15 16 17]
[ 14 15 16 17 18]
[ 15 16 17 18 19]
[ 16 17 18 19 20]
[ 17 18 19 20 21]
[ 18 19 20 21 22]
[ 19 20 21 22 23]
[ 20 21 22 23 24]
[ 21 22 23 24 25]
[ 22 23 24 25 26]
[ 23 24 25 26 27]
[ 24 25 26 27 28]
[ 25 26 27 28 29]
[ 26 27 28 29 30]
[ 27 28 29 30 31]
[ 28 29 30 31 20]
[ 29 30 31 20 32]
[ 30 31 20 32 33]
[ 31 20 32 33 34]
[ 20 32 33 34 35]
[ 32 33 34 35 13]
[ 33 34 35 13 14]
[ 34 35 13 14 20]
[ 35 13 14 20 36]
[ 13 14 20 36 37]
[ 14 20 36 37 36]
[ 20 36 37 36 38]
[ 36 37 36 38 39]
[ 37 36 38 39 40]
[ 36 38 39 40 41]
[ 38 39 40 41 31]
[ 39 40 41 31 42]
[ 40 41 31 42 4834]
[ 41 31 42 4834 4834]
[ 0 0 0 0 0]
..........
[ 0 0 0 0 0]]
train_y[0] [0 1 1 1 2 2 3 4 4 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0]
train_len [48 19 47 ... 66 53 70]
pred_test,test_loss,test_acc = model.run() ##进行神经网络的训练
今天就写到main.py文件吧,剩下的会继续更新
有不妥的地方,可以互相交流哦