允中 发自 凹非寺

量子位 报道 | 公众号 QbitAI

在自然语言处理中,情感分析一般是指判断一段文本所表达的情绪状态。其中,一段文本可以是一个句子,一个段落或一个文档。情绪状态可以是两类,如(正面,负面),(高兴,悲伤);也可以是三类,如(积极,消极,中性)等等。

情感分析的应用场景十分广泛,如把用户在购物网站(亚马逊、天猫、淘宝等)、旅游网站、电影评论网站上发表的评论分成正面评论和负面评论;或为了分析用户对于某一产品的整体使用感受,抓取产品的用户评论并进行情感分析等等。

今天是5月20日,PaddlePaddle教你用情感分析算法体会女神心意。

在下文中,我们将以情感分析为例,介绍使用深度学习的方法进行端对端的短文本分类,并使用PaddlePaddle完成全部相关实验。

项目地址:

https://github.com/PaddlePaddle/book/blob/develop/06.understand_sentiment/README.cn.md

应用背景

在自然语言处理中,情感分析属于典型的文本分类问题,即把需要进行情感分析的文本划分为其所属类别。文本分类涉及文本表示分类方法两个问题。

在深度学习的方法出现之前,主流的文本表示方法为词袋模型BOW(bag of words),话题模型等等;分类方法有SVM(support vector machine), LR(logistic regression)等等。

对于一段文本,BOW表示会忽略其词顺序、语法和句法,将这段文本仅仅看做是一个词集合,因此BOW方法并不能充分表示文本的语义信息。

例如,句子“这部电影糟糕透了”和“一个乏味,空洞,没有内涵的作品”在情感分析中具有很高的语义相似度,但是它们的BOW表示的相似度为0。又如,句子“一个空洞,没有内涵的作品”和“一个不空洞而且有内涵的作品”的BOW相似度很高,但实际上它们的意思很不一样。

在本教程中,我们所要介绍的深度学习模型克服了BOW表示的上述缺陷,它在考虑词顺序的基础上把文本映射到低维度的语义空间,并且以端对端(end to end)的方式进行文本表示及分类,其性能相对于传统方法有显著的提升[1]。

模型概览

本教程所使用的文本表示模型为卷积神经网络(Convolutional Neural Networks)和循环神经网络(Recurrent Neural Networks)及其扩展。下面依次介绍这几个模型。

文本卷积神经网络简介(CNN)

对卷积神经网络来说,首先使用卷积处理输入的词向量序列,产生一个特征图(feature map),对特征图采用时间维度上的最大池化(max pooling over time)操作得到此卷积核对应的整句话的特征,最后,将所有卷积核得到的特征拼接起来即为文本的定长向量表示,对于文本分类问题,将其连接至softmax即构建出完整的模型。

在实际应用中,我们会使用多个卷积核来处理句子,窗口大小相同的卷积核堆叠起来形成一个矩阵,这样可以更高效的完成运算。另外,我们也可使用窗口大小不同的卷积核来处理句子,图1表示卷积神经网络文本分类模型,不同颜色表示不同大小的卷积核操作。

对于一般的短文本分类问题,上文所述的简单的文本卷积网络即可达到很高的正确率[1]。若想得到更抽象更高级的文本特征表示,可以构建深层文本卷积神经网络[2,3]。

循环神经网络(RNN)

循环神经网络是一种能对序列数据进行精确建模的有力工具。实际上,循环神经网络的理论计算能力是图灵完备的[4]。自然语言是一种典型的序列数据(词序列),近年来,循环神经网络及其变体(如long short term memory[5]等)在自然语言处理的多个领域,如语言模型、句法解析、语义角色标注(或一般的序列标注)、语义表示、图文生成、对话、机器翻译等任务上均表现优异甚至成为目前效果最好的方法。

循环神经网络按时间展开后如图2所示:在第t时刻,网络读入第t个输入(向量表示)及前一时刻隐层的状态值 (向量表示,一般初始化为0向量),计算得出本时刻隐层的状态值,重复这一步骤直至读完所有输入。如果将循环神经网络所表示的函数记为f,则其公式可表示为:

其中是输入到隐层的矩阵参数,是隐层到隐层的矩阵参数,为隐层的偏置向量(bias)参数,σ为sigmoid函数。

