基于自回歸模型的酒店評論生成

《DeepSeek大模型高性能核心技術與多模態融合開發(人工智能技術叢書)》(王曉華)【摘要 書評 試讀】- 京東圖書

我們使用新架構的模型完成情感分類,可以看到,使用注意力機制可以很好地對特征進行抽取從而完成二分類的情感分類任務。

然而使用自注意力的模型并不僅限于此,除了經典的分類任務外,我們還可以使用增加了旋轉位置編碼RoPE的模型來完成文本生成。

4.3.1? 數據集的準備與讀取

在上一節中,我們已經完成了情感數據集的基本讀取,并掌握了漢字文本內容編碼的方法。對于本節的任務,即基于自回歸模型的酒店評論生成,數據集的準備與讀取代碼如下:

import numpy as np
from tqdm import tqdm
import torchimport tokenizer
tokenizer_emo = tokenizer.Tokenizer(model_path="../vocab/my_model.model")print(tokenizer_emo.vocab_size())
max_length = 48token_list = []
with open("../../dataset/ChnSentiCorp.txt", mode="r", encoding="UTF-8") as emotion_file:for line in tqdm(emotion_file.readlines()):line = line.strip().split(",")text = "".join(line[1:]) + '※'if True:token = tokenizer_emo.encode(text)for id in token:token_list.append(id)
token_list = torch.tensor(token_list * 2)class TextSamplerDataset(torch.utils.data.Dataset):def __init__(self, data = token_list, seq_len = max_length):super().__init__()self.data = dataself.seq_len = seq_lendef __getitem__(self, index):rand_start = torch.randint(0, self.data.size(0) - self.seq_len, (1,))full_seq = self.data[rand_start : rand_start + self.seq_len + 1].long()return full_seq[:-1],full_seq[1:]def __len__(self):return self.data.size(0) // self.seq_len

這里我們首先對文本內容進行讀取,需要注意的是,對于每行的文本內容,我們不像上一節進行情感判定時每行作為一份準備進行存儲,而是使用了首位相連的形式進行添加。這樣做的目的符合我們文本生成任務的訓練形式,即只需要按格式生成文本內容,而無需去了解所代表的含義。

TextSamplerDataset進行采樣時我們也是隨機截取了特定一段的文本進行輸出,因為隨機截取可以在一定程度上增加文本的多樣性,增強了模型的健壯性。

4.3.2? 基于自回歸文本生成模型的設計

接下來,我們需要實現基于自回歸文本生成模型的設計。首先是基本的模型設計,相對于上一節完成的分類模型,自回歸文本生成模型由于是生成任務,需要額外地添加位置編碼,即我們在本章第一節講解的旋轉位置編碼。添加了旋轉位置編碼的注意力模型如下所示。

class MultiHeadAttention_MHA(torch.nn.Module):def __init__(self, d_model, attention_head_num):super(MultiHeadAttention_MHA, self).__init__()self.attention_head_num = attention_head_numself.d_model = d_modelassert d_model % attention_head_num == 0self.scale = d_model ** -0.5self.softcap_value = 50.self.per_head_dmodel = d_model // attention_head_numself.qkv_layer = torch.nn.Linear(d_model, 3 * d_model)self.rotary_embedding = RotaryEmbedding(self.per_head_dmodel // 2, use_xpos=True)self.out_layer = torch.nn.Linear(d_model, d_model)def forward(self, embedding, past_length = 0):qky_x = self.qkv_layer(embedding)q, k, v = torch.split(qky_x, split_size_or_sections=self.d_model, dim=-1)q = einops.rearrange(q, "b s (h d) -> b h s d", h=self.attention_head_num)k = einops.rearrange(k, "b s (h d) -> b h s d", h=self.attention_head_num)v = einops.rearrange(v, "b s (h d) -> b h s d", h=self.attention_head_num)q, k = self.rotary_embedding.rotate_queries_and_keys(q, k, seq_dim=2)q = q * self.scalesim = einops.einsum(q, k, 'b h i d, b h j d -> b h i j')#sim = softclamp(sim, self.softcap_value)mask_value = -torch.finfo(sim.dtype).maxi, j = sim.shape[-2:]causal_mask = torch.ones((i, j), dtype=torch.bool).triu(past_length).to(embedding.device)sim = sim.masked_fill(causal_mask, mask_value)attn = sim.softmax(dim=-1)out = einops.einsum(attn, v, 'b h i j, b h j d -> b h i d')embedding = einops.rearrange(out, "b h s d -> b s (h d)")embedding = self.out_layer(embedding)return embedding

