Home

Awesome

<h1 align="center">Fancy-NLP</h1> <p align="center">NLP for human. A fast and easy-to-use natural language processing (NLP) toolkit, satisfying your imagination about NLP.</p> <p align="left"><a href="https://github.com/boat-group/fancy-nlp/blob/master/README.md"><sup>→ English version</sup></a></p> <div align="center"> <img src="./img/fancy-nlp_300-180_white.jpg"> </div> <p align="center"> <a href="https://github.com/boat-group/fancy-nlp/stargazers"> <img src="https://img.shields.io/github/stars/boat-group/fancy-nlp.svg?colorA=orange&colorB=orange&logo=github" alt="GitHub stars"> </a> <a href="https://github.com/boat-group/fancy-nlp/network/members"> <img src="https://img.shields.io/github/forks/boat-group/fancy-nlp.svg?colorA=orange&colorB=orange&logo=github" alt="GitHub forks"> </a> <a href="https://travis-ci.org/boat-group/fancy-nlp"> <img src="https://travis-ci.org/boat-group/fancy-nlp.svg?branch=master" alt="Build status"> </a> <a href="https://pypi.org/project/fancy-nlp"> <img src="https://img.shields.io/pypi/v/fancy-nlp.svg?colorB=brightgreen" alt="Pypi package"> </a> <a href="https://pypi.org/project/fancy-nlp"> <img src="https://img.shields.io/pypi/dm/fancy-nlp" alt="PyPI - Downloads"> </a> <a href="https://github.com/boat-group/fancy-nlp/blob/master/LICENSE"> <img src="https://img.shields.io/github/license/boat-group/fancy-nlp.svg" alt="GitHub license"> </a> <a href="https://coveralls.io/github/boat-group/fancy-nlp?branch=master"> <img src="https://coveralls.io/repos/github/boat-group/fancy-nlp/badge.svg?branch=master" alt="Coverage status"> </a> <a href="http://commitizen.github.io/cz-cli/"> <img src="https://img.shields.io/badge/commitizen-friendly-brightgreen.svg" alt="Commitizen friendly"> </a> </p> <p align="center"> <a href="#基本介绍">基本介绍</a> • <a href="#安装">安装</a> • <a href="#入门指引">入门指引</a> • <a href="#详细教程">详细教程</a> • <a href="#荣誉奖励">荣誉奖励</a> • <a href="#如何贡献代码">如何贡献代码</a> • <a href="#引用">引用</a> • <a href="#致谢">致谢</a> </p> <h2 align="center">基本介绍</h2>

Fancy-NLP 是由腾讯商品广告策略组团队构建的用于建设商品画像的文本知识挖掘工具,其支持诸如实体提取、文本分类和文本相似度匹配等多种常见 NLP 任务。与当前业界常用框架相比,其能够支持用户进行快速的功能实现:既可以满足高阶用户对模型进行深度定制,也可以让普通用户快速利用预训练的模型快速进行功能实践。在当前的商品广告业务场景中,我们利用该工具快速挖掘海量商品数据的特征,从而支持广告商品推荐等模块中。

项目的初衷是希望提供一套易用的NLP工具,其直接面向使用场景,满足用户对NLP任务的需求,使得用户无需处理复杂的预处理等中间过程,直接针对输入的自然语言文本来完成多种NLP任务,实现所想即所得!

Fancy 是什么寓意?对于当前众多的NLP任务,例如实体识别(Named Entity Recognition, NER)、文本分类以及文本相似度匹配(Sentence Pair Matching, SPM),大多数工具的设计都是偏向于模型的训练和评估。当普通用户希望将这些模型应用于实际业务场景中时,往往需要进行复杂的预处理和部署配置,这些过程往往和用户所期望的流程不符。因此 Fancy 的寓意为满足你的想象,你可以在 Fancy-NLP 中实现对 NLP 任务各个环节的一键式处理,高效将模型应用于实际的需求场景中。

<h2 align="center">安装</h2>

Fancy-NLP 当前支持在Python 3环境下使用,且在Python 3.6中进行了完整的测试。当前的版本中已全面依赖 Tensorflow 2.x,如果你对模块的兼容性有所担忧,我们建议你使用 virtualenv 来创建虚拟环境以使用本工具。

Fancy-NLP 支持使用 pip 来进行一键式安装:

pip install fancy-nlp
<h2 align="center">入门指引</h2>