在处理自然语言时,一般会先将词(one-hot表示)映射为其词向量表示,然后再作为循环神经网络每一时刻的输入。此外,可以根据实际需要的不同在循环神经网络的隐层上连接其它层。如,可以把一个循环神经网络的隐层输出连接至下一个循环神经网络的输入构建深层(deep or stacked)循环神经网络,或者提取最后一个时刻的隐层状态作为句子表示进而使用分类模型等等。

长短期记忆网络(LSTM)

对于较长的序列数据,循环神经网络的训练过程中容易出现梯度消失或爆炸现象[6]。LSTM能够解决这一问题。相比于简单的循环神经网络,LSTM增加了记忆单元c、输入门i、遗忘门f及输出门o。这些门及记忆单元组合起来大大提升了循环神经网络处理长序列数据的能力。若将基于LSTM的循环神经网络表示的函数记为F,则其公式为:

F由下列公式组合而成[7]:

其中,分别表示输入门,遗忘门,记忆单元及输出门的向量值,带角标的W及b为模型参数,tanh为双曲正切函数,⊙表示逐元素(elementwise)的乘法操作。输入门控制着新输入进入记忆单元c的强度,遗忘门控制着记忆单元维持上一时刻值的强度,输出门控制着输出记忆单元的强度。三种门的计算方式类似,但有着完全不同的参数,它们各自以不同的方式控制着记忆单元c,如图3所示:

LSTM通过给简单的循环神经网络增加记忆及控制门的方式,增强了其处理远距离依赖问题的能力。类似原理的改进还有Gated Recurrent Unit (GRU)[8],其设计更为简洁一些。这些改进虽然各有不同,但是它们的宏观描述却与简单的循环神经网络一样(如图2所示),即隐状态依据当前输入及前一时刻的隐状态来改变,不断地循环这一过程直至输入处理完毕:

其中,Recrurent可以表示简单的循环神经网络、GRU或LSTM。

栈式双向LSTM(Stacked Bidirectional LSTM)

对于正常顺序的循环神经网络,包含了t时刻之前的输入信息,也就是上文信息。同样,为了得到下文信息,我们可以使用反方向(将输入逆序处理)的循环神经网络。结合构建深层循环神经网络的方法(深层神经网络往往能得到更抽象和高级的特征表示),我们可以通过构建更加强有力的基于LSTM的栈式双向循环神经网络[9],来对时序数据进行建模。

如图4所示(以三层为例),奇数层LSTM正向,偶数层LSTM反向,高一层的LSTM使用低一层LSTM及之前所有层的信息作为输入,对最高层LSTM序列使用时间维度上的最大池化即可得到文本的定长向量表示(这一表示充分融合了文本的上下文信息,并且对文本进行了深层次抽象),最后我们将文本表示连接至softmax构建分类模型。

基于PaddlePaddle的实战

PaddlePaddle简介

PaddlePaddle(paddlepaddle.org)是百度研发的深度学习框架。除了核心框架之外,PaddlePaddle还提供了丰富的工具组件。官方开源了多个工业级应用模型,涵盖自然语言处理、计算机视觉、推荐引擎等多个领域,并开放了多个领先的预训练中文模型。4月23日深度学习开发者峰会上,PaddlePaddle发布了一系列新特性和应用案例。

数据集介绍

我们以IMDB情感分析数据集为例进行介绍。IMDB数据集的训练集和测试集分别包含25000个已标注过的电影评论。其中,负面评论的得分小于等于4,正面评论的得分大于等于7,满分10分。


aclImdb|- test   |-- neg   |-- pos|- train   |-- neg   |-- pos   |-- neg   |-- pos|- train   |-- neg   |-- pos

PaddlePaddle在 dataset/imdb.py 中实现了imdb数据集的自动下载和读取,并提供了读取字典、训练数据、测试数据等API。

配置模型

在该示例中,我们实现了两种文本分类算法,文本卷积神经网络,和栈式双向LSTM。我们首先引入要用到的库和定义全局变量:


from __future__ import print_functionimport paddleimport paddle.fluid as fluidimport numpy as npimport sysimport mathCLASS_DIM = 2     #情感分类的类别数EMB_DIM = 128     #词向量的维度HID_DIM = 512     #隐藏层的维度STACKED_NUM = 3   #LSTM双向栈的层数BATCH_SIZE = 128  #batch的大小import print_functionimport paddleimport paddle.fluid as fluidimport numpy as npimport sysimport math

