RNN расшифровывается как Recurrent Neural Network. Это класс искусственных нейронных сетей, которые используют последовательные данные или данные временных рядов. В основном он используется для решения порядковых или временных проблем.

Синтаксис:

torch.nn.RNN(input_size, hidden_layer, num_layer, bias=True, batch_first=False, dropout = 0, bidirectional = False)

Параметры:

  • input_size: во входных данных x количество ожидаемых функций.
  • скрытый_слой: количество объектов в скрытом состоянии.
  • num_layer: num_layer используется в качестве нескольких повторяющихся слоев.
  • bias: если смещение имеет значение False, то слой не использует веса смещения.
  • batch_first: если пакет_первый имеет значение True, то предоставляются входные и выходные тензоры(пакет, последовательность, функция) вместо(последовательность, пакет, функция). Значение по умолчанию пакетного_первого — False.
  • dropout: если ненулевое значение, инициировать слой выпадения на выходе каждого уровня RNN, исключая последний слой, с вероятностью выпадения, равной выпадению. Значение отсева по умолчанию — 0.
  • bidirectional: если True, то он становится двунаправленным RNN. Значение двунаправленной связи по умолчанию — False.
Содержание

Пример

Рекуррентная нейронная сеть — это своего рода нейронная сеть, в которой выходные данные предыдущего шага сохраняются в качестве входных данных для текущего шага.

Важной особенностью RNN является скрытое состояние, которое запоминает некоторую информацию о последовательности.

Код:

В следующем коде мы импортируем модуль факела, из которого мы сможем рассчитать выходные данные RNN.

  • Recnn = nn.RNN(12, 22, 4) используется для работы над задачей прогнозирования последовательности с использованием
  • РНН.
  • inp = torch.randn(7, 5, 12) используется для генерации случайных чисел в качестве входных данных.
  • outp, hn = Recnn(inp, h) используется для получения выходных данных.
  • print(outp) используется для печати вывода на экран.
import torch
import torch.nn as nn
recnn = nn.RNN(12, 22, 4)
inp = torch.randn(7, 5, 12)
h = torch.randn(4, 5, 22)
outp, hn = recnn(inp, h)
print(outp)

Выход:

После запуска приведенного выше кода мы получаем следующий вывод, в котором видим, что значение PyTorch RNN печатается на экране.

Пример PyTorch RNN

RNN-ячейка

Ячейка RNN — это все, что имеет состояние и выполняет некоторые операции, которые принимают матрицу входных данных.

Клетки RNN отличаются от систематических нейронов в том смысле, что у них есть состояние и они могут запоминать информацию из прошлого.

синтаксис:

torch.nn.RNNCell(input_size, hidden_size, bias = True, nonlinearity = 'tanh', device = None, dtype = None)

Параметры:

  • input_size количество ожидаемых функций во входных данных x.
  • hidden_size — количество объектов в скрытом состоянии в виде h.
  • bias. Если смещение имеет значение False, то слой не использует вес смещения. Значение смещения по умолчанию — True.
  • nonlinearity: по умолчанию — tanh. Используется может быть как тан, так и релу.

Функция активации

Функция активации PyTorch RNN определяется как то, как взвешенная сумма входных данных преобразуется в выходные данные узла или узлов на уровне сети.

Код:

В следующем коде мы импортируем модуль факела, из которого начнет работать функция активации модели rnn.

  • traindt = dtsets.MNIST(root=’./data’, train=True, Transform=transform.ToTensor(), download=True) используется в качестве набора данных.
  • self.hidendim = скрытый размер используется как скрытое измерение.
  • self.layerdim=layerdim используется как количество скрытых слоев.
  • self.rnn = nn.RNN(inpdim,hidendim,layerdim,batt_first=True,nonlinearity=’relu’) используется для построения модели rnn.
  • self.fc = nn.Linear(hidendim, outpdim) используется как слой считывания.
  • h = torch.zeros(self.layerdim, y.size(0), self.hidendim).requires_grad_() инициализирует скрытое состояние нулями.
  • outp = self.fc(outp[:, -1, :]) используется как индекс скрытого состояния объекта последнего времени.
  • optim = torch.optim.SGD(mdl.parameters(), lr=l_r) используется для инициализации оптимизатора.
  • imgs = imgs.view(-1, seqdim, inpdim).requires_grad_() используется для загрузки изображений в виде тензора с градиентом
  • optim.zero_grad() используется как четкий градиент относительно параметра.
  • loss = criter(outps, lbls) используется для расчета потерь.
  • optim.step() используется как параметр обновления.
  • outps = mdl(imgs) используется как прямой проход только для получения выходных данных.
  • _, предсказанный = torch.max(outps.data, 1) используется для получения прогноза на основе максимального значения.
  • ttl += lbls.size(0) используется как общее количество меток.
  • crrct +=(predicted == lbls).sum() используется как общее количество правильных прогнозов.
  • print(‘Итерация: {}. Потеря: {}. Точность: {}’.format(iter, loss.item(), accu)) используется для печати точности на экране.
