安装 TensorFlow 之 textsum 文章自动摘要

前言

这里不讨论算法的问题,这里讨论如何在Linux上安装并运行 这个开源项目,面向入门机器学习的读者,所以我会倾向于写得详细(啰嗦)。

介绍和资料

尽管这里只是说「安装和运行 textsum」,但是我们还是得简单知道一些算法知识,当然,时间不过可以跳过,直接ctrl + F 「安装」就能看到正文。

在GitHub的TensorFlow开源项目中,基于 LSTM(Long Short-Term Memory)模型的textsum,将输入的文章导入 RNN(Recurrent Neural Networks) 并输出得到的文章摘要。

《安装 TensorFlow 之 textsum 文章自动摘要》
GitHub上TensorFLow开源的 文章自动摘要模型「textsum」,点击↓访问GitHub
tensorflow/modelsgithub.com《安装 TensorFlow 之 textsum 文章自动摘要》
《安装 TensorFlow 之 textsum 文章自动摘要》
《安装 TensorFlow 之 textsum 文章自动摘要》 seq2seq mdoel

图注:模型读取了输入句子 “ABC”,然后输出“WXYZ”。模型会在输出<结束标签>(<EOS>) 后停止预测内容。 注意!
LSTM 是反向读取序列的,因为这样子做能建立起许多数据间短期的依赖关系,并让优化更加容易。

Figure 1: Our model reads an input sentence “ABC” and produces “WXYZ” as the output sentence. The model stops making predictions after outputting the end-of-sentence token.

Note that the LSTM reads the input sentence in reverse, because doing so introduces many short term dependencies in the data that make the

optimization problem much easier.

简单的说,textsum 使用的 seq2seq model 就是:

用一个LSTM 去读取输入序列,每次用一个 timestep 去得到对输入序列的一个大的固定矢量描述,然后使用另一个LSTM 从这个矢量里提取出想要的输出序列。(见上图)

The idea is to use one LSTM to read the input sequence, one timestep at a time, to obtain large fixeddimensional vector representation, and then to use another LSTM to extract the output sequence from that vector (fig. 1).

By the way,

介绍算法的paper 在这里↓,自己去看

Sequence to Sequence Learning with Neural Networks.pdf

为何LSTM 要反向读取输入序列?Stack Overflow有较好的回答了↓

NStepLSTM and Seq2Seq model 然后 ctrl+F[reserved]

1.安装和运行 textsum

这里使用的是 TensorFlow + Bazel(需要前置 jdk 1.8)

环境 (报错很多时候与环境有关)

  • Debian 8.9 Linux-3.16.0-4-amd64-x86_64-with-debian-8.9
  • bazel 0.11.1 (构建文件系统)
  • java 1.8.0_121
  • Python 2.7.9 [GCC 4.9.2] on linux2
  • Python 3.4.2 [GCC 4.9.1] on linux
  • TensorFlow 1.6.0 (Python2)
  • TensorFlow 1.6.0 (Python3)

安装Bazel,JDK 8,TensorFlow

『JDK 8 的安装』

Installing Bazel on Ubuntu

记得检查是否已经安装了 JDK 8,像我喜欢用 PyCharm写Python,早就装好了。

安装 jdk1.8 的一种方法
deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -

『bazel 的安装』

sudo apt-get update && sudo apt-get install bazel
sudo apt-get upgrade bazel

bazelbuild/bazel←bazel下载地址,打开之后找匹配的版本

《安装 TensorFlow 之 textsum 文章自动摘要》
《安装 TensorFlow 之 textsum 文章自动摘要》 等等,好像发现了什么?长野原美绪?四斋蒸恶心 ( °△°||)︴

『TensorFlow 的安装』

TensorFlow 推荐直接用Python 的pip 安装。pip版本推荐大于 9.0.1

pip install tensorflow

注意,我运行的时候,没有指定运行运行时候的Python 版本,使得我的系统默认调用 Python2来运行这个程序。所以如果你安装了 TensorFlow 而报错的时候显示没有找到,那么你可能要看看另外一个版本的Python 是否也安装了TensorFLow。

『textsum 代码文件夹的下载』

下载GitHub上 TensorFlow 开源项目的 textsum 模型,就是直接把整个文件夹复制下来

