Zephyrnet-logo

Sentimentanalyse met LSTM en TorchText met code en uitleg

Datum:

In dit artikel zullen we alle details zien die u moet weten voor de analyse van sentimentgegevens met behulp van het LSTM-netwerk met behulp van de torchtext-bibliotheek. We zullen zien hoe spacy tokenizer te gebruiken in torchtext data class en het gebruik van tabular en bucket iterator. We zullen de inbeddingsmatrix met of zonder vooraf getrainde Handschoen-inbedding als invoer gebruiken en we zullen ook zien hoe tekstgegevens van verschillende lengtes in een batch met pack_padded_sequence kunnen worden verwerkt. En u kunt deze technieken gebruiken in uw probleem

Wat zijn Field en LabelField?

In sentimentgegevens hebben we tekstgegevens en labels (sentimenten). De torchtext bedacht zijn tekstverwerkingsgegevenstypen in NLP. De tekstgegevens worden gebruikt met gegevenstype: Veld en het gegevenstype voor de klasse zijn LabelVeld. In de oudere versie PyTorch kun je deze datatypes importeren uit torchtext.data maar in de nieuwe versie vind je deze in torchtext.legacy.data. U kunt gedetailleerde informatie vinden voor Field hier.

Enkele belangrijke argumenten van de datatypes die je gaat gebruiken zijn 'tokenize', 'use_vocab', 'batch_first', 'include_lengths', 'sequentiële' en 'lower'. Laten we eerst het argument tokenize begrijpen. In eenvoudige bewoordingen is tokenisatie een proces om uw zin op te splitsen in woorden of meer basiswoorden. Je kunt tokenize op veel manieren gebruiken, ofwel door je functie van een tokenizer te definiëren, of je kunt een functie in torch definiëren met get_tokenizer, of je kunt een ingebouwde tokenizer van Field gebruiken. Eerst zullen we spacy installeren, dan zullen we de tokenizer-functie zien.

pip install spacy python -m spacy download en_core_web_sm
# Build tokenizer def tokenizer(text): return [token.text for token in spacy_en.tokenizer(text)]

Je kunt ook definiëren met torch get_tokenizer (een andere manier om te definiëren):

van torchtext.data.utils import get_tokenizer tokenizer = get_tokenizer('spacy', language='en_core_web_sm')

Laten we eens kijken naar de uitvoer van een van de tokenizers die we hierboven hebben gedefinieerd. Beide zijn hetzelfde.

