基于LSTM/BLSTM/CNNBLSTM的命名实体识别任务代码的解析--1

 

原始代码来源于github,具体网址为:https://github.com/heshenghuan/LSTM-CRF.git

但读入语料不是用的模板,而是自己写的读取数据的代码

 

本人对深度学习的理解:

  1. 处理数据:将数据处理成网络可以读取的格式
  2. 网络的搭建:“函数”的各种调用
  3. 训练:喂入神经网络数据进行训练,可能需要经过一定的时间
  4. 测试:对训练出的模型进行测试,并选取评估参数对训练出的模型进行量化的评估,即所谓的模型的好坏
  5. 调参数:尝试着对神经网络的参数进行调试(其实就是试试,看哪个参数使模型测试出的结果比较好)

(本人刚接触神经网络不久,一些看法仅代表自己的看法,若是有不同的地方,可以一起交流)

 

下面对代码进行简单的解释(本人的理解+百度)

 

程序主要包括:

main.py   主程序

model.py  神经网络模型设置程序

pretreatment.py :数据预处理程序

git上面还有其他的py文件,感兴趣的可以自己下载看一下

 

1、main.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 <type 'numpy.ndarray'> 46658 <type 'numpy.ndarray'> 46658 <type 'numpy.ndarray'>

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文件吧,剩下的会继续更新

有不妥的地方,可以互相交流哦

猜你喜欢

转载自blog.csdn.net/yangfengling1023/article/details/81120109