国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

IMDB電影評論的情感分析——paddle

這篇具有很好參考價(jià)值的文章主要介紹了IMDB電影評論的情感分析——paddle。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

?項(xiàng)目地址:IMDB電影評論的情感分析 - 飛槳AI Studio星河社區(qū) (baidu.com)

1. 實(shí)驗(yàn)介紹

1.1 實(shí)驗(yàn)?zāi)康?/h3>
  1. 理解并掌握循環(huán)神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)知識點(diǎn),包括模型的時序結(jié)構(gòu)、模型的前向傳播、反向傳播等
  2. 掌握長短時記憶網(wǎng)絡(luò)LSTM和門控循環(huán)單元網(wǎng)絡(luò)GRU的設(shè)計(jì)原理
  3. 熟悉如何使用飛槳深度學(xué)習(xí)開源框架構(gòu)建循環(huán)神經(jīng)網(wǎng)絡(luò)

1.2 實(shí)驗(yàn)內(nèi)容

自然語言是人類傳遞信息的一種載體,同時它也能表達(dá)人類交流時的一種情感。一段對話或者一句評論都能蘊(yùn)含著豐富的感情色彩:比如高興、快樂、喜歡、討厭、憂傷等等。

如圖2 所示,利用機(jī)器自動分析這些情感傾向,不但有助于幫助企業(yè)了解消費(fèi)者對其產(chǎn)品的感受,為產(chǎn)品改進(jìn)提供依據(jù);同時還有助于企業(yè)分析商業(yè)伙伴們的態(tài)度,以便更好地進(jìn)行商業(yè)決策。通常情況下,往往將情感分析任務(wù)定義為一個分類問題,即使用計(jì)算機(jī)判定給定的一段文字所表達(dá)的情感屬于積極情緒,還是消極情緒。

本實(shí)驗(yàn)將基于LSTM建模情感分析模型,對IMDB電影評論進(jìn)行情感傾向分析,這有助于幫助消費(fèi)者了解一部電影的質(zhì)量,也可用于電影的推薦。

IMDB電影評論的情感分析——paddle,深度學(xué)習(xí),自然語言處理,情感分析,paddle,人工智能,深度學(xué)習(xí),自然語言處理,情感分析

圖2 情感分析圖

1.3 實(shí)驗(yàn)環(huán)境

本實(shí)驗(yàn)支持在實(shí)訓(xùn)平臺或本地環(huán)境操作,建議使用實(shí)訓(xùn)平臺。

  • 實(shí)訓(xùn)平臺:如果選擇在實(shí)訓(xùn)平臺上操作,無需安裝實(shí)驗(yàn)環(huán)境。實(shí)訓(xùn)平臺集成了實(shí)驗(yàn)必須的相關(guān)環(huán)境,代碼可在線運(yùn)行,同時還提供了免費(fèi)算力,即使實(shí)踐復(fù)雜模型也無算力之憂。
  • 本地環(huán)境:如果選擇在本地環(huán)境上操作,需要安裝Python3.7、飛槳開源框架2.0等實(shí)驗(yàn)必須的環(huán)境,具體要求及實(shí)現(xiàn)代碼請參見《本地環(huán)境安裝說明》。

可以通過如下代碼導(dǎo)入實(shí)驗(yàn)環(huán)境。

# 導(dǎo)入paddle及相關(guān)包
import paddle
import paddle.nn.functional as F
import re
import random
import tarfile
import requests
import numpy as np

paddle.seed(0)
random.seed(0)
np.random.seed(0)
print(paddle.__version__)

1.4 實(shí)驗(yàn)設(shè)計(jì)

本實(shí)驗(yàn)的模型實(shí)現(xiàn)方案如 圖3 所示,模型的輸入是文本數(shù)據(jù),模型的輸出就是文本的情感標(biāo)簽。在建模過程中,對于輸入的電影評論文本,首先需要進(jìn)行數(shù)據(jù)處理(比如分詞,構(gòu)建詞表,過長文本截?cái)?,過短文本填充等);然后使用長短時記憶網(wǎng)絡(luò)LSTM對文本序列進(jìn)行編碼,獲得文本的語義向量表示;最后經(jīng)過全連接層和softmax處理得到文本分類為積極情感和消極情感的概率。

IMDB電影評論的情感分析——paddle,深度學(xué)習(xí),自然語言處理,情感分析,paddle,人工智能,深度學(xué)習(xí),自然語言處理,情感分析

圖3 電影評論情感分析設(shè)計(jì)方案

2. 實(shí)驗(yàn)詳細(xì)實(shí)現(xiàn)

IMDB電影評論情感分析實(shí)驗(yàn)流程如 圖4 所示,包含如下7個步驟:

  1. 數(shù)據(jù)處理:根據(jù)網(wǎng)絡(luò)接收的數(shù)據(jù)格式,完成相應(yīng)的預(yù)處理操作,保證模型正常讀??;
  2. 模型構(gòu)建:設(shè)計(jì)情感分析模型,判斷文本的情感傾向;
  3. 訓(xùn)練配置:實(shí)例化模型,選擇模型計(jì)算資源(CPU或者GPU),指定模型迭代的優(yōu)化算法;
  4. 模型訓(xùn)練:執(zhí)行多輪訓(xùn)練不斷調(diào)整參數(shù),以達(dá)到較好的效果;
  5. 模型保存:將模型參數(shù)保存到指定位置,便于后續(xù)推理或繼續(xù)訓(xùn)練使用;
  6. 模型評估:對訓(xùn)練好的模型進(jìn)行評估測試,觀察準(zhǔn)確率和Loss;
  7. 模型推理:選取一段電影評論數(shù)據(jù),通過模型推理出評論文本所屬的情感類別。

IMDB電影評論的情感分析——paddle,深度學(xué)習(xí),自然語言處理,情感分析,paddle,人工智能,深度學(xué)習(xí),自然語言處理,情感分析?

圖4 IMDB電影評論的情感分析實(shí)驗(yàn)流程

2.1 數(shù)據(jù)處理

數(shù)據(jù)處理部分包含數(shù)據(jù)集介紹、IMDB數(shù)據(jù)集下載、讀取數(shù)據(jù)至內(nèi)存、轉(zhuǎn)換數(shù)據(jù)格式并組裝數(shù)據(jù)為mini-batch形式,以便模型處理。數(shù)據(jù)處理的總體流程如?圖5?所示。