在入门指引中,我们将使用预训练模型来带你快速了解和体验 Fancy-NLP 的基本功能。

注:我们将在随后不断优化多种场景(不同标注数据)的实体识别模型,以供用户直接使用,如果你有相关数据集,也欢迎在 issue 中给我们积极反馈

实体识别使用指引

当前版本的 Fancy-NLP 可以默认加载使用了 MSRA NER 子集数据 训练得到的NER模型,其能够对中文文本中的组织机构(ORG)、地点(LOC)以及人物(PER)实体进行识别,默认加载的基础模型是为了便于用户直接体验。若想直接使用自己训练的自定义模型,你可以参照后续详细教程中的介绍,来构建你的实体提取系统。

初始化实体识别应用程序

>>> from fancy_nlp.applications import NER
>>> ner_app = NER()

第一次运行以上代码时,会从云端下载预训练的 NER 模型。

输出文本中的实体信息

>>> ner_app.analyze('同济大学位于上海市杨浦区,校长为陈杰')
{'text': '同济大学位于上海市杨浦区,校长为陈杰',
 'entities': [
  {'name': '同济大学',
   'type': 'ORG',
   'score': 1.0,
   'beginOffset': 0,
   'endOffset': 4},
  {'name': '上海市',
   'type': 'LOC',
   'score': 1.0,
   'beginOffset': 6,
   'endOffset': 9},
  {'name': '杨浦区',
   'type': 'LOC',
   'score': 1.0,
   'beginOffset': 9,
   'endOffset': 12},
  {'name': '陈杰',
   'type': 'PER',
   'score': 1.0,
   'beginOffset': 16,
   'endOffset': 18}]}

限制输出结果中,每种实体只保留一个实体,取得分最高的实体

>>> ner_app.restrict_analyze('同济大学位于上海市杨浦区,校长为陈杰')
{'text': '同济大学位于上海市杨浦区,校长为陈杰',
 'entities': [
  {'name': '同济大学',
   'type': 'ORG',
   'score': 1.0,
   'beginOffset': 0,
   'endOffset': 4},
  {'name': '杨浦区',
   'type': 'LOC',
   'score': 1.0,
   'beginOffset': 9,
   'endOffset': 12},
  {'name': '陈杰',
   'type': 'PER',
   'score': 1.0,
   'beginOffset': 16,
   'endOffset': 18}]}

查看具体的序列标注结果

>>> ner_app.predict('同济大学位于上海市杨浦区,校长为陈杰')
['B-ORG',
 'I-ORG',
 'I-ORG',
 'I-ORG',
 'O',
 'O',
 'B-LOC',
 'I-LOC',
 'I-LOC',
 'B-LOC',
 'I-LOC',
 'I-LOC',
 'O',
 'O',
 'O',
 'O',
 'B-PER',
 'I-PER']

文本分类使用指引

Fancy-NLP 中默认加载了在当前公开的中文新闻标题分类数据集训练得到的文本分类模型,其能够针对新闻标题文本,预测其所属的新闻类别。

初始化文本分类应用程序

>>> from fancy_nlp.applications import TextClassification
>>> text_classification_app = TextClassification()

第一次运行以上程序时,会从云端下载预训练模型。

直接预测文本类别

>>> text_classification_app.predict('苹果iOS占移动互联网流量份额逾65% 位居第一')
'科技'

输出文本分类得到的目标类别和得分

>>> text_classification_app.analyze('苹果iOS占移动互联网流量份额逾65% 位居第一')
('科技', 0.9996544)

文本相似度匹配使用指引

Fancy-NLP 中默认加载了在当前公开的微众银行客服问句匹配数据集训练得到的文本相似度匹配模型,其能够针对所提供的文本对,预测其是否表达相同的意图。

初始化文本相似度匹配应用程序

>>> from fancy_nlp.applications import SPM
>>> spm_app = SPM()

第一次运行以上程序时,会从云端下载预训练的文本相似度匹配模型。

预测文本对是否表达相同意图

>>> spm_app.predict(('未满足微众银行审批是什么意思', '为什么我未满足微众银行审批'))
'1'

预测结果中,1表示相同意图或相似文本,0表示不同意图或不相似文本。

预测文本对是否表达相同意图及其在不同标签上的得分