CLASS_DIM = 2     #情感分类的类别数EMB_DIM = 128     #词向量的维度HID_DIM = 512     #隐藏层的维度STACKED_NUM = 3   #LSTM双向栈的层数BATCH_SIZE = 128  #batch的大小

文本卷积神经网络

我们构建神经网络 convolution_net,示例代码如下。 需要注意的是:fluid.nets.sequence_conv_pool 包含卷积和池化层两个操作。


#文本卷积神经网络def convolution_net(data, input_dim, class_dim, emb_dim, hid_dim):    emb = fluid.layers.embedding(        input=data, size=[input_dim, emb_dim], is_sparse=True)    conv_3 = fluid.nets.sequence_conv_pool(        input=emb,        num_filters=hid_dim,        filter_size=3,        act="tanh",        pool_type="sqrt")    conv_4 = fluid.nets.sequence_conv_pool(        input=emb,        num_filters=hid_dim,        filter_size=4,        act="tanh",        pool_type="sqrt")    prediction = fluid.layers.fc(        input=[conv_3, conv_4], size=class_dim, act="softmax")    return predictiondef convolution_net(data, input_dim, class_dim, emb_dim, hid_dim):    emb = fluid.layers.embedding(        input=data, size=[input_dim, emb_dim], is_sparse=True)    conv_3 = fluid.nets.sequence_conv_pool(        input=emb,        num_filters=hid_dim,        filter_size=3,        act="tanh",        pool_type="sqrt")    conv_4 = fluid.nets.sequence_conv_pool(        input=emb,        num_filters=hid_dim,        filter_size=4,        act="tanh",        pool_type="sqrt")    prediction = fluid.layers.fc(        input=[conv_3, conv_4], size=class_dim, act="softmax")    return prediction

网络的输入 input_dim 表示的是词典的大小,class_dim 表示类别数。这里,我们使用 sequence_conv_pool API实现了卷积和池化操作。

栈式双向LSTM

栈式双向神经网络stacked_lstm_net的代码片段如下:


#栈式双向LSTMdef stacked_lstm_net(data, input_dim, class_dim, emb_dim, hid_dim, stacked_num):    assert stacked_num % 2 == 1    #计算词向量    emb = fluid.layers.embedding(        input=data, size=[input_dim, emb_dim], is_sparse=True)    #第一层栈    #全连接层    fc1 = fluid.layers.fc(input=emb, size=hid_dim)    #lstm层    lstm1, cell1 = fluid.layers.dynamic_lstm(input=fc1, size=hid_dim)    inputs = [fc1, lstm1]    #其余的所有栈结构    for i in range(2, stacked_num + 1):        fc = fluid.layers.fc(input=inputs, size=hid_dim)        lstm, cell = fluid.layers.dynamic_lstm(            input=fc, size=hid_dim, is_reverse=(i % 2) == 0)        inputs = [fc, lstm]    #池化层    fc_last = fluid.layers.sequence_pool(input=inputs[0], pool_type='max')    lstm_last = fluid.layers.sequence_pool(input=inputs[1], pool_type='max')    #全连接层,softmax预测    prediction = fluid.layers.fc(        input=[fc_last, lstm_last], size=class_dim, act='softmax')return predictiondef stacked_lstm_net(data, input_dim, class_dim, emb_dim, hid_dim, stacked_num):    assert stacked_num % 2 == 1    #计算词向量    emb = fluid.layers.embedding(        input=data, size=[input_dim, emb_dim], is_sparse=True)

    #第一层栈    #全连接层    fc1 = fluid.layers.fc(input=emb, size=hid_dim)    #lstm层    lstm1, cell1 = fluid.layers.dynamic_lstm(input=fc1, size=hid_dim)

    inputs = [fc1, lstm1]

    #其余的所有栈结构    for i in range(2, stacked_num + 1):        fc = fluid.layers.fc(input=inputs, size=hid_dim)        lstm, cell = fluid.layers.dynamic_lstm(            input=fc, size=hid_dim, is_reverse=(i % 2) == 0)        inputs = [fc, lstm]

    #池化层    fc_last = fluid.layers.sequence_pool(input=inputs[0], pool_type='max')    lstm_last = fluid.layers.sequence_pool(input=inputs[1], pool_type='max')

    #全连接层,softmax预测    prediction = fluid.layers.fc(        input=[fc_last, lstm_last], size=class_dim, act='softmax')return prediction