其中的參數past_length=0的作用是對因果掩碼進行設計,在這里triu(past_length)函數的作用是是從past_length的位置開始,生成一個對三角矩陣,對這個不理解的讀者可以嘗試如下函數:

causal_mask = torch.ones((5, 5), dtype=torch.bool).triu(0)

causal_mask = torch.ones((5, 5), dtype=torch.bool).triu(2)

打印結果并比較其中內容。

而基于標準注意力層完成的自回歸模型如下所示。

from torch import Tensor
import torch, math, einops
from moudle import attention_moudle,feedforward_layerclass EncoderBlock(torch.nn.Module):def __init__(self, d_model, num_heads):super(EncoderBlock, self).__init__()self.d_model = d_modelself.num_heads = num_headsself.attention_norm = torch.nn.RMSNorm(d_model)self.self_attention = attention_moudle.MultiHeadAttention(d_model, num_heads)self.ffn = feedforward_layer.Swiglu(d_model)def forward(self, embedding):residual = embeddingembedding = self.attention_norm(embedding)embedding = self.self_attention(embedding)embedding = self.ffn(embedding)return embedding + residualclass Encoder(torch.nn.Module):def __init__(self, d_model, num_heads, num_layers = 3):super(Encoder, self).__init__()self.layers = torch.nn.ModuleList([EncoderBlock(d_model, num_heads) for _ in range(num_layers)])def forward(self, embedding):for layer in self.layers:embedding = layer(embedding)return embeddingclass GeneratorModule(torch.nn.Module):def __init__(self, d_model, num_heads,vocab_size = 3120):super(GeneratorModule, self).__init__()self.embedding_layer = torch.nn.Embedding(vocab_size, d_model)self.encoder = Encoder(d_model, num_heads)self.logits = torch.nn.Linear(d_model, vocab_size)def forward(self, x):embedding = self.embedding_layer(x)embedding = self.encoder(embedding)logits = self.logits(embedding)return logits

同樣地,我們在模型設計中,使用了Block模塊化的設計思想完成模型的設計,通過堆疊多個模塊,對文本的特征進行抽取,并在logits層轉換后輸出。

另外還需要注意的是,由于我們目標是完成自回歸生成任務,而在輸出時則需要一個專門的輸出格式的函數對其進行輸出,代碼如下所示。

@torch.no_grad()def generate(self, prompt=None, n_tokens_to_gen=20, temperature=1., top_k=3, sample=False, eos_token=2, device="cuda"):"""根據給定的提示(prompt)生成一段指定長度的序列。參數:- seq_len: 生成序列的總長度。- prompt: 序列生成的起始提示,可以是一個列表。- temperature: 控制生成序列的隨機性。溫度值越高,生成的序列越隨機;溫度值越低,生成的序列越確定。- eos_token: 序列結束標記的token ID,默認為2。- return_seq_without_prompt: 是否在返回的序列中不包含初始的提示部分,默認為True。返回:- 生成的序列(包含或不包含初始提示部分,取決于return_seq_without_prompt參數的設置)。"""# 將輸入的prompt轉換為torch張量,并確保它在正確的設備上(如GPU或CPU)。]self.eval()# prompt = torch.tensor(prompt)prompt = prompt.clone().detach().requires_grad_(False).to(device)input_ids = promptfor token_n in range(n_tokens_to_gen):with torch.no_grad():indices_to_input = input_idsnext_token_logits = self.forward(indices_to_input)next_token_logits = next_token_logits[:, -1]probs = torch.nn.softmax(next_token_logits, dim=-1) * temperature(batch, vocab_size) = probs.shapeif top_k is not None:(values, indices) = torch.topk(probs, k=top_k)probs[probs < values[:, -1, None]] = 0probs = probs / probs.sum(axis=1, keepdims=True)if sample:next_indices = torch.multinomial(probs, num_samples=1)else:next_indices = torch.argmax(probs, dim=-1)[:, None]input_ids = torch.cat([input_ids, next_indices], dim=1)return input_ids

