2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Sisällysluettelo
3. Arvioi PEGASUS CNN/DailyMail-tietojoukossa
4. Koulutuksen yhteenvetomalli
1. Arvioi PEGASUS:n suorituskyky SAMSumilla
AGI tai Artificial General Intelligence on tekoälyjärjestelmä, jolla on ihmisen älykkyystasoja. Se ei voi vain suorittaa tiettyjä tehtäviä, vaan myös ymmärtää, oppia ja soveltaa tietoa monenlaisten ongelmien ratkaisemiseksi suurella autonomialla ja sopeutumiskyvyllä. AGI:n kykyjä ovat muun muassa itseoppiminen, itsensä kehittäminen, itsensä sopeuttaminen ja kyky ratkaista erilaisia monimutkaisia ongelmia ilman ihmisen väliintuloa.
- Se mitä AGI voi tehdä, on hyvin laajaa:
Toimialueiden välinen tehtävien suorittaminen: AGI voi käsitellä tehtäviä useissa toimialueissa, eikä se rajoitu tiettyihin sovellusskenaarioihin.
Autonominen oppiminen ja sopeutuminen: AGI voi oppia kokemuksesta ja sopeutua uusiin ympäristöihin ja tilanteisiin.
Luova ajattelu: AGI osaa ajatella innovatiivisesti ja keksiä uusia ratkaisuja.
Sosiaalinen vuorovaikutus: AGI pystyy monimutkaiseen sosiaaliseen vuorovaikutukseen ihmisten kanssa ja ymmärtää emotionaalisia ja sosiaalisia signaaleja.
- Mitä tulee AGI:n tulevaisuuden kehitysnäkymiin, sitä pidetään yhtenä tekoälytutkimuksen perimmäisistä tavoitteista ja sillä on valtava muutospotentiaali:
Teknologinen innovaatio: Koneoppimisen ja hermoverkkojen kaltaisten teknologioiden kehittyessä AGI:n toteutuminen saattaa olla lähempänä.
Tieteidenvälinen integraatio: AGI:n toteuttaminen edellyttää tiedon yhdistämistä useilta tieteenaloilta, kuten tietojenkäsittelytieteestä, neurotieteestä ja psykologiasta.
Eettiset ja sosiaaliset näkökohdat: AGI:n kehittäminen edellyttää eettisten ja sosiaalisten asioiden, kuten yksityisyyden, turvallisuuden ja työllisyyden, huomioon ottamista.
Parannetut oppimis- ja mukautumisominaisuudet: Tulevat AGI-järjestelmät voivat käyttää kehittyneitä algoritmeja oppiakseen ympäristöstä ja optimoidakseen käyttäytymistä.
Multimodaalinen vuorovaikutus: AGI:lla on useita havainnointi- ja vuorovaikutusmenetelmiä vuorovaikutuksessa ihmisten ja muiden järjestelmien kanssa.
Hugging Face on yksi suosituimmista avoimen lähdekoodin koneoppimisyhteisöistä ja -alustoista maailmassa, ja sillä on tärkeä rooli AGI-aikakaudella. Se tarjoaa runsaasti valmiiksi koulutettuja malleja ja tietojoukkoja, mikä edistää koneoppimisen alan kehitystä. Hugging Facelle on ominaista helppokäyttöisyys ja avoimuus Transformers-kirjastonsa kautta se tarjoaa käyttäjille kätevän tavan käsitellä tekstiä. Tekoälyteknologian kehityksen myötä Hugging Face -yhteisöllä on jatkossakin tärkeä rooli tekoälyteknologian kehittämisen ja soveltamisen edistämisessä, erityisesti multimodaalisen tekoälyteknologian kehittämisessä Hugging Face -yhteisö laajentaa malliensa monipuolisuutta ja tietojoukot, mukaan lukien multimodaaliset tiedot, kuten kuvat, ääni ja video.
- AGI:n aikakaudella Hugging Face saattaa tulla esiin seuraavilla tavoilla:
Mallin jakaminen: Mallinjakoalustana Hugging Face jatkaa edistyneiden AGI-mallien jakamisen ja yhteistyön edistämistä.
Avoimen lähdekoodin ekosysteemi: Hugging Facen avoimen lähdekoodin ekosysteemi auttaa nopeuttamaan AGI-teknologian kehitystä ja innovointia.
Työkalut ja palvelut: Tarjoa runsaasti työkaluja ja palveluita tukemaan kehittäjiä ja tutkijoita heidän tutkimuksessaan ja sovelluksissaan AGI-alalla.
Etiikka ja sosiaalinen vastuu: Hugging Face keskittyy tekoälyn etiikkaan ja edistää vastuullisten AGI-mallien kehittämistä ja soveltamista varmistaakseen teknologisen kehityksen eettisten standardien mukaisesti.
AGI:lla, kehittyneenä tekoälyn muotona tulevaisuudessa, on laajat sovellusnäkymät, ja Hugging Face avoimen lähdekoodin yhteisönä tulee olemaan avainroolissa AGI:n kehittämisen ja soveltamisen edistämisessä.
(Huomaa: Seuraava koodi saattaa vaatia tieteellisen Internet-yhteyden toimiakseen)
Sinun on ehkä täytynyt tehdä yhteenveto asiakirjasta, mukaan lukien tutkimusartikkeli, tulosraportti tai sähköpostisarja. Jos ajattelet sitä, tämä vaatii erilaisia kykyjä, mukaan lukien pitkän muodon sisällön ymmärtäminen, sisällön perusteleminen ja sitten sujuvan tekstin tuottaminen, joka kattaa alkuperäisen asiakirjan pääteemat. Lisäksi uutisartikkelin tarkka yhteenveto eroaa hyvin paljon laillisen sopimuksen yhteenvedosta ja vaatii siksi monimutkaisia toimialueen yleistysominaisuuksia. Näistä syistä tekstin yhteenveto (tekninen termi on tekstin yhteenveto) on vaikea tehtävä hermokielimalleille, mukaan lukien muuntajamalleille. Näistä haasteista huolimatta tekstin yhteenveto voi nopeuttaa merkittävästi toimialueen asiantuntijoiden työnkulkua Yritykset voivat tiivistää sisäistä tietämystä, tehdä sopimuksia, luoda automaattisesti sosiaalisen median julkaisusisältöä jne. Siksi tekstin yhteenveto NLP-tehtävä on arvokas.
Haasteiden ymmärtämiseksi tässä osiossa tarkastellaan Transformerin esikoulutettujen mallien hyödyntämistä tekstin yhteenvedossa. Yhteenveto on klassinen sekvenssistä sekvenssiin (seq2seq) tehtävä, joka vaatii syöttötekstin ja kohdetekstin.
Tekstin yhteenveto on luonnollinen kielenkäsittelytehtävä, jonka tavoitteena on poimia pitkästä tekstistä tiivistä ja tärkeää tietoa ja luoda lyhyt versio. Tekstin yhteenveto voidaan jakaa kahteen päätyyppiin: purkava yhteenveto ja generatiivinen yhteenveto.
- Poimittava yhteenveto
Tiivistelmä valitsee tärkeät lauseet tai kappaleet alkuperäisestä tekstistä ja poimii nämä sisällöt suoraan tiivistelmiksi. Tämä menetelmä ei muuta sanoja ja lauserakennetta alkuperäisessä tekstissä.
Toteutusperiaate:
- Ominaisuuden purkaminen: Ensin on poimittava tekstin erilaisia ominaisuuksia, kuten sanan tiheys, lauseen sijainti, avainsanat, nimetyt entiteetit jne.
- Tärkeyspisteytys: Poimittujen ominaisuuksien perusteella jokaiselle lauseelle lasketaan pisteet sen tärkeyden määrittämiseksi.
- Lauseen valinta: Tärkeyspisteiden perusteella valitaan tärkeimmät lauseet yhteenvedon rakentamiseksi.
vaikeus:
- Tärkeysmittaus: Kuinka mitata tarkasti lauseiden suhteellinen tärkeys.
- Redundanssin eliminointi: Vältä valitsemasta lauseita, joissa on toistuvaa sisältöä.
Toteutusmenetelmä:
- Sääntöihin perustuva lähestymistapa: käyttää ennalta määritettyjä sääntöjä ja tilastollisia menetelmiä lauseiden valitsemiseen.
- Koneoppimismenetelmä: Käytä ohjattuja oppimisalgoritmeja oppiaksesi valitsemaan tärkeitä lauseita harjoitustietojen perusteella.
- Generatiivinen yhteenveto
Generatiivinen yhteenveto toimii ymmärtämällä alkuperäistä tekstiä ja luomalla uusia lauseita tiivistämään sen sisältöä. Tämä lähestymistapa luo luonnollisemman ja johdonmukaisemman yhteenvedon, mutta on myös monimutkaisempi.
Toteutusperiaate:
- Enkooderi-dekooderi-arkkitehtuuri: Käyttää sekvenssistä sekvenssiin (Seq2Seq) -mallia, jossa kooderi koodaa syötetyn tekstin kontekstivektoreihin ja dekooderi luo yhteenvedot kontekstivektoreiden perusteella.
- Huomiomekanismi: Dekoodausprosessin aikana malli voi keskittyä syöttötekstin eri osiin tuottaakseen asiaankuuluvampaa sisältöä.
- Valmiiksi koulutettu malli: Käytä valmiiksi koulutettuja kielimalleja (kuten BERT, GPT jne.) parantaaksesi luotujen yhteenvetojen laatua.
vaikeus:
- Sisällön johdonmukaisuus: Luodun yhteenvedon on säilytettävä looginen johdonmukaisuus ja vältettävä sisältökatkoja.
- Tietojen eheys: Varmistaa, että luotu yhteenveto sisältää tärkeimmät tiedot alkuperäisestä tekstistä.
- Mallin monimutkaisuus: Generatiiviset yhteenvetomallit ovat yleensä monimutkaisempia kuin poimivat yhteenvetomallit ja vaativat enemmän laskentaresursseja ja koulutusdataa.
Toteutusmenetelmä:
- Klassinen Seq2Seq-malli: kuten LSTM-pohjainen kooderi-dekooderimalli.
- Valmiiksi koulutetut muuntajamallit: kuten BERTSUM, T5, BART jne.
- Tekstin yhteenveto Hugging Face -sovelluksessa
Hugging Face tarjoaa erilaisia valmiiksi koulutettuja malleja ja työkaluja tekstin yhteenvetotehtävien toteuttamiseen. Seuraavassa on joitain yleisesti käytettyjä tekstin yhteenvetomalleja ja kuinka niitä käytetään:
- Yhteenveto käyttämällä esikoulutettuja malleja
Seuraavassa on esimerkkikoodi tekstin yhteenvetoon käyttämällä Hugging Facen tarjoamaa BART-mallia:
from transformers import BartForConditionalGeneration, BartTokenizer # 加载预训练的BART模型和对应的tokenizer model_name = "facebook/bart-large-cnn" model = BartForConditionalGeneration.from_pretrained(model_name) tokenizer = BartTokenizer.from_pretrained(model_name) # 输入文本 input_text = """Your text to summarize goes here.""" # 对输入文本进行tokenize,并添加必要的模型输入 inputs = tokenizer([input_text], max_length=1024, return_tensors='pt') # 使用模型生成摘要 summary_ids = model.generate(inputs['input_ids'], num_beams=4, max_length=150, early_stopping=True) # 将生成的token序列转换回文本 summary = tokenizer.decode(summary_ids[0], skip_special_tokens=True) print(summary)
- Tuetut yhteenvetomallit
Hugging Face tarjoaa erilaisia valmiiksi koulutettuja malleja tekstin yhteenvetoon, mukaan lukien, mutta ei rajoittuen:
- BART (facebook/bart-large-cnn)
- T5 (t5-small, t5-base, t5-large, t5-3b, t5-11b)
- PEGASUS (google/pegasus-xsum, google/pegasus-cnn_dailymail)
- Harjoittele oma yhteenvetomallisi
Jos sinun on sopeuduttava paremmin toimialuekohtaisiin tekstin yhteenvetotehtäviin, voit hienosäätää esikoulutettua mallia käyttämällä omaa tietojoukkoasi. Tässä on yksinkertainen hienosäätöesimerkki:
from transformers import Trainer, TrainingArguments, BartForConditionalGeneration, BartTokenizer from datasets import load_dataset # 加载数据集 dataset = load_dataset("cnn_dailymail", "3.0.0") # 加载预训练的BART模型和tokenizer model_name = "facebook/bart-large-cnn" model = BartForConditionalGeneration.from_pretrained(model_name) tokenizer = BartTokenizer.from_pretrained(model_name) # 数据预处理 def preprocess_function(examples): inputs = [doc for doc in examples['article']] model_inputs = tokenizer(inputs, max_length=1024, truncation=True) # 设定摘要作为目标 with tokenizer.as_target_tokenizer(): labels = tokenizer(examples['highlights'], max_length=150, truncation=True) model_inputs['labels'] = labels['input_ids'] return model_inputs tokenized_dataset = dataset.map(preprocess_function, batched=True) # 定义训练参数 training_args = TrainingArguments( output_dir="./results", evaluation_strategy="epoch", learning_rate=2e-5, per_device_train_batch_size=4, per_device_eval_batch_size=4, num_train_epochs=3, weight_decay=0.01, ) # 使用Trainer进行训练 trainer = Trainer( model=model, args=training_args, train_dataset=tokenized_dataset["train"], eval_dataset=tokenized_dataset["validation"], ) trainer.train()Tekstin yhteenveto on monimutkainen ja haastava luonnollisen kielen käsittelytehtävä. Käyttämällä Hugging Facen tarjoamia esikoulutettuja malleja ja työkaluja tekstin yhteenvedon toteutusprosessia voidaan yksinkertaistaa huomattavasti. Käyttäjät voivat valita sopivan mallin erityistarpeiden mukaan ja hienosäätää sitä parhaan yhteenvetovaikutelman saavuttamiseksi.
Tässä osiossa rakennamme oman enkooderi-dekooderimallimme pakataksemme usean henkilön keskustelut tiiviiksi yhteenvedoksi. Mutta ennen sitä katsotaanpa klassista datajoukkoa yhteenvedon alalla: CNN/DailyMail-korpus.
Nyt ehdot ovat valmiit mallin täydelliseen arvioimiseen: meillä on CNN/DailyMail-testijoukon tietojoukko, ROUGE-mittari arviointia varten ja yhteenvetomalli.
- # 导入所需的库
- import matplotlib.pyplot as plt # 导入 matplotlib.pyplot,用于绘制图形
- import pandas as pd # 导入 pandas,用于数据处理
- from datasets import load_dataset, load_metric # 从 datasets 库中导入 load_dataset 和 load_metric 函数
- from transformers import AutoModelForSeq2SeqLM, AutoTokenizer # 从 transformers 库中导入 AutoModelForSeq2SeqLM 和 AutoTokenizer
-
- # 加载 CNN/DailyMail 数据集,版本为 3.0.0
- dataset = load_dataset("cnn_dailymail", "3.0.0")
-
- # 加载 ROUGE 评价指标,用于计算文本摘要的质量
- rouge_metric = load_metric("rouge", cache_dir=None)
-
- # 定义要计算的 ROUGE 分数的名称列表
- rouge_names = ["rouge1", "rouge2", "rougeL", "rougeLsum"]
Meidän täytyy vain koota palat yhteen. Ensin arvioimme kolmen lauseen vertailumallin suorituskykyä:
- # 定义一个函数,用于评估基线模型生成的摘要
- def evaluate_summaries_baseline(dataset, metric, column_text="article", column_summary="highlights"):
- # 使用 three_sentence_summary 函数对数据集中的每篇文章生成摘要
- summaries = [three_sentence_summary(text) for text in dataset[column_text]]
-
- # 将生成的摘要和参考摘要添加到评价指标中
- metric.add_batch(predictions=summaries, references=dataset[column_summary])
-
- # 计算评价指标的分数
- score = metric.compute()
-
- # 返回评价指标的分数
- return score
Käytämme sitten funktiota datan osajoukkoon. Koska CNN/DailyMail-tietojoukon testiosa sisältää noin 10 000 näytettä, tiivistelmien luominen kaikista näistä artikkeleista vie paljon aikaa. Muista luvusta 5, että jokainen luotu merkki on ohjattava eteenpäin mallin läpi. 100 tokenin luominen näytettä kohti vaatisi miljoonan eteenpäin kulkua, ja jos käyttäisimme sädehakua, tämä luku olisi myös kerrottava säteiden lukumäärällä. Laskennan nopeuttamiseksi otamme testijoukon alinäytteen ja käytämme lopulta 1000 näytettä arviointiin. Tällä tavalla voimme suorittaa PEGASUS-mallin arvioinnin yhdellä GPU:lla alle tunnissa ja saada vakaat pistearviot:
- # 从测试集中随机抽取1000条样本,用于评估
- test_sampled = dataset["test"].shuffle(seed=42).select(range(1000))
-
- # 使用基线模型生成摘要并评估其质量
- score = evaluate_summaries_baseline(test_sampled, rouge_metric)
-
- # 将评价指标的分数存储在字典中
- rouge_dict = dict((rn, score[rn].mid.fmeasure) for rn in rouge_names)
-
- # 将评价指标的分数转换为DataFrame格式,并转置以便显示
- pd.DataFrame.from_dict(rouge_dict, orient="index", columns=["baseline"]).T
operaation tulos:
rouge1 | rouge2 | rougeL | rougeLsum | |
perusviiva | 0.38928 | 0.171296 | 0.245061 | 0.354239 |
Pisteet ovat enimmäkseen huonompia kuin edellisessä esimerkissä, mutta silti parempia kuin GPT-2:lla! Noudatamme nyt samaa kaavaa PEGASUS-mallin arvioinnissa:
- # 导入 tqdm 模块,用于显示进度条
- from tqdm import tqdm
- # 导入 torch 模块,用于使用 GPU 或 CPU 进行计算
- import torch
-
- # 设置设备为 GPU(如果可用)或 CPU
- device = "cuda" if torch.cuda.is_available() else "cpu"
-
- def chunks(list_of_elements, batch_size):
- """将 list_of_elements 按 batch_size 切分成多个小块"""
- for i in range(0, len(list_of_elements), batch_size):
- yield list_of_elements[i : i + batch_size]
-
- def evaluate_summaries_pegasus(dataset, metric, model, tokenizer,
- batch_size=16, device=device,
- column_text="article",
- column_summary="highlights"):
- """评估使用 Pegasus 模型生成的摘要"""
-
- # 将文章和摘要分别按 batch_size 切分成多个小块
- article_batches = list(chunks(dataset[column_text], batch_size))
- target_batches = list(chunks(dataset[column_summary], batch_size))
-
- # 使用 tqdm 显示进度条,遍历每个文章批次和相应的摘要批次
- for article_batch, target_batch in tqdm(
- zip(article_batches, target_batches), total=len(article_batches)):
-
- # 对文章批次进行标记,将其转换为模型输入的张量
- inputs = tokenizer(article_batch, max_length=1024, truncation=True,
- padding="max_length", return_tensors="pt")
-
- # 使用 Pegasus 模型生成摘要
- summaries = model.generate(input_ids=inputs["input_ids"].to(device),
- attention_mask=inputs["attention_mask"].to(device),
- length_penalty=0.8, num_beams=8, max_length=128)
-
- # 解码生成的摘要,将其从张量转换为字符串
- decoded_summaries = [tokenizer.decode(s, skip_special_tokens=True,
- clean_up_tokenization_spaces=True)
- for s in summaries]
- decoded_summaries = [d.replace("", " ") for d in decoded_summaries]
-
- # 将生成的摘要和目标摘要添加到评价指标中
- metric.add_batch(predictions=decoded_summaries, references=target_batch)
-
- # 计算评价指标分数
- score = metric.compute()
- return score
Selitetään tämä arviointikoodi yksityiskohtaisesti. Ensin jaoimme tietojoukon pienempiin eriin, jotta niitä voidaan käsitellä samanaikaisesti. Sitten jokaiselle erälle tokenisoimme syöteartikkelit ja syötämme ne gener()-funktioon yhteenvedon luomiseksi sädehaun avulla. Käytämme samoja sukupolviparametreja kuin paperissa. Rangaistusparametrin uusi pituus varmistaa, että malli ei tuota liian pitkiä sekvenssejä.Lopuksi dekoodaamme tuloksena olevan tekstin korvaamalla<n> tunnukset ja lisää dekoodattu teksti mittariin viitetekstin kanssa. Lopuksi laskemme ja palautamme ROUGE-pisteet. Nyt käytämme jälleen AutoModelForSeq2SeqLM-luokkaa seq2seq-sukupolvitehtävässä mallin lataamiseen ja sen arvioimiseen:
- # 从 transformers 库中导入用于序列到序列任务的模型和标记器
- from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
-
- # 设置模型检查点名称,使用 Google 的 PEGASUS 模型,预训练于 CNN/DailyMail 数据集
- model_ckpt = "google/pegasus-cnn_dailymail"
-
- # 从预训练的模型检查点中加载标记器和模型,并将模型移动到指定的设备(CPU 或 GPU)
- tokenizer = AutoTokenizer.from_pretrained(model_ckpt)
- model = AutoModelForSeq2SeqLM.from_pretrained(model_ckpt).to(device)
-
- # 使用评估函数 evaluate_summaries_pegasus 评估 PEGASUS 模型生成的摘要
- # 输入参数包括测试数据、ROUGE 评价指标、模型、标记器和批处理大小
- score = evaluate_summaries_pegasus(test_sampled, rouge_metric,
- model, tokenizer, batch_size=8)
-
- # 从评估结果中提取 ROUGE 分数,将其转换为字典格式,其中键为 ROUGE 指标名称,值为 F-measure 分数
- rouge_dict = dict((rn, score[rn].mid.fmeasure) for rn in rouge_names)
-
- # 将 ROUGE 分数字典转换为 pandas 数据框,并以 "pegasus" 作为索引
- pd.DataFrame(rouge_dict, index=["pegasus"])
operaation tulos:
(Tilapäisestä virheestä ilmoitetaan täällä:
TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto
, suoritetut tulokset vertailua varten esimerkein ovat seuraavat)
rouge1 | rouge2 | rougeL | rougeLsum | |
pegasus | 0.43438 | 0.210883 | 0.307195 | 0.373231 |
Nämä luvut ovat hyvin lähellä paperin tuloksia. Tärkeää tässä on huomata, että kunkin tunnuksen menetys ja tarkkuus ovat jossain määrin irrotettuja ROUGE-pisteistä. Häviö on riippumaton dekoodausstrategiasta, kun taas ROUGE-pistemäärä on vahvasti kytketty.
Koska ROUGE ja BLEU saavuttavat paremman häviön tai tarkkuuden kuin ihmisen arvioinnin, sinun tulee keskittyä niihin luodessasi tekstin luontimalleja ja tutkia ja valita dekoodausstrategioita huolellisesti. Nämä mittarit eivät kuitenkaan ole läheskään täydellisiä, joten ihmisen arviointi on aina otettava huomioon.
Nyt kun meillä on arviointitoiminto, voimme kouluttaa oman yhteenvetomallimme.
Tässä vaiheessa olemme käyneet läpi monia tekstin yhteenvedon ja arvioinnin yksityiskohtia, ja nyt käytämme tätä tietämystä mukautetun tekstin yhteenvetomallin kouluttamiseen! Räätälöityyn sovellukseemme käytämme Samsungin kehittämää SAMSum-tietosarjaa (httss://oreil.ly/n1ggq ), tämä tietojoukko sisältää sarjan keskusteluja ja lyhyitä yhteenvetoja. Nämä keskustelut voivat edustaa asiakkaiden ja puhelinkeskusten välistä vuorovaikutusta ja luoda tarkkoja yhteenvetoja, jotka auttavat parantamaan asiakaspalvelua ja havaitsemaan yleisiä malleja asiakkaiden pyynnöissä. Ladataan ensin tietojoukko ja katsotaan esimerkki:
- # 从 datasets 库中导入用于加载数据集的函数
- from datasets import load_dataset
-
- # 加载 SamSum 数据集,该数据集包含对话和相应的摘要
- dataset_samsum = load_dataset("samsum",trust_remote_code=True)
-
- # 获取数据集的每个划分(训练集、验证集、测试集)的长度,并存储在列表 split_lengths 中
- split_lengths = [len(dataset_samsum[split]) for split in dataset_samsum]
-
- # 打印每个数据集划分的长度
- print(f"Split lengths: {split_lengths}")
-
- # 打印训练集中列的名称(特征)
- print(f"Features: {dataset_samsum['train'].column_names}")
-
- # 打印测试集中第一个对话样本
- print("nDialogue:")
- print(dataset_samsum["test"][0]["dialogue"])
-
- # 打印测试集中第一个对话样本的摘要
- print("nSummary:")
- print(dataset_samsum["test"][0]["summary"])
(Huomaa: saatat joutua asentamaan py7zr, pip install py7zr)
operaation tulos:
Split lengths: [14732, 819, 818] Features: ['id', 'dialogue', 'summary'] Dialogue: Hannah: Hey, do you have Betty's number? Amanda: Lemme check Hannah: <file_gif> Amanda: Sorry, can't find it. Amanda: Ask Larry Amanda: He called her last time we were at the park together Hannah: I don't know him well Hannah: <file_gif> Amanda: Don't be shy, he's very nice Hannah: If you say so.. Hannah: I'd rather you texted him Amanda: Just text him 🙂 Hannah: Urgh.. Alright Hannah: Bye Amanda: Bye bye Summary: Hannah needs Betty's number but Amanda doesn't have it. She needs to contact Larry.
Keskustelut näyttävät samalta kuin chattaisit tekstiviestillä tai WhatsAppilla, mukaan lukien emojit ja GIF-paikkamerkit. Dialogikenttä sisältää koko tekstin, kun taas yhteenvetokenttä on yhteenveto dialogista. Voiko CNN/DailyMail-tietojoukossa hienosäädetty malli käsitellä tätä tietojoukkoa? Katsotaanpa!
Ensin suoritamme saman yhteenvedon luontiprosessin käyttämällä PEGASUSia nähdäksemme tulosteen. Voimme käyttää uudelleen CNN/DailyMail-yhteenvedon luomaa koodia:
- # 使用已加载的summarization管道对测试集中的第一个对话样本进行摘要
- pipe_out = pipe(dataset_samsum["test"][0]["dialogue"])
-
- # 打印生成的摘要标题
- print("Summary:")
-
- # 打印生成的摘要文本,并将每个句子的句号后面的空格替换为换行符
- # 这行代码会输出生成的摘要,其中 ". " 替换为 ".n" 使其更易读
- print(pipe_out[0]["summary_text"].replace(" .", ".n"))
operaation tulos:
Summary: Hannah asks Amanda for Betty's number. Amanda can't find it. Hannah asks Larry. Amanda asks Larry to text him. Hannah says she'll text him back. Hannah calls it a day and says she's going to go home. Hannah: "Bye bye"
Näemme, että malli yrittää pääasiassa tehdä yhteenvetoa poimimalla keskustelun keskeisiä lauseita. Tämä saattaa toimia suhteellisen hyvin CNN/DailyMail-tietojoukossa, mutta SAMSumissa yhteenveto on abstraktimpi ja vaikutus ei välttämättä ole hyvä. Voimme vahvistaa tämän suorittamalla koko ROUGE-arvioinnin testisarjassa:
- # 使用评估函数 evaluate_summaries_pegasus 对 SamSum 数据集的测试集进行摘要生成评估
- # 传入的参数包括数据集、评价指标、模型、tokenizer、文本列名、摘要列名和批量大小
- score = evaluate_summaries_pegasus(dataset_samsum["test"], rouge_metric, model,
- tokenizer, column_text="dialogue",
- column_summary="summary", batch_size=8)
-
- # 创建一个字典 rouge_dict,用于存储 ROUGE 评分的中值 F-measure 值
- rouge_dict = dict((rn, score[rn].mid.fmeasure) for rn in rouge_names)
-
- # 将 ROUGE 评分字典转换为 Pandas 数据框,并以 "pegasus" 为索引
- pd.DataFrame(rouge_dict, index=["pegasus"])
operaation tulos:
(Tilapäisestä virheestä ilmoitetaan täällä:
TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto
, suoritetut tulokset vertailua varten esimerkein ovat seuraavat)
rouge1 | rouge2 | rougeL | rougeLsum | |
pegasus | 0.29617 | 0.087803 | 0.229604 | 0.229514 |
Vaikka tulokset eivät ole mahtavia, se ei ole odottamaton, koska se on kaukana CNN/DailyMail-tietojen jakelusta. Siitä huolimatta arviointiprosessin asettamisella ennen koulutusta on kaksi etua: voimme suoraan mitata mittareilla koulutuksen onnistumista ja meillä on hyvä lähtökohta. Tietojoukossamme olevan mallin hienosäädön pitäisi parantaa ROUGE-mittaria välittömästi. Jos parannusta ei tapahdu, tiedämme, että harjoitussilmukassamme on jotain vialla.
Ennen kuin harjoittelemme dataa, tarkastelemme nopeasti tulo- ja lähtöpituusjakaumia:
- # 编码训练集中的对话文本和摘要,并计算其长度
- d_len = [len(tokenizer.encode(s)) for s in dataset_samsum["train"]["dialogue"]]
- s_len = [len(tokenizer.encode(s)) for s in dataset_samsum["train"]["summary"]]
-
- # 创建一个包含两个子图的图形对象
- fig, axes = plt.subplots(1, 2, figsize=(10, 3.5), sharey=True)
-
- # 绘制对话文本的长度分布直方图
- axes[0].hist(d_len, bins=20, color="C0", edgecolor="C0")
- axes[0].set_title("Dialogue Token Length")
- axes[0].set_xlabel("Length")
- axes[0].set_ylabel("Count")
-
- # 绘制摘要的长度分布直方图
- axes[1].hist(s_len, bins=20, color="C0", edgecolor="C0")
- axes[1].set_title("Summary Token Length")
- axes[1].set_xlabel("Length")
-
- # 调整子图布局,使其更加紧凑
- plt.tight_layout()
-
- # 显示绘制的图形
- plt.show()
operaation tulos:
(Tilapäisestä virheestä ilmoitetaan täällä:
TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto
, suoritetut tulokset vertailua varten esimerkein ovat seuraavat)
Voimme nähdä, että useimmat keskustelut ovat paljon lyhyempiä kuin CNN/DailyMail-artikkelit, ja kussakin on noin 100-200 merkkiä. Samoin yhteenvedot ovat paljon lyhyempiä, noin 20–40 merkkiä (saman pituisia kuin keskimääräinen twiitti).
Muistakaamme nämä tulokset ensin, käytämme niitä myöhemmin. Ensin meidän on tokenisoitava tietojoukko. Asetamme dialogin ja yhteenvedon enimmäispituudeksi 1024 ja 128:
- def convert_examples_to_features(example_batch):
- """
- 将示例批处理转换为模型输入特征。
-
- Args:
- - example_batch (dict): 包含对话和摘要的示例批处理字典。
-
- Returns:
- - dict: 包含转换后特征的字典,包括输入编码和目标编码。
- """
- # 对对话文本进行编码处理,生成输入编码
- input_encodings = tokenizer(example_batch["dialogue"], max_length=1024,
- truncation=True)
-
- # 使用目标编码器处理摘要文本,生成目标编码
- with tokenizer.as_target_tokenizer():
- target_encodings = tokenizer(example_batch["summary"], max_length=128,
- truncation=True)
-
- # 返回包含输入编码、目标标签和注意力掩码的字典
- return {
- "input_ids": input_encodings["input_ids"],
- "attention_mask": input_encodings["attention_mask"],
- "labels": target_encodings["input_ids"]
- }
-
- # 使用 map 方法将 SamSum 数据集转换为 PyTorch 格式
- dataset_samsum_pt = dataset_samsum.map(convert_examples_to_features,
- batched=True)
-
- # 设置数据集格式为 Torch 张量类型,并指定列名
- columns = ["input_ids", "labels", "attention_mask"]
- dataset_samsum_pt.set_format(type="torch", columns=columns)
operaation tulos:
(Tilapäisestä virheestä ilmoitetaan täällä:
TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto)
Tokenisointivaiheessa on uusi asia: tokenizer.as_target_tokenizer() -konteksti. Jotkin mallit vaativat erikoistunnuksia dekooderin sisääntulossa, joten on tärkeää erottaa kooderin ja dekooderin tulojen tunnukset. With-lauseessa (kutsutaan kontekstinhallintaohjelmaksi) tokenizer tietää, että se on tokenoiva dekooderille.
Nyt meidän on luotava tietojen järjestäjä. Useimmissa tapauksissa voimme käyttää oletuskollaajaa, joka kerää kaikki tensorit eräksi ja pinoaa ne. Yhteenvetotehtävää varten meidän ei tarvitse vain pinota tuloja, vaan myös valmistella kohteet dekooderin puolella. PEGASUS on enkooderi-dekooderi Transformer ja siksi siinä on klassinen sekv2seq-arkkitehtuuri. Seq2seq-asetuksessa yleinen lähestymistapa on käyttää opettajan pakottamista dekooderissa. Tätä strategiaa käytettäessä dekooderi vastaanottaa sisääntulotunnisteita (sama kuin vain dekooderille tarkoitettu malli, kuten GPT-2), jotka siirretään merkinnällä yhden kohdan oikealle kooderin lähdön lisäksi. Siksi, kun dekooderi ennustaa seuraavaa merkkiä, se saa syötteenä todellisen arvon, joka on siirretty yhden paikan oikealle, kuten seuraavassa taulukossa näkyy:
- # 示例文本序列和标签生成过程
- text = ['PAD', 'Transformers', 'are', 'awesome', 'for', 'text', 'summarization']
-
- # 初始化存储每步结果的列表
- rows = []
-
- # 循环生成每步的数据行
- for i in range(len(text)-1):
- rows.append({
- 'step': i+1, # 步骤号,从1开始
- 'decoder_input': text[:i+1], # 解码器输入序列,从文本开始到当前位置
- 'label': text[i+1] # 标签,当前位置的下一个词
- })
-
- # 创建数据帧,并以步骤号作为索引
- pd.DataFrame(rows).set_index('step')
operaation tulos:
askel | dekooderin_tulo | etiketti |
1 | [PAD] | Muuntajat |
2 | [PAD, Transformers] | ovat |
3 | [PAD, Transformers, ovat] | mahtava |
4 | [PAD, Transformers, ovat mahtavia] | varten |
5 | [PAD, Transformers, ovat mahtavia, varten] | teksti |
6 | [PAD, Transformers, ovat, mahtavia, tekstille] | yhteenveto |
Siirrämme sitä yhden kohdan oikealle, jotta dekooderi näkee vain edellisen oikean merkinnän, ei nykyisiä tai tulevia huomautuksia. Pelkkä vaihtaminen riittää, koska dekooderissa on naamioitu itsehuomiomekanismi, joka peittää kaikki nykyiset ja tulevat tulot.
Siksi erää valmistellessa asetimme tulon dekooderille siirtämällä huomautusta yhden kohdan oikealle. Myöhemmin varmistamme, että täyttötunnisteet jätetään huomiotta annotaatiossa asettamalla ne arvoon -100. Itse asiassa meidän ei tarvitse suorittaa näitä vaiheita manuaalisesti, koska DataCollatorForSeq2Seq tekee kaiken puolestamme:
- # 导入 Seq2Seq 数据集整理器模块
- from transformers import DataCollatorForSeq2Seq
-
- # 创建 Seq2Seq 数据集整理器实例
- seq2seq_data_collator = DataCollatorForSeq2Seq(tokenizer, model=model)
Sitten, kuten tavallista, määritimme TrainingArguments koulutukselle:
- # 导入训练参数和训练器模块
- from transformers import TrainingArguments, Trainer
-
- # 定义训练参数
- training_args = TrainingArguments(
- output_dir='pegasus-samsum', # 模型输出目录
- num_train_epochs=1, # 训练的轮数
- warmup_steps=500, # 学习率预热步数
- per_device_train_batch_size=1, # 每个设备的训练批次大小
- per_device_eval_batch_size=1, # 每个设备的评估批次大小
- weight_decay=0.01, # 权重衰减率
- logging_steps=10, # 训练日志记录步数
- push_to_hub=True, # 是否推送到模型中心
- evaluation_strategy='steps', # 评估策略
- eval_steps=500, # 评估步数间隔
- save_steps=1e6, # 模型保存步数间隔
- gradient_accumulation_steps=16 # 梯度累积步数
- )
Ero aiemmista asetuksista on, että tällä kertaa on uusi parametri gradient_accumulation_steps. Koska malli on erittäin suuri, meidän on asetettava erän kooksi 1. Liian pienet eräkoot voivat kuitenkin vaikuttaa konvergenssiin. Tämän ongelman ratkaisemiseksi voimme käyttää näppärää temppua, jota kutsutaan gradientin kertymiseksi. Kuten nimestä voi päätellä, sen sijaan, että laskemme gradientit koko erälle kerralla, laskemme ja aggregoimme gradientit erissä. Kun olemme koonneet tarpeeksi gradientteja, suoritamme optimointivaiheen. Tämä on luonnollisesti hitaampaa kuin kaiken tekeminen kerralla, mutta se säästää paljon GPU-muistia.
Nyt kirjaudumme sisään Hugging Faceen, jotta voimme työntää mallin Hubiin harjoituksen jälkeen:
- from huggingface_hub import notebook_login
-
- notebook_login()
operaation tulos:
Nyt meillä on kaikki mitä tarvitsemme kouluttajan alustamiseen, mukaan lukien malli, tokenisaattori, koulutusparametrit, tietojen järjestäjät sekä koulutus- ja arviointitietojoukot:
- from transformers import TrainingArguments, Trainer
-
- # 创建一个 Trainer 实例用于训练序列到序列模型。
- trainer = Trainer(
- model=model, # 要训练的序列到序列模型
- args=training_args, # 定义的训练参数
- tokenizer=tokenizer, # 用于预处理输入数据的分词器
- data_collator=seq2seq_data_collator, # 用于批处理数据的数据整理器
- train_dataset=dataset_samsum_pt["train"], # 训练数据集
- eval_dataset=dataset_samsum_pt["validation"] # 评估数据集
- )
operaation tulos:
(Tilapäisestä virheestä ilmoitetaan täällä:
TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto)
Olemme valmiita harjoittelemaan. Kun koulutus on valmis, voimme suorittaa arviointitoiminnon suoraan testisarjassa nähdäksemme, kuinka malli suoriutui:
- from transformers import TrainingArguments, Trainer
-
- # 开始训练模型
- trainer.train()
-
- # 使用评估函数评估 Pegasus 模型的摘要质量
- score = evaluate_summaries_pegasus(
- dataset_samsum["test"], rouge_metric, trainer.model, tokenizer,
- batch_size=2, column_text="dialogue", column_summary="summary")
-
- # 提取 ROUGE 指标结果
- rouge_dict = dict((rn, score[rn].mid.fmeasure) for rn in rouge_names)
-
- # 创建 DataFrame 显示 ROUGE 指标
- pd.DataFrame(rouge_dict, index=[f"pegasus"])
operaation tulos:
(Tilapäisestä virheestä ilmoitetaan täällä:
TypeError: Couldn't build proto file into descriptor pool: duplicate file name sentencepiece_model.proto
, suoritetut tulokset vertailua varten esimerkein ovat seuraavat)
rouge1 | rouge2 | rougeL | rougeLsum | |
pegasus | 0.42761 | 0.200571 | 0.340648 | 0.340738 |
Voimme nähdä, että ROUGE-pistemäärä on huomattavasti parantunut malliin verrattuna ilman hienosäätöä, joten vaikka edellinen malli oli myös koulutettu yhteenvetosukupolviksi, se ei sopeutunut hyvin uuteen toimialueeseen. Työnnetään mallimme Hubiin:
- # 将训练完成的模型推送到 Hub 上
- trainer.push_to_hub("Training complete!")
Seuraavaksi käytämme tätä mallia luodaksemme yhteenvedot meille.
Voit myös arvioida luodut tulokset osana harjoitussilmukkaa: käytä TrainingArguments-laajennusta nimeltä Seq2SeqTrainingArguments ja määritäpreced_with_generate=True. Välitä tämä omalle kouluttajalle nimeltä Seq2SeqTrainer, joka käyttää generointifunktiota () mallin eteenpäinlähetyksen sijaan ennusteiden luomiseen arviointia varten. Kokeile!
Kun tarkastellaan tappioita ja ROUGE-pisteitä, malli näyttää osoittavan merkittävää parannusta alkuperäiseen malliin verrattuna, joka oli koulutettu vain CNN/DailyMailissa. Yhdestä testisarjan näytteestä luotu yhteenveto näyttää tältä:
- import transformers
-
- # 设置transformers的日志级别为错误,以减少输出日志
- transformers.logging.set_verbosity_error()
-
- # 定义生成摘要时的参数
- gen_kwargs = {"length_penalty": 0.8, "num_beams": 8, "max_length": 128}
-
- # 从测试集中选择一个示例
- sample_text = dataset_samsum["test"][0]["dialogue"]
- reference = dataset_samsum["test"][0]["summary"]
-
- # 使用预训练的pegasus-samsum模型创建摘要管道
- pipe = pipeline("summarization", model="transformersbook/pegasus-samsum")
-
- # 输出对话和参考摘要
- print("Dialogue:")
- print(sample_text)
- print("nReference Summary:")
- print(reference)
-
- # 使用模型生成摘要并输出
- print("nModel Summary:")
- print(pipe(sample_text, **gen_kwargs)[0]["summary_text"])
operaation tulos:
Dialogue: Hannah: Hey, do you have Betty's number? Amanda: Lemme check Hannah: <file_gif> Amanda: Sorry, can't find it. Amanda: Ask Larry Amanda: He called her last time we were at the park together Hannah: I don't know him well Hannah: <file_gif> Amanda: Don't be shy, he's very nice Hannah: If you say so.. Hannah: I'd rather you texted him Amanda: Just text him 🙂 Hannah: Urgh.. Alright Hannah: Bye Amanda: Bye bye Reference Summary: Hannah needs Betty's number but Amanda doesn't have it. She needs to contact Larry. Model Summary: Amanda can't find Betty's number. Larry called Betty last time they were at the park together. Hannah wants Amanda to text Larry instead of calling Betty.
Tämä on hyvin samanlainen kuin viiteyhteenveto. Näyttää siltä, että malli on oppinut syntetisoimaan keskustelut tiivistelmiksi sen sijaan, että poimiisi vain kohtia. Nyt viimeiseen testiin: Kuinka malli toimii mukautetuilla tuloilla?
- # 自定义对话示例
- custom_dialogue = """
- Thom: Hi guys, have you heard of transformers?
- Lewis: Yes, I used them recently!
- Leandro: Indeed, there is a great library by Hugging Face.
- Thom: I know, I helped build it ;)
- Lewis: Cool, maybe we should write a book about it. What do you think?
- Leandro: Great idea, how hard can it be?!
- Thom: I am in!
- Lewis: Awesome, let's do it together!
- """
-
- # 使用预训练的pegasus-samsum模型生成摘要,并输出摘要结果
- print(pipe(custom_dialogue, **gen_kwargs)[0]["summary_text"])
operaation tulos:
Thom and Lewis wanted to write a book about transformers. They came up with the idea with the help of Hugging Face's Leandro. The book will be called "Transformers: The Power of Transformers" and will be published in 2015. The project is currently in the planning stages.
Luotu mukautettu keskusteluyhteenveto on järkevä. Se tekee hyvin yhteenvedon siitä, mistä kaikki keskustelussa olleet halusivat kirjoittaa kirjan yhdessä sen sijaan, että poimittaisiin vain yksi lause. Se esimerkiksi yhdistää rivit 3 ja 4 yhdeksi loogiseks yhdistelmäksi.