以上的栈式双向LSTM抽象出了高级特征并把其映射到和分类类别数同样大小的向量上。最后一个全连接层的’softmax’激活函数用来计算分类属于某个类别的概率。

重申一下,此处我们可以调用 convolution_net 或 stacked_lstm_net 的任何一个网络结构进行训练学习。我们以 convolution_net 为例。

接下来我们定义预测程序(inference_program)。预测程序使用convolution_net 来对 fluid.layer.data 的输入进行预测。


def inference_program(word_dict):    data = fluid.layers.data(        name="words", shape=[1], dtype="int64", lod_level=1)    dict_dim = len(word_dict)    net = convolution_net(data, dict_dim, CLASS_DIM, EMB_DIM, HID_DIM)    # net = stacked_lstm_net(data, dict_dim, CLASS_DIM, EMB_DIM, HID_DIM, STACKED_NUM)return net    data = fluid.layers.data(        name="words", shape=[1], dtype="int64", lod_level=1)

    dict_dim = len(word_dict)    net = convolution_net(data, dict_dim, CLASS_DIM, EMB_DIM, HID_DIM)    # net = stacked_lstm_net(data, dict_dim, CLASS_DIM, EMB_DIM, HID_DIM, STACKED_NUM)return net

我们这里定义了 training_program。它使用了从 inference_program 返回的结果来计算误差。我们同时定义了优化函数 optimizer_func 。

因为是有监督的学习,训练集的标签也在fluid.layers.data中定义了。在训练过程中,交叉熵用来在fluid.layer.cross_entropy中作为损失函数。

在测试过程中,分类器会计算各个输出的概率。第一个返回的数值规定为cost。



def train_program(prediction):  label = fluid.layers.data(name="label", shape=[1], dtype="int64")    cost = fluid.layers.cross_entropy(input=prediction, label=label)    avg_cost = fluid.layers.mean(cost)    accuracy = fluid.layers.accuracy(input=prediction, label=label)    return [avg_cost, accuracy]   #返回平均cost和准确率acc#优化函数def optimizer_func():    return fluid.optimizer.Adagrad(learning_rate=0.002)1], dtype="int64")    cost = fluid.layers.cross_entropy(input=prediction, label=label)    avg_cost = fluid.layers.mean(cost)    accuracy = fluid.layers.accuracy(input=prediction, label=label)    return [avg_cost, accuracy]   #返回平均cost和准确率acc#优化函数def optimizer_func():    return fluid.optimizer.Adagrad(learning_rate=0.002)"int64")    cost = fluid.layers.cross_entropy(input=prediction, label=label)    avg_cost = fluid.layers.mean(cost)    accuracy = fluid.layers.accuracy(input=prediction, label=label)    return [avg_cost, accuracy]   #返回平均cost和准确率acc

#优化函数def optimizer_func():    return fluid.optimizer.Adagrad(learning_rate=0.002)

训练模型

定义训练环境

定义你的训练是在CPU上还是在GPU上:


use_cuda = False  #在cpu上进行训练place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()#在cpu上进行训练place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()

定义数据提供器

下一步是为训练和测试定义数据提供器。提供器读入一个大小为 BATCH_SIZE的数据。paddle.dataset.imdb.word_dict 每次会在乱序化后提供一个大小为BATCH_SIZE的数据,乱序化的大小为缓存大小buf_size。

注意:读取IMDB的数据可能会花费几分钟的时间,请耐心等待。


print("Loading IMDB word dict....")word_dict = paddle.dataset.imdb.word_dict()print ("Reading training data....")train_reader = paddle.batch(    paddle.reader.shuffle(        paddle.dataset.imdb.train(word_dict), buf_size=25000),    batch_size=BATCH_SIZE)print("Reading testing data....")test_reader = paddle.batch(paddle.dataset.imdb.test(word_dict), batch_size=BATCH_SIZE)feed_order = ['words', 'label']pass_num = 1word_dict = paddle.dataset.imdb.word_dict()

