Zephyrnet Logosu

LSTM ve TorchText ile Kod ve Açıklama ile Duygu Analizi

Tarih:

Bu makalede, meşale metni kitaplığını kullanarak LSTM ağını kullanarak duygu verisi analizi için bilmeniz gereken her ayrıntıyı göreceğiz. Torç metni veri sınıfında boşluk belirteci nasıl kullanılacağını ve tablo ve kova yineleyicinin kullanımını göreceğiz. Giriş olarak önceden eğitilmiş Glove gömme ile veya olmadan gömme matrisini kullanacağız ve ayrıca pack_padded_sequence ile bir toplu işte farklı uzunluklardaki metin verilerinin nasıl işleneceğini göreceğiz. Ve bu teknikleri probleminizde kullanabilirsiniz.

Field ve LabelField nedir?

Duygu verilerinde, metin verilerimiz ve etiketlerimiz (duygular) var. Torç metni, metin işleme veri türleri ile NLP'de ortaya çıktı. Metin verileri, veri türüyle kullanılır: Alan ve sınıf için veri türü Etiket Alanı. PyTorch'un eski sürümünde, bu veri türlerini Torchtext.data'dan içe aktarabilirsiniz, ancak yeni sürümde bunu torchtext.legacy.data'da bulacaksınız. Alan için detaylı bilgi bulabilirsiniz okuyun.

Kullanacağınız veri türlerinin bazı önemli argümanları 'tokenize', 'use_vocab', 'batch_first', 'include_lengths', 'sequential' ve 'lower'dır. Önce tokenize argümanını anlayalım. Basit kelimelerle ifade etmek, cümlenizi kelimelere veya daha temel kelimelere bölme işlemidir. Belirteçleştirmeyi bir belirteç işlevinizi tanımlayarak birçok şekilde kullanabilirsiniz ya da get_tokenizer ile torçta bir işlev tanımlayabilirsiniz ya da dahili bir Alan belirteci kullanabilirsiniz. İlk önce spacy kuracağız, ardından tokenizer işlevini göreceğiz.

pip yükleme boşluklu python -m boşluklu indirme en_core_web_sm
# Tokenizer def tokenizer(text) oluştur: [token.text for token in spacy_en.tokenizer(text)] döndür

Ayrıca torç get_tokenizer kullanarak da tanımlayabilirsiniz (tanımlamanın başka bir yolu):

Torchtext.data.utils'den içe aktar get_tokenizer tokenizer = get_tokenizer('spacy', dil='en_core_web_sm')

Yukarıda tanımladığımız belirteçlerden herhangi birinin çıktısını görelim. İkisi de aynı.

print(tokenizer("Bütün gün koşamam"))
Çıktı:
['Ben', 'ca', "değil", 'koş', 'bütün', 'gün']

Tokenizer'ı tanımladıktan sonra, Filed'ınıza iletebilirsiniz. Dosyalanmış, giriş metniniz için veri türüdür. Makale amacıyla, bir CSV dosyasında bazı örnek verileri tanımlayalım.

örnek veriler | Duygu Analizi LSTM TorchText

METİN = data.Field(tokenize=tokenizer, use_vocab=Doğru, alt=Doğru, batch_first=Doğru, include_lengths=Doğru) LABEL = data.LabelField(dtype=torch.long, batch_first=Doğru, sıralı=Yanlış) alanlar = [( 'metin', METİN), ('etiket', ETİKET)]

Yukarıdaki veri kümesinde ve kodda: Metin girişi sıralı veridir ve sıralı argüman varsayılan olarak True'dur, bu nedenle kodun ilk satırını geçmemize gerek yoktur ve bunu etiket alanına iletiyoruz. include_lengths argümanı, bir partideki her cümlenin uzunluğunu döndürür, bunu bu makalenin BucketIterator bölümünde daha ayrıntılı olarak göreceğiz. Tokenizer'ı yukarıda yaptığımız herhangi bir tokenizer işlevini kullanmadan da Alan içinde kullanabiliriz (yukarıda tanımladığımız tokenizer işlevlerinin hiçbirini kullanmıyoruz)-