在上面代碼中,我們按照自回歸模型的性質,每次根據傳入的文本,生成下一個字符,之后我們將獲取的字符進行轉換,再拼接到原始文本中,這樣依次拼接的結果即獲取到完整的生成內容。

4.3.3? 評論生成模型模型的訓練

下面就是情感評論生成模型的訓練,在這里我們可以仿照前面章節訓練的過程,直接對模型進行訓練,代碼如下所示。

import math
from tqdm import tqdm
import torch
from torch.utils.data import DataLoader
import modeldevice = "cuda"
model = model.GeneratorModule(d_model=312,num_heads=6)
model.to(device)
save_path = "./saver/generator_model.pth"
model.load_state_dict(torch.load(save_path),strict=False)BATCH_SIZE = 360
seq_len = 48
import get_data_emotiontrain_dataset = get_data_emotion.TextSamplerDataset(get_data_emotion.token_list,seq_len=seq_len)
train_loader = (DataLoader(train_dataset, batch_size=BATCH_SIZE,shuffle=True))optimizer = torch.optim.AdamW(model.parameters(), lr = 2e-4)
lr_scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer,T_max = 1200,eta_min=2e-5,last_epoch=-1)
criterion = torch.nn.CrossEntropyLoss()for epoch in range(60):pbar = tqdm(train_loader,total=len(train_loader))for token_inp,token_tgt in pbar:token_inp = token_inp.to(device)token_tgt = token_tgt.to(device)logits = model(token_inp)loss = criterion(logits.view(-1, logits.size(-1)), token_tgt.view(-1))optimizer.zero_grad()loss.backward()optimizer.step()lr_scheduler.step()  # 執行優化器pbar.set_description(f"epoch:{epoch +1}, train_loss:{loss.item():.5f}, lr:{lr_scheduler.get_last_lr()[0]*1000:.5f}")torch.save(model.state_dict(), save_path)

讀者可以自行嘗試運行代碼查看結果。

4.3.4? 使用訓練好的模型生成評論

接下來,我們需要使用訓練好的模型生成對應的評論。根據自回歸模型的指引,我們只需要設置一個起始內容,即可根據需要生成特定的文本。代碼如下:

import torch
import modelimport tokenizer
tokenizer_emo = tokenizer.Tokenizer(model_path="../vocab/my_model.model")device = "cuda"
model = model.GeneratorModule(d_model=384,num_heads=6)
model.to(device)save_path = "./saver/generator_model.pth"
model.load_state_dict(torch.load(save_path),strict=False)model.to(device)
model.eval()for _ in range(10):text = "位置"prompt_token = tokenizer_emo.encode(text)prompt_token = torch.tensor([prompt_token]).long().to(device)result_token = model.generate(prompt=prompt_token, n_tokens_to_gen=64,top_k=5,temperature=0.99,device=device)[0].cpu().numpy()text = tokenizer_emo.decode(result_token).split("※")[0]print(text)

部分生成結果如下所示。

位置很好,就在火車站對面,離火車站很近的了,交通很便利,從機場來講是到市中心,去機場的機場,可以坐在車上。
位置不錯,在市中心,交通方便,房間也很大,服務也很好,就是房間的隔音效果比較差,而且很多人性化的服務,服務也不錯,總的來說很滿意
位置很不錯,離火車站很近也很方便。房間裝修很好,就是電視太小。
位置很好,就在繁華的路邊,出門走5分鐘就可以到了。總體來說還可以。
位置很好,就在火車站附近,步行到中心也很方便。房間也很干凈,就是有一點點小,不過還是挺干凈的,服務員也很有禮貌,有機會會來度假區住這樣的酒店很

讀者可以自行嘗試學習。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/bicheng/75928.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/75928.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/75928.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于轉置卷積