print ("Reading training data....")train_reader = paddle.batch(    paddle.reader.shuffle(        paddle.dataset.imdb.train(word_dict), buf_size=25000),    batch_size=BATCH_SIZE)print("Reading testing data....")test_reader = paddle.batch(paddle.dataset.imdb.test(word_dict), batch_size=BATCH_SIZE)

feed_order = ['words', 'label']pass_num = 1

word_dict 是一个字典序列,是词和label的对应关系,运行下一行可以看到具体内容:


word_dict

每行是如(’limited’: 1726)的对应关系,该行表示单词limited所对应的label是1726。

构造训练器

训练器需要一个训练程序和一个训练优化函数。


main_program = fluid.default_main_program()star_program = fluid.default_startup_program()prediction = inference_program(word_dict)train_func_outputs = train_program(prediction)avg_cost = train_func_outputs[0]test_program = main_program.clone(for_test=True)sgd_optimizer = optimizer_func()sgd_optimizer.minimize(avg_cost)exe = fluid.Executor(place)prediction = inference_program(word_dict)train_func_outputs = train_program(prediction)avg_cost = train_func_outputs[0]

test_program = main_program.clone(for_test=True)

sgd_optimizer = optimizer_func()sgd_optimizer.minimize(avg_cost)exe = fluid.Executor(place)

该函数用来计算训练中模型在test数据集上的结果


def train_test(program, reader):    count = 0    feed_var_list = [        program.global_block().var(var_name) for var_name in feed_order    ]    feeder_test = fluid.DataFeeder(feed_list=feed_var_list, place=place)    test_exe = fluid.Executor(place)    accumulated = len([avg_cost, accuracy]) * [0]    for test_data in reader():        avg_cost_np = test_exe.run(            program=program,            feed=feeder_test.feed(test_data),            fetch_list=[avg_cost, accuracy])        accumulated = [            x[0] + x[1][0] for x in zip(accumulated, avg_cost_np)        ]        count += 1    return [x / count for x in accumulated]    count = 0    feed_var_list = [        program.global_block().var(var_name) for var_name in feed_order    ]    feeder_test = fluid.DataFeeder(feed_list=feed_var_list, place=place)    test_exe = fluid.Executor(place)    accumulated = len([avg_cost, accuracy]) * [0]    for test_data in reader():        avg_cost_np = test_exe.run(            program=program,            feed=feeder_test.feed(test_data),            fetch_list=[avg_cost, accuracy])        accumulated = [            x[0] + x[1][0] for x in zip(accumulated, avg_cost_np)        ]        count += 1    return [x / count for x in accumulated]

提供数据并构建主训练循环

feed_order 用来定义每条产生的数据和 fluid.layers.data 之间的映射关系。比如,imdb.train 产生的第一列的数据对应的是words这个特征。


# Specify the directory path to save the parametersparams_dirname = "understand_sentiment_conv.inference.model"feed_order = ['words', 'label']pass_num = 1  #训练循环的轮数#程序主循环部分def train_loop():#启动上文构建的训练器feed_var_list_loop = [    main_program.global_block().var(var_name) for var_name in feed_order]feeder = fluid.DataFeeder(feed_list=feed_var_list_loop,place=place) exe.run(star_program)    #训练循环    for epoch_id in range(pass_num):        for step_id, data in enumerate(train_reader()):            #运行训练器              metrics = exe.run(main_program,                              feed=feeder.feed(data),                              fetch_list=[var.name for var in train_func_outputs])            #测试结果    print("step: {0}, Metrics {1}".format(                    step_id, list(map(np.array, metrics))))    if (step_id + 1) % 10 == 0:                    avg_cost_test, acc_test = train_test(test_program,                                                         test_reader)                    print('Step {0}, Test Loss {1:0.2}, Acc {2:0.2}'.format(                        step_id, avg_cost_test, acc_test))                    print("Step {0}, Epoch {1} Metrics {2}".format(                        step_id, epoch_id, list(map(np.array, metrics))))                if math.isnan(float(metrics[0])):                    sys.exit("got NaN loss, training failed.")            if params_dirname is not None:                fluid.io.save_inference_model(params_dirname, ["words"],                                              prediction, exe) #保存模型train_loop()params_dirname = "understand_sentiment_conv.inference.model"