import torch
import torch.nn as nn
import torchvision.transforms as transform
import torchvision.datasets as dtsets
traindt = dtsets.MNIST(root='./data', 
                            train=True, 
                            transform=transform.ToTensor(),
                            download=True)

testdt = dtsets.MNIST(root='./data', 
                           train=False, 
                           transform=transform.ToTensor())
batchsiz = 80
nitrs = 2800
numepoch = nitrs /(len(traindt) / batchsiz)
numepoch = int(numepoch)

trainldr = torch.utils.data.DataLoader(dataset=traindt, 
                                           batch_size=batchsiz, 
                                           shuffle=True)

testldr = torch.utils.data.DataLoader(dataset=testdt, 
                                          batch_size=batchsiz, 
                                          shuffle=False)
class rnn(nn.Module):
    def __init__(self, inpdim, hidendim, layerdim, outpdim):
        super(rnn, self).__init__()
        self.hidendim = hidendim

        self.layerdim = layerdim

        self.rnn = nn.RNN(inpdim, hidendim, layerdim, batch_first=True, nonlinearity='relu')
        self.fc = nn.Linear(hidendim, outpdim)

    def forward(self, y):
        h = torch.zeros(self.layerdim, y.size(0), self.hidendim).requires_grad_()
        outp, hx = self.rnn(y, h.detach())
        outp = self.fc(outp[:, -1, :]) 
        return outp
inpdim = 28
hidendim = 80
layerdim = 1
outpdim = 10
mdl = rnn(inpdim, hidendim, layerdim, outpdim)
criter= nn.CrossEntropyLoss()
l_r = 0.01

optim = torch.optim.SGD(mdl.parameters(), lr=l_r)  
list(mdl.parameters())[0].size()
seqdim = 28  

itr = 0
for epoch in range(numepoch):
    for x,(imgs, lbls) in enumerate(trainldr):
        mdl.train()
        imgs = imgs.view(-1, seqdim, inpdim).requires_grad_()
        optim.zero_grad()
        outps = mdl(imgs)
        loss = criter(outps, lbls)
        loss.backward()

        optim.step()

        itr += 1

        if itr % 500 == 0:
            mdl.eval()       
            crrct = 0
            ttl = 0
            for imgs, lbls in testldr:
                imgs = imgs.view(-1, seqdim, inpdim)

                outps = mdl(imgs)
                _, predicted = torch.max(outps.data, 1)

                ttl += lbls.size(0)

                crrct +=(predicted == lbls).sum()

            accu = 100 * crrct / ttl

            print('Iteration: {}. Loss: {}. Accuracy: {}'.format(iter, loss.item(), accu))

Выход:

В следующем выводе мы видим, что точность модели rnn отображается на экране.

Функция активации PyTorch rnn

Бинарная классификация

Бинарная классификация может предсказывать один или два класса или классификацию нескольких классов, которая предполагает прогнозирование одного из более чем двух классов.

Код:

В следующем коде мы импортируем модуль факела, из которого мы сможем предсказать один или два класса с помощью двоичной классификации.

  • устройство = torch.device(‘cuda’, если torch.cuda.is_available(), иначе ‘cpu’) используется в качестве конфигурации устройства.
  • nn.Linear() используется для создания нейронной сети прямого распространения.
  • modl = RNNModel(inpsize, hidsize, numlayrs, numclases).to(device).to(device) используется для инициализации модели RNN.
  • optim = optim.Adam(modl.parameters(), lr = 0.01) используется для инициализации оптимизатора.
  • print(f”num_epochs: {numepchs}”) используется для печати количества эпох.