&#x1f9e0; 具體講解神經網絡中的轉置卷積&#xff08;Transposed Convolution&#xff09; &#x1f9ed; 1. 轉置卷積的動機&#xff1a;為什么我們需要它&#xff1f; 標準卷積通常會降低特征圖的空間尺寸&#xff08;比如從 64x64 → 32x32&#xff09;&#xff0c;這對…

JavaScript 模塊化詳解( CommonJS、AMD、CMD、ES6模塊化)

一.CommonJS 1.概念 CommonJS 規范概述了同步聲明依賴的模塊定義。這個規范主要用于在服務器端實現模塊化代碼組 織&#xff0c;但也可用于定義在瀏覽器中使用的模塊依賴。CommonJS 模塊語法不能在瀏覽器中直接運行&#xff1b;在瀏覽器端&#xff0c;模塊需要提前編譯打包處理…

TCP BBR 的優化

前段時間&#xff0c;老板發了篇資料&#xff0c;下面是我學習的相關記錄整理。 https://aws.amazon.com/cn/blogs/china/talking-about-network-optimization-from-the-flow-control-algorithm/ PS&#xff1a;ubuntu24默認使用的tcp控制算法。還是 cubic sysctl net.ipv4.tc…

什么是異步?

什么是異步&#xff1f; 異步是一個術語&#xff0c;用于描述不需要同時行動或協調就能獨立運行的流程。這一概念在技術和計算領域尤為重要&#xff0c;它允許系統的不同部分按自己的節奏運行&#xff0c;而無需等待同步信號或事件。在區塊鏈技術中&#xff0c;異步是指網絡中…

SSM婚紗攝影網的設計

&#x1f345;點贊收藏關注 → 添加文檔最下方聯系方式咨詢本源代碼、數據庫&#x1f345; 本人在Java畢業設計領域有多年的經驗&#xff0c;陸續會更新更多優質的Java實戰項目希望你能有所收獲&#xff0c;少走一些彎路。&#x1f345;關注我不迷路&#x1f345; 項目視頻 SS…

石頭剪刀布游戲

自己寫的一個石頭剪刀布游戲&#xff0c;如果有需要更改的地方請指出 #define _CRT_SECURE_NO_WARNINGS // scanf_s編寫起來太過于麻煩&#xff0c;直接把這個警告關掉&#xff0c;便于編寫。 #include <stdio.h> #include <stdlib.h> #include <time.h> //…

大數據系列之:Kerberos

大數據系列之&#xff1a;Kerberos 基本概念工作流程安全特性應用場景總結加密原理Kerberos認證流程更改您的密碼授予賬戶訪問權限票證管理Kerberos 票據屬性使用 kinit 獲取票據使用 klist 查看票據使用 kdestroy 銷毀票據.k5identity 文件描述 Kerberos 是一種網絡認證協議&a…

WPF 免費UI 控件HandyControl

示例效果和代碼 直接可以用 Button 按鈕 | HandyOrg 1.安裝 , 輸入 HandyControl 2.<!--配置HandyControl--> <!--配置HandyControl--> <ResourceDictionary Source"pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/> …

windows部署docker

1.下載docker 打開瀏覽器&#xff0c;訪問 Docker Desktop 下載頁面。 2.安裝 Docker Desktop 運行安裝程序&#xff1a; 雙擊下載的 Docker Desktop 安裝包&#xff0c;啟動安裝程序。 選擇安裝選項&#xff1a; 按照屏幕上的指示進行操作。建議選擇默認選項&#xff0c;包…

【Linux】遠程登錄時,使用圖形界面報錯:MoTTY X11 proxy: Unsupported authorisation protocol

1、問題描述 使用 MobaXterm 遠程登錄Ubuntu后,使用sudo權限運行圖形界面程序報錯: MoTTY X11 proxy: Unsupported authorisation protocol (gpartedbin:10518): Gtk-WARNING **: 22:01:34.377: cannot open display: localhost:10.02、查看SSH配置 修改 SSH 服務端配置,…