print(tokenizer("Ik kan niet de hele dag rennen"))
Output:
['I', 'ca', 'n't', 'run', 'heel', 'day']

Nadat u de tokenizer hebt gedefinieerd, kunt u deze doorgeven aan uw Filed. Gearchiveerd is het gegevenstype voor uw invoertekst. Laten we voor het artikeldoel enkele voorbeeldgegevens definiëren in een CSV-bestand.

voorbeeldgegevens | Sentimentanalyse LSTM TorchText

TEXT = data.Field(tokenize=tokenizer, use_vocab=True, lower=True, batch_first=True, include_lengths=True) LABEL = data.LabelField(dtype=torch.long, batch_first=True, sequentiële=False) velden = [( 'tekst', TEKST), ('label', LABEL)]

In de bovenstaande dataset en de code: Tekstinvoer is sequentiële gegevens en het sequentiële argument is standaard True, dus het is niet nodig om de eerste regel code door te geven en we geven het door in het labelveld. Het argument include_lengths retourneert de lengte van elke zin in een batch, we zullen dit in meer detail bekijken in de BucketIterator-sectie van dit artikel. We kunnen tokenizer ook binnen het veld gebruiken zonder een tokenizer-functie te gebruiken die we hierboven hebben gedaan (we gebruiken geen van de tokenizer-functies die we hierboven hebben gedefinieerd) -

TEXT = data.Field(use_vocab=True, lower=True, tokenize='spacy', tokenizer_language='en_core_web_sm', batch_first=True, include_lengths=True)

TabularDataset voor het project

In torchtext hebben we TabularDataset en het is een zeer nuttige klasse voor NLP-doeleinden, die de gegevens leest in elk formaat CSV, TSV of JSON. Het veldargument wordt in deze klasse doorgegeven. We hebben de klasse gedefinieerd en de klasse herhaald om onze gegevens hieronder te bekijken.

training_data = data.TabularDataset( path='sample.csv', format='csv', fields=fields, skip_header=True, ) bijvoorbeeld in training_data.examples: print(example.text, example.label)
Output:
['zij', 'goed'] 1 ['hij', 'is', 'verdrietig'] 2 ['ik', 'ben', 'erg', 'gelukkig'] 1

We zullen hetzelfde doen als wat we altijd doen, gegevens opsplitsen in treinen en testgegevens zoals we doen met train_test_split van Sklearn. Hier heeft TabularDataset zelf een splitsingsfunctie en we zullen die functie gebruiken om onze gegevens te splitsen met een willekeurige status:

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

Inbedding van handschoenen voor sentimentanalyse LSTM TorchText

Tot nu toe hebben we onze gegevens gelezen en omgezet in TabularDataset. Nu zullen we zien hoe we inbedding in deze gegevens kunnen gebruiken. Ik geef elementaire informatieve opmerkingen over inbedding, die nuttig voor u zullen zijn als u niet op de hoogte bent. Neural Net behandelt alleen getallen. Inbedding zet woorden om in gehele getallen en er is een vector die overeenkomt met elk geheel getal. Raadpleeg de onderstaande afbeelding, stel dat we 10k woorden in ons woordenboek hebben en je hebt elk woord een waarde tussen 1 en 10k toegekend.

Maak een nulvector van dimensie 10k. Stel nu dat u het woord "man" wilt vertegenwoordigen, omdat de waarde 1 is in het woordenboek (zie de afbeelding hieronder), dus plaats in de vector 1 in de eerste index en bewaar anderen naar nul. Dergelijke typen vectoren zijn een-hot-coderingsvectoren en het probleem met deze vectoren is hun afmeting. Als we 2B-woorden in ons woordenboek hebben, moeten we een 2B-dimensievector maken.

Om zo'n probleem op te lossen, genereren we een dichte vector en Handschoen is zo'n benadering die een dichte vector voor een woord heeft. Hier zullen we vooraf getrainde Glove Embedding downloaden en gebruiken in ons probleem. Je kunt de Glove-vector downloaden met behulp van de toorts en alle dimensionale details zijn hier te vinden link.

handschoen inbedding

                                                                     Figuur 2: vectoren weergave van woorden

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

In de bovenstaande code hebben we de vector geïnitialiseerd en onze woordenschat voor trainingsgegevens met deze vector opgebouwd. Ik bedoel, we krijgen een vector voor alle bekende tokens uit de dataset (woord/token). We kunnen ook de omvang van de woordenschat beperken. Als je het Glove-tekstbestand niet hebt, gebruik dan de volgende code om de vector te downloaden. Het cache-argument helpt u het gedownloade bestand op te slaan voor toekomstig gebruik. Ik bedoel, het is niet nodig om hetzelfde bestand steeds opnieuw te downloaden.

cache = '.vector_cache' indien niet os.path.exists(cache): os.mkdir(cache) vectors = Glove(name='840B', dim=50, cache=cache)

Als je het vocabulaire hebt opgebouwd, kun je het woordenboek bekijken. Hier heb ik kleine gegevens, zodat ik hier hele tokens kan afdrukken voor demonstratiedoeleinden.

print(lijst(TEKST.vocab.stoi.items()))
output:
[('', 0), ('', 1), ('ben', 2), ('goed', 3), ('blij', 4), ('hij', 5), ('i ', 6), ('is', 7), ('verdrietig', 8), ('zij', 9), ('erg', 10)]

Als het je is opgevallen, hebben we twee extra tokens UNK en PAD en de bijbehorende indices van deze twee zijn 0 en 1. Als je de vector wilt zien die overeenkomt met token='good', kun je dit doen met de onderstaande code.

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

Hier bevat TEXT.vocab.vectors 50 dimensionale vectoren voor 11 verschillende tokens. TEXT.vocab.stoi converteert string naar integer(index). De vectoren voor UNK en PAD zijn altijd nulvectoren. Ik druk de waarden niet af omdat het hier meer ruimte in beslag neemt, maar je kunt ermee spelen. Nu krijg ik het apparaattype dat ik heb omdat het in Bucket-Iterator zal worden gebruikt.

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

BucketIterator voor sentimentanalyse LSTM TorchText

Laten we vóór het codegedeelte van BucketIterator de noodzaak ervan begrijpen. Deze iterator herschikt onze gegevens zodat vergelijkbare lengtes van reeksen in één batch vallen met aflopende volgorde tot reekslengte (seq_len=Aantal tokens in een zin). Als we de tekst van length=[4,6,8,5] hebben en we willen deze gegevens in twee batches splitsen, zal de BucketIterator deze splitsen in [8,6] en [5,4].

bucketiterator |Sentimentanalyse LSTM TorchText
                                                               Afbeelding 3: BucketIterator voor één batch

Het rangschikken van gegevens in aflopende volgorde is vereist voor efficiënte berekeningen. Moeten we het vraagteken vervangen door PAD-tokens? In dit artikel krijg je het antwoord. BucketIterator helpt om een ​​vergelijkbare lengte van zinnen in één batch te houden. Dit vermindert de overheadkosten van paddingtokens voor computationele gezichtspunten, kijk eerst hoe u de BucketIterator codeert:

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=True, sort=False )