IMDB電影評論的情感分析——paddle,深度學(xué)習(xí),自然語言處理,情感分析,paddle,人工智能,深度學(xué)習(xí),自然語言處理,情感分析

圖5 數(shù)據(jù)處理流程

2.1.1 數(shù)據(jù)集介紹

本實(shí)驗(yàn)使用的數(shù)據(jù)為IMDB電影評論數(shù)據(jù)集。IMDB是一份關(guān)于電影評論的數(shù)據(jù)集,消費(fèi)者對電影進(jìn)行評論時可以進(jìn)行打分,滿分是10分。IMDB將消費(fèi)者對電影的評論按照評分的高低篩選出了積極評論和消極評論,如果評分>=7,則認(rèn)為是積極評論;如果評分<=4,則認(rèn)為是消極評論。所以IMDB數(shù)據(jù)集是一份關(guān)于情感分析的經(jīng)典二分類數(shù)據(jù)集,其中訓(xùn)練集和測試集數(shù)量各為25000條。

2.1.2 數(shù)據(jù)下載

首先,需要下載IMDB數(shù)據(jù)集,該數(shù)據(jù)集包括訓(xùn)練和測試集。數(shù)據(jù)集下載的代碼如下:

def download():
    # 通過python的requests類,下載存儲在
    # https://dataset.bj.bcebos.com/imdb%2FaclImdb_v1.tar.gz的文件
    corpus_url = "https://dataset.bj.bcebos.com/imdb%2FaclImdb_v1.tar.gz"
    web_request = requests.get(corpus_url)
    corpus = web_request.content

    # 將下載的文件寫在當(dāng)前目錄的aclImdb_v1.tar.gz文件內(nèi)
    with open("./aclImdb_v1.tar.gz", "wb") as f:
        f.write(corpus)
    f.close()

download()

2.1.3 數(shù)據(jù)讀取

下載后的數(shù)據(jù)集aclImdb_v1.tar.gz是一個壓縮文件,可以使用python的rarfile庫進(jìn)行解壓,解壓代碼如下所示:

# 數(shù)據(jù)解壓代碼
!tar -xzvf aclImdb_v1.tar.gz
aclImdb/train/unsup/38074_0.txt
IOPub data rate exceeded.
The notebook server will temporarily stop sending output
to the client in order to avoid crashing it.
To change this limit, set the config variable
`--NotebookApp.iopub_data_rate_limit`.

Current values:
NotebookApp.iopub_data_rate_limit=1000000.0 (bytes/sec)
NotebookApp.rate_limit_window=3.0 (secs)

解壓之后目錄結(jié)構(gòu)如?圖6?所示:

IMDB電影評論的情感分析——paddle,深度學(xué)習(xí),自然語言處理,情感分析,paddle,人工智能,深度學(xué)習(xí),自然語言處理,情感分析

圖6 IMDB數(shù)據(jù)集解壓目錄

本實(shí)驗(yàn)主要用到目錄train(訓(xùn)練集)和test(測試集)的內(nèi)容,訓(xùn)練集和測試集的目錄結(jié)構(gòu)的含義解釋是一致的。以訓(xùn)練集為例,訓(xùn)練數(shù)據(jù)按照標(biāo)簽分別放到了目錄pos(積極的評論)和neg(消極的評論)下,每個子目錄均由若干小文件組成,每個小文件內(nèi)部都是一段用戶關(guān)于某個電影的真實(shí)評價(jià),以及觀眾對這個電影的情感傾向。

接下來,根據(jù)IMDB數(shù)據(jù)集的組織形式,便可將IMDB數(shù)據(jù)讀取到內(nèi)存,代碼如下:

# 讀取數(shù)據(jù)
def load_imdb(is_training):
    
    # 將讀取的數(shù)據(jù)放到列表data_set里
    data_set = []

    # data_set中每個元素都是一個二元組:(句子,label),其中l(wèi)abel=0表示消極情感,label=1表示積極情感
    for label in ["pos", "neg"]:
        with tarfile.open("./aclImdb_v1.tar.gz") as tarf:
            path_pattern = "aclImdb/train/" + label + "/.*\.txt$" if is_training \
                else "aclImdb/test/" + label + "/.*\.txt$"
            path_pattern = re.compile(path_pattern)
            tf = tarf.next()
            while tf != None:
                if bool(path_pattern.match(tf.name)):
                    sentence = tarf.extractfile(tf).read().decode()
                    sentence_label = 0 if label == 'neg' else 1
                    data_set.append((sentence, sentence_label)) 
                tf = tarf.next()

    return data_set

train_corpus = load_imdb(True)
test_corpus = load_imdb(False)

# 打印第一條數(shù)據(jù),查看數(shù)據(jù)格式:(句子,label)
print(train_corpus[0])

2.1.4 數(shù)據(jù)格式轉(zhuǎn)換

模型是無法直接處理文本數(shù)據(jù)的,在自然語言處理中,常規(guī)的做法是先將文本進(jìn)行分詞,然后將每個詞映射為該詞在詞典中的id,方便模型后續(xù)根據(jù)這個id找到該詞的詞向量。那這里就涉及到了這樣幾個流程:分詞、組建詞表、將文本中的詞映射為詞典id。

  • 分詞

先來看分詞問題,因?yàn)镮MDB數(shù)據(jù)集本身是英文語料,所以只需要根據(jù)空格進(jìn)行分詞即可,代碼如下:

def data_preprocess(corpus):
    data_set = []
    for sentence, sentence_label in corpus:
        # 將所有的句子轉(zhuǎn)換為小寫,一方面可以減小詞表的大小,另一方面也有助于效果提升
        sentence = sentence.strip().lower()
        sentence = sentence.split(" ")
        
        data_set.append((sentence, sentence_label))

    return data_set

train_set = data_preprocess(train_corpus)
test_set = data_preprocess(test_corpus)

