如何使用RNN模型实现文本自动生成

优采云 发布时间: 2020-08-07 21:48

  在自然语言处理中,另一个重要的应用领域是自动书写文本. 关键字,关键词和自动摘要提取都属于该领域的应用程序. 但是,这些应用程序的产生越来越多. 在这里,我们介绍了另一个应用程序: 从少到多的生成,包括句子复制,从关键字和主题生成文章或段落.

  基于关键字的自动文本生成模型

  本章的第一部分介绍了一些用于基于关键字生成文本段落的处理技术. 它主要是通过应用诸如关键字提取和同义词识别之类的技术来实现的. 实现过程将在下面进行解释和介绍.

  场景

  放置搜索引擎广告时,我们需要为广告写一个句子说明. 通常,模型的输入是一些关键字. 例如,假设广告的关键词为“花”和“便宜”,我们要放置的广告是花卉广告. 对于此输入,我们希望生成一定数量的候选单句广告描述.

  对于这种场景,也可以输入一个句子. 例如,我以前手动写过一个例子: “这个周末,白色的小花只有99元,还有免费送货和免费送货!”. 您需要复制一定数量的句子,这些句子的表达方式不同,但根据此句子具有相似的含义. 在这里,我们介绍一种基于关键字的文本(一个句子)自动生成模型.

  原理

  模型处理流程如图1所示.

  

  图1完成候选句子的提取后,有必要根据候选句子的数量来确定后续操作. 如果选择的候选句子大于或等于所需数目,则根据句子相似度从低到高选择指定数目的句子. 否则,必须复制该句子. 这里采用了根据指定模板进行同义词替换和重写的方案.

  实现

  计算候选句子的代码如下:

  Map result = new HashMap();

if (type == 0) {//输入为关键词

result = getKeyWordsSentence(keyWordsList);

}else {

result = getWordSimSentence(sentence);

}

//得到候选集数量大于等于要求的数量则对结果进行裁剪