>>> spm_app.analyze(('未满足微众银行审批是什么意思', '为什么我未满足微众银行审批'))
('1', array([1.6599501e-09, 1.0000000e+00], dtype=float32))
<h2 align="center">详细教程</h2>

详细教程中,你可以了解如何使用 Fancy-NLP 使用你自己的数据集,构建适用于满足自定义场景的自定义模型,并对 Fancy-NLP 的接口有着更加全面的了解。

数据下载

为了完整的体验以下教程,你需要下载我们使用的数据集和BERT 模型:

你可以将下载的数据移动至与examples目录平级,最终的目录结构如下:

.
├── datasets
│   ├── ner
│   │   └── msra
│   │       ├── test_data
│   │       └── train_data
│   ├── spm
│   │   └── webank
│   │       ├── BQ_dev.txt
│   │       ├── BQ_test.txt
│   │       └── BQ_train.txt
│   └── text_classification
│       └── toutiao
│           ├── toutiao_cat_data.txt
│           └── toutiao_label_dict.txt
├── examples
│   ├── bert_combination.py
│   ├── bert_fine_tuning.py
│   ├── bert_single.py
│   ├── ner_example.py
│   ├── spm_example.py
│   └── text_classification_example.py
└── pretrained_embeddings
    └── chinese_L-12_H-768_A-12
        ├── bert_config.json
        ├── bert_model.ckpt.data-00000-of-00001
        ├── bert_model.ckpt.index
        ├── bert_model.ckpt.meta
        └── vocab.txt

从而你可以直接运行示例程序。例如, python examples/ner_example.py

实体识别任务

我们依然采用上文提到过的 MSRA NER 子集数据 为例,来介绍如何使用已有的数据集,来训练属于自己的实体识别模型。以下所有代码片段的完整版,可参考 examples/ner_example.py

数据集准备

在 Fancy-NLP 中,实体识别应用程序支持使用标准的 NER 数据集格式,每个待识别的字符和其对应的标签采用 \t 分隔,句子与句子之间采用空行分隔。标签的格式可以是 BIOBIOES 等常见的标准格式。

加载训练集和验证集

使用 Fancy-NLP 提供的接口,我们可以直接对数据集进行加载,并处理成模型所需要的格式。

from fancy_nlp.applications import NER
ner_app = NER(use_pretrained=False)

from fancy_nlp.utils import load_ner_data_and_labels
train_data, train_labels = load_ner_data_and_labels('datasets/ner/msra/train_data')
valid_data, valid_labels = load_ner_data_and_labels('datasets/ner/msra/test_data')

load_ner_data_and_labels 实现了对 NER 数据集的有效加载,你可以直接将需要加载的数据(训练集、验证集或测试集)文件路径作为参数,这里使用了测试集来作为验证集。实际任务中,你应该具有各自独立的验证集和测试集,从而获得有价值的测试评估结果。

训练模型

当获得了有效的数据后,NER 应用程序就可以开始直接进行模型的训练。

checkpoint_dir = 'pretrained_models'
model_name = 'msra_ner_bilstm_cnn_crf'
ner_app.fit(train_data, train_labels, valid_data, valid_labels,
            ner_model_type='bilstm_cnn',
            char_embed_trainable=True,
            callback_list=['modelcheckpoint', 'earlystopping', 'swa'],
            checkpoint_dir=checkpoint_dir,
            model_name=model_name,
            load_swa_model=True)

对于 NER 应用程序的 fit 接口,你需要传入之前处理过的训练集和验证集样本,其余参数的含义如下:

使用测试集评估模型效果

test_data, test_labels = load_ner_data_and_labels('datasets/ner/msra/test_data')
ner_app.score(test_data, test_labels)

这里依然使用 load_ner_data_and_labels 来处理测试集数据。得到有效的数据格式后,直接使用 NER 应用程序的 score 接口来获取模型在测试集中的得分。

保存训练模型

在训练完模型后,需要将任务需要的所有模型相关文件进行保存,以便于在外部其它应用中使用 Fancy-NLP 训练过的模型。

import os
ner_app.save(
    preprocessor_file=os.path.join(checkpoint_dir, f'{model_name}_preprocessor.pkl'),
    json_file=os.path.join(checkpoint_dir, f'{model_name}.json'))

NER应用程序的 save 接口可以用来将模型的结构文件(json)以及权重文件(hdf5)和预处理的相关结果(pickle)进行持久化保存:

加载先前训练得到的模型进行预测

ner_app.load(
    preprocessor_file=os.path.join(checkpoint_dir, f'{model_name}_preprocessor.pkl'),
    json_file=os.path.join(checkpoint_dir, f'{model_name}.json'),
    weights_file=os.path.join(checkpoint_dir, f'{model_name}_swa.hdf5'))

此时的 ner_app 就已经具有了对样本进行预测的能力,你就可以完成在 入门指引 中提到的相关预测功能。例如,analyzerestrict_analyze

文本分类任务

我们依然采用上文提到过的 中文新闻标题分类数据集 为例,来介绍如何使用已有的数据集,来训练属于自己的文本分类模型。以下所有代码片段的完整版,可参考 examples/text_classification_example.py

数据集准备

在 Fancy-NLP 中,文本分类应用程序支持使用原始文本采用固定分隔符分隔的数据集格式,其可以有多余的和文本分类任务无关的列,只需要保证标签列和输入文本列都处于统一的固定位置即可。

此外,对于分类标签,还需要准备一份标签和标签ID的映射文件,其由两列组成:第一列为标签在数据集中的原始名称,通常为一些编码的ID;第二列为标签原始名称对应的可读名称。该文件的对应关系,将用于在模型预测时,直接输出可读的标签名称。

加载训练集和验证集

使用 Fancy-NLP 提供的接口,我们可以直接对数据集进行加载,并处理成模型所需要的格式。

from fancy_nlp.applications import TextClassification
text_classification_app = TextClassification(use_pretrained=False)

data_file = 'datasets/text_classification/toutiao/toutiao_cat_data.txt'

from fancy_nlp.utils import load_text_classification_data_and_labels
train_data, train_labels, valid_data, valid_labels, test_data, test_labels =
    load_text_classification_data_and_labels(data_file,
                                             label_index=1,
                                             text_index=3,
                                             delimiter='_!_',
                                             split_mode=2,
                                             split_size=0.3)

load_ner_data_and_labels 实现了对文本分类数据集的有效加载,你可以直接将需要加载的数据(训练集、验证集或测试集)文件路径作为参数,这里使用了完整的数据来划分训练集、验证集和测试集。除了数据文件,上述其余参数的具体含义为:

训练模型

当获得了有效的数据后,文本分类应用程序就可以开始直接进行模型的训练。

dict_file = 'datasets/text_classification/toutiao/toutiao_label_dict.txt'
model_name = 'toutiao_text_classification_cnn'
checkpoint_dir = 'pretrained_models'
text_classification_app.fit(
    train_data, train_labels, valid_data, valid_labels,
    text_classification_model_type='cnn',
    char_embed_trainable=True,
    callback_list=['modelcheckpoint', 'earlystopping', 'swa'],
    checkpoint_dir=checkpoint_dir,
    model_name=model_name,
    label_dict_file=dict_file,
    max_len=60,
    load_swa_model=True)

对于文本分类应用程序的 fit 接口,你需要传入之前处理过的训练集和验证集样本,其余参数的含义如下:

使用测试集评估模型效果

text_classification_app.score(test_data, test_labels)

这里可以直接使用文本分类应用程序的 score 接口来获取模型在测试集中的得分。

保存训练模型

在训练完模型后,需要将任务需要的所有模型相关文件进行保存,以便于在外部其它应用中使用 Fancy-NLP 训练过的模型。

import os
text_classification_app.save(
    preprocessor_file=os.path.join(checkpoint_dir, f'{model_name}_preprocessor.pkl'),
    json_file=os.path.join(checkpoint_dir, f'{model_name}.json'))

文本分类应用程序的 save 接口可以用来将模型的结构文件(json)以及权重文件(hdf5)和预处理的相关结果(pickle)进行持久化保存:

加载先前训练得到的模型进行预测

text_classification_app.load(
    preprocessor_file=os.path.join(checkpoint_dir, f'{model_name}_preprocessor.pkl'),
    json_file=os.path.join(checkpoint_dir, f'{model_name}.json'),
    weights_file=os.path.join(checkpoint_dir, f'{model_name}_swa.hdf5'))

此时的 text_classification_app 就已经具有了对样本进行预测的能力,你就可以完成在 入门指引 中提到的相关预测功能。例如,predictanalyze

文本相似度匹配任务