import torch
import torch.nn as nn
from torchvision import datasets as dtsets
from torchvision.transforms import ToTensor
traindt = dtsets.MNIST(
    root = 'data',
    train = True,                         
    transform = ToTensor(), 
    download = True,            
)
testdt = dtsets.MNIST(
    root = 'data', 
    train = False, 
    transform = ToTensor()
)
from torch.utils.data import DataLoader
ldrs = {
    'train' : torch.utils.data.DataLoader(traindt, 
                                          batch_size=100, 
                                          shuffle=True, 
                                          num_workers=1),
    
    'test'  : torch.utils.data.DataLoader(testdt, 
                                          batch_size=100, 
                                          shuffle=True, 
                                          num_workers=1),
}
ldrs

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
device
seqleng = 32
inpsize = 32
hidsize = 132
numlayrs = 6
numclases = 14
batchsiz = 100
numepchs = 6
l_r = 0.01
class RNNModel(nn.Module):
    
    def __init__(self, inpsiz, hidsize, numlayrs, numclases):
        super(RNNModel, self).__init__()
        self.hidden_size = hidsize
        self.num_layers = numlayrs
        self.lstm = nn.LSTM(inpsize, hidsize, numlayrs, batch_first=True)
        self.fc = nn.Linear(hidsize, numclases)
        

modl = RNNModel(inpsize, hidsize, numlayrs, numclases).to(device).to(device)
print(modl)
losfunc = nn.CrossEntropyLoss()
losfunc
from torch import optim
optim = optim.Adam(modl.parameters(), lr = 0.01)   
optim
def train(numepchs, modl, ldrs):
    print(f"num_epochs: {numepchs}")
    print(f"model: {modl}")
    print(f"loaders['train']: {ldrs['train']}")
    
   
train(numepchs, modl, ldrs)

Выход:

В следующем выводе мы видим, что двоичная классификация PyTorch RNN выполняется на экране.

Бинарная классификация PyTorch RNN

Анализ настроений

Анализ настроений — это задача прогнозного моделирования, в которой модель обучается прогнозировать двойственность текстовых данных, таких как положительные, отрицательные или нейтральные.

Код:

  • characts = set(».join(text)) используется для объединения всего предложения и извлечения уникального символа.
  • int2char = dict(enumerate(characts)) используется для сопоставления целого числа с символом.
  • inpseq.append(text[x][:-1]) используется для удаления последнего символа входной последовательности.
  • targseq.append(text[x][1:]) используется для удаления первого символа из целевой последовательности.
  • Features = np.zeros((batchsiz, seqleng, dicsiz), dtype=np.float32) создание многомерного массива с желаемыми выходными формами.
  • Hiden = self.init_hidden(batchsiz) используется для инициализации скрытого состояния.
  • modl = RNNModel(inpsize=dicsiz, outpsize=dicsiz, hiendim=12, nlayrs=1) создает экземпляр модели с гиперпараметром.
  • optim = torch.optim.Adam(modl.parameters(), lr=l_r) используется для инициализации оптимизатора.
  • print(‘Epochs: {}/{}………….’.format(epoch, nepchs), end=’ ‘) используется для печати эпох.
import torch
from torch import nn

import numpy as np
text = ['hey Guides','How are you','Have a nice day']


characts = set(''.join(text))

int2char = dict(enumerate(characts))

char2int = {char: ind for ind, char in int2char.items()}

maxleng = len(max(text, key=len))

for x in range(len(text)):
  while len(text[x])<maxleng:
      text[x] += ' '

inpseq = []
targseq = []

for x in range(len(text)):

  inpseq.append(text[x][:-1])

  targseq.append(text[x][1:])
  print("Input Sequence: {}\nTarget Sequence: {}".format(inpseq[x], targseq[x]))
for i in range(len(text)):
    inpseq[i] = [char2int[character] for character in inpseq[x]]
    targseq[i] = [char2int[character] for character in targseq[x]]
dicsiz = len(char2int)
seqleng = maxleng - 1
batchsiz = len(text)

def one_hot_encode(sequen, dicsiz, seqleng, batchsiz):
    features = np.zeros((batchsiz, seqleng, dicsiz), dtype=np.float32)

    for x in range(batchsiz):
        for y in range(seqleng):
            features[x, y, sequen[x][y]] = 1
    return features