# 打印訓(xùn)練集中的第一條數(shù)據(jù)
print(train_set[0])
(['zentropa', 'has', 'much', 'in', 'common', 'with', 'the', 'third', 'man,', 'another', 'noir-like', 'film', 'set', 'among', 'the', 'rubble', 'of', 'postwar', 'europe.', 'like', 'ttm,', 'there', 'is', 'much', 'inventive', 'camera', 'work.', 'there', 'is', 'an', 'innocent', 'american', 'who', 'gets', 'emotionally', 'involved', 'with', 'a', 'woman', 'he', "doesn't", 'really', 'understand,', 'and', 'whose', 'naivety', 'is', 'all', 'the', 'more', 'striking', 'in', 'contrast', 'with', 'the', 'natives.<br', '/><br', '/>but', "i'd", 'have', 'to', 'say', 'that', 'the', 'third', 'man', 'has', 'a', 'more', 'well-crafted', 'storyline.', 'zentropa', 'is', 'a', 'bit', 'disjointed', 'in', 'this', 'respect.', 'perhaps', 'this', 'is', 'intentional:', 'it', 'is', 'presented', 'as', 'a', 'dream/nightmare,', 'and', 'making', 'it', 'too', 'coherent', 'would', 'spoil', 'the', 'effect.', '<br', '/><br', '/>this', 'movie', 'is', 'unrelentingly', 'grim--"noir"', 'in', 'more', 'than', 'one', 'sense;', 'one', 'never', 'sees', 'the', 'sun', 'shine.', 'grim,', 'but', 'intriguing,', 'and', 'frightening.'], 1)
  • 組建詞表

在經(jīng)過切詞后,需要構(gòu)造一個詞典,后續(xù)把每個詞都轉(zhuǎn)化成一個ID,便于神經(jīng)網(wǎng)絡(luò)訓(xùn)練。按照如下方式生成詞典:

  1. 統(tǒng)計(jì)訓(xùn)練語料中的單詞的頻率,然后根據(jù)頻率大小生成詞典,頻率高的詞在詞典的前邊,頻率低的詞在后邊。
  2. 添加單詞"[oov]",它表示詞表中沒有覆蓋到的詞,即模型在預(yù)測時,很可能遇到詞表中沒有的單詞,這樣的單詞也叫未登錄詞,這時候會將未登錄詞統(tǒng)一映射為"[oov]"
  3. 添加單詞"[pad]",它用于填充文本到指定的文本長度,以便每次傳入到模型中的一批文本的長度是一致的

為了方便記憶,習(xí)慣將這些特殊單詞放在詞典的最前邊,代碼如下:


# 構(gòu)造詞典,統(tǒng)計(jì)每個詞的頻率,并根據(jù)頻率將每個詞轉(zhuǎn)換為一個整數(shù)id
def build_dict(corpus):
    word_freq_dict = dict()
    for sentence, _ in corpus:
        for word in sentence:
            if word not in word_freq_dict:
                word_freq_dict[word] = 0
            word_freq_dict[word] += 1

    word_freq_dict = sorted(word_freq_dict.items(), key = lambda x:x[1], reverse = True)
    
    word2id_dict = dict()
    word2id_freq = dict()

    # 一般來說,我們把oov和pad放在詞典前面,給他們一個比較小的id,這樣比較方便記憶,并且易于后續(xù)擴(kuò)展詞表
    word2id_dict['[oov]'] = 0
    word2id_freq[0] = 1e10

    word2id_dict['[pad]'] = 1
    word2id_freq[1] = 1e10

    for word, freq in word_freq_dict:
        word2id_dict[word] = len(word2id_dict)
        word2id_freq[word2id_dict[word]] = freq

    return word2id_freq, word2id_dict

word2id_freq, word2id_dict = build_dict(train_set)
vocab_size = len(word2id_freq)
print("there are totoally %d different words in the corpus" % vocab_size)
for _, (word, word_id) in zip(range(5), word2id_dict.items()):
    print("word %s, its id %d, its word freq %d" % (word, word_id, word2id_freq[word_id]))
there are totoally 252173 different words in the corpus
word [oov], its id 0, its word freq 10000000000
word [pad], its id 1, its word freq 10000000000
word the, its id 2, its word freq 322174
word a, its id 3, its word freq 159949
word and, its id 4, its word freq 158556
  • 映射為詞典id

在完成word2id詞典建立之后,還需要將語料中的所有文本處理成ID序列,具體是將每個文本中的單詞映射為詞典的id。如果句子中的詞不在詞表內(nèi),則替換成單詞"[oov]",相應(yīng)的代碼如下:

# 把語料轉(zhuǎn)換為id序列
def convert_corpus_to_id(corpus, word2id_dict):
    data_set = []
    for sentence, sentence_label in corpus:
        sentence = [word2id_dict[word] if word in word2id_dict \
                    else word2id_dict['[oov]'] for word in sentence]    
        data_set.append((sentence, sentence_label))
    return data_set

train_set = convert_corpus_to_id(train_set, word2id_dict)
test_set = convert_corpus_to_id(test_set, word2id_dict)

# 打印訓(xùn)練數(shù)據(jù)中的第一條文本
print(train_set[0])
([22216, 41, 76, 8, 1136, 17, 2, 874, 979, 167, 69425, 24, 283, 707, 2, 19881, 5, 16628, 11952, 37, 100421, 52, 7, 76, 5733, 415, 912, 52, 7, 32, 1426, 299, 36, 195, 2299, 644, 17, 3, 282, 27, 141, 61, 7447, 4, 555, 25364, 7, 35, 2, 51, 3590, 8, 2691, 17, 2, 69426, 13, 688, 428, 26, 6, 142, 11, 2, 874, 160, 41, 3, 51, 14841, 4458, 22216, 7, 3, 218, 6262, 8, 10, 6919, 382, 10, 7, 100422, 12, 7, 1394, 15, 3, 100423, 4, 242, 12, 104, 5041, 54, 2368, 2, 4828, 109, 13, 255, 20, 7, 32280, 100424, 8, 51, 68, 30, 29571, 30, 102, 1010, 2, 4142, 18952, 11069, 18, 11636, 4, 12644], 1)

2.1.5 組裝mini-batch

在訓(xùn)練模型時,通常將數(shù)據(jù)分批傳入模型進(jìn)行訓(xùn)練,每批數(shù)據(jù)作為一個mini-batch。所以還需要將所有數(shù)據(jù)按批次(mini-batch)劃分,每個batch數(shù)據(jù)包含兩部分:文本數(shù)據(jù)和文本對應(yīng)的情感標(biāo)簽label。但是這里涉及到一個問題,一個mini-batch數(shù)據(jù)中通常包含若干條文本,每條文本的長度不一致,這樣就會給模型訓(xùn)練帶來困難。