我们依然采用上文提到过的 微众银行客服问句匹配数据集 为例,介绍如何使用已有的数据集来训练属于自己的文本相似度匹配模型。以下所有代码片段的完整版,可参考 examples/spm_example.py

数据集准备

在 Fancy-NLP 中,文本相似度匹配任务应用程序支持使用原始文本采用\t分隔的数据集格式,其由三列组成:第一列和第二列分别为一组文本对;第三列为样本的标签,1表示文本语义相似,0表示不相似。

加载训练集和验证集

使用 Fancy-NLP 提供的接口,我们可以直接对数据集进行加载,并处理成模型所需要的格式。

from fancy_nlp.applications import SPM
spm_app = applications.SPM(use_pretrained=False)

train_file = 'datasets/spm/webank/BQ_train.txt'
valid_file = 'datasets/spm/webank/BQ_dev.txt'

from fancy_nlp.utils import load_spm_data_and_labels
train_data, train_labels = load_spm_data_and_labels(train_file)
valid_data, valid_labels = load_spm_data_and_labels(valid_file)

load_spm_data_and_labels 实现了对文本相似度匹配数据集的有效加载,你可以直接将需要加载的数据(训练集、验证集或测试集)文件路径作为参数。

训练模型

当获得了有效的数据后,文本相似度匹配应用程序就可以开始直接进行模型的训练。

model_name = 'spm_siamese_cnn'
checkpoint_dir = 'pretrained_models'
spm_app.fit(train_data, train_labels, valid_data, valid_labels,
            spm_model_type='siamese_cnn',
            word_embed_trainable=True,
            callback_list=['modelcheckpoint', 'earlystopping', 'swa'],
            checkpoint_dir=checkpoint_dir,
            model_name=model_name,
            max_len=60,
            load_swa_model=True)

对于文本相似度匹配应用程序的 fit 接口,你需要传入之前处理过的训练集和验证集样本,其余参数的含义如下:

使用测试集评估模型效果

test_file = 'datasets/spm/webank/BQ_test.txt'
test_data, test_labels = load_spm_data_and_labels(test_file)
spm_app.score(test_data, test_labels)

这里可以直接使用文本相似度匹配应用程序的 score 接口来获取模型在测试集中的得分。

保存训练模型

在训练完模型后,需要将任务需要的所有模型相关文件进行保存,以便于在外部其它应用中使用 Fancy-NLP 训练过的模型。

import os
spm_app.save(
    preprocessor_file=os.path.join(checkpoint_dir, f'{model_name}_preprocessor.pkl'),
    json_file=os.path.join(checkpoint_dir, f'{model_name}.json'))

文本相似度匹配应用程序的 save 接口可以用来将模型的结构文件(json)以及权重文件(hdf5)和预处理的相关结果(pickle)进行持久化保存:

加载先前训练得到的模型进行预测

spm_app.load(
    preprocessor_file=os.path.join(checkpoint_dir, f'{model_name}_preprocessor.pkl'),
    json_file=os.path.join(checkpoint_dir, f'{model_name}.json'),
    weights_file=os.path.join(checkpoint_dir, f'{model_name}_swa.hdf5'))

此时的 spm_app 就已经具有了对样本进行预测的能力,你可以继续完成在 入门指引 中提到的相关预测功能。例如,predictanalyze

BERT 模型的使用

Facny-NLP 提供了各种使用 BERT 模型的方法:

要想在 Fancy-NLP 中使用 BERT,你只需要下载好预训练的 BERT 模型(如谷歌官方提供的中文 BERT 模型、百度提供的 ERNIE 模型(提取码:iq74)、哈尔滨工业大学提供的 BERT-wwm 模型)。之后就可以在相关应用程序的 fit 方法中传入 BERT 模型的词表文件、配置文件、模型文件的路径。下面以实体识别应用程序为例给出三种使用方法的示范。完整的示例代码,请参考 examples/bert_fine_tuning.pyexamples/bert_single.pyexamples/bert_combination.py

注意 BERT 模型只能与字符向量共同使用,不能与词向量共同使用。

微调 BERT 模型

import tensorflow as tf
from fancy_nlp.applications import NER
ner_app = NER(use_pretrained=False)