if (result.size() >= number) {

result = sub(result, number);

}else {

//得到候选集数量小于要求的数量则对结果进行添加

result = add(result, number);

}

  实现句子相似度过滤计算的代码如下.

  for (String sen : sentenceList) {

//对待识别语句进行分词处理

List wordsList1 = parse(sentence);

List wordsList2 = parse(sen);

//首先判断两个语句是不是满足目标变换

boolean isPatternSim = isPatternSimSentence(wordsList1, wordsList2);

if (!isPatternSim) {//不满足目标变换

//首先计算两个语句的bi-gram相似度

double tmp = getBigramSim(wordsList1, wordsList2);

//这里的筛选条件是相似度小于阈值,因为bi-gram的相似度越小,代表两者越相似

if (threshold > tmp) {

result.put(sen,tmp);

}

}else {

result.put(sen,0.0);

}

}

  展开

  本节介绍的方案是: 文本到文本的生成. 这种情况通常主要涉及文本处理技术,例如文本摘要,句子压缩,文本复制和句子融合. 其中,本节涉及文本摘要和句子重写两个方面. 如上所述,文本摘要主要包括关键字提取,短语提取,句子提取等. 根据不同的实现方法,句子复制可以大致分为以下几种类型.

  基于统计模型和语义分析生成模型的重写方法. 这种方法是根据语料库中的数据进行统计以获得大量转换概率分布,然后根据已知的先验知识替换输入语料库. 这种方法的句子是根据分析结果生成的. 从某种意义上说,生成是在分析的指导下实现的. 因此,重写的句子可以具有良好的句子结构. 但是它所依赖的语料库非常大,需要手动注释大量数据. 对于这些问题,新的深度学习技术可以解决其中的一些问题. 同时,结合知识图谱的深度学习,可以更好地利用人类知识,并最大限度地减少训练样本的数据需求. RNN模型实现文本自动生成

  第6.1.2节介绍了一些基于短文本输入获取长文本的处理技术. 这里主要使用RNN网络,它利用其处理序列数据的能力来实现文本序列数据的自动填充. 这里是其实现细节的解释和介绍.

  场景

  在做广告的过程中,我们可能会遇到这种情况: 一个描述文本是从一个句子生成的,文本长度在200到300个单词之间. 输入也可能是某些主题的关键字.

  这时,我们需要一种算法,该算法可基于少量的文本输入生成大量的文本. 这是一种算法: RNN算法. 我们已在5.3节中介绍了该算法,并使用该算法将拼音转换为汉字. 实际上,这两个场景的模式相同,并且根据给定的文本信息生成其他文本信息. 区别在于,前者将生成与当前元素相对应的汉字,而这里将生成与当前元素相对应的下一个汉字.

  原理

  与5.3节相同,我们仍在这里使用简单RNN模型. 因此,整个计算流程图如图3所示.

  

  图3

  代码

  实现特征训练计算的代码如下:

   public double train(List x, List y) {

alreadyTrain = true;

double minError = Double.MAX_VALUE;

for (int i = 0; i < totalTrain; i++) {

//定义更新数组

double[][] weightLayer0_update = new double[weightLayer0.length][weightLayer0[0].length];

double[][] weightLayer1_update = new double[weightLayer1.length][weightLayer1[0].length];

double[][] weightLayerh_update = new double[weightLayerh.length][weightLayerh[0].length];

List hiddenLayerInput = new ArrayList();

List outputLayerDelta = new ArrayList();

double[] hiddenLayerInitial = new double[hiddenLayers];

//对于初始的隐含层变量赋值为0

Arrays.fill(hiddenLayerInitial, 0.0);

hiddenLayerInput.add(hiddenLayerInitial);

double overallError = 0.0;

//前向网络计算预测误差

overallError = propagateNetWork(x, y, hiddenLayerInput,

outputLayerDelta, overallError);

if (overallError < minError) {

minError = overallError;

}else {

continue;

}

first2HiddenLayer = Arrays.copyOf(hiddenLayerInput.get(hiddenLayerInput.size()-1), hiddenLayerInput.get(hiddenLayerInput.size()-1).length);

double[] hidden2InputDelta = new double[weightLayerh_update.length];

//后向网络调整权值矩阵

hidden2InputDelta = backwardNetWork(x, hiddenLayerInput,

outputLayerDelta, hidden2InputDelta,weightLayer0_update, weightLayer1_update, weightLayerh_update);

weightLayer0 = matrixAdd(weightLayer0, matrixPlus(weightLayer0_update, alpha));

weightLayer1 = matrixAdd(weightLayer1, matrixPlus(weightLayer1_update, alpha));

weightLayerh = matrixAdd(weightLayerh, matrixPlus(weightLayerh_update, alpha));

}

return -1.0;

}

  实现预测计算的代码如下:

   public double[] predict(double[] x) {

if (!alreadyTrain) {

new IllegalAccessError("model has not been trained, so can not to be predicted!!!");

}

double[] x2FirstLayer = matrixDot(x, weightLayer0);

double[] firstLayer2Hidden = matrixDot(first2HiddenLayer, weightLayerh);

if (x2FirstLayer.length != firstLayer2Hidden.length) {

new IllegalArgumentException("the x2FirstLayer length is not equal with firstLayer2Hidden length!");

}

for (int i = 0; i < x2FirstLayer.length; i++) {

firstLayer2Hidden[i] += x2FirstLayer[i];

}

firstLayer2Hidden = sigmoid(firstLayer2Hidden);

double[] hiddenLayer2Out = matrixDot(firstLayer2Hidden, weightLayer1);

hiddenLayer2Out = sigmoid(hiddenLayer2Out);

return hiddenLayer2Out;

}

  展开

  根据不同的输入法,可以将文本的生成分为以下几种类型:

  文本到文本的生成. 即,输入是文本,输出也是文本. 图片到文字. 即,输入是图像,而输出是文本. 数据到文本. 即,输入是数据,输出是文本. 其他. 也就是说,输入形式不是以上三种,但输出也是文本. 由于此类输入较难概括,因此将其归类为其他.

  其中,第二和第三部分最近发展很快,尤其是随着诸如深度学习和知识图谱之类的尖端技术的发展. 基于图像生成的文本描述的实验结果将不断更新. 基于GAN(专业神经网络)的图像文本生成技术已经实现了非常大的地图,不仅可以基于图片生成非常好的描述,还可以基于文本输入生成相应的图片.

  从数据生成文本,当前主要用于新闻写作. 中英文都取得了长足的进步. 美联社代表英文版本,腾讯代表中文版本. 当然,这两个都不是纯粹将数据用作输入,而是结合了以上四种情况的新闻写作.

  从技术上讲,当前有两种主流的实现方法: 一种是基于符号的,由知识图表示. 这种类型的方法使用更多的人类先验知识,并处理更多收录语义成分的文本. 另一种是基于统计(连接)的,即基于大量文本学习不同文本之间的组合规则,然后根据输入推断出可能的组合作为输出. 深度学习和知识图的结合,两者之间存在明显的融合现象,应该成为实现未来技术突破的重要节点.

  编者注: 本书主要从三个方面介绍与自然语言处理有关的一些技术: 语义模型的详细说明,自然语言处理系统的基本算法和实际系统情况. 分别从应用原理,数学原理,代码实现和当前方法的思考四个方面对每种算法进行解释.

  单击以查看详细信息:

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线