METİN = data.Field(use_vocab=Doğru, alt=Doğru, tokenize='spacy', tokenizer_language='en_core_web_sm', batch_first=True, include_lengths=Doğru)

Proje için TabularDataset

Torchtext'te TabularDataset'e sahibiz ve bu, verileri herhangi bir CSV, TSV veya JSON formatında okuyan NLP amaçları için çok kullanışlı bir sınıftır. Alan argümanı bu sınıfta iletilecektir. Aşağıdaki verilerimizi görmek için sınıfı tanımladık ve sınıfı yineledik.

training_data = data.TabularDataset( path='sample.csv', format='csv', field=fields, skip_header=True, ) örneğin training_data.examples içinde: print(example.text, example.label)
Çıktı:
['o', 'iyi'] 1 ['o', 'o', 'üzgün'] 2 ['ben', 'am', 'çok', 'mutlu'] 1

Her zaman yaptığımızın aynısını yapacağız, Sklearn'in train_test_split ile yaptığımız gibi verileri trenlere ve test verilerine böleceğiz. Burada TabularDataset'in bir bölme işlevi vardır ve bu işlevi verilerimizi rastgele bir durumla bölmek için kullanacağız:

train_data, val_data = training_data.split(split_ratio=0.7, random_state=random.seed(SEED))

Duygu Analizi için Eldiven Gömme LSTM TorchText

Bu noktaya kadar verilerimizi okuduk ve TabularDataset'e dönüştürdük. Şimdi bu verilerde gömmenin nasıl kullanılacağını göreceğiz. Gömme ile ilgili temel bilgilendirici notlar veriyorum, eğer bilmiyorsanız işinize yarayacaktır. Sinir Ağı sadece sayılarla ilgilenir. Gömme, kelimeleri tam sayılara dönüştürür ve her tam sayıya karşılık gelen bir vektör vardır. Aşağıdaki resme bakın, sözlüğümüzde 10k kelime olduğunu ve her kelimeye 1 ile 10k arasında bir değer atadığınızı varsayalım.

10k boyutunda bir sıfır vektörü oluşturun, Şimdi, "man" kelimesini temsil etmek istediğinizi varsayalım, çünkü değeri sözlükte 1'dir (aşağıdaki resme bakın), bu nedenle vektörde ilk dizine 1 koyun ve diğerlerini saklayın sıfıra. Bu tür vektörler tek sıcak kodlama vektörleridir ve bu vektörlerle ilgili sorun boyutlarıdır. Eğer sözlüğümüzde 2B kelime varsa 2B boyutlu bir vektör yapmalıyız.

Böyle bir sorunun üstesinden gelmek için yoğun bir vektör oluşturuyoruz ve Eldiven, bir kelime için yoğun bir vektöre sahip olan böyle bir yaklaşımdır. Burada, problemimizde önceden eğitilmiş Eldiven Gömmesini indirip kullanacağız. Eldiven vektörünü meşale kullanarak indirebilir ve tüm boyutsal detayları bu adreste bulabilirsiniz. Link.

eldiven yerleştirme

                                                                     Şekil 2: kelimelerin vektörlerle temsili

                                      
vektörler = Vektörler(name='glove.6B.50d.txt') TEXT.build_vocab(train_data, vectors=vectors, max_size=10000, min_freq=1) LABEL.build_vocab(train_data)

Yukarıdaki kodda, vektörü başlattık ve bu vektör ile eğitim verisi sözlüğümüzü oluşturduk. Yani, veri setinden (kelime/ belirteç) bilinen tüm belirteçler için bir vektör elde ederiz. Ayrıca kelime dağarcığının boyutunu da sınırlayabiliriz. Eldiven metin dosyanız yoksa, vektörü indirmek için aşağıdaki kodu kullanın. Önbellek argümanı, indirilen dosyayı ileride kullanmak üzere saklamanıza yardımcı olacaktır. Yani aynı dosyayı tekrar tekrar indirmeye gerek yok.

önbellek = '.vector_cache' os.path.exists(cache) değilse: os.mkdir(cache) vectors = Glove(name='840B', dim=50, cache=cache)