feed_order = ['words', 'label']pass_num = 1  #训练循环的轮数

#程序主循环部分def train_loop():#启动上文构建的训练器feed_var_list_loop = [    main_program.global_block().var(var_name) for var_name in feed_order]feeder = fluid.DataFeeder(feed_list=feed_var_list_loop,place=place) exe.run(star_program)

    #训练循环    for epoch_id in range(pass_num):        for step_id, data in enumerate(train_reader()):            #运行训练器            metrics = exe.run(main_program,                              feed=feeder.feed(data),                              fetch_list=[var.name for var in train_func_outputs])

            #测试结果    print("step: {0}, Metrics {1}".format(                    step_id, list(map(np.array, metrics))))    if (step_id + 1) % 10 == 0:                    avg_cost_test, acc_test = train_test(test_program,                                                         test_reader)                    print('Step {0}, Test Loss {1:0.2}, Acc {2:0.2}'.format(                        step_id, avg_cost_test, acc_test))

                    print("Step {0}, Epoch {1} Metrics {2}".format(                        step_id, epoch_id, list(map(np.array, metrics))))                if math.isnan(float(metrics[0])):                    sys.exit("got NaN loss, training failed.")            if params_dirname is not None:                fluid.io.save_inference_model(params_dirname, ["words"],                                              prediction, exe) #保存模型train_loop()

训练过程处理

我们在训练主循环里打印了每一步输出,可以观察训练情况。

开始训练

最后,我们启动训练主循环来开始训练。训练时间较长,如果为了更快的返回结果,可以通过调整损耗值范围或者训练步数,以减少准确率的代价来缩短训练时间。


train_loop(fluid.default_main_program())

应用模型

构建预测器

和训练过程一样,我们需要创建一个预测过程,并使用训练得到的模型和参数来进行预测,params_dirname 用来存放训练过程中的各个参数。


place = fluid.CUDAPlace(0) if use_cuda else fluid.CPUPlace()exe = fluid.Executor(place)inference_scope = fluid.core.Scope()if use_cuda else fluid.CPUPlace()exe = fluid.Executor(place)inference_scope = fluid.core.Scope()

生成测试用输入数据

为了进行预测,我们任意选取3个评论。请随意选取您看好的3个。我们把评论中的每个词对应到word_dict中的id。如果词典中没有这个词,则设为unknown。 然后我们用create_lod_tensor来创建细节层次的张量


reviews_str = [    'read the book forget the movie', 'this is a great movie', 'this is very bad']reviews = [c.split() for c in reviews_str]UNK = word_dict['<unk>']lod = []for c in reviews:    lod.append([word_dict.get(words, UNK) for words in c])base_shape = [[len(c) for c in lod]]tensor_words = fluid.create_lod_tensor(lod, base_shape, place)'read the book forget the movie', 'this is a great movie', 'this is very bad']reviews = [c.split() for c in reviews_str]

UNK = word_dict['<unk>']lod = []for c in reviews:    lod.append([word_dict.get(words, UNK) for words in c])

base_shape = [[len(c) for c in lod]]

tensor_words = fluid.create_lod_tensor(lod, base_shape, place)

应用模型并进行预测

现在我们可以对每一条评论进行正面或者负面的预测啦。


with fluid.scope_guard(inference_scope):    [inferencer, feed_target_names,     fetch_targets] = fluid.io.load_inference_model(params_dirname, exe)reviews_str = [    'read the book forget the moive’,’this is a great moive',    'this is very bad']reviews = [c.split() for c in reviews_str]UNK = word_dict['<unk>']lod = []for c in reviews:    lod.append([np.int64(word_dict.get(words, UNK)) for words in c])base_shape = [[len(c) for c in lod]]tensor_words = fluid.create_lod_tensor(lod, base_shape,place)assert feed_target_names[0] == "words"results = exe.run(inferencer,                      feed={feed_target_names[0]: tensor_words},                      fetch_list=fetch_targets,                      return_numpy=False)    np_data = np.array(results[0])    for i, r in enumerate(np_data):        print("Predict probability of ", r[0], " to be positive and ", r[1],              " to be negative for review \'", reviews_str[i], "\'")

    [inferencer, feed_target_names,     fetch_targets] = fluid.io.load_inference_model(params_dirname, exe)