通常的做法是設(shè)定一個最大長度max_seq_len,對于大于該長度的文本進(jìn)行截?cái)?,小于該長度的文本使用"[pad]"進(jìn)行填充。這樣就能將每個batch的所有文本長度進(jìn)行統(tǒng)一,以便模型訓(xùn)練。組裝mini-batch的代碼如下:


def build_batch(word2id_dict, corpus, batch_size, epoch_num, max_seq_len, shuffle = True, drop_last = True):

    sentence_batch = []
    sentence_label_batch = []

    for _ in range(epoch_num): 

        #每個epoch前都shuffle一下數(shù)據(jù),有助于提高模型訓(xùn)練的效果。但是對于預(yù)測任務(wù),不要做數(shù)據(jù)shuffle
        if shuffle:
            random.shuffle(corpus)

        for sentence, sentence_label in corpus:
            sentence_sample = sentence[:min(max_seq_len, len(sentence))]
            if len(sentence_sample) < max_seq_len:
                for _ in range(max_seq_len - len(sentence_sample)):
                    sentence_sample.append(word2id_dict['[pad]'])
            
            sentence_batch.append(sentence_sample)
            sentence_label_batch.append([sentence_label])

            if len(sentence_batch) == batch_size:
                yield np.array(sentence_batch).astype("int64"), np.array(sentence_label_batch).astype("int64")
                sentence_batch = []
                sentence_label_batch = []
    if not drop_last and len(sentence_batch) > 0:
        yield np.array(sentence_batch).astype("int64"), np.array(sentence_label_batch).astype("int64")

batch_iters = build_batch(word2id_dict, train_set, batch_size=3, epoch_num=3, max_seq_len=30)
# 答應(yīng)第一個batch,查看數(shù)據(jù)shape
batch = next(batch_iters)
print("batch type: ", type(batch))
print("text shape: ", batch[0].shape)
print("label shape: ", batch[1].shape)
batch type:  <class 'tuple'>
text shape:  (3, 30)
label shape:  (3, 1)

2.2 模型構(gòu)建

2.2.1 模型結(jié)構(gòu)

上一節(jié)已經(jīng)完成了數(shù)據(jù)處理部分,接下來將構(gòu)建模型結(jié)構(gòu)。本節(jié)將利用長短時記憶網(wǎng)絡(luò)(LSTM)進(jìn)行情感分析建模,LSTM模型是一個時序模型,如?圖7?所示,每個時間步驟接收當(dāng)前的單詞輸入和上一步的狀態(tài)進(jìn)行處理,同時每個時間步驟會輸出一個單詞和當(dāng)前步驟的狀態(tài)。每個時間步驟在時序上可以看做對應(yīng)著一個LSTM單元,它對應(yīng)著兩個狀態(tài):單元狀態(tài)和隱狀態(tài),其中單元狀態(tài)代表遺忘之前單元信息并融入新的單詞信息后,當(dāng)前LSTM單元的狀態(tài);隱狀態(tài)是單元狀態(tài)對外的輸出狀態(tài),每個時間步驟生成單詞時利用的就是隱狀態(tài)。

LSTM會根據(jù)時序關(guān)系依次處理每個時間步驟的輸入,在將一個文本的所有單詞全部傳入LSTM模型后,LSTM模型最后輸出的隱狀態(tài)可以被看作是融合了之前所有單詞的狀態(tài)向量,因此這個狀態(tài)變量也可以視為整串文本的語義向量。

將這個語義向量傳入到線性層,再經(jīng)過softmax處理后便可得到文本屬于積極情感和消極情感的概率。

IMDB電影評論的情感分析——paddle,深度學(xué)習(xí),自然語言處理,情感分析,paddle,人工智能,深度學(xué)習(xí),自然語言處理,情感分析

圖7 情感分析模型網(wǎng)絡(luò)結(jié)構(gòu)示意圖

2.2.2 模型計(jì)算

在了解了本實(shí)驗(yàn)建模的大致流程后,本節(jié)詳細(xì)剖析下該網(wǎng)絡(luò)計(jì)算時發(fā)生的事情,其中模型計(jì)算的部分可參考?圖8?:

  1. 模型訓(xùn)練時通常以batch的形式按批訓(xùn)練模型,每個batch包含訓(xùn)練文本和文本對應(yīng)的情感標(biāo)簽,假設(shè)當(dāng)前batch的訓(xùn)練文本數(shù)據(jù)的shape為:[batch_size, max_seq_len],它代表本次迭代訓(xùn)練語料共有batch_size個,每條語料長度均為max_seq_len。這里需要注意,該文本數(shù)據(jù)從數(shù)據(jù)處理階段獲得,已經(jīng)將單詞映射為了字典id。

  2. 模型的輸入包含兩個部分,訓(xùn)練文本和文本對應(yīng)的情感標(biāo)簽。模型在計(jì)算之前,需要將訓(xùn)練文本中每個單詞的id轉(zhuǎn)換為詞向量(也成為word embedding),這個根據(jù)單詞id查找詞向量的操作成為embedding lookup。 在實(shí)現(xiàn)過程中,本節(jié)將利用飛槳提供的paddle.nn.Embedding,通過這個類能夠很方便地根據(jù)單詞id查找詞向量,假設(shè)詞向量的維度為embedding_size,則以上[batch_size, max_seq_len]的文本數(shù)據(jù)映射之后,將變成[batch_size, max_seq_len, embedding_size]的向量,它代表每個訓(xùn)練batch共batch_size條文本,每個文本長度均包含max_seq_len個單詞,每個單詞的維度為embedding_size。

  3. 在映射完詞向量之后,便可以將batch數(shù)據(jù)[batch_size, max_seq_len, embedding_size]傳入給LSTM模型,這里將借助paddle.nn.LSTM進(jìn)行建模,在計(jì)算之后,便可得到該batch文本對應(yīng)的語義向量,假設(shè)該語義向量的維度為hidden_size,其shape為[batch_size, hidden_size],它代表共有batch_size個語義向量,即每條文本對應(yīng)一個語義向量,每個向量維度為hidden_size。

  4. 將該語義向量傳入線性層中,經(jīng)過矩陣計(jì)算便可得到一個2維向量。具體來講,語義向量的shape為[batch_size, hidden_size],線性層的權(quán)重shape為[hidden_size, 2],這里的2主要是考慮到IMDB數(shù)據(jù)集是個2分類任務(wù),在兩者進(jìn)行矩陣相乘后,便可得到[batch_size, 2]的矩陣,前邊一列的數(shù)字代表消極情感,后邊一列的數(shù)字代表積極情感。

  5. 然后將此[batch_size, 2]的矩陣通過softmax進(jìn)行歸一化處理,要求前邊一列的數(shù)字加上后邊一列的數(shù)字為1,并且每個數(shù)字取值范圍為[0, 1],經(jīng)過這步處理后,可以將前邊一列的數(shù)字看成這條文本是消極情感的概率,后邊一列的數(shù)字可以看成這條文本是積極情感的概率。