tensorflow/modelsgithub.com《安装 TensorFlow 之 textsum 文章自动摘要》

由于GitHub没有提供下载某个文件夹的按钮,似乎想要获得textsum 就需要下载整个TensorFlow,显然,这是愚蠢的行为,我们不应该去做。

比较Geek的处理方法是:登录某些网站(DownGit),粘贴连接,直接下载。

https://minhaskamal.github.io/DownGit/minhaskamal.github.io
DownGit
DownGitminhaskamal.github.io
《安装 TensorFlow 之 textsum 文章自动摘要》
《安装 TensorFlow 之 textsum 文章自动摘要》

『检查』

安装完 jdk 8,bazel,TensorFLow后,记得看看是否装上了,我喜欢顺便看看版本

java -version
    java version "1.8.0_121"
    Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
    Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

bazel version
    Build label: 0.11.1
    Build target: bazel-out/k8-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
    Build time: Tue May 14 07:48:23 +50148 (1520362424903)
    Build timestamp: 1520362424903
    Build timestamp as int: 1520362424903

>>> import tensorflow as tf
>>> tf.__version__
'1.6.0'

2.准备工作目录

参考textsum 目录(就是上面通过GitDown下载的textsum.zip)中的 README.md 文件,安装这里面提供的步骤,构建工作目录。

当然这一份 README.md ←你已经见过了,就在 GitHub textsum 的那个页面下方。

首先找一个合适的地方,建立一个不被打扰的工作目录,比如我

cd Videos  # 刚好在资源管理器有按钮可以直接去
mkdir Yonv_CWD  # Current Working Directory,Yonv这个名字是我随便起的

cd Yonv_CWD
#!注意,这里新建一个空的文件(注意不是文件夹而是空文件)
# WORKSPACE 是 bazel生成工作环境所必须的一个标记
touch WORKSPACW

# 这里是放训练集的,里面待会需要放入 二进制文件training-* 和 文本文件vocab
mkdir data

# 然后,退回到原来的 Yonv_CWD,开始用 bazel 建立工作环境
cd ..
bazel build -c opt --config=cuda textsum/...
# 注意,如果你的电脑没有 CUDA (Compute Unified Device Architecture)
# 也就是没有NVIDIA 的GPU的话,这一项就没必要加了
# 注意,textsum/... 后面的三个“...” 
$ bazel build -c opt textsum/...
...............
INFO: Analysed 7 targets (12 packages loaded).
INFO: Found 7 targets...
INFO: Elapsed time: 2.153s, Critical Path: 0.02s
INFO: Build completed successfully, 1 total action


# 强行加上也没关系,反正它只是WARRNING
# 再者说,学C++ 的人,难道会在乎终端返回的 WARRNING?
$ bazel build -c opt --config=cuda textsum/...
...............
WARNING: Config values are not defined in any .rc file: cuda
INFO: Analysed 7 targets (12 packages loaded).
INFO: Found 7 targets...
INFO: Elapsed time: 3.325s, Critical Path: 0.04s
INFO: Build completed successfully, 4 total actions

《安装 TensorFlow 之 textsum 文章自动摘要》
《安装 TensorFlow 之 textsum 文章自动摘要》 蓝色选中的三个文件是 bazel 运行前必备的,其他的lnk 是运行后才生产的,log 是我自己建立的

3.运行textsum

3.1 准备数据集

在GitHub下载的 textsum中,有用于测试的数据集,作者把这个数据集称为 toy,这个玩具一样的测试数据集很小,只有33KB,姑且将就一下。

把 YonvCWD/textsum/data 里面的 data 和 vocab 文件复制(反正不大)到 Yonv_CWD/data 里面,然后把 data文件重命名为 training-0(非必要)

cd Yonv_CWD
cp testsum/data/vocab data/vocab
cp testsum/data/data  data/training-0

3.1 生成自己的数据

这个一部分还在施工中,等我中文的数据清洗完,我会再完善这里的。

值得一提的是:为了加速计算,数据集除了 vocab,像 training-* validation-* test-* 都是二进制的,可以用 textsum/data/convertexample.py 去转化,转化的代码记录在 这个py文件的开头备注里面了,摘抄出来是↓

python data_convert_example.py \
    --command binary_to_text \
    --in_file data/data \
    --out_file data/text_data