解決 Hugging Face SentenceTransformer 下載失敗的完整指南:ProxyError、SSLError與手動下載方案

問題背景 在使用 Hugging Face 的 SentenceTransformer 加載預訓練模型 all-MiniLM-L6-v2 時&#xff0c;遇到了以下錯誤&#xff1a; 代理連接失敗&#xff08;ProxyError / SSLError: KRB5_S_TKT_NYV&#xff09;大文件下載中斷&#xff08;unexpected EOF while reading&a…

MySQL——DQL的單表查詢

1、查詢表中所有的字段&#xff08;列&#xff09; 語法&#xff1a;select * from 表名; * 是通配符&#xff0c;用來表示所有的字段&#xff08;列&#xff09;。 select 表示查詢哪些列。 from 表示從哪張表中查詢。 2、查詢表中指定的字段 語法&#xff1a;select 列…

開源RuoYi AI助手平臺的未來趨勢

近年來&#xff0c;人工智能技術的迅猛發展已經深刻地改變了我們的生活和工作方式。 無論是海外的GPT、Claude等國際知名AI助手&#xff0c;還是國內的DeepSeek、Kimi、Qwen等本土化解決方案&#xff0c;都為用戶提供了前所未有的便利。然而&#xff0c;對于那些希望構建屬于自…

[WUSTCTF2020]CV Maker1

進來是個華麗的界面&#xff0c;我們先跟隨這個網頁創造一個用戶 發現了一個上傳端口&#xff0c;嘗試上傳一個php文件并抓包 直接上傳進不去&#xff0c;加個GIF89A uploads/d41d8cd98f00b204e9800998ecf8427e.php 傳入 并且報告了 上傳路徑&#xff0c;然后使用蟻劍連接

Spring 中的 IOC

&#x1f331; 一、什么是 IOC&#xff1f; &#x1f4d6; 定義&#xff08;通俗理解&#xff09;&#xff1a; IOC&#xff08;Inversion of Control&#xff0c;控制反轉&#xff09; 是一種設計思想&#xff1a;對象不再由你自己創建和管理&#xff0c;而是交給 Spring 容器…

Vue2-實現elementUI的select全選功能

文章目錄 使用 Element UI 的全選功能自定義選項來模擬全選 在使用 Element UI 的 el-select組件時&#xff0c;實現“全選”功能&#xff0c;通常有兩種方式&#xff1a;一種是使用內置的全選功能&#xff0c;另一種是通過自定義選項來模擬全選。 使用 Element UI 的全選功能…

小菜Go:Ubuntu下Go語言開發環境搭建

前置要求Ubuntu環境搭建 文章推薦 此處推薦一個比較好的文章&#xff0c;基本按部就班就歐克~ 安裝虛擬機&#xff08;VMware&#xff09;保姆級教程&#xff08;附安裝包&#xff09;_vmware虛擬機-CSDN博客 安裝可能遇到的問題 虛擬機安裝遇到的問題如&#xff1a;Exception…

安卓中app_process運行報錯Aborted,怎么查看具體的報錯日志

我在pc端生成了一個jar包&#xff0c;可以正常執行&#xff0c;但是導入到安卓的/data/local/tmp下面執行就會報錯 執行命令如下&#xff1a; adb shell cd /data/local/tmp app_process -Djava.class.path/data/local/tmp/demo.jar /data/local/tmp com.example.demo.Hello然…

Python 面向對象 - 依賴倒置原則 (DIP)

1. 核心概念 依賴倒置原則(Dependency Inversion Principle, DIP) 是SOLID原則中的"D"&#xff0c;包含兩個關鍵點&#xff1a; 高層模塊不應依賴低層模塊&#xff0c;二者都應依賴抽象抽象不應依賴細節&#xff0c;細節應依賴抽象 2. 使用場景 典型應用場景 系…

centos7 yum install docker 安裝錯誤

1、錯誤信息&#xff1a; [rootlocalhost atguigu]# yum install docker 已加載插件&#xff1a;fastestmirror, langpacks Repository base is listed more than once in the configuration Loading mirror speeds from cached hostfile Could not retrieve mirrorlist http:…