IMDB電影評論的情感分析——paddle,深度學(xué)習(xí),自然語言處理,情感分析,paddle,人工智能,深度學(xué)習(xí),自然語言處理,情感分析

圖8 模型計(jì)算樣例

class?paddle.nn.Embedding(num_embeddings, embedding_dim, padding_idx=None, sparse=False, weight_attr=None, name=None)

關(guān)鍵參數(shù)含義如下:

  • num_embeddings (int) - 嵌入字典的大小, input中的id必須滿足 0 =< id < num_embeddings 。
  • embedding_dim (int) - 每個嵌入向量的維度。
  • padding_idx (int|long|None) - padding_idx的配置區(qū)間為 [-weight.shape[0], weight.shape[0]],如果配置了padding_idx,那么在訓(xùn)練過程中遇到此id時會被用
  • sparse (bool) - 是否使用稀疏更新,在詞嵌入權(quán)重較大的情況下,使用稀疏更新能夠獲得更快的訓(xùn)練速度及更小的內(nèi)存/顯存占用。
  • weight_attr (ParamAttr|None) - 指定嵌入向量的配置,包括初始化方法,具體用法請參見 ParamAttr ,一般無需設(shè)置,默認(rèn)值為None。

class?paddle.nn.LSTM(input_size, hidden_size, num_layers=1, direction='forward', dropout=0., time_major=False, weight_ih_attr=None, weight_hh_attr=None, bias_ih_attr=None, bias_hh_attr=None)

關(guān)鍵參數(shù)含義如下:

  • input_size (int) - 輸入的大小。
  • hidden_size (int) - 隱藏狀態(tài)大小。
  • num_layers (int,可選) - 網(wǎng)絡(luò)層數(shù)。默認(rèn)為1。
  • direction (str,可選) - 網(wǎng)絡(luò)迭代方向,可設(shè)置為forward或bidirect(或bidirectional)。默認(rèn)為forward。
  • time_major (bool,可選) - 指定input的第一個維度是否是time steps。默認(rèn)為False。
  • dropout (float,可選) - dropout概率,指的是出第一層外每層輸入時的dropout概率。默認(rèn)為0。
  • weight_ih_attr (ParamAttr,可選) - weight_ih的參數(shù)。默認(rèn)為None。
  • weight_hh_attr (ParamAttr,可選) - weight_hh的參數(shù)。默認(rèn)為None。
  • bias_ih_attr (ParamAttr,可選) - bias_ih的參數(shù)。默認(rèn)為None。
  • bias_hh_attr (ParamAttr,可選) - bias_hh的參數(shù)。默認(rèn)為None。

網(wǎng)絡(luò)計(jì)算對應(yīng)的代碼如下:

# 定義一個用于情感分類的網(wǎng)絡(luò)實(shí)例,SentimentClassifier
class SentimentClassifier(paddle.nn.Layer):
    
    def __init__(self, hidden_size, vocab_size, embedding_size, class_num=2, num_steps=128, num_layers=1, init_scale=0.1, dropout_rate=None):
        
        # 參數(shù)含義如下:
        # 1.hidden_size,表示embedding-size,hidden和cell向量的維度
        # 2.vocab_size,模型可以考慮的詞表大小
        # 3.embedding_size,表示詞向量的維度
        # 4.class_num,情感類型個數(shù),可以是2分類,也可以是多分類
        # 5.num_steps,表示這個情感分析模型最大可以考慮的句子長度
        # 6.num_layers,表示網(wǎng)絡(luò)的層數(shù)
        # 7.dropout_rate,表示使用dropout過程中失活的神經(jīng)元比例
        # 8.init_scale,表示網(wǎng)絡(luò)內(nèi)部的參數(shù)的初始化范圍,長短時記憶網(wǎng)絡(luò)內(nèi)部用了很多Tanh,Sigmoid等激活函數(shù),\
        # 這些函數(shù)對數(shù)值精度非常敏感,因此我們一般只使用比較小的初始化范圍,以保證效果
        super(SentimentClassifier, self).__init__()
        self.hidden_size = hidden_size
        self.vocab_size = vocab_size
        self.embedding_size = embedding_size
        self.class_num = class_num
        self.num_steps = num_steps
        self.num_layers = num_layers
        self.dropout_rate = dropout_rate
        self.init_scale = init_scale
       
        # 聲明一個LSTM模型,用來把每個句子抽象成向量
        self.simple_lstm_rnn = paddle.nn.LSTM(input_size=hidden_size, hidden_size=hidden_size, num_layers=num_layers)

        # 聲明一個embedding層,用來把句子中的每個詞轉(zhuǎn)換為向量
        self.embedding = paddle.nn.Embedding(num_embeddings=vocab_size, embedding_dim=embedding_size, sparse=False, 
                                    weight_attr=paddle.ParamAttr(initializer=paddle.nn.initializer.Uniform(low=-init_scale, high=init_scale)))
        
        # 聲明使用上述語義向量映射到具體情感類別時所需要使用的線性層
        self.cls_fc = paddle.nn.Linear(in_features=self.hidden_size, out_features=self.class_num, 
                             weight_attr=None, bias_attr=None)
        
        # 一般在獲取單詞的embedding后,會使用dropout層,防止過擬合,提升模型泛化能力
        self.dropout_layer = paddle.nn.Dropout(p=self.dropout_rate, mode='upscale_in_train')

    # forwad函數(shù)即為模型前向計(jì)算的函數(shù),它有兩個輸入,分別為:
    # input為輸入的訓(xùn)練文本,其shape為[batch_size, max_seq_len]
    # label訓(xùn)練文本對應(yīng)的情感標(biāo)簽,其shape維[batch_size, 1]
    def forward(self, inputs):
        # 獲取輸入數(shù)據(jù)的batch_size
        batch_size = inputs.shape[0]

        # 本實(shí)驗(yàn)?zāi)J(rèn)使用1層的LSTM,首先我們需要定義LSTM的初始hidden和cell,這里我們使用0來初始化這個序列的記憶
        init_hidden_data = np.zeros(
            (self.num_layers, batch_size, self.hidden_size), dtype='float32')
        init_cell_data = np.zeros(
            (self.num_layers, batch_size, self.hidden_size), dtype='float32')

        # 將這些初始記憶轉(zhuǎn)換為飛槳可計(jì)算的向量,并且設(shè)置stop_gradient=True,避免這些向量被更新,從而影響訓(xùn)練效果
        init_hidden = paddle.to_tensor(init_hidden_data)
        init_hidden.stop_gradient = True
        init_cell = paddle.to_tensor(init_cell_data)
        init_cell.stop_gradient = True

        # 對應(yīng)以上第2步,將輸入的句子的mini-batch轉(zhuǎn)換為詞向量表示,轉(zhuǎn)換后輸入數(shù)據(jù)shape為[batch_size, max_seq_len, embedding_size]
        x_emb = self.embedding(inputs)
        x_emb = paddle.reshape(x_emb, shape=[-1, self.num_steps, self.embedding_size])
        # 在獲取的詞向量后添加dropout層
        if self.dropout_rate is not None and self.dropout_rate > 0.0:
            x_emb = self.dropout_layer(x_emb)
        
        # 對應(yīng)以上第3步,使用LSTM網(wǎng)絡(luò),把每個句子轉(zhuǎn)換為語義向量
        # 返回的last_hidden即為最后一個時間步的輸出,其shape為[self.num_layers, batch_size, hidden_size]
        rnn_out, (last_hidden, last_cell) = self.simple_lstm_rnn(x_emb, (init_hidden, init_cell))
        # 提取最后一層隱狀態(tài)作為文本的語義向量,其shape為[batch_size, hidden_size]
        last_hidden = paddle.reshape(last_hidden[-1], shape=[-1, self.hidden_size])

        # 對應(yīng)以上第4步,將每個句子的向量表示映射到具體的情感類別上, logits的維度為[batch_size, 2]
        logits = self.cls_fc(last_hidden)

        return logits