Ik hoop dat elk argument hier voor zich spreekt, we hebben de batchgrootte van 2 doorgegeven. Kies de batchgrootte verstandig, want het is een cruciale hyperparameter en de waarde ervan hangt ook af van hoeveel gegevens u in uw GPU/CPU-geheugen kunt verwerken. We hebben niet de hele dataset gesorteerd, maar we hebben de datamonsters wel binnen een batch gesorteerd (sort_within_batch=True). Bekijk hoe onze batches eruitzien:

voor batch_no, batch in enumerate(train_itr): text, batch_len = batch.text print(text, batch_len) print(batch.label)
output:
(tensor([[ 6, 2, 10, 4], [ 5, 7, 8, 1]]), tensor([4, 3])) tensor([0, 1])

Elke batch bevat de token-ID's en labels, hier hebben we ook de lengte van elke zin in een batch omdat we include_length als waar hebben doorgegeven in het TEKST-veld. Als je meer zinnen van verschillende lengte hebt, zul je zien dat BucketIterator de gegevens heel mooi rangschikt.

Basisprincipes van het LSTM-model

Lange-kortetermijngeheugen (LSTM) is een familielid van RNN. RNN leert de sequentiële relatie en dit is de reden waarom RNN goed werkt in NLP omdat het volgende token wat informatie heeft van de vorige tokens. LSTM kan langere sequenties leren in vergelijking met RNN of GRU. Voorbeeld: "I ik ga geen sorry zeggen, en dit is ook niet my fout."

Hier is dezelfde persoon die geen sorry wil zeggen er ook zeker van dat hij niet schuldig is. Om dergelijke logica te begrijpen, moet het netwerk in staat zijn om de relatie tussen het eerste woord en het laatste woord van een zin te leren, indien nodig. Voor langere zinnen moet het netwerk de relevante relatie tussen alle woorden en de volgorde van de reeks begrijpen (welke token de volgende is in de zin).

De LSTM speelt hier een zeer goede rol en onthoudt een langere afhankelijkheid in de reeks vanwege het vermogen om relevante informatie te onthouden en oneerbiedige informatie in een reeks te vergeten. Je kunt dit verkennen dit artikel voor meer details krijg je alle basisprincipes van RNN.

Invoervorm en verborgen

De invoer kan op twee manieren worden gegeven: 1. (Sequence First: Sequence Length, Batch Size, Input Dimension) 2. (Batch First: Batch Size, Sequence Length, Input Dimension). We zullen hier het tweede formaat van de invoer gebruiken. We hebben de batchgrootte al gedefinieerd in de BucketIterator, de sequence_length is het aantal tokens in een batch en de invoerdimensie is de handschoenvectordimensie die in ons geval 50 is.