reviews_str = [    'read the book forget the moive’,’this is a great moive',    'this is very bad']reviews = [c.split() for c in reviews_str]

UNK = word_dict['<unk>']lod = []for c in reviews:    lod.append([np.int64(word_dict.get(words, UNK)) for words in c])

base_shape = [[len(c) for c in lod]]

tensor_words = fluid.create_lod_tensor(lod, base_shape,place)assert feed_target_names[0] == "words"results = exe.run(inferencer,                      feed={feed_target_names[0]: tensor_words},                      fetch_list=fetch_targets,                      return_numpy=False)    np_data = np.array(results[0])    for i, r in enumerate(np_data):        print("Predict probability of ", r[0], " to be positive and ", r[1],              " to be negative for review \'", reviews_str[i], "\'")

感兴趣的小伙伴可以在PaddlePaddle官网上阅读其他相关文档内容:http://www.paddlepaddle.org/

参考文献:

  1. Kim Y. Convolutional neural networks for sentence classification[J]. arXiv preprint arXiv:1408.5882, 2014.

  2. Kalchbrenner N, Grefenstette E, Blunsom P. A convolutional neural network for modelling sentences[J]. arXiv preprint arXiv:1404.2188, 2014.

  3. Yann N. Dauphin, et al. Language Modeling with Gated Convolutional Networks[J] arXiv preprint arXiv:1612.08083, 2016.

  4. Siegelmann H T, Sontag E D. On the computational power of neural nets[C]//Proceedings of the fifth annual workshop on Computational learning theory. ACM, 1992: 440-449.

  5. Hochreiter S, Schmidhuber J. Long short-term memory[J]. Neural computation, 1997, 9(8): 1735-1780.

  6. Bengio Y, Simard P, Frasconi P. Learning long-term dependencies with gradient descent is difficult[J]. IEEE transactions on neural networks, 1994, 5(2): 157-166.

  7. Graves A. Generating sequences with recurrent neural networks[J]. arXiv preprint arXiv:1308.0850, 2013.

  8. Cho K, Van Merriënboer B, Gulcehre C, et al. Learning phrase representations using RNN encoder-decoder for statistical machine translation[J]. arXiv preprint arXiv:1406.1078, 2014.

  9. Zhou J, Xu W. End-to-end learning of semantic role labeling using recurrent neural networks[C]//Proceedings of the Annual Meeting of the Association for Computational Linguistics. 2015.

小程序|get更多AI学习干货

加入社群

量子位AI社群开始招募啦,量子位社群分:AI讨论群、AI+行业群、AI技术群;

欢迎对AI感兴趣的同学,在量子位公众号(QbitAI)对话界面回复关键字“微信群”,获取入群方式。(技术群与AI+行业群需经过审核,审核较严,敬请谅解)

量子位 QbitAI · 头条号签约作者

վ'ᴗ' ի 追踪AI技术和产品新动态

喜欢就点「在看」吧 !

