zoukankan      html  css  js  c++  java
  • PaddlePaddle 极简入门实践三:简单循环神经网络情感分析

    #coding:utf-8
    '''
    created on February 11 15:38 2019

    @author:zhulma
    '''
    import paddle
    import paddle.dataset.imdb as imdb
    import paddle.fluid as fluid
    import numpy as np


    # 简单的循环神经网络
    def rnn_net(ipt, input_dim):
    # 将句子分词的IDs作为输入
    emb = fluid.layers.embedding(input=ipt, size=[input_dim, 128], is_sparse=True)
    sentence = fluid.layers.fc(input=emb, size=128, act='tanh')

    # 循环神经网络块
    rnn = fluid.layers.DynamicRNN()
    with rnn.block():
    word = rnn.step_input(sentence)
    prev = rnn.memory(shape=[128])
    hidden = fluid.layers.fc(input=[word, prev], size=128, act='relu')
    rnn.update_memory(prev, hidden)
    rnn.output(hidden)

    last = fluid.layers.sequence_last_step(rnn()) # 这个接口通常使用在序列函数最后一步
    out = fluid.layers.fc(input=last, size=2, act='softmax')
    return out


    # 长短期记忆网络
    def lstm_net(ipt, input_dim):
    # 将句子分词的词向量作为输入
    emb = fluid.layers.embedding(input=ipt, size=[input_dim, 128], is_sparse=True)
    # 第一个全连接层
    fc1 = fluid.layers.fc(input=emb, size=128)
    # 进行一个长短期记忆操作
    lstm1, _ = fluid.layers.dynamic_lstm(input=fc1, size=128)

    # 第一个最大序列池操作
    fc2 = fluid.layers.sequence_pool(input=fc1, pool_type='max')
    # 第二个最大序列池操作
    lstm2 = fluid.layers.sequence_pool(input=lstm1, pool_type='max')

    # 以softmax作为全连接的输出层,大小为2,也就是只有正反面两种评价
    out = fluid.layers.fc(input=[fc2, lstm2], size=2, act='softmax')
    return out


    #定义输入数据,lod_level不为0指定输入数据为序列数据
    words=fluid.layers.data(name='words',shape=[1],dtype='int64',lod_level=1)
    label=fluid.layers.data(name='label',shape=[1],dtype='int64')


    #读取数据字典
    print('加载数据字典中...')
    word_dict=imdb.word_dict()
    #获取数据字典长度
    dict_dim=len(word_dict)


    #获取长短期记忆网络
    model=lstm_net(words,dict_dim)
    #获取循环神经网络
    #model=rnn_net(words,dict_dim)

    #定义损失函数和准确率,分类问题还是使用交叉熵损失函数
    cost=fluid.layers.cross_entropy(input=model,label=label)
    avg_cost=fluid.layers.mean(cost)
    accuracy=fluid.layers.accuracy(input=model,label=label)

    #克隆一个测试程序
    test_program=fluid.default_main_program().clone(for_test=True)


    #选择优化器,这里选择Adagrad优化方法,这种优化方法多用于处理稀疏数据
    optimizer=fluid.optimizer.AdagradOptimizer(learning_rate=0.002)
    opt=optimizer.minimize(avg_cost)

    #创建执行器,这次数据集很大,但是我的虚拟机也跑不了CUDA,有条件的就跑CUDA
    place=fluid.CPUPlace()
    #place=fluid.CUDAPlace(1)
    exe=fluid.Executor(place)
    #初始化参数
    exe.run(fluid.default_startup_program())

    #由于数据集比较大,为了加快数据的读取速度,使用paddle.reader.shuffle()先将数据按照设置的大小读入到缓存中,并且打乱顺序
    #获取训练和测试数据
    print("获取训练数据中...")
    train_reader=paddle.batch(paddle.reader.shuffle(imdb.train(word_dict),25000),batch_size=128)
    print("获取测试数据中...")
    test_reader=paddle.batch(imdb.test(word_dict),batch_size=128)

    #定义数据输入维度
    feeder=fluid.DataFeeder(place=place,feed_list=[words,label])


    #开始训练
    for pass_id in range(1):#跑一遍我的虚拟机就够呛,但是为了收敛效果更好,就跑三遍吧
    train_cost=0
    for batch_id,data in enumerate(train_reader()):
    train_cost=exe.run(program=fluid.default_main_program(),feed=feeder.feed(data),fetch_list=[avg_cost])
    if batch_id%50==0:
    print('Pass:%d,Batch:%d,Cost:%0.5f'%(pass_id,batch_id,train_cost[0]))
    #开始测试
    test_costs=[]
    test_accs=[]
    for batch_id,data in enumerate(test_reader()):
    test_cost,test_acc=exe.run(program=test_program,feed=feeder.feed(data),fetch_list=[avg_cost,accuracy])
    test_costs.append(test_cost[0])
    test_accs.append(test_acc[0])
    #计算这次batch经过后,平均的损失值和准确率
    test_cost=(sum(test_costs)/len(test_costs))
    test_acc=(sum(test_accs)/len(test_accs))
    print('Test:%d,Cost:%0.5f,acc:%0.5f'%(pass_id,test_cost,test_acc))


    #预测数据
    #定义预测句子,第一个是中性的,第二个是偏向正面的,第三个是偏向负面
    test_str=['I read the book','I am so happy','this is a bad movie']
    #将句子转化成一个个单词
    reviews=[c.split() for c in test_str]

    #将句子中的单词转换成字典中的标签
    #字典中没有的单词一律标签为<unk>对应的标签
    unk=word_dict['<unk>']
    #获取每句话对应的标签
    lod=[]
    for c in reviews:
    #需要将单词进行字符串的utf-8编码转换,对于没见过的单词就使用<unk>的标签
    lod.append([word_dict.get(words.encode('utf-8'),unk) for words in c])

    #获取输入数据维度的大小,换句话说就是获取每句话的单词数量
    base_shape=[[len(c) for c in lod]]

    #将想要预测的数据转换成张量,准备开始预测
    tensor_words=fluid.create_lod_tensor(lod,base_shape,place)

    #开始预测
    results=exe.run(program=test_program,feed={'words':tensor_words,'label':np.array([[0],[0],[0]]).astype('int64')},fetch_list=[model])

    #打印每句话的正负面概率
    for i,r in enumerate(results[0]):
    print('%s的预测结果是:正面概率为:%0.5f,反面概率为:%0.5f'%(test_str[i],r[0],r[1]))



  • 相关阅读:
    cnblogs blogStats All In One
    ESLint & vue template indent validate All In One
    vue & elementui 表单验证 bug All In One
    vue 表单验证 rule.message bug All In One
    vue 表单验证 rule message bug All In One
    Node.js & TypeScript error All In One
    VS2010如何调试IIS上的网站
    用LINQ查询XML并绑定给GridView显示
    SQLServer2008评估期已过解决方法
    ASP.NET给用户控件(.ascx)增加属性
  • 原文地址:https://www.cnblogs.com/zhulimin/p/13195367.html
Copyright © 2011-2022 走看看