python data_convert_example.py \
    --command text_to_binary \
    --in_file data/text_data \
    --out_file data/binary_data

《安装 TensorFlow 之 textsum 文章自动摘要》
《安装 TensorFlow 之 textsum 文章自动摘要》

左上:Yonv_CWD/data文件夹中的数据集

左下:Yonv_CWD/textsum/data文件夹中,尝试用convertexample.py 程序进行二进制 和 文本之间的转化: data(二进制) → testdata(文本)→ binary_data(二进制)

右二:打开后的vocab文件,可以看到是单词的频数表,其中<UNK></d>等是标签

右一:转化后的test_data文件,可以看到有 “abstract=” , “article=” 的标记

虽然这里使用了textsum 提供的测试数据(toy ^_^),少了数据获取和清洗步骤,但是我们总算是可以继续进行下去了。

3.2 训练、评估、输出

依照README.md 提供的语句,我们有三段脚本需要运行,依次是训练、评估、输出

# Run the training.
$ bazel-bin/textsum/seq2seq_attention \
    --mode=train \
    --article_key=article \  # 对应training-0(更名前是data文件)中的 标签"article"
    --abstract_key=abstract \# 对应training-0(更名前是data文件)中的 标签"abstract"
    --data_path=data/training-* \  # 这个文件是之前准备的
    --vocab_path=data/vocab \
    --log_root=textsum/log_root \  # 中间文件会保留在这里+
    --train_dir=textsum/log_root/train

# Run the eval. Try to avoid running on the same machine as training.
$ bazel-bin/textsum/seq2seq_attention \
    --mode=eval \
    --article_key=article \
    --abstract_key=abstract \
    --data_path=data/validation-* \  # 如果你只是想测试依然程序是否正常,直接复制 training-0吧
    --vocab_path=data/vocab \
    --log_root=textsum/log_root \
    --eval_dir=textsum/log_root/eval

# Run the decode. Run it when the model is mostly converged.
$ bazel-bin/textsum/seq2seq_attention \
    --mode=decode \
    --article_key=article \
    --abstract_key=abstract \
    --data_path=data/test-* \  # 如果你只是想测试依然程序是否正常,直接复制 training-0然后改名吧
    --vocab_path=data/vocab \
    --log_root=textsum/log_root \
    --decode_dir=textsum/log_root/decode \
    --beam_size=8

如果运行成功,那么它们的结果依次是:

training部分

$ bazel-bin/textsum/seq2seq_attention \
    --mode=train \
    --article_key=article \
    --abstract_key=abstract \
    --data_path=data/training-* \
    --vocab_path=data/vocab \
    --log_root=textsum/log_root \
    --train_dir=textsum/log_root/train

WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/nn_impl.py:1346: softmax_cross_entropy_with_logits (from tensorflow.python.ops.nn_ops) is deprecated and will be removed in a future version.
Instructions for updating:

Future major versions of TensorFlow will allow gradients to flow
into the labels input on backprop by default.

See tf.nn.softmax_cross_entropy_with_logits_v2.

WARNING:tensorflow:From /home/user/Videos/CWD/bazel-bin/textsum/seq2seq_attention.runfiles/__main__/textsum/seq2seq_attention.py:96: __init__ (from tensorflow.python.training.supervisor) is deprecated and will be removed in a future version.
Instructions for updating:
Please switch to tf.train.MonitoredTrainingSession
2018-03-19 13:55:43.347757: I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
running_avg_loss: 9.001080
running_avg_loss: 8.945733
...
吃个饭回来
...
running_avg_loss: 0.000241
running_avg_loss: 0.000298

eval 部分(validation)

$ bazel-bin/textsum/seq2seq_attention \
    --mode=eval \
    --article_key=article \
    --abstract_key=abstract \
    --data_path=data/validation-* \
    --vocab_path=data/vocab \
    --log_root=textsum/log_root \
    --eval_dir=textsum/log_root/eval

running_avg_loss: 0.000611
running_avg_loss: 0.000951
running_avg_loss: 0.000459
running_avg_loss: 0.000200
...

prediction 部分(test)输出部分

输出结果会在
Yonv_CWD/textsum/log_root/decode 文件夹中看到