De verborgen vorm is (aantal richtingen * aantal lagen, batchgrootte, verborgen grootte). Sentimenttekstinformatie kan worden geëxtraheerd met behulp van bidirectionele LSTM, dus het aantal richtingen is 2, we zullen 2 LSTM-lagen gebruiken, dus de waarde is in ons geval 2. De batchgrootte die we al hebben besproken en de verborgen grootte, u kunt een geschikte waarde kiezen 8, 16, 32, 64, enz.

invoervorm van LSTM
                                                   Afbeelding 4: Invoervorm voor LSTM(RNN)

Model

class SentimentClassifier(nn.Module): def __init__(self, vocab_size, embed_dim, hidden, n_label, n_layers): super(SentimentClassifier, self).__init__() self.hidden = hidden self.n_layers = n_layers self.embed = nn. Insluiten (vocab_size, embed_dim) self.lstm = nn.LSTM(embed_dim, hidden, num_layers=n_layers, bidirectioneel=True, batch_first=True)#dropout=0.2 self.fc = nn.Linear(hidden * 2, n_label) def forward (self, input, actual_batch_len): embed_out = self.embed(input) hidden = torch.zeros(self.n_layers * 2 , input.shape[0], self.hidden) cell = torch.zeros( self.n_layers * 2 , input.shape[0], self.hidden) pack_out = nn.utils.rnn.pack_padded_sequence( embed_out, actual_batch_len,batch_first=True).to(apparaat) out_lstm, (hidden, cell) = self.lstm(pack_out, ( hidden, cell))#dropout hidden = torch.cat((hidden[-2,:,:], hidden[-1,:,:]),dim=1) out = self.fc(hidden) return out VOCAB_SIZE = len(TEXT.vocab) EMBEDDING_DIM = TEXT.vocab.vectors.shape[1] HIDDEN= 64 NUM_LABEL = 4 # aantal klassen NUM_LA YERS = 2 model = SentimentClassifier (VOCAB_SIZE, EMBEDDING_DIM, HIDDEN, NUM_LABEL, NUM_LAYERS)

Dit is ons model, maak je geen zorgen we zullen deze code stap voor stap breken. VOCAB_SIZE: Totaal aantal tokens in dataset, EMBEDDING_DIM: Handschoen vectordimensie (50 hier), HIDDEN we hebben 64 genomen, NUM_LABEL is ons aantal klassen en NUM_LAYERS is 2: 2 gestapelde LSTM-laag. Eerst hebben we de inbeddingslaag gedefinieerd die een afbeelding is van de woordenschatgrootte op een dichte vector, dit is de reden dat we de totale woordenschatgrootte hebben toegewezen aan de vectordimensie. Bekijk een voorbeeld voor het insluiten van toorts waarbij we slechts 2 tokens in de vocab hebben en we willen dat deze in een 4-dimensionale vector wordt omgezet:

emb = nn.Embedding(2,4)# size of vocab = 2, vector len = 4 print(emb.weight)
output:
tensor([[ 0.2626, -0.7775, -0.7230, 0.6391], [-0.7772, 0.4914, -0.9622, 1.2316]], required_grad=True)