inpseq = one_hot_encode(inpseq, dicsiz, seqleng, batchsiz)
inpseq = torch.from_numpy(inpseq)
target_seq = torch.Tensor(targseq)

is_cuda = torch.cuda.is_available()

if is_cuda:
    device = torch.device("cuda")
    print("gpu is available")
else:
    device = torch.device("cpu")
    print("gpu is not available, CPU used")
class RNNModel(nn.Module):
    def __init__(self, inpsize, outpsize, hidendim, nlayrs):
        super(RNNModel, self).__init__()

        # Defining some parameters
        self.hidendim = hidendim
        self.nlayrs = nlayrs

        #Defining the layers
        self.rnn = nn.RNN(inpsize, hidendim, nlayrs, batch_first=True)   
        # Fully connected layer
        self.fc = nn.Linear(hidendim, outpsize)
    
    def forward(self, z):
        
        batchsiz = z.size(0)
        hiden = self.init_hidden(batchsiz)


        outp, hiden = self.rnn(z, hiden)

        outp = outp.contiguous().view(-1, self.hidendim)
        outp = self.fc(outp)
        
        return outp, hiden
    
    def init_hidden(self, batchsiz):
        
        hiden = torch.zeros(self.nlayrs, batchsiz, self.hidendim)
        return hiden

modl = RNNModel(inpsize=dicsiz, outpsize=dicsiz, hidendim=12, nlayrs=1)
modl.to(device)
nepchs = 100
l_r=0.01
criter = nn.CrossEntropyLoss()
optim = torch.optim.Adam(modl.parameters(), lr=l_r)
for epoch in range(1, nepchs + 1):
        optim.zero_grad()
        inpseq.to(device)
        outp, hiden = modl(inpseq)
        loss = criter(outp, target_seq.view(-1).long())
        loss.backward() 
        optim.step() 

        if epoch%10 == 0:
            print('Epochs: {}/{}.............'.format(epoch, nepchs), end=' ')
            print("Loss: {:.4f}".format(loss.item()))

Выход:

После запуска приведенного выше кода мы получаем следующий вывод, в котором видим, что эпохи и потери выводятся на экран.

Анализ настроений PyTorch RNN

Языковая модель

  • Языковая модель RNN — это своего рода языковая модель нейронной сети, которая переносит модель RNN в сеть.
  • RNN приемлем для моделирования последовательных данных, например, на естественном языке.

Код:

В следующем коде мы импортируем модуль torch, из которого мы знаем о модели обучения RNN.

  • traindt = dtsets.MNIST(root=’dataset/’, train=True, Transform=transforms.ToTensor(), download=True) используется для загрузки набора данных.
  • modl = RNNlM(inpsize, hidensize, numlayrs, numclasses, sequlen).to(device) используется для инициализации модели RNN.
  • optim = optim.Adam(modl.parameters(), lr=l_r) используется для инициализации оптимизатора.
  • print(f’Got {numcrct}/{numsmples} с точностью {float(numcrct)/float(numsmples)*100:.2f}’) modl.train() используется для печати точности модели.
import torch
from tqdm import tqdm
import torch.nn as nn
import torch.optim as optim
import torchvision.datasets as dtsets
from torch.utils.data import DataLoader
from torchvision.transforms import transforms

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

# Declaring Hyper-parameters
inpsize = 28
sequlen = 28
numlayrs = 2
hidensize = 254
numclasses = 10
l_r = 0.001
batchsiz = 62
numepchs = 2
class RNNlM(nn.Module):
   
   def __init__(self, inpsize, hidensize, numlayrs, numclasses, sequlen):
      super(RNNlM, self).__init__()
      self.hidensize = hidensize
      self.numlayrs = numlayrs
      self.lstm = nn.LSTM(inpsize, hidensize, numlayrs, batch_first=True)
      self.fc = nn.Linear(hidensize*sequlen, numclasses)
   
   def forward(self, data):
      h = torch.zeros(self.numlayrs, data.size(0), self.hidensize).to(device)
      c = torch.zeros(self.numlayrs, data.size(0), self.hidensize).to(device)
      
      outp, _ = self.lstm(data,(h, c))
      outp = outp.reshape(outp.shape[0], -1)
      outp = self.fc(outp)
      return outp

traindt = dtsets.MNIST(root='dataset/', train=True, transform=transforms.ToTensor(), download=True)
testdt = dtsets.MNIST(root='dataset/', train=False, transform=transforms.ToTensor(), download=True)