2.3 訓(xùn)練配置

本節(jié)將定義模型訓(xùn)練時用到的一些組件和資源,包括定義模型的實(shí)例化對象,選擇模型訓(xùn)練和或評估時需要使用的計(jì)算資源(CPU或者GPU),指定模型訓(xùn)練迭代的優(yōu)化算法。 其中,本節(jié)實(shí)驗(yàn)將默認(rèn)使用GPU進(jìn)行訓(xùn)練,通過調(diào)用?paddle.get_device()?來查看當(dāng)前實(shí)驗(yàn)環(huán)境是否有GPU可用,優(yōu)先使用GPU進(jìn)行訓(xùn)練。

paddle.get_device()

  • 該功能返回當(dāng)前程序運(yùn)行的全局設(shè)備,返回的是一個類似于 cpu 或者 gpu:0 字符串,如果沒有設(shè)置全局設(shè)備,當(dāng)cuda可用的時候返回 gpu:0 ,當(dāng)cuda不可用的時候返回 cpu 。

另外,本實(shí)驗(yàn)將使用?paddle.optimizer.Adam()?算法進(jìn)行模型迭代優(yōu)化。

class?paddle.optimizer.Adam(learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08, parameters=None, weight_decay=None, grad_clip=None, name=None, lazy_mode=False)

關(guān)鍵參數(shù)含義如下:

  • learning_rate (float|_LRScheduler) - 學(xué)習(xí)率,用于參數(shù)更新的計(jì)算??梢允且粋€浮點(diǎn)型值或者一個_LRScheduler類,默認(rèn)值為0.001
  • beta1 (float|Tensor, 可選) - 一階矩估計(jì)的指數(shù)衰減率,是一個float類型或者一個shape為[1],數(shù)據(jù)類型為float32的Tensor類型。默認(rèn)值為0.9
  • beta2 (float|Tensor, 可選) - 二階矩估計(jì)的指數(shù)衰減率,是一個float類型或者一個shape為[1],數(shù)據(jù)類型為float32的Tensor類型。默認(rèn)值為0.999
  • epsilon (float, 可選) - 保持?jǐn)?shù)值穩(wěn)定性的短浮點(diǎn)類型值,默認(rèn)值為1e-08
  • parameters (list, 可選) - 指定優(yōu)化器需要優(yōu)化的參數(shù)。
  • weight_decay (float|WeightDecayRegularizer,可選) - 正則化方法。
  • grad_clip (GradientClipBase, 可選) – 梯度裁剪的策略。 默認(rèn)值為None,此時將不進(jìn)行梯度裁剪。
  • name (str, 可選)- 該參數(shù)供開發(fā)人員打印調(diào)試信息時使用,具體用法請參見 Name ,默認(rèn)值為None
  • lazy_mode (bool, 可選) - 設(shè)為True時,僅更新當(dāng)前具有梯度的元素。

訓(xùn)練配置的代碼如下:

# 定義訓(xùn)練參數(shù)
epoch_num = 5
batch_size = 128

learning_rate = 0.01
dropout_rate = 0.2
num_layers = 1
hidden_size = 256
embedding_size = 256
max_seq_len = 128
vocab_size = len(word2id_freq)

# 檢測是否可以使用GPU,如果可以優(yōu)先使用GPU
use_gpu = True if paddle.get_device().startswith("gpu") else False
if use_gpu:
    paddle.set_device('gpu:0')

# 實(shí)例化模型
sentiment_classifier = SentimentClassifier(hidden_size, vocab_size, embedding_size,  num_steps=max_seq_len, num_layers=num_layers, dropout_rate=dropout_rate)

