安装SyntaxNet的工作环境,遇到很多麻烦,到后来发现如果不走弯路,其实并不麻烦。
1 我最开始是安装anaconda。(python2.7版本)
https://www.continuum.io/downloads
这个包安装完后python pip numpy都解决了,而且还不用改环境变量。
2 然后用pip 安装mock和asciitree和protobuf
用apt-get安装swig
3 当然tensorflow
pip install https://storage.googleapis.com/tensorflow/mac/tensorflow-0.5.0-py2-none-any.whl
上面这些都很easy
其中比较难解决的是bazel,
具体看这个https://bazel.build/versions/master/docs/install.html
先去github把它的安装文件下载下来
https://github.com/bazelbuild/bazel/releases
1. Install JDK 8
sudoadd−apt−repositoryppa:webupd8team/java
sudo apt-get update
$ sudo apt-get install oracle-java8-installer
Note: You might need to sudo apt-get install software-properties-common if you don’t have the add-apt-repository command. See here.
Ubuntu Wily (15.10). To install OpenJDK 8:
$ sudo apt-get install openjdk-8-jdk
Install other required packages
$ sudo apt-get install pkg-config zip g++ zlib1g-dev unzip
Download Bazel
Download the Bazel installer for your operating system.
Run the installer
Run the installer:
chmod+xbazel−version−installer−os.sh
./bazel-version-installer-os.sh –user
The –user flag installs Bazel to the
HOME/bindirectoryonyoursystemandsetsthe.bazelrcpathto
HOME/.bazelrc. Use the –help command to see additional installation options.
If you ran the Bazel installer with the –user flag as above, the Bazel executable is installed in your $HOME/bin directory. It’s a good idea to add this directory to your default paths, as follows:
exportPATH="
PATH:$HOME/bin”
You can also add this command to your ~/.bashrc file.
最后就clone工程
git clone –recursive https://github.com/tensorflow/models.git
cd models/syntaxnet/tensorflow
./configure
cd ..
bazel test syntaxnet/… util/utf8/…
保持联网的情况下,10几分钟之后会出现 pass 17test 。(ps
我是在windows下连的服务器,不能联网所以用了ccproxy,而且里面python,bazel,swig,numpy,numpy都装好了,我只安装了anaconda,覆盖服务器的python版本)
然后说一下使用的一些经历。
数据的话http://cs.stanford.edu/~danqi/data/PTB_SD_3_3_0.zip这个ok
不过里面的gold可以用,不带gold的那组数据空行中有个制表符,所以会报错Check failed: fields.size() >= 8 (2 vs. 8)Every line has to have at least 8 tab separated fields.
,所以如果你要用不带gold的那组数据的话,要把每句话之间的空行中的\t去掉。
有了这个数据
1 先跑pos tag
而syntaxnet有个context.pbtxt这个文件你可以把它理解成,训练过程中的数据的路径名字都被写在这里,你只需要把这些路径和名字对上号,在下面输入commad的时候,直接用名字,
所以我把context.pbtxt中的training-corpus,和tuning-corpus的所在路径改成上面下载数据所在的路径。所以下面的commad都不用变。最后那个–params=128.什么的表示训练的参数会保存到128-0.08-3600-0.9-0 的文件夹
bazel-bin/syntaxnet/parser_trainer –task_context=syntaxnet/context.pbtxt –arg_prefix=brain_pos –compute_lexicon –graph_builder=greedy –training_corpus=training-corpus –tuning_corpus=tuning-corpus –output_path=models –batch_size=32 –decay_steps=3600 –hidden_layer_sizes=128 –learning_rate=0.08 –momentum=0.9 –seed=0 –params=128-0.08-3600-0.9-0
这个程序
task_context=syntaxnet/context.pbtxt 表示训练所需的数据的路径都被写在这个文件中
arg_prefix=brain_pos 我训练的是pos tag,如果是parse则要改为brain_parser
-compute_lexicon 应该是表示根据数据统计词频和词典的意思
-graph_builder=greedy 训练时greedy还是beam
output_path=models训练中的输出都会保存到models下面的brain_pos/greedy/128-0.08-3600-0.9-0 中,包括词典 什么index 2 word word 2 index。
这个pos tag的训练过程1个小时左右,最后的正确率96%多
然后用这个pos tag为数据打上tag,但其实我们的数据已经有tag了。
这一步是用那个bazell eval命令
2 所以直接可以用这个数据来做dependency parsing。为什么不能直接训练parsing model呢?
因为在训练parsing的过程中需要用到前面训练pos tag的中间文件,这些文件都被保存在
models/brain_pos/greedy/128-0.08-3600-0.9-0 中就是一些label index的映射文件。
ps这个目录下还有个context是后面会用到的,它和前面那个context.pbtxt是一个东西的,只是他把这些中间文件的路径也写入到context的文件中,也就是后面我们用这个context就可以找到postag所生成的中间文件的位置。
接下来local training
bazel-bin/syntaxnet/parser_trainer \
–arg_prefix=brain_parser \
–batch_size=32 \
–projectivize_training_set \
–decay_steps=4400 \
–graph_builder=greedy \
–hidden_layer_sizes=200,200 \
–learning_rate=0.08 \
–momentum=0.85 \
–output_path=models \
–task_context=models/brain_pos/greedy/128-0.08-3600-0.9-0/context \
–seed=4 \
–training_corpus=training-corpus \
–tuning_corpus=tuning-corpus \
–params=200x200-0.08-4400-0.85-4
–task_context=models/brain_pos/greedy/128-0.08-3600-0.9-0/context
这句就表示我要用postag生成的context作为我的文档接口,通过它我能找到需要的文件
–training_corpus=training-corpus \
–tuning_corpus=tuning-corpus \
之所以不是tagged_training_corpus=training-corpus \
是因为前面说过我们的数据是带tag的所以不用再用postag 标记
训练出的model会保存到models/brain_parser/greedy/200x200-0.08-4400-0.85-4
3 gobal training
bazel-bin/syntaxnet/parser_trainer \
–arg_prefix=brain_parser \
–batch_size=32\ 记得beam改成32
–decay_steps=100 \
–graph_builder=structured \ 这个参数具体作用不太清楚,但是models/parser下会有个
structured的文件,这和greedy是等价的,它里面有gobal的model
–hidden_layer_sizes=200,200 \
–learning_rate=0.02 \
–momentum=0.9 \
–output_path=models \
–task_context=models/brain_parser/greedy/200x200-0.08-4400-0.85-4/context \
//会用到loacl train生成的文件 所以用loacl train生成的context,和前面道理一样
–seed=0 \
–training_corpus=projectivized-training-corpus \ //这个是loacl生成的文件,上面的上面那行context中有他的具体路径
–tuning_corpus=tuning-corpus \ //我们的tuning文件也tag过,不用再加入个tagged文件
–params=200x200-0.02-100-0.9-0 \
–pretrained_params=models/brain_parser/greedy/200x200-0.08-4400-0.85-4/model \
–pretrained_params_names=\
embedding_matrix_0,embedding_matrix_1,embedding_matrix_2,\
bias_0,weights_0,bias_1,weights_1
如此训练完成。
此外如果你想修改这个代码的某一部分。
其中还是在你运行commad的文件下,也就是bazel-bin所在的文件夹下面的syntaxnet中包含了其中的大部分代码。有c++有python,如果运行有错,可以找到有错的文件,修改后。
其中有个很重要的BUILD文件
其中有 cc libraries
cc tests
py graph builder and trainer等阻块。
比如你修改了cc文件,
使用bazel build :parser_ops.so(冒号后面的表示BUILD文件中的那些name表示你要重新build的组块名称)
它就会把cc这些相关的文件重新编译,其中每个name都有个deps与他对应,表示重新编译这部分的内容所依赖的那些文件。
bazel build相当于以前的make makefile编译。
优点是你只需重新编译你修改的那个文件所依赖的那些文件而不是整个工程。
大致就这么多了,希望各位少走弯路,对你能够起到帮助,笔者比较懒,所以博客组织比较乱,望见谅。