In de bovenstaande code zijn de eerste en tweede uitvoerlijst een 4-dimensionale inbeddingsvector voor respectievelijk emb(0)[token 1] en emb(1)[token[2]. Het tweede dat we in de classifier hebben gedefinieerd, is de LSTM-laag, we hebben de vector (inbeddingsdimensie) in kaart gebracht op het verborgene. U kunt ook passeren afvaller in LSTM voor regularisatie. Eindelijk hebben we een volledig verbonden laag gedefinieerd, wat resulteerde in ons gewenste aantal klassen en de invoer voor deze lineaire transformatie is twee keer de verborgen. Waarom hebben twee keer verborgen? Omdat dit bidirectionele LSTM is en we de laatste verborgen cellen aaneenschakelen vanuit de voorwaartse en achterwaartse richting van de laatste laag van LSTM (aangezien we bidirectionele LSTM-lagen hebben).

Tijd om te bespreken wat we hebben gedaan in de forward-methode van de SentimentClassifier-klasse. We geven invoer met twee argumenten door (batchgegevens) en het aantal tokens in elke reeks van de batch. De allereerste keer hebben we input doorgegeven aan de inbeddingslagen die we hebben gemaakt, maar wacht... Deze inbedding is zich niet bewust van de inbedding van de handschoen, die we zojuist eerder hebben gedownload. Als je geen voorgetrainde inbedding wilt gebruiken, ga je gang (parameters leren van de grond af voor de inbedding) doe anders de volgende code om bestaande vectoren te kopiëren voor elk token dat we hebben.

model.embed.weight.data.copy_(TEXT.vocab.vectors) print(model.embed.weight)
Output:
tensor([[ 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]])

De eerste twee vectoren zijn nulvectoren omdat ze de UNK- en PAD-tokens vertegenwoordigen (zoals we hebben gezien in de sectie over het inbedden van handschoenen). Door de vooraf getrainde inbedding te kopiëren, kan ons model veel sneller convergeren omdat de tokens al goed gepositioneerd zijn in een hyperdimensionale ruimte. Vergeet dus niet bestaande vectoren uit de vooraf getrainde inbedding te kopiëren.

De verborgen en cel moeten worden gereset voor het eerste token van elke nieuwe zin in LSTM en dit is de reden dat we deze op nul hebben geïnitialiseerd voordat we deze aan de LSTM hebben doorgegeven. Als we de verborgen en cel niet op nul zetten, doet Torch het, dus het is hier optioneel. We gebruikten pack_padded_sequence en de vraag is waarom? Zoals je je herinnert, zagen we in figuur 3 vraagtekens voor lege fiches, ga gewoon naar boven als je ze hebt gemist.

pack_padded_sequence

Vervolgens gebruikten we pack_padded_sequence op de inbeddingsuitvoer. Omdat BucketIterator de reeksen van vergelijkbare lengte in één batch heeft gegroepeerd met aflopende volgorde van reekslengte, en dit is essentieel voor pack_padded_sequence. De pack_padded_sequence retourneert u nieuwe batches van de bestaande batch. Ik zal je alle basisprincipes geven via code:

batchcreatie
                                   Afbeelding 5: Batchcreatie pack_padded_sequence
data: tensor([[ 6, 2, 10, 4], [ 9, 3, 1, 1]]) # 1 is opgevuld token len: tensor ([4, 2])

Laten we een reeks van twee zinnen nemen (1) "Ik ben erg blij" (2) "Ze is goed". De token_ids zijn hierboven geschreven met lengte [4,2]. De pack_padded_sequence converteert de gegevens naar batches van [2, 2, 1, 1] zoals weergegeven in figuur 5. Laten we dit begrijpen met een klein voorbeeld met code die we doorgeven de inbeddingsuitvoer naar pack_padded_sequence met een lijst van seq_len die we hebben [4, 2].

voor batch in train_itr: text, len = batch.text emb = nn.Embedding(vocab_size, EMB_DIM) emb.weight.data.copy_(TEXT.vocab.vectors) emb_out = emb(text) pack_out = nn.utils.rnn. pack_padded_sequence(emb_out, len, batch_first=True) rnn = nn.RNN(EMB_DIM, 4, batch_first=True) out, hidden = rnn(pack_out)

Als we de verborgen hier afdrukken, krijgen we:

Verborgen uitvoer: [[[ 0.9451, -0.9984, -0.4613, 0.9768], [ 0.9672, -0.9905, -0.1192, 0.9983]]]

Als we de volledige uitvoer afdrukken, krijgen we:

rnn_output:
[[ 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, -0.4613, 0.9768]]

Zie figuur 5 voor deze uitleg (focus op paars omlijnde lopers). De verborgen van het laatste token zal het sentiment voor de zin verklaren. Hier is de eerste verborgen uitvoer, die overeenkomt met het laatste token ("happy") van de eerste reeks en in de rnn_output-lijst is het de laatste. De voorlaatste (5e) rnn_output is ("goed") hier niet van toepassing. Maar de laatste verborgen uitvoer behoort tot het laatste token van de tweede reeks ("goed") en het is de 4e rnn_output. Als onze reekslengte en dataset groeien, kunnen we veel berekeningen besparen met pack_padded_sequence. U kunt de uitvoer transformeren naar zijn oorspronkelijke vorm van reeksen door de volgende regels af te drukken en ik laat dit deel aan u over om te analyseren.

print(nn.utils.rnn.pad_packed_sequence(uit, batch_first=True))

Nu hebben we alle vereiste dingen voltooid die we moeten weten, we hebben gegevens in onze handen, we hebben ons model gereed gemaakt en we hebben Glove-inbedding gekopieerd naar de inbedding van ons model. Dus uiteindelijk zullen we enkele hyperparameters definiëren, waarna we beginnen met trainingsgegevens.

Bereken verlies

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

We hebben gedefinieerd CrossEntropyVerlies (multi-class) als een verliesfunctie omdat we 4 nummers van de outputklasse hebben en we Adam als de optimizer hebben gebruikt. Als je je herinnert dat we de gegevens hebben doorgegeven aan het apparaat in BucketIterator, dus als je Cuda hebt, roep dan de model.to()-methode aan omdat gegevens en model zich in hetzelfde geheugen moeten bevinden, ofwel CPU of GPU. Nu zullen we functies definiëren om het verlies en de nauwkeurigheid van ons model te berekenen.

def nauwkeurigheid(preds, y): _, preds = torch.max(preds, dim=1) acc = torch.sum(preds == y) / len(y) return acc def calculatorLoss(model, batch, criterium): text, text_len = batch.text preds = model(text, text_len.to('cpu') ) loss = criterium(preds, batch.label) acc = nauwkeurigheid (preds, batch.label) retourverlies, len(batch.label ), acc

De nauwkeurigheidsfunctie bestaat uit eenvoudige fakkelbewerkingen: het matchen van onze voorspellingen met de werkelijke cijfers. In berekenenVerlies we hebben invoer doorgegeven aan ons model, het enige dat hier opvalt, is dat we de batch_sequence_lengths (text_len in bovenstaande code) eerder naar de CPU hebben verschoven.

Tijdperk lus

N_EPOCH = 100 voor i in range(N_EPOCH): model.train() train_len, train_acc, train_loss = 0, [], [] voor batch_no, batch in enumerate(train_itr): opt.zero_grad() loss, blen, acc = calculatorLoss( model, batch, criterium) train_loss.append(loss * blen) train_acc.append(acc * blen) train_len = train_len + blen loss.backward() opt.step() train_epoch_loss = np.sum(train_loss) / train_len train_epoch_acc = np.sum( train_acc) / train_len model.eval() met torch.no_grad(): voor batch in val_itr: val_results = [calculateLoss(model, batch, criterium) voor batch in val_itr] loss, batch_len, acc = zip( *val_results) epoch_loss = np.sum(np.multiply(loss, 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()))

Als Torch nieuw voor u is: we gebruiken drie belangrijke functionaliteiten (1) zero_grad om alle gradiënten in te stellen op nul (2) loss.backward() om de gradiënten te berekenen (3) opt.step() om de parameters bij te werken. Al deze drie zijn alleen voor trainingsgegevens, dus we stellen torch.no_grad() in tijdens de evaluatiefase.

Conclusie

Wauw, we hebben dit artikel voltooid en het is tijd voor u om uw dataset in de praktijk te brengen. In mijn ervaring met veel toepassingen in de echte wereld, gebruiken we in de branche veel sentimentanalyse. Ik hoop dat dit artikel je veel beter helpt begrijpen dan voorheen. Tot de volgende keer met een ander interessant NLP-artikel.

Alle afbeeldingen die in dit artikel worden gebruikt, zijn ontworpen door de auteur.

De media die in dit artikel worden getoond, zijn geen eigendom van Analytics Vidhya en worden naar goeddunken van de auteur gebruikt.

PlatoAi. Web3 opnieuw uitgevonden. Gegevensintelligentie versterkt.
Klik hier om toegang te krijgen.

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

spot_img

Laatste intelligentie

spot_img

Chat met ons

Hallo daar! Hoe kan ik u helpen?