trainldr = DataLoader(dataset=traindt, batch_size=batchsiz, shuffle=True)
testldr = DataLoader(dataset=testdt, batch_size=batchsiz, shuffle=True)

modl = RNNlM(inpsize, hidensize, numlayrs, numclasses, sequlen).to(device)

criter = nn.CrossEntropyLoss()
optim = optim.Adam(modl.parameters(), lr=l_r)

# Training Loop
ep = 1
for epoch in tqdm(range(numepchs), desc=f'Training model for epoch {ep}/{numepchs}', total=numepchs):
   for batch_idx,(data, trgt) in enumerate(trainldr):
      data = data.to(device).squeeze(1)
      trgts = trgt.to(device)
      scores = modl(data)
      loss = criter(scores, trgts)
      optim.zero_grad()
      loss.backward()
      optim.step()
   print(f'epoch: {epoch + 1} step: {batch_idx + 1}/{len(trainldr)} loss: {loss}')
   ep += 1
   # Evaluating our RNN model
def check_accuracy(ldr, modlrnnlm):
   if ldr.dataset.train:
      print('Check accuracy on training data')
   else:
      print('Check accuracy on test data')
   
   numcrct = 0
   numsmples = 0
   modlrnnlm.eval()
   with torch.no_grad():
      for i,j in ldr:
         i = i.to(device).squeeze(1)
         j = j.to(device)
         score = modlrnnlm(i)
         _, predictions = score.max(1)
         numcrct +=(predictions == j).sum()
         numsmples += predictions.size(0)
      
      print(f'Got {numcrct}/{numsmples} with accuracy {float(numcrct)/float(numsmples)*100:.2f}')
   modl.train()
   

check_accuracy(trainldr, modl)
check_accuracy(testldr, modl)

Выход:

В следующем выводе мы видим, что точность данных поезда и тестовых данных выводится на экран.

Модель обучения PyTorch RNN

Загрузчик данных

Набор данных загружает обучающие или тестовые данные в память, или загрузчик данных получает данные из набора данных и распределяет их по пакетам.

Код:

В следующем коде мы импортируем модуль факела, из которого мы сможем загрузить набор данных RNN.

  • class RNN(nn.Module): используется для определения класса RNN.
  • traindt = datasets.MNIST(root=’dataset/’, train=True, Transform=transforms.ToTensor(), download=True) используется в качестве набора данных.
  • trainldr = DataLoader(dataset=traindt,atch_size=batchsiz, shuffle=True) используется для загрузки набора данных.
import torch
from tqdm import tqdm
import torch.nn as nn
import torch.optim as optim
import torchvision.datasets as datasets
from torch.utils.data import DataLoader
from torchvision.transforms import transforms
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
inpsize = 30
seqlen = 30
numlayrs = 4
hidensize = 258
numclasses = 12
lr = 0.001
batchsiz = 66
numepchs = 4
class RNN(nn.Module):
   
   def __init__(self, inpsize, hidensize, numlayrs, numclasses, seqlen):
      super(RNN, self).__init__()
      self.hidensize = hidensize
      self.numlayrs = numlayrs
      self.lstm = nn.LSTM(inpsize, hidensize, numlayrs, batch_first=True)
      self.fc = nn.Linear(hidensize*seqlen, numclasses)
   
   def forward(self, data):
      h1 = torch.zeros(self.numlayers, data.size(0), self.hidensize).to(device)
      c1 = torch.zeros(self.numlayers, data.size(0), self.hidensize).to(device)
      
      outp, _ = self.lstm(data,(h1, c1))
      outp = outp.reshape(outp.shape[0], -1)
      outp = self.fc(outp)
      return outp
     
traindt = datasets.MNIST(root='dataset/', train=True, transform=transforms.ToTensor(), download=True)
testdt = datasets.MNIST(root='dataset/', train=False, transform=transforms.ToTensor(), download=True)

trainldr = DataLoader(dataset=traindt, batch_size=batchsiz, shuffle=True)
testldr = DataLoader(dataset=testdt, batch_size=batchsiz, shuffle=True)

Выход:

После запуска приведенного выше кода мы получаем следующий вывод, в котором видим, что данные модели RNN можно загрузить на экран.

Загрузчик данных PyTorch RNN

Добавить комментарий