user@debian:~/Videos/Yonv_CWD/textsum/log_root/decode$ zsh
➜  decode ls
decode1521440441  decode1521445096  ref1521440441  ref1521445096
➜  decode ls -al
总用量 1360
drwxr-xr-x 2 user user   4096 3月  19 22:31 .
drwxr-xr-x 5 user user   4096 3月  19 17:50 ..
-rw-r--r-- 1 user user      0 3月  19 14:20 decode1521440441
-rw-r--r-- 1 user user 647350 3月  19 17:50 decode1521445096
-rw-r--r-- 1 user user      0 3月  19 14:20 ref1521440441
-rw-r--r-- 1 user user 729342 3月  19 17:50 ref1521445096

可以看到,如果运行失败,那么即便会产出文件,它也是空的

成功产出的文件打开后是这样的

《安装 TensorFlow 之 textsum 文章自动摘要》
《安装 TensorFlow 之 textsum 文章自动摘要》 由于数据集小,所以产出的结果也只能是这样了

output=czechs outdrink germans in beer-guzzling stakes .
output=mexican financial markets end turbulent week .
output=abb to sell electrical explosion-proof equipment business .
output=mexican financial markets end turbulent week .
output=moslem rights group wants narcotic khat legalised .
output=abb to sell electrical explosion-proof equipment business .
output=mexican financial markets end turbulent week .
output=croatians vote in three constituencies .

如果你没有成功输出,那么可以看看我下面的『错误处理』

3.3错误处理

运行中如果出现类似错误,那么是因为你vocab格式不对,里面本来会有<标签>的,你需要17832:

Bad line: 
...
assert vocab.CheckVocab(data.SENTENCE_START) > 0

运行中如果出现类似错误,那么是因为你数据集 training-0 格式不对,你需要17832:

Exception in thread Thread-24809:
...
DecodeError: Error parsing message
...
MemoryError

运行中如果出现类似错误,不要理会它,没事的,相反的,如果你改了state_is_tuple=False,那么当TensorFlow 版本大于1.0 的时候你反而会出错:

...
state_is_tuple=False
...

运行中如果报错,类似于(出现某个很大的多维数组):

ValueError: Could not flatten dictionary. Key had 2 elements, but value had 1 elements. Key: [<tf.Tensor 'seq2seq/encoder3/bidirectional_rnn/fw/fw/cond_119/Merge_1:0' shape=(8, 256) dtype=float32>, <tf.Tensor 'seq2seq/encoder3/bidirectional_rnn/fw/fw/cond_119/Merge_2:0' shape=(8, 256) dtype=float32>], value: [array([[[ 2.723167  , -1.924321  , -0.09930453, ..., -0.57662404,
        -1.633333  ,  5.6171    ],
       [ 2.723167  , -1.924321  , -0.09930453, ..., -0.57662404,
        -1.633333  ,  5.6171    ],
       [ 2.723167  , -1.924321  , -0.09930453, ..., -0.57662404,
        -1.633333  ,  5.6171    ],
       ...,
       ...,
        [ 2.723167  , -1.924321  , -0.09930453, ..., -0.57662404,
         -1.633333  ,  5.6171    ],
        [ 2.723167  , -1.924321  , -0.09930453, ..., -0.57662404,
         -1.633333  ,  5.6171    ],
        [ 2.723167  , -1.924321  , -0.09930453, ..., -0.57662404,
         -1.633333  ,  5.6171    ]]], dtype=float32)].

那么是因为TensorFlow 1.0>= 的兼容问题

只要把 seq2seq_attention_model.py 文件中的 [state_is_tuple=True] 改回 [state_is_tuple=False]] (然而好多人需要把这个改回来,是因为想解决之前的另一个报错,才修改了这个文件(又改回来了))

yONV_CWD/textsum/seq2seq_attention_model.py
# replace [state_is_tuple=False] as [state_is_tuple=True]

他们↓ 也遇到这个问题了,并且ctrl+f[fix] 在某一行可以找到解决方法,就是把 文件中的[state_is_tuple=True] 改回 [state_is_tuple=False]

#TextSum# – Error running decode: Could not flatten dictionary. Key had 2 elements, but value had 1 elements · Issue #417 · tensorflow/models

    原文作者:曾伊言
    原文地址: https://zhuanlan.zhihu.com/p/34708542
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