Kelime dağarcığı oluşturduğunuz zaman, sözlüğe göz atabilirsiniz. Burada küçük verilerim var, böylece gösterim amacıyla tüm jetonları buraya yazdırabilirim.

print(list(TEXT.vocab.stoi.items()))
çıktı:
[('', 0), ('', 1), ('am', 2), ('iyi', 3), ('mutlu', 4), ('o', 5), ('i ', 6), ('öyle', 7), ('üzgün', 8), ('o', 9), ('çok', 10)]

Dikkat ettiyseniz, UNK ve PAD adında iki adet fazladan jetonumuz var ve bu ikisinin karşılık gelen indeksleri 0 ve 1'dir.

print(TEXT.vocab.vectors[TEXT.vocab.stoi['iyi']])

Burada TEXT.vocab.vectors, 50 farklı simge için 11 boyutlu vektör içerir. TEXT.vocab.stoi, dizeyi tamsayıya (index) dönüştürür. UNK ve PAD vektörleri her zaman sıfır vektörlerdir. Burada daha fazla yer kaplayacağı için değerleri yazdırmıyorum, ancak onunla oynayabilirsiniz. Şimdi sahip olduğum cihaz tipini alıyorum çünkü Bucket-Iterator'da kullanılacak.

cihaz = meşale.device('cuda' eğer meşale.cuda.is_available() yoksa 'cpu')

Duygu Analizi için BucketIterator LSTM TorchText

BucketIterator'ın kod kısmından önce, buna olan ihtiyacı anlayalım. Bu yineleyici verilerimizi yeniden düzenler, böylece benzer uzunluklardaki diziler, dizi uzunluğuna azalan sırayla tek bir partiye düşer (seq_len=Bir cümledeki belirteç sayısı). Uzunluk=[4,6,8,5] metnine sahipsek ve bu verileri iki gruba bölmek istiyorsak BucketIterator onu [8,6] ve [5,4] olarak bölecektir.

kova yineleyici |Duygu Analizi LSTM TorchText
                                                               Şekil 3: Bir toplu iş için BucketIterator

Verimli hesaplamalar için verilerin azalan sırada düzenlenmesi gerekir. Soru işaretini PAD belirteçleriyle değiştirmeli miyiz? Cevabı bu yazıda alacaksınız. BucketIterator, benzer uzunluktaki cümleleri tek bir grupta tutmaya yardımcı olur. Bu, hesaplama bakış açıları için dolgu belirteçlerinin ek yükünü azaltacaktır, önce BucketIterator'ın nasıl kodlanacağına bakın:

BTACH_SZIE = 2 train_itr, val_itr = BucketIterator.splits( (train_data, val_data), batch_size=BATCH_SIZE, sort_key=lambda x:len(x.text), device=device, shuffle=True, sort_within_batch=Doğru, sort=Fal

Burada her argümanın açıklayıcı olduğunu umuyorum, parti boyutu 2'yi geçtik. Parti boyutunu akıllıca seçin çünkü bu çok önemli bir hiper parametredir ve değeri de GPU/CPU belleğinizde ne kadar veri işleyebileceğinize bağlıdır. Tüm veri kümesini sıralamadık ama veri örneklerini bir toplu iş (sort_within_batch=True) içinde sıraladık. Partilerimizin nasıl göründüğüne bakın:

toplu iş_no, numaralandırmada toplu iş(train_itr): metin, toplu iş_len = toplu iş.metin yazdır(metin, toplu iş_len) yazdır(batch.label)
çıktı:
(tensör([[ 6, 2, 10, 4], [ 5, 7, 8, 1]]), tensör([4, 3])) tensör([0, 1])

Her toplu iş belirteç kimliklerini ve etiketlerini içerir, burada bir toplu iş içindeki her bir cümlenin uzunluğunu da aldık çünkü METİN Alanında include_length'i doğru olarak geçtik. Farklı uzunluklarda daha fazla cümleniz varsa, BucketIterator'ın verileri çok güzel bir şekilde düzenlediğini göreceksiniz.

LSTM Modelinin Temelleri

Uzun kısa süreli bellek (LSTM), RNN'nin bir aile üyesidir. RNN sıralı ilişkiyi öğrenir ve RNN'nin NLP'de iyi çalışmasının nedeni budur çünkü bir sonraki belirteç önceki belirteçlerden bazı bilgilere sahiptir. LSTM, RNN veya GRU'ya kıyasla daha uzun dizileri öğrenebilir. Örnek: "I üzgünüm demeyeceğim ve bu değil my arıza.”

Burada özür dilemek istemeyen aynı kişi suçlu olmadığından da emindir. Böyle bir mantığı anlamak için ağ, gerekirse bir cümlenin ilk kelimesi ile son kelimesi arasındaki ilişkiyi öğrenebilmelidir. Daha uzun cümleler için, ağ, tüm kelimeler arasındaki ilgili ilişkiyi ve dizinin sırasını anlamalıdır (hangi belirteç cümlede bir sonraki sırada gelir).

LSTM burada çok iyi bir rol oynar ve ilgili bilgileri hatırlama ve bir dizideki saygısız bilgileri unutma yeteneği nedeniyle dizideki daha uzun bağımlılığı hatırlar. Bunu keşfedebilirsin göre daha fazla ayrıntı için tüm RNN temellerini alacaksınız.

Giriş Şekli ve Gizli

Girdi iki şekilde verilebilir: 1. (Önce Sıra: Sıra Uzunluğu, Parti Büyüklüğü, Girdi Boyutu) 2. (Önce Parti: Parti Büyüklüğü, Sıra Uzunluğu, Girdi Boyutu). Burada girdinin ikinci biçimini kullanacağız. Parti boyutunu BucketIterator'da zaten tanımlamıştık, dizi_uzunluğu bir toplu iş içindeki belirteçlerin sayısıdır ve girdi boyutu, bizim durumumuzda 50 olan Eldiven vektör boyutudur.

Gizli şekil (Yön No * Katman Sayısı, Parti Boyutu, Gizli Boyut) şeklindedir. Duyarlılık metni bilgisi Çift Yönlü LSTM kullanılarak çıkarılabilir, bu nedenle yön sayısı 2'dir, 2 adet LSTM katmanı kullanacağız, bu nedenle bizim durumumuzda değeri 2'dir. Daha önce tartıştığımız parti boyutu ve gizli boyut, uygun değeri 8, 16, 32, 64, vb. seçebilirsiniz.

LSTM'nin giriş şekli
                                                   Şekil 4: LSTM(RNN) için giriş şekli

Model

class SentimentClassifier(nn.Module): def __init__(self, vocab_size, embed_dim, hidden, n_label, n_layers): super(SentimentClassifier, self).__init__() self.hidden = gizli self.n_layers = n_layers self.embed = nn. Gömme(vocab_size, embed_dim) self.lstm = nn.LSTM(embed_dim, gizli, num_layers=n_layers, iki yönlü=True, batch_first=True)#dropout=0.2 self.fc = nn.Linear(hidden * 2, n_label) def ileri (self, input, fact_batch_len): embed_out = self.embed(input) hidden = torch.zeros(self.n_layers * 2 , input.shape[0], self.hidden) hücre = torch.zeros( self.n_layers * 2 , input.shape[0], self.hidden) pack_out = nn.utils.rnn.pack_padded_sequence( embed_out, fact_batch_len,batch_first=True).to(cihaz) out_lstm, (gizli, hücre) = self.lstm(pack_out, ( gizli, hücre))#dropout hidden = torch.cat((hidden[-2,:,:], hidden[-1,:,:]),dim=1) out = self.fc(hidden) geri dön VOCAB_SIZE = len(TEXT.vocab) EMBEDDING_DIM = TEXT.vocab.vectors.shape[1] HIDDEN= 64 NUM_LABEL = 4 # sınıf sayısı NUM_LA YERS = 2 model = SentimentClassifier(VOCAB_SIZE, EMBEDDING_DIM, HIDDEN, NUM_LABEL, NUM_LAYERS)

Bu bizim modelimiz merak etmeyin bu kodu adım adım kıracağız. VOCAB_SIZE: Veri kümesindeki toplam jeton, EMBEDDING_DIM: Eldiven vektör boyutu (burada 50), GİZLİ 64 aldık, NUM_LABEL sınıf sayımız ve NUM_LAYERS 2: 2 yığın LSTM katmanı. İlk olarak, kelime boyutunun yoğun bir vektöre eşlenmesi olan gömme katmanını tanımladık, bu nedenle, toplam kelime boyutunu vektör boyutuna eşledik. Kelime dağarcığında sadece 2 jetonumuz olduğu ve 4 boyutlu bir vektöre dönüşmesini istediğimiz yerde meşale yerleştirme için bir örneğe bakın:

emb = nn.Gömme(2,4)# kelime hazinesi = 2, vektör len = 4 print(göm.ağırlık)
çıktı:
tensör([[ 0.2626, -0.7775, -0.7230, 0.6391], [-0.7772, 0.4914, -0.9622, 1.2316]], gerekli_grad=Doğru)

Yukarıdaki kodda, birinci ve ikinci çıktı listesi sırasıyla emb(4)[token 0] ve emb(1)[token[1] için 2 boyutlu bir gömme vektörüdür. Sınıflandırıcıda tanımladığımız ikinci şey LSTM katmanıdır, vektörün (Gömülü boyut) gizli olana eşlenmesini yaptık. sen de geçebilirsin bırakmak düzenleme için LSTM'de. Sonunda, istediğimiz sayıda sınıfla sonuçlanan tam bağlantılı bir katman tanımladık ve bu lineer dönüşümün girdisi, gizli olanın iki katıdır. Neden iki kez gizlendi? Çünkü bu çift yönlü LSTM ve son gizli hücreleri son LSTM katmanının ileri ve geri yönünden birleştiriyoruz (Çift yönlü LSTM katmanlarımız olduğu için).

SentimentClassifier sınıfının ileri yönteminde ne yaptığımızı tartışmanın zamanı geldi. İki bağımsız değişken girdisini (toplu veri) ve partinin her dizisindeki belirteç sayısını geçiyoruz. İlk önce oluşturduğumuz gömme katmanlarına girdi geçtik ama bekleyin….. Bu gömme, daha önce indirdiğimiz Glove gömme işleminden haberdar değil. Önceden eğitilmiş herhangi bir yerleştirme kullanmak istemiyorsanız, devam edin (gömme için sıfırdan öğrenen parametreler), sahip olduğumuz her simge için mevcut vektörleri kopyalamak için aşağıdaki kodu yapın.

model.embed.weight.data.copy_(TEXT.vocab.vectors) print(model.embed.weight)
Çıktı:
tensör([[ 0.0000, 0.0000, 0.0000, ..., 0.0000, 0.0000, 0.0000], [ 0.0000, 0.0000, 0.0000, ..., 0.0000, 0.0000, 0.0000], [-0.2660, 0.4732, 0.3187, ... , -0.1116, -0.2955, -0.2576], ..., [ 0.1777, 0.1764, 0.0684, ..., 0.1164, -0.0368, 0.1446], [ 0.4121, 0.0792, -0.4929, ..., 0.0564, 0.1322, -0.5023], [ 0.5183, 0.0194, 0.0089, ..., 0.2638, -0.0442, -0.3650]])

İlk iki vektör, UNK ve PAD belirteçlerini temsil ettikleri için sıfır vektörlerdir (eldiven yerleştirme bölümünde gördüğümüz gibi). Önceden eğitilmiş yerleştirmeyi kopyalamak, jetonlar bazı hiper boyutlu uzayda zaten iyi konumlandırılmış olduğundan modelimizin çok daha hızlı yakınsamasına yardımcı olacaktır. Bu nedenle, önceden eğitilmiş yerleştirmeden mevcut vektörleri kopyalamayı unutmayın.

LSTM'deki her yeni cümlenin ilk belirteci için gizli ve hücrenin sıfırlanması gerekir ve bu, onu LSTM'ye geçmeden önce sıfıra başlatmamızın nedenidir. Gizli ve hücreyi sıfıra ayarlamazsak Torch yapar, bu yüzden burada isteğe bağlıdır. pack_padded_sequence kullandık ve soru neden? Hatırladığınız gibi boş jetonlar için şekil 3'te soru işaretleri görmüştük, kaçırdıysanız yukarı çıkmanız yeterli.

pack_padded_sequence

Sonra gömme çıktısında pack_padded_sequence kullandık. BucketIterator, benzer uzunluktaki dizileri, azalan dizi uzunluğuna sahip bir toplu işte gruplandırdığından ve bu, pack_padded_sequence için gereklidir. pack_padded_sequence, size mevcut gruptan yeni gruplar döndürür. Size tüm temel bilgileri kod aracılığıyla vereceğim:

toplu oluşturma
                                   Şekil 5: Toplu oluşturma pack_padded_sequence
data: tensör([[ 6, 2, 10, 4], [ 9, 3, 1, 1]]) # 1 dolgulu belirteç len: tensör([4, 2])

İki cümleden oluşan bir grup yapalım (1) “Çok mutluyum” (2) “O iyi”. token_id'ler yukarıda [4,2] uzunluğunda yazılmıştır. pack_padded_sequence, verileri şekil 2'te gösterildiği gibi [2, 1, 1, 5] kümelerine dönüştürür. Bunu, geçmekte olduğumuz kodla birlikte küçük bir örnekle anlayalım. gömme çıktısı, elimizdeki seq_len listesiyle pack_padded_sequence'a [4, 2].

train_itr içindeki toplu iş için: metin, len = toplu.metin emb = nn.Gömme(vocab_size, EMB_DIM) emb.weight.data.copy_(TEXT.vocab.vectors) emb_out = emb(metin) pack_out = nn.utils.rnn. pack_padded_sequence(emb_out, len, batch_first=Doğru) rnn = nn.RNN(EMB_DIM, 4, batch_first=True) çıktı, gizli = rnn(pack_out)

Gizli olanı buraya yazdırırsak şunu elde ederiz:

Gizli Çıkış: [[[ 0.9451, -0.9984, -0.4613, 0.9768], [ 0.9672, -0.9905, -0.1192, 0.9983]]]

Tam çıktıyı yazdırırsak şunu elde ederiz:

rnn_çıktı:
[[ 0.9092, -0.9358, -0.8513, 0.9401], [ 0.8691, -0.9776, 0.5006, 0.1485], [ 0.8109, -0.9987, 0.9487, 0.9641], [ 0.9672, -0.9905, -0.1192 -0.9983, -0.9926, 0.9055], [ 0.5543, -0.9884, -0.9451, 0.9984]]

Bu açıklama için şekil 5'e bakın (mor çizgili jetonlara odaklanın). Son jetonun gizlenmesi, cümlenin hissini açıklayacaktır. İşte ilk dizinin son belirtecine (“mutlu”) karşılık gelen ilk gizli çıktı ve rnn_output listesinde sonuncusu. İkinci son(5.) rnn_output burada ("iyi") kullanılmaz. Ancak son gizli çıktı, ikinci dizinin ("iyi") son belirtecine aittir ve 4. rnn_output'tur. Dizi uzunluğumuz ve veri setimiz büyüyecekse pack_padded_sequence ile çok fazla hesaplama kaydedebiliriz. Aşağıdaki satırları yazdırarak çıktıyı orijinal dizi formuna dönüştürebilirsiniz ve bu kısmı analiz etmeniz için size bırakıyorum.

print(nn.utils.rnn.pad_packed_sequence(çıkış, toplu_ilk=Doğru))

Artık bilmemiz gereken tüm gerekli şeyleri tamamladık, elimizde veriler var, modelimizi hazır hale getirdik ve Glove embedding'i modelimizin embedding'ine kopyaladık. Sonunda bazı hiper parametreler tanımlayacağız ve ardından eğitim verilerine başlayacağız.

Kayıp Hesapla

opt = torch.optim.Adam(model.parameters(), lr=0.001) kriter = nn.CrossEntropyLoss() model.to(cihaz)

tanımladık ÇaprazEntropiKayıp (çoklu sınıf) çıktı sınıfının 4 sayısına sahip olduğumuz ve optimize edici olarak Adam'ı kullandığımız için bir kayıp fonksiyonu olarak. Verileri cihaza BucketIterator'da ilettiğimizi hatırlıyorsanız, Cuda'nız varsa model.to() yöntemini çağırın çünkü veri ve model aynı bellekte, CPU veya GPU'da olacaktır. Şimdi modelimizin kaybını ve doğruluğunu hesaplamak için fonksiyonları tanımlayacağız.

def doğruluk(preds, y): _, preds = torch.max(preds, dim= 1) acc = torch.sum(preds == y) / len(y) return acc def hesaplaKayıp(model, parti, kriter): text, text_len = batch.text preds = model(text, text_len.to('cpu') ) kayıp = kriter(preds, batch.label) acc = doğruluk(preds, batch.label) dönüş kaybı, len(batch.label) ), hesap

Doğruluk işlevi, basitçe Torç işlemlerinden oluşur: tahminlerimizi gerçeklerle eşleştirmek. İçinde hesaplaKayıp modelimize girdi geçtik, burada dikkat edilmesi gereken tek şey, daha önce batch_sequence_lengths'i (yukarıdaki kodda text_len) CPU'ya kaydırdık.

Dönem Döngüsü

N_EPOCH = 100 i in range(N_EPOCH): model.train() train_len, train_acc, train_loss = 0, [], [] batch_no için toplu iş numaralandırma(train_itr): opt.zero_grad() kayıp, blen, acc = hesapla( model, toplu iş, kriter) train_loss.append(kayıp * blen) train_acc.append(acc * blen) train_len = train_len + blen kayıp.backward() opt.step() train_epoch_loss = np.sum(train_loss) / train_len train_epoch_acc = np.sum( train_acc ) / train_len model.eval() meşale ile.no_grad(): val_itr içindeki toplu iş için: val_results = [val_itr içindeki toplu iş için [hesaplaKayıp( model, toplu iş, ölçüt)] kayıp, toplu iş_len, acc = zip( *val_results) epoch_loss = np.sum(np.multiply(kayıp, batch_len)) / np.sum(batch_len) epoch_acc = np.sum(np.multiply(acc , batch_len)) / np.sum(batch_len) print(' epoch:{}/{} epoch_train_loss:{:.4f},epoch_train_acc:{:.4f}' ' epoch_val_loss:{:.4f},epoch_val_acc:{:.4f}'.format(i+1, N_EPOCH, train_epoch_loss .item(), train_epoch_acc.item(), epoch_loss.item(), epoch_acc.item()))

Torch'ta yeniyseniz: tüm degradeleri sıfıra ayarlamak için üç önemli işlev (1) zero_grad (2) gradyanları hesaplamak için (3) loss.backward() parametreleri güncellemek için opt.step() kullanırız. Bu üçü de sadece eğitim verileri içindir, bu nedenle değerlendirme aşamasında torch.no_grad() ayarını yapıyoruz.

Sonuç

Vay canına, bu makaleyi tamamladık ve şimdi veri kümenizi uygulamanızın zamanı geldi. Birçok gerçek dünya uygulamasındaki deneyimime göre, endüstride yoğun olarak duygu analizi kullanıyoruz. Umarım bu makale öncekinden çok daha iyi anlamanıza yardımcı olur. Bir dahaki sefere başka bir ilginç NLP makalesinde görüşmek üzere.

Bu makalede kullanılan tüm görseller yazar tarafından tasarlanmıştır.

Bu makalede gösterilen medya Analytics Vidhya'ya ait değildir ve Yazarın takdirine bağlı olarak kullanılır.

Plato Ai. Web3 Yeniden Düşünüldü. Güçlendirilmiş Veri Zekası.
Erişmek için buraya tıklayın.

Kaynak: https://www.analyticsvidhya.com/blog/2021/09/sentiment-analysis-with-lstm-and-torchtext-with-code-and-explanation/

spot_img

En Son İstihbarat

spot_img