# 指定優(yōu)化策略,更新模型參數(shù)
optimizer = paddle.optimizer.Adam(learning_rate=learning_rate, beta1=0.9, beta2=0.999, parameters= sentiment_classifier.parameters()) 
W0414 16:53:49.788056    99 device_context.cc:362] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 10.1, Runtime API Version: 10.1
W0414 16:53:49.800664    99 device_context.cc:372] device: 0, cuDNN Version: 7.6.

2.4 模型訓(xùn)練

2.4.1 訓(xùn)練過程

上文已經(jīng)實(shí)現(xiàn)了模型結(jié)構(gòu),并且完成了訓(xùn)練的配置,接下來就可以開始訓(xùn)練模型了。在訓(xùn)練過程中,可以分為四個步驟:獲取數(shù)據(jù)、傳入模型進(jìn)行前向計(jì)算、反向傳播和參數(shù)更新。訓(xùn)練過程中的每次迭代基本都是在循環(huán)往復(fù)地執(zhí)行這四個步驟。具體的模型訓(xùn)練代碼如下:

# 記錄訓(xùn)練過程中的損失變化情況,可用于后續(xù)畫圖查看訓(xùn)練情況
losses = []
steps = []

def train(model):
    # 開啟模型訓(xùn)練模式
    model.train()
    
    # 建立訓(xùn)練數(shù)據(jù)生成器,每次迭代生成一個batch,每個batch包含訓(xùn)練文本和文本對應(yīng)的情感標(biāo)簽
    train_generator = build_batch(word2id_dict, train_set, batch_size, epoch_num, max_seq_len)
    
    for step, (sentences, labels) in enumerate(train_generator):
        # 獲取數(shù)據(jù),并將張量轉(zhuǎn)換為Tensor類型
        sentences = paddle.to_tensor(sentences)
        labels = paddle.to_tensor(labels)
        
        # 前向計(jì)算,將數(shù)據(jù)feed進(jìn)模型,并得到預(yù)測的情感標(biāo)簽和損失
        logits = model(sentences)

        # 計(jì)算損失
        loss = F.cross_entropy(input=logits, label=labels, soft_label=False)
        loss = paddle.mean(loss)

        # 后向傳播
        loss.backward()
        # 更新參數(shù)
        optimizer.step()
        # 清除梯度
        optimizer.clear_grad()

        if step % 100 == 0:
            # 記錄當(dāng)前步驟的loss變化情況
            losses.append(loss.numpy()[0])
            steps.append(step)
            # 打印當(dāng)前l(fā)oss數(shù)值
            print("step %d, loss %.3f" % (step, loss.numpy()[0]))

train(sentiment_classifier)
step 0, loss 0.694
step 100, loss 0.696
step 200, loss 0.477
step 300, loss 0.368
step 400, loss 0.093
step 500, loss 0.072
step 600, loss 0.008
step 700, loss 0.004
step 800, loss 0.007
step 900, loss 0.021

2.4.2 訓(xùn)練可視化

訓(xùn)練過程中,每隔100 steps記錄一下loss值,圖9?展示了這些loss變化的情況,其中縱軸代表loss數(shù)值,橫軸代表訓(xùn)練的step。整體來看,loss隨著訓(xùn)練步數(shù)的增加而不斷下降,最終平穩(wěn),這說明本次實(shí)驗(yàn)中模型的訓(xùn)練是有效的。IMDB電影評論的情感分析——paddle,深度學(xué)習(xí),自然語言處理,情感分析,paddle,人工智能,深度學(xué)習(xí),自然語言處理,情感分析

圖9 訓(xùn)練過程中l(wèi)oss變化圖

根據(jù)loss數(shù)值畫圖的代碼如下:


import matplotlib.pyplot as plt

# 開始畫圖,橫軸是訓(xùn)練step,縱軸是損失
plt.plot(steps, losses, "-o")
plt.xlabel("step")
plt.ylabel("loss")
plt.savefig("./loss.png")
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/__init__.py:107: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  from collections import MutableMapping
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/rcsetup.py:20: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  from collections import Iterable, Mapping
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/colors.py:53: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  from collections import Sized
2022-04-14 16:54:39,166 - INFO - font search path ['/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf', '/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/afm', '/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts']
2022-04-14 16:54:39,656 - INFO - generated new fontManager
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/cbook/__init__.py:2349: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  if isinstance(obj, collections.Iterator):
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/cbook/__init__.py:2366: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  return list(data) if isinstance(data, collections.MappingView) else data

2.5 模型保存

在模型訓(xùn)練完成后,需要將模型和優(yōu)化器參數(shù)保存到磁盤,用于模型推理或繼續(xù)訓(xùn)練。保存模型的代碼如下,通過paddle.save?API實(shí)現(xiàn)模型參數(shù)和優(yōu)化器參數(shù)的保存。

model_name = "sentiment_classifier"

# 保存訓(xùn)練好的模型參數(shù)
paddle.save(sentiment_classifier.state_dict(), "{}.pdparams".format(model_name))
# 保存優(yōu)化器參數(shù),方便后續(xù)模型繼續(xù)訓(xùn)練
paddle.save(optimizer.state_dict(), "{}.pdopt".format(model_name))

2.6 模型評估

在模型訓(xùn)練完成后,需要使用測試集對模型進(jìn)行評估,驗(yàn)證模型效果。首先需要加載訓(xùn)練好的模型,然后就可以開始測試模型了。具體地,先以batch的形式獲取測試數(shù)據(jù),然后傳入模型進(jìn)行前向計(jì)算,最后根據(jù)模型計(jì)算得出的情感分類標(biāo)簽統(tǒng)計(jì)結(jié)果。

本節(jié)將采用一個混淆矩陣的方式統(tǒng)計(jì)結(jié)果,混淆矩陣是用來統(tǒng)計(jì)分類結(jié)果的分析表,如下圖所示,它根據(jù)測試集真實(shí)的類別和模型預(yù)測的類別進(jìn)行匯總,共可以分為如下四種情況:

  1. 真正例(Ture Positive):樣本的真實(shí)標(biāo)簽是正例,模型預(yù)測結(jié)果也是正例,簡稱TP
  2. 假正例(False Positive):樣本的真實(shí)標(biāo)簽是反例,模型預(yù)測結(jié)果卻是正例,簡稱FP
  3. 真反例(True Negative):樣本的真實(shí)標(biāo)簽是反例,模型預(yù)測結(jié)果也是反例,簡稱TN
  4. 假反例(False Negative):樣本的真實(shí)標(biāo)簽是正例,模型預(yù)測結(jié)果卻是反例,簡稱FN