from fancy_nlp.utils import load_ner_data_and_labels
train_data, train_labels = load_ner_data_and_labels('datasets/ner/msra/train_data')
valid_data, valid_labels = load_ner_data_and_labels('datasets/ner/msra/test_data')
ner_app.fit(train_data, train_labels, valid_data, valid_labels,
            ner_model_type='bert',
            use_char=False,       
            use_word=False,
            use_bert=True,
            bert_vocab_file='pretrained_embeddings/chinese_L-12_H-768_A-12/vocab.txt',
            bert_config_file='pretrained_embeddings/chinese_L-12_H-768_A-12/bert_config.json',
            bert_checkpoint_file='pretrained_embeddings/chinese_L-12_H-768_A-12/bert_model.ckpt',
            bert_trainable=True,
            optimizer=tf.keras.optimizers.Adam(1e-5),
            callback_list=['modelcheckpoint', 'earlystopping', 'swa'],
            checkpoint_dir='pretrained_models',
            model_name='msra_ner_bert_crf',
            load_swa_model=True)

在以上代码片段中,需要注意的是:

使用 BERT 模型的输出向量作为下游任务模型的特征输入

from fancy_nlp.applications import NER
ner_app = NER(use_pretrained=False)

from fancy_nlp.utils import load_ner_data_and_labels
train_data, train_labels = load_ner_data_and_labels('datasets/ner/msra/train_data')
valid_data, valid_labels = load_ner_data_and_labels('datasets/ner/msra/test_data')
ner_app.fit(train_data, train_labels, valid_data, valid_labels,
            ner_model_type='bilstm_cnn',
            use_char=False,
            use_word=False,       
            use_bert=True,
            bert_vocab_file='pretrained_embeddings/chinese_L-12_H-768_A-12/vocab.txt',
            bert_config_file='pretrained_embeddings/chinese_L-12_H-768_A-12/bert_config.json',
            bert_checkpoint_file='pretrained_embeddings/chinese_L-12_H-768_A-12/bert_model.ckpt',
            bert_trainable=False,
            optimizer='adam',
            callback_list=['modelcheckpoint', 'earlystopping', 'swa'],
            checkpoint_dir='pretrained_models',
            model_name='msra_ner_bilstm_cnn_bert_crf',
            load_swa_model=True)

在以上代码片段中,需要注意的是:

结合 BERT 输出向量以及其他特征向量

import tensorflow as tf
from fancy_nlp.applications import NER
ner_app = NER(use_pretrained=False)

from fancy_nlp.utils import load_ner_data_and_labels
train_data, train_labels = load_ner_data_and_labels('datasets/ner/msra/train_data')
valid_data, valid_labels = load_ner_data_and_labels('datasets/ner/msra/test_data')
ner_app.fit(train_data, train_labels, valid_data, valid_labels,
            ner_model_type='bilstm_cnn',
            use_char=True,
            use_word=False,
            use_bert=True,
            bert_vocab_file='pretrained_embeddings/chinese_L-12_H-768_A-12/vocab.txt',
            bert_config_file='pretrained_embeddings/chinese_L-12_H-768_A-12/bert_config.json',
            bert_checkpoint_file='pretrained_embeddings/chinese_L-12_H-768_A-12/bert_model.ckpt',
            bert_trainable=True,
            optimizer=tf.keras.optimizers.Adam(1e-5),
            callback_list=['modelcheckpoint', 'earlystopping', 'swa'],
            checkpoint_dir='pretrained_models',
            model_name='msra_ner_bilstm_cnn_char_bert_crf',
            load_swa_model=True)

在以上代码片段中,需要注意的是:

<h2 align="center">荣誉奖励</h2> <h2 align="center">如何贡献代码</h2>

请有意改进 Fancy NLP 代码的开发者遵循一下规范来提交 Pull requests:

<h2 align="center">引用</h2>

如果你在相关研究过程中使用了 Fancy NLP,你可以将以下内容加入到引用列表中

@misc{tencent2019fancynlp,
  title={Fancy-NLP},
  author={Li Yang and Shiyao Xu and Shijia E},
  howpublished={\url{https://github.com/boat-group/fancy-nlp}},
  year={2019}
}
<h2 align="center">致谢</h2> <p align="right"><a href="#Fancy-NLP"><sup>▴ 返回顶部</sup></a></p>

本项目的灵感来自于众多的优秀的开源项目,尤其是Keras,正如Keras的slogan: Deep learning for human 所说,我们希望 Fancy NLP 是 NLP for human,尤其在中文领域。