520礼包 | 情感分析算法从原理到PaddlePaddle实战全解相关推荐

  1. 情感分析算法从原理到PaddlePaddle实战全解

    在自然语言处理中,情感分析一般是指判断一段文本所表达的情绪状态.其中,一段文本可以是一个句子,一个段落或一个文档.情绪状态可以是两类,如(正面,负面),(高兴,悲伤):也可以是三类,如(积极,消极,中 ...

  2. 视频分析算法的原理简介

       视频分析算法的原理简介 视频分析技术来源于计算机视觉,它能够在图象及图象描述之间建立映射关系,从而使计算机能够通过图象处理和分析来理解画面中的内容,其实质是"自动分析和抽取视频源中的关 ...

  3. 岭回归算法的原理和代码实战

    岭回归算法的原理和代码实战 前言 学过吴恩达老师的机器学习入门课程都应该知道,在逻辑回归那一讲,吴老师提到了使用正则化来防止逻辑回归模型过拟合.而岭回归在这里的作用是一样的,同样也是防止模型过拟合.这 ...

  4. R语言使用survminer包生存分析及可视化(ggsurvplot)实战详解:从数据集导入、生存对象生成、ggsurvplot可视化参数配置、设置、可视化对比

    R语言使用survminer包生存分析及可视化(ggsurvplot)实战详解:从数据集导入.生存对象生成.ggsurvplot可视化参数配置.设置.可视化对比 目录 R语言使用survminer包生 ...

  5. 情感分析算法在阿里小蜜的应用实践

    来自:DataFunTalk 主要作者:宋双永 阿里达摩院 算法专家 编辑整理:Hoh 导读:人机对话一直是自然语言处理领域内的重要研究方向之一,近年来随着人机交互技术的进步,对话系统正逐渐走向实际应 ...

  6. 深度学习核心技术精讲100篇(四十六)-情感分析算法在阿里小蜜的应用实践

    前言 人机对话一直是自然语言处理领域内的重要研究方向之一,近年来随着人机交互技术的进步,对话系统正逐渐走向实际应用.其中,智能客服系统受到了很多企业尤其是中大型企业的广泛关注.智能客服系统旨在解决传统 ...

  7. 情感分析——深入snownlp原理和实践

    一.snownlp简介 snownlp是什么? SnowNLP是一个python写的类库,可以方便的处理中文文本内容,是受到了TextBlob的启发而写的,由于现在大部分的自然语言处理库基本都是针对英 ...

  8. Python编曲实践(九):如何计算并估计音乐的调性(大/小调+主音)?Krumhansl-Schmuckler调性分析算法的原理与实现

    前言 之前,我在 Python编曲实践(五)中记录了构建MIDI数据集Free MIDI Library的过程,其中预处理阶段十分重要的一个步骤是移调,即把所有音乐的调性调整为C大调或A小调,这样会使 ...

  9. 基于双向LSTM的影评情感分析算法设计学习记录

    引言 需求分析,技术可行性(目前的研究进度),主流怎么做?我要如何做? 随着互联网技术的飞速发展及联网的便捷,越来越多的人在网上表达自己的意见.其中,电影评论受到广泛关注.很多人选择在闲暇时间观看电影 ...

最新文章

  1. Java项目:教务管理系统(java+JSP+Spring+SpringBoot+layui+maven)
  2. 身份证号信息后台匹配
  3. mysql使用释放资源_数据库--释放mysql数据库资源
  4. 机器学习(四)——损失函数
  5. 推荐一个golang的json库
  6. julia有 pytorch包吗_用 PyTorch 实现基于字符的循环神经网络 | Linux 中国
  7. 作者:牛新(1983-),男,博士,国防科学技术大学并行与分布处理重点实验室助理研究员...
  8. jdk和tomcat
  9. Python新闻网站项目-3.Gerapy爬虫分布式部署
  10. 带你彻底弄明白!java简历模板下载
  11. Win10系统无法使用VGAPlayer软件播放asf格式和VGA文件
  12. 【HBuilderX】预编译器错误:代码使用了scss/sass语言,但未安装相应的编译器插件,请前往插件市场安装该插件:
  13. js判断Lodop驱动是否安装
  14. 生物信息中的Python 01 | 从零开始处理基因序列
  15. python Flask 编写 api 接口,CORS 解决 flask 跨域问题
  16. Android 获得 usb 权限的两种方式
  17. WMLS10自动建立BIN位(模板配置)
  18. 再生龙盘对盘拷贝Linux
  19. 清除DataGridView的全部内容,包括标题行
  20. 如何解决win10应用商店打不开——错误码0x80131500

热门文章

  1. “苹果正在走下神坛” | 畅言
  2. UCan下午茶杭州站:突破困惑,为大数据商业化变现探寻出路
  3. 黑客瞄准美国 ATM 机,疯狂窃取超百万美元资金
  4. JavaScript 年度调查报告:React、Vue 和 Angular 三分天下,谁将在 2018 年独占鳌头?
  5. 怒肝三个月啃完这110道面试题,跳槽薪资翻倍
  6. oppoJava面试!java开发视频聊天
  7. JAVA day15 Collection(集合)、Iterator迭代器、泛型<E>
  8. android 应用自动退出,android – 应用程序自动退出,没有任何警告或错误
  9. php iis日志分析,星外系统IIS日志分析常用的几个命令小结
  10. oppo怎么广告接入_OPPO游戏创游无境 构建强大的游戏生态