以上四種情況中,TP和TN代表模型預(yù)測對的結(jié)果,F(xiàn)P和FN代表模型預(yù)測錯誤的結(jié)果,可以通過這四個指標(biāo)大小判斷模型訓(xùn)練的效果。另外還可以根據(jù)這幾個統(tǒng)計(jì)值計(jì)算模型的整體準(zhǔn)確率:accuracy = (TP+TN)/(TP+FP+TN+FN)

IMDB電影評論的情感分析——paddle,深度學(xué)習(xí),自然語言處理,情感分析,paddle,人工智能,深度學(xué)習(xí),自然語言處理,情感分析

圖10 混淆矩陣

在本實(shí)驗(yàn)中,假設(shè)將積極的樣本視為正例,消極的樣本視為負(fù)例,那就可以根據(jù)混淆矩陣進(jìn)行統(tǒng)計(jì)結(jié)果了。從上節(jié)可以得知,模型輸出的標(biāo)簽是個[batch_size, 2]的矩陣,是經(jīng)過softmax后的結(jié)果,前一列代表相應(yīng)樣本是負(fù)例的概率,后一列代表是正例的概率,兩者之和為1。對于一個樣本,如果正例的概率大于反例的概率,這代表模型預(yù)測結(jié)果是正例,否則是反例。具體的模型評估代碼如下:

def evaluate(model):
    # 開啟模型測試模式,在該模式下,網(wǎng)絡(luò)不會進(jìn)行梯度更新
    model.eval()

    # 定義以上幾個統(tǒng)計(jì)指標(biāo)
    tp, tn, fp, fn = 0, 0, 0, 0

    # 構(gòu)造測試數(shù)據(jù)生成器
    test_generator = build_batch(word2id_dict, test_set, batch_size, 1, max_seq_len)
    
    for sentences, labels in test_generator:
        # 將張量轉(zhuǎn)換為Tensor類型
        sentences = paddle.to_tensor(sentences)
        labels = paddle.to_tensor(labels)
        # 獲取模型對當(dāng)前batch的輸出結(jié)果
        logits = model(sentences)

        # 使用softmax進(jìn)行歸一化
        probs = F.softmax(logits)

        # 把輸出結(jié)果轉(zhuǎn)換為numpy array數(shù)組,比較預(yù)測結(jié)果和對應(yīng)label之間的關(guān)系,并更新tp,tn,fp和fn
        probs = probs.numpy()
        for i in range(len(probs)):
            # 當(dāng)樣本是的真實(shí)標(biāo)簽是正例
            if labels[i][0] == 1:
                # 模型預(yù)測是正例
                if probs[i][1] > probs[i][0]:
                    tp += 1
                # 模型預(yù)測是負(fù)例
                else:
                    fn += 1
            # 當(dāng)樣本的真實(shí)標(biāo)簽是負(fù)例
            else:
                # 模型預(yù)測是正例
                if probs[i][1] > probs[i][0]:
                    fp += 1
                # 模型預(yù)測是負(fù)例
                else:
                    tn += 1

    # 整體準(zhǔn)確率
    accuracy = (tp + tn) / (tp + tn + fp + fn)
    
    # 輸出最終評估的模型效果
    print("TP: {}\nFP: {}\nTN: {}\nFN: {}\n".format(tp, fp, tn, fn))
    print("Accuracy: %.4f" % accuracy)

# 加載訓(xùn)練好的模型進(jìn)行預(yù)測,重新實(shí)例化一個模型,然后將訓(xùn)練好的模型參數(shù)加載到新模型里面
saved_state = paddle.load("./sentiment_classifier.pdparams")
sentiment_classifier = SentimentClassifier(hidden_size, vocab_size, embedding_size,  num_steps=max_seq_len, num_layers=num_layers, dropout_rate=dropout_rate)
sentiment_classifier.load_dict(saved_state)

# 評估模型
evaluate(sentiment_classifier)
TP: 8938
FP: 2324
TN: 10156
FN: 3542
Accuracy: 0.7650

2.7 模型推理

任意輸入一個電影評論方面的文本,如:“this movie is so wonderful. I watched it three times”,通過模型推理驗(yàn)證模型訓(xùn)練效果,實(shí)現(xiàn)代碼如下。

# 模型預(yù)測代碼
def infer(model, text):
    model.eval()
    # 數(shù)據(jù)處理
    sentence = text.split(" ")
    tokens = [word2id_dict[word] if word in word2id_dict \
                    else word2id_dict['[oov]'] for word in sentence] 

    # 截?cái)嗷蛘咛畛湫蛄械?    tokens = tokens[:max_seq_len]
    tokens = tokens+[word2id_dict['[pad]']]*(max_seq_len-len(tokens))

    # 構(gòu)造輸入模型的數(shù)據(jù)
    tokens = paddle.to_tensor(tokens, dtype="int64").unsqueeze(0)

    # 計(jì)算發(fā)射分?jǐn)?shù)
    logits = model(tokens)
    probs = F.softmax(logits)

    # # 解析出分?jǐn)?shù)最大的標(biāo)簽
    id2label={0:"消極情緒", 1:"積極情緒"}
    max_label_id = paddle.argmax(logits, axis=1).numpy()[0]
    pred_label = id2label[max_label_id]

    print("Label: ", pred_label)

title = "this movie is so great. I watched it three times already"
infer(sentiment_classifier, title)
Label:  積極情緒

3. 實(shí)驗(yàn)總結(jié)

本實(shí)驗(yàn)基于長短時記憶網(wǎng)絡(luò)LSTM實(shí)現(xiàn)了IMDB電影評論的情感分析模型。通過本實(shí)驗(yàn)掌握了通過飛槳實(shí)現(xiàn)電影評論情感分析任務(wù)實(shí)驗(yàn)流程。大家可以在此實(shí)驗(yàn)的基礎(chǔ)上,嘗試開發(fā)對電商商品評論的情感分析模型。文章來源地址http://www.zghlxwxcb.cn/news/detail-806423.html

到了這里,關(guān)于IMDB電影評論的情感分析——paddle的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包