PyTorch - Guia rápido

PyTorch é definido como uma biblioteca de aprendizado de máquina de código aberto para Python. Ele é usado para aplicativos como processamento de linguagem natural. É inicialmente desenvolvido pelo grupo de pesquisa de inteligência artificial do Facebook e o software Pyro da Uber para programação probabilística que é construído sobre ele.

Originalmente, o PyTorch foi desenvolvido por Hugh Perkins como um wrapper Python para o LusJIT baseado no framework Torch. Existem duas variantes do PyTorch.

O PyTorch reprojeta e implementa o Torch em Python enquanto compartilha as mesmas bibliotecas C principais para o código de back-end. Os desenvolvedores do PyTorch ajustaram esse código de back-end para executar o Python com eficiência. Eles também mantiveram a aceleração de hardware baseada em GPU, bem como os recursos de extensibilidade que tornaram o Torch baseado em Lua.

Características

Os principais recursos do PyTorch são mencionados abaixo -

Easy Interface- PyTorch oferece API fácil de usar; portanto, é considerado muito simples de operar e roda em Python. A execução do código neste framework é bastante fácil.

Python usage- Esta biblioteca é considerada Pythonic, que se integra perfeitamente com a pilha de ciência de dados Python. Assim, pode alavancar todos os serviços e funcionalidades oferecidos pelo ambiente Python.

Computational graphs- PyTorch fornece uma excelente plataforma que oferece gráficos computacionais dinâmicos. Assim, um usuário pode alterá-los durante o tempo de execução. Isso é muito útil quando um desenvolvedor não tem ideia de quanta memória é necessária para criar um modelo de rede neural.

PyTorch é conhecido por ter três níveis de abstração, conforme mostrado abaixo -

  • Tensor - array n-dimensional imperativo que roda em GPU.

  • Variável - Nó no gráfico computacional. Isso armazena dados e gradiente.

  • Módulo - Camada de rede neural que armazenará o estado ou pesos aprendíveis.

Vantagens do PyTorch

A seguir estão as vantagens do PyTorch -

  • É fácil depurar e entender o código.

  • Inclui muitas camadas como tocha.

  • Inclui muitas funções de perda.

  • Pode ser considerado uma extensão NumPy para GPUs.

  • Permite construir redes cuja estrutura depende da própria computação.

TensorFlow vs. PyTorch

Veremos as principais diferenças entre TensorFlow e PyTorch abaixo -

PyTorch TensorFlow

PyTorch está intimamente relacionado à estrutura Torch baseada em lua que é ativamente usada no Facebook.

O TensorFlow é desenvolvido pelo Google Brain e usado ativamente no Google.

PyTorch é relativamente novo em comparação com outras tecnologias competitivas.

O TensorFlow não é novo e é considerado uma ferramenta portátil por muitos pesquisadores e profissionais do setor.

PyTorch inclui tudo de maneira imperativa e dinâmica.

O TensorFlow inclui gráficos estáticos e dinâmicos como uma combinação.

O gráfico de computação no PyTorch é definido durante o tempo de execução.

O TensorFlow não inclui nenhuma opção de tempo de execução.

O PyTorch inclui implantação de recursos para estruturas móveis e incorporadas.

O TensorFlow funciona melhor com estruturas incorporadas.

PyTorch é uma estrutura popular de aprendizado profundo. Neste tutorial, consideramos “Windows 10” como nosso sistema operacional. As etapas para uma configuração ambiental bem-sucedida são as seguintes -

Passo 1

O link a seguir inclui uma lista de pacotes que inclui pacotes adequados para PyTorch.

https://drive.google.com/drive/folders/0B-X0-FlSGfCYdTNldW02UGl4MXM

Tudo que você precisa fazer é baixar os respectivos pacotes e instalá-los conforme mostrado nas seguintes imagens -

Passo 2

Envolve a verificação da instalação do framework PyTorch usando o Anaconda Framework.

O seguinte comando é usado para verificar o mesmo -

conda list

“Lista Conda” mostra a lista de frameworks que estão instalados.

A parte destacada mostra que o PyTorch foi instalado com sucesso em nosso sistema.

A matemática é vital em qualquer algoritmo de aprendizado de máquina e inclui vários conceitos básicos da matemática para obter o algoritmo certo projetado de uma maneira específica.

A importância dos tópicos de matemática para o aprendizado de máquina e ciência de dados é mencionada abaixo -

Agora, vamos nos concentrar nos principais conceitos matemáticos de aprendizado de máquina, que são importantes do ponto de vista do Processamento de Linguagem Natural -

Vetores

Vetor é considerado uma matriz de números contínua ou discreta e o espaço que consiste em vetores é chamado de espaço vetorial. As dimensões espaciais dos vetores podem ser finitas ou infinitas, mas foi observado que os problemas de aprendizado de máquina e ciência de dados lidam com vetores de comprimento fixo.

A representação vetorial é exibida conforme mencionado abaixo -

temp = torch.FloatTensor([23,24,24.5,26,27.2,23.0])
temp.size()
Output - torch.Size([6])

No aprendizado de máquina, lidamos com dados multidimensionais. Portanto, os vetores tornam-se muito importantes e são considerados recursos de entrada para qualquer declaração de problema de previsão.

Escalares

Os escalares são denominados como tendo dimensões zero contendo apenas um valor. Quando se trata de PyTorch, ele não inclui um tensor especial com dimensões zero; portanto, a declaração será feita da seguinte forma -

x = torch.rand(10)
x.size()
Output - torch.Size([10])

Matrizes

A maioria dos dados estruturados é geralmente representada na forma de tabelas ou uma matriz específica. Usaremos um conjunto de dados chamado Boston House prices, que está disponível na biblioteca de aprendizado de máquina scikit-learn do Python.

boston_tensor = torch.from_numpy(boston.data)
boston_tensor.size()
Output: torch.Size([506, 13])
boston_tensor[:2]
Output:
Columns 0 to 7
0.0063 18.0000 2.3100 0.0000 0.5380 6.5750 65.2000 4.0900
0.0273 0.0000 7.0700 0.0000 0.4690 6.4210 78.9000 4.9671
Columns 8 to 12
1.0000 296.0000 15.3000 396.9000 4.9800
2.0000 242.0000 17.8000 396.9000 9.1400

O princípio básico da rede neural inclui uma coleção de elementos básicos, ou seja, neurônio artificial ou perceptron. Inclui várias entradas básicas como x1, x2… .. xn que produz uma saída binária se a soma for maior que o potencial de ativação.

A representação esquemática do neurônio de amostra é mencionada abaixo -

A saída gerada pode ser considerada como a soma ponderada com potencial de ativação ou viés.

$$ Output = \ sum_jw_jx_j + Bias $$

A arquitetura típica de rede neural é descrita abaixo -

As camadas entre a entrada e a saída são chamadas de camadas ocultas, e a densidade e o tipo de conexão entre as camadas é a configuração. Por exemplo, uma configuração totalmente conectada tem todos os neurônios da camada L conectados aos de L + 1. Para uma localização mais pronunciada, podemos conectar apenas uma vizinhança local, digamos nove neurônios, à próxima camada. A Figura 1-9 ilustra duas camadas ocultas com conexões densas.

Os vários tipos de redes neurais são os seguintes -

Redes Neurais Feedforward

As redes neurais feedforward incluem unidades básicas da família de redes neurais. A movimentação de dados neste tipo de rede neural é da camada de entrada para a camada de saída, por meio das atuais camadas ocultas. A saída de uma camada serve como camada de entrada com restrições em qualquer tipo de loop na arquitetura de rede.

Redes Neurais Recorrentes

Redes Neurais Recorrentes são quando o padrão de dados muda conseqüentemente ao longo de um período. No RNN, a mesma camada é aplicada para aceitar os parâmetros de entrada e exibir os parâmetros de saída na rede neural especificada.

As redes neurais podem ser construídas usando o pacote torch.nn.

É uma rede simples de feed-forward. Ele pega a entrada, a alimenta por várias camadas uma após a outra e, finalmente, fornece a saída.

Com a ajuda do PyTorch, podemos usar as seguintes etapas para o procedimento de treinamento típico para uma rede neural -

  • Defina a rede neural que possui alguns parâmetros (ou pesos) aprendíveis.
  • Itere sobre um conjunto de dados de entradas.
  • Entrada de processo através da rede.
  • Calcule a perda (até que ponto a saída está correta).
  • Propagar gradientes de volta aos parâmetros da rede.
  • Atualize os pesos da rede, normalmente usando uma atualização simples conforme fornecido abaixo
rule: weight = weight -learning_rate * gradient

A Inteligência Artificial é uma tendência hoje em dia em maior medida. O aprendizado de máquina e o aprendizado profundo constituem inteligência artificial. O diagrama de Venn mencionado abaixo explica a relação entre aprendizado de máquina e aprendizado profundo.

Aprendizado de Máquina

O aprendizado de máquina é a arte da ciência que permite que os computadores atuem de acordo com os algoritmos projetados e programados. Muitos pesquisadores acreditam que o aprendizado de máquina é a melhor maneira de progredir em direção à IA de nível humano. Inclui vários tipos de padrões como -

  • Padrão de Aprendizagem Supervisionada
  • Padrão de aprendizagem não supervisionado

Aprendizado Profundo

Aprendizado profundo é um subcampo do aprendizado de máquina em que os algoritmos em questão são inspirados na estrutura e função do cérebro, chamados de Redes Neurais Artificiais.

O aprendizado profundo ganhou muita importância por meio do aprendizado supervisionado ou a partir de dados e algoritmos rotulados. Cada algoritmo de aprendizado profundo passa pelo mesmo processo. Inclui hierarquia de transformação não linear de entrada e usa para criar um modelo estatístico como saída.

O processo de aprendizado de máquina é definido usando as seguintes etapas -

  • Identifica conjuntos de dados relevantes e os prepara para análise.
  • Escolhe o tipo de algoritmo a ser usado.
  • Constrói um modelo analítico com base no algoritmo usado.
  • Treina o modelo em conjuntos de dados de teste, revisando-o conforme necessário.
  • Executa o modelo para gerar pontuações de teste.

Neste capítulo, discutiremos a principal diferença entre os conceitos de aprendizado profundo e máquina.

Quantidade de dados

O aprendizado de máquina funciona com diferentes quantidades de dados e é usado principalmente para pequenas quantidades de dados. O aprendizado profundo, por outro lado, funciona de maneira eficiente se a quantidade de dados aumentar rapidamente. O diagrama a seguir descreve o funcionamento do aprendizado de máquina e do aprendizado profundo em relação à quantidade de dados -

Dependências de Hardware

Os algoritmos de aprendizado profundo são projetados para depender fortemente de máquinas de ponta, ao contrário dos algoritmos de aprendizado de máquina tradicionais. Algoritmos de aprendizado profundo executam uma grande quantidade de operações de multiplicação de matrizes que requerem um grande suporte de hardware.

Engenharia de Recursos

A engenharia de recursos é o processo de colocar conhecimento de domínio em recursos especificados para reduzir a complexidade dos dados e criar padrões que sejam visíveis aos algoritmos de aprendizagem.

Por exemplo, os padrões de aprendizado de máquina tradicionais se concentram em pixels e outros atributos necessários para o processo de engenharia de recursos. Algoritmos de aprendizado profundo se concentram em recursos de alto nível de dados. Ele reduz a tarefa de desenvolver um novo extrator de recursos para cada novo problema.

PyTorch inclui um recurso especial de criação e implementação de redes neurais. Neste capítulo, criaremos uma rede neural simples com uma camada oculta desenvolvendo uma única unidade de saída.

Devemos usar os seguintes passos para implementar a primeira rede neural usando PyTorch -

Passo 1

Primeiro, precisamos importar a biblioteca PyTorch usando o comando abaixo -

import torch 
import torch.nn as nn

Passo 2

Defina todas as camadas e o tamanho do lote para iniciar a execução da rede neural como mostrado abaixo -

# Defining input size, hidden layer size, output size and batch size respectively
n_in, n_h, n_out, batch_size = 10, 5, 1, 10

etapa 3

Como a rede neural inclui uma combinação de dados de entrada para obter os respectivos dados de saída, estaremos seguindo o mesmo procedimento dado abaixo -

# Create dummy input and target tensors (data)
x = torch.randn(batch_size, n_in)
y = torch.tensor([[1.0], [0.0], [0.0], 
[1.0], [1.0], [1.0], [0.0], [0.0], [1.0], [1.0]])

Passo 4

Crie um modelo sequencial com a ajuda de funções embutidas. Usando as linhas de código abaixo, crie um modelo sequencial -

# Create a model
model = nn.Sequential(nn.Linear(n_in, n_h),
   nn.ReLU(),
   nn.Linear(n_h, n_out),
   nn.Sigmoid())

Etapa 5

Construa a função de perda com a ajuda do otimizador Gradient Descent como mostrado abaixo -

Construct the loss function
criterion = torch.nn.MSELoss()
# Construct the optimizer (Stochastic Gradient Descent in this case)
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)

Etapa 6

Implemente o modelo de gradiente descendente com o loop iterativo com as linhas de código fornecidas -

# Gradient Descent
for epoch in range(50):
   # Forward pass: Compute predicted y by passing x to the model
   y_pred = model(x)

   # Compute and print loss
   loss = criterion(y_pred, y)
   print('epoch: ', epoch,' loss: ', loss.item())

   # Zero gradients, perform a backward pass, and update the weights.
   optimizer.zero_grad()

   # perform a backward pass (backpropagation)
   loss.backward()

   # Update the parameters
   optimizer.step()

Etapa 7

A saída gerada é a seguinte -

epoch: 0 loss: 0.2545787990093231
epoch: 1 loss: 0.2545052170753479
epoch: 2 loss: 0.254431813955307
epoch: 3 loss: 0.25435858964920044
epoch: 4 loss: 0.2542854845523834
epoch: 5 loss: 0.25421255826950073
epoch: 6 loss: 0.25413978099823
epoch: 7 loss: 0.25406715273857117
epoch: 8 loss: 0.2539947032928467
epoch: 9 loss: 0.25392240285873413
epoch: 10 loss: 0.25385022163391113
epoch: 11 loss: 0.25377824902534485
epoch: 12 loss: 0.2537063956260681
epoch: 13 loss: 0.2536346912384033
epoch: 14 loss: 0.25356316566467285
epoch: 15 loss: 0.25349172949790955
epoch: 16 loss: 0.25342053174972534
epoch: 17 loss: 0.2533493936061859
epoch: 18 loss: 0.2532784342765808
epoch: 19 loss: 0.25320762395858765
epoch: 20 loss: 0.2531369626522064
epoch: 21 loss: 0.25306645035743713
epoch: 22 loss: 0.252996027469635
epoch: 23 loss: 0.2529257833957672
epoch: 24 loss: 0.25285571813583374
epoch: 25 loss: 0.25278574228286743
epoch: 26 loss: 0.25271597504615784
epoch: 27 loss: 0.25264623761177063
epoch: 28 loss: 0.25257670879364014
epoch: 29 loss: 0.2525072991847992
epoch: 30 loss: 0.2524380087852478
epoch: 31 loss: 0.2523689270019531
epoch: 32 loss: 0.25229987502098083
epoch: 33 loss: 0.25223103165626526
epoch: 34 loss: 0.25216227769851685
epoch: 35 loss: 0.252093642950058
epoch: 36 loss: 0.25202515721321106
epoch: 37 loss: 0.2519568204879761
epoch: 38 loss: 0.251888632774353
epoch: 39 loss: 0.25182053446769714
epoch: 40 loss: 0.2517525553703308
epoch: 41 loss: 0.2516847252845764
epoch: 42 loss: 0.2516169846057892
epoch: 43 loss: 0.2515493929386139
epoch: 44 loss: 0.25148195028305054
epoch: 45 loss: 0.25141456723213196
epoch: 46 loss: 0.2513473629951477
epoch: 47 loss: 0.2512802183628082
epoch: 48 loss: 0.2512132525444031
epoch: 49 loss: 0.2511464059352875

O treinamento de um algoritmo de aprendizado profundo envolve as seguintes etapas -

  • Construindo um pipeline de dados
  • Construindo uma arquitetura de rede
  • Avaliando a arquitetura usando uma função de perda
  • Otimizando os pesos da arquitetura de rede usando um algoritmo de otimização

Treinar um algoritmo de aprendizado profundo específico é o requisito exato para converter uma rede neural em blocos funcionais, conforme mostrado abaixo -

Com relação ao diagrama acima, qualquer algoritmo de aprendizado profundo envolve a obtenção dos dados de entrada, construindo a respectiva arquitetura que inclui um monte de camadas embutidas neles.

Se você observar o diagrama acima, a precisão é avaliada usando uma função de perda com relação à otimização dos pesos da rede neural.

Neste capítulo, discutiremos alguns dos termos mais comumente usados ​​no PyTorch.

PyTorch NumPy

Um tensor PyTorch é idêntico a um array NumPy. Um tensor é um array n-dimensional e com relação a PyTorch, ele fornece muitas funções para operar nesses tensores.

Os tensores PyTorch geralmente utilizam GPUs para acelerar seus cálculos numéricos. Esses tensores que são criados no PyTorch podem ser usados ​​para ajustar uma rede de duas camadas a dados aleatórios. O usuário pode implementar manualmente as passagens para frente e para trás pela rede.

Variáveis ​​e Autograd

Ao usar o autograd, a passagem para a frente de sua rede definirá um computational graph - os nós no gráfico serão tensores e as arestas serão funções que produzem tensores de saída a partir de tensores de entrada.

Os tensores PyTorch podem ser criados como objetos variáveis ​​em que uma variável representa um nó no gráfico computacional.

Gráficos Dinâmicos

Os gráficos estáticos são bons porque o usuário pode otimizar o gráfico desde o início. Se os programadores estiverem reutilizando o mesmo gráfico repetidamente, essa otimização inicial potencialmente cara pode ser mantida, já que o mesmo gráfico é executado continuamente.

A principal diferença entre eles é que os gráficos computacionais do Tensor Flow são estáticos e o PyTorch usa gráficos computacionais dinâmicos.

Pacote Optim

O pacote otim em PyTorch abstrai a ideia de um algoritmo de otimização que é implementado de várias maneiras e fornece ilustrações de algoritmos de otimização comumente usados. Isso pode ser chamado na instrução de importação.

Multiprocessamento

O multiprocessamento suporta as mesmas operações, para que todos os tensores funcionem em vários processadores. A fila terá seus dados movidos para a memória compartilhada e enviará apenas um identificador para outro processo.

O PyTorch inclui um pacote chamado torchvision que é usado para carregar e preparar o conjunto de dados. Inclui duas funções básicas: Dataset e DataLoader, que ajudam na transformação e carregamento do dataset.

Conjunto de Dados

O conjunto de dados é usado para ler e transformar um ponto de dados do conjunto de dados fornecido. A sintaxe básica a ser implementada é mencionada abaixo -

trainset = torchvision.datasets.CIFAR10(root = './data', train = True,
   download = True, transform = transform)

DataLoader é usado para embaralhar e agrupar dados. Ele pode ser usado para carregar os dados em paralelo com trabalhadores de multiprocessamento.

trainloader = torch.utils.data.DataLoader(trainset, batch_size = 4,
   shuffle = True, num_workers = 2)

Exemplo: Carregando arquivo CSV

Usamos o pacote Python Panda para carregar o arquivo csv. O arquivo original tem o seguinte formato: (nome da imagem, 68 pontos de referência - cada ponto de referência tem ax, coordenadas y).

landmarks_frame = pd.read_csv('faces/face_landmarks.csv')

n = 65
img_name = landmarks_frame.iloc[n, 0]
landmarks = landmarks_frame.iloc[n, 1:].as_matrix()
landmarks = landmarks.astype('float').reshape(-1, 2)

Neste capítulo, vamos nos concentrar no exemplo básico de implementação de regressão linear usando o TensorFlow. A regressão logística ou regressão linear é uma abordagem de aprendizado de máquina supervisionada para a classificação de categorias discretas de ordem. Nosso objetivo neste capítulo é construir um modelo pelo qual um usuário pode prever o relacionamento entre variáveis ​​preditoras e uma ou mais variáveis ​​independentes.

A relação entre essas duas variáveis ​​é considerada linear, ou seja, se y for a variável dependente ex for considerada a variável independente, então a relação de regressão linear de duas variáveis ​​será semelhante à equação mencionada abaixo -

Y = Ax+b

Em seguida, devemos projetar um algoritmo para regressão linear que nos permite entender dois conceitos importantes dados abaixo -

  • Função de Custo
  • Algoritmos de gradiente descendente

A representação esquemática da regressão linear é mencionada abaixo

Interpretando o resultado

$$ Y = ax + b $$

  • O valor de a é a inclinação.

  • O valor de b é o y − intercept.

  • r é o correlation coefficient.

  • r2 é o correlation coefficient.

A visão gráfica da equação de regressão linear é mencionada abaixo -

As etapas a seguir são usadas para implementar a regressão linear usando PyTorch -

Passo 1

Importe os pacotes necessários para criar uma regressão linear em PyTorch usando o código abaixo -

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import seaborn as sns
import pandas as pd
%matplotlib inline

sns.set_style(style = 'whitegrid')
plt.rcParams["patch.force_edgecolor"] = True

Passo 2

Crie um único conjunto de treinamento com o conjunto de dados disponível conforme mostrado abaixo -

m = 2 # slope
c = 3 # interceptm = 2 # slope
c = 3 # intercept
x = np.random.rand(256)

noise = np.random.randn(256) / 4

y = x * m + c + noise

df = pd.DataFrame()
df['x'] = x
df['y'] = y

sns.lmplot(x ='x', y ='y', data = df)

etapa 3

Implementar regressão linear com bibliotecas PyTorch conforme mencionado abaixo -

import torch
import torch.nn as nn
from torch.autograd import Variable
x_train = x.reshape(-1, 1).astype('float32')
y_train = y.reshape(-1, 1).astype('float32')

class LinearRegressionModel(nn.Module):
   def __init__(self, input_dim, output_dim):
      super(LinearRegressionModel, self).__init__()
      self.linear = nn.Linear(input_dim, output_dim)

   def forward(self, x):
      out = self.linear(x)
      return out
input_dim = x_train.shape[1]
output_dim = y_train.shape[1]
input_dim, output_dim(1, 1)
model = LinearRegressionModel(input_dim, output_dim)
criterion = nn.MSELoss()
[w, b] = model.parameters()

def get_param_values():
   return w.data[0][0], b.data[0]

def plot_current_fit(title = ""):
plt.figure(figsize = (12,4))
plt.title(title)
plt.scatter(x, y, s = 8)
w1 = w.data[0][0]
b1 = b.data[0]
x1 = np.array([0., 1.])
y1 = x1 * w1 + b1
plt.plot(x1, y1, 'r', label = 'Current Fit ({:.3f}, {:.3f})'.format(w1, b1))
plt.xlabel('x (input)')
plt.ylabel('y (target)')
plt.legend()
plt.show()
plot_current_fit('Before training')

O gráfico gerado é o seguinte -

O aprendizado profundo é uma divisão do aprendizado de máquina e é considerado um passo crucial dado pelos pesquisadores nas últimas décadas. Os exemplos de implementação de aprendizado profundo incluem aplicativos como reconhecimento de imagem e reconhecimento de voz.

Os dois tipos importantes de redes neurais profundas são fornecidos abaixo -

  • Redes Neurais Convolucionais
  • Redes Neurais Recorrentes.

Neste capítulo, iremos nos concentrar no primeiro tipo, ou seja, Redes Neurais Convolucionais (CNN).

Redes Neurais Convolucionais

As redes neurais convolucionais são projetadas para processar dados por meio de várias camadas de matrizes. Esse tipo de rede neural é usado em aplicativos como reconhecimento de imagem ou reconhecimento de rosto.

A principal diferença entre a CNN e qualquer outra rede neural comum é que a CNN recebe a entrada como uma matriz bidimensional e opera diretamente nas imagens, em vez de focar na extração de recursos em que outras redes neurais se concentram.

A abordagem dominante da CNN inclui solução para problemas de reconhecimento. Grandes empresas como Google e Facebook têm investido em projetos de pesquisa e desenvolvimento de projetos de reconhecimento para realizar as atividades com maior agilidade.

Cada rede neural convolucional inclui três idéias básicas -

  • Respectivos campos locais
  • Convolution
  • Pooling

Vamos entender cada uma dessas terminologias em detalhes.

Campos Respectivos Locais

A CNN utiliza correlações espaciais que existem nos dados de entrada. Cada uma nas camadas concorrentes de redes neurais se conecta a alguns neurônios de entrada. Esta região específica é chamada de Campo Receptivo Local. Ele se concentra apenas em neurônios ocultos. O neurônio oculto processará os dados de entrada dentro do campo mencionado, sem perceber as mudanças fora do limite específico.

A representação do diagrama de geração dos respectivos campos locais é mencionada abaixo -

Convolução

Na figura acima, observamos que cada conexão aprende um peso de neurônio oculto com uma conexão associada ao movimento de uma camada para outra. Aqui, os neurônios individuais realizam uma mudança de tempos em tempos. Este processo é denominado “convolução”.

O mapeamento de conexões da camada de entrada para o mapa de feições ocultas é definido como “pesos compartilhados” e o viés incluído é chamado de “viés compartilhado”.

Pooling

As redes neurais convolucionais usam camadas de pooling que são posicionadas imediatamente após a declaração da CNN. Ele recebe a entrada do usuário como um mapa de recursos que sai das redes convolucionais e prepara um mapa de recursos condensado. O agrupamento de camadas ajuda na criação de camadas com neurônios de camadas anteriores.

Implementação de PyTorch

As etapas a seguir são usadas para criar uma rede neural convolucional usando PyTorch.

Passo 1

Importe os pacotes necessários para criar uma rede neural simples.

from torch.autograd import Variable
import torch.nn.functional as F

Passo 2

Crie uma classe com representação em lote de rede neural convolucional. Nosso formato de lote para a entrada x tem dimensão de (3, 32, 32).

class SimpleCNN(torch.nn.Module):
   def __init__(self):
      super(SimpleCNN, self).__init__()
      #Input channels = 3, output channels = 18
      self.conv1 = torch.nn.Conv2d(3, 18, kernel_size = 3, stride = 1, padding = 1)
      self.pool = torch.nn.MaxPool2d(kernel_size = 2, stride = 2, padding = 0)
      #4608 input features, 64 output features (see sizing flow below)
      self.fc1 = torch.nn.Linear(18 * 16 * 16, 64)
      #64 input features, 10 output features for our 10 defined classes
      self.fc2 = torch.nn.Linear(64, 10)

etapa 3

Calcule a ativação das primeiras mudanças de tamanho de convolução de (3, 32, 32) a (18, 32, 32).

O tamanho da dimensão muda de (18, 32, 32) para (18, 16, 16). Remodele a dimensão dos dados da camada de entrada da rede neural devido à qual o tamanho muda de (18, 16, 16) para (1, 4608).

Lembre-se de que -1 infere essa dimensão da outra dimensão fornecida.

def forward(self, x):
   x = F.relu(self.conv1(x))
   x = self.pool(x)
   x = x.view(-1, 18 * 16 *16)
   x = F.relu(self.fc1(x))
   #Computes the second fully connected layer (activation applied later)
   #Size changes from (1, 64) to (1, 10)
   x = self.fc2(x)
   return(x)

Redes neurais recorrentes são um tipo de algoritmo orientado para aprendizagem profunda que segue uma abordagem sequencial. Em redes neurais, sempre assumimos que cada entrada e saída é independente de todas as outras camadas. Esses tipos de redes neurais são chamados de recorrentes porque executam cálculos matemáticos de maneira sequencial, completando uma tarefa após a outra.

O diagrama abaixo especifica a abordagem completa e o funcionamento das redes neurais recorrentes -

Na figura acima, c1, c2, c3 e x1 são considerados como entradas que incluem alguns valores de entrada ocultos, nomeadamente h1, h2 e h3, fornecendo a respectiva saída de o1. Agora vamos nos concentrar na implementação do PyTorch para criar uma onda senoidal com a ajuda de redes neurais recorrentes.

Durante o treinamento, seguiremos uma abordagem de treinamento para nosso modelo com um ponto de dados por vez. A sequência de entrada x consiste em 20 pontos de dados e a sequência de destino é considerada igual à sequência de entrada.

Passo 1

Importe os pacotes necessários para implementar redes neurais recorrentes usando o código abaixo -

import torch
from torch.autograd import Variable
import numpy as np
import pylab as pl
import torch.nn.init as init

Passo 2

Vamos definir os hiperparâmetros do modelo com o tamanho da camada de entrada definido como 7. Haverá 6 neurônios de contexto e 1 neurônio de entrada para criar a sequência alvo.

dtype = torch.FloatTensor
input_size, hidden_size, output_size = 7, 6, 1
epochs = 300
seq_length = 20
lr = 0.1
data_time_steps = np.linspace(2, 10, seq_length + 1)
data = np.sin(data_time_steps)
data.resize((seq_length + 1, 1))

x = Variable(torch.Tensor(data[:-1]).type(dtype), requires_grad=False)
y = Variable(torch.Tensor(data[1:]).type(dtype), requires_grad=False)

Iremos gerar dados de treinamento, onde x é a sequência de dados de entrada ey é a sequência de destino necessária.

etapa 3

Os pesos são inicializados na rede neural recorrente usando distribuição normal com média zero. W1 representará a aceitação das variáveis ​​de entrada e w2 representará a saída que é gerada conforme mostrado abaixo -

w1 = torch.FloatTensor(input_size, 
hidden_size).type(dtype)
init.normal(w1, 0.0, 0.4)
w1 = Variable(w1, requires_grad = True)
w2 = torch.FloatTensor(hidden_size, output_size).type(dtype)
init.normal(w2, 0.0, 0.3)
w2 = Variable(w2, requires_grad = True)

Passo 4

Agora, é importante criar uma função para feed forward que defina exclusivamente a rede neural.

def forward(input, context_state, w1, w2):
   xh = torch.cat((input, context_state), 1)
   context_state = torch.tanh(xh.mm(w1))
   out = context_state.mm(w2)
   return (out, context_state)

Etapa 5

A próxima etapa é iniciar o procedimento de treinamento da implementação de onda senoidal recorrente da rede neural. O loop externo itera sobre cada loop e o loop interno itera através do elemento de sequência. Aqui, também calcularemos o erro quadrático médio (MSE), que ajuda na previsão de variáveis ​​contínuas.

for i in range(epochs):
   total_loss = 0
   context_state = Variable(torch.zeros((1, hidden_size)).type(dtype), requires_grad = True)
   for j in range(x.size(0)):
      input = x[j:(j+1)]
      target = y[j:(j+1)]
      (pred, context_state) = forward(input, context_state, w1, w2)
      loss = (pred - target).pow(2).sum()/2
      total_loss += loss
      loss.backward()
      w1.data -= lr * w1.grad.data
      w2.data -= lr * w2.grad.data
      w1.grad.data.zero_()
      w2.grad.data.zero_()
      context_state = Variable(context_state.data)
   if i % 10 == 0:
      print("Epoch: {} loss {}".format(i, total_loss.data[0]))

context_state = Variable(torch.zeros((1, hidden_size)).type(dtype), requires_grad = False)
predictions = []

for i in range(x.size(0)):
   input = x[i:i+1]
   (pred, context_state) = forward(input, context_state, w1, w2)
   context_state = context_state
   predictions.append(pred.data.numpy().ravel()[0])

Etapa 6

Agora, é hora de plotar a onda senoidal conforme a necessidade.

pl.scatter(data_time_steps[:-1], x.data.numpy(), s = 90, label = "Actual")
pl.scatter(data_time_steps[1:], predictions, label = "Predicted")
pl.legend()
pl.show()

Resultado

O resultado do processo acima é o seguinte -

Neste capítulo, vamos nos concentrar mais em torchvision.datasetse seus vários tipos. PyTorch inclui os seguintes carregadores de conjunto de dados -

  • MNIST
  • COCO (legendagem e detecção)

O conjunto de dados inclui a maioria dos dois tipos de funções fornecidas abaixo -

  • Transform- uma função que obtém uma imagem e retorna uma versão modificada do material padrão. Eles podem ser compostos junto com as transformações.

  • Target_transform- uma função que pega o alvo e o transforma. Por exemplo, recebe a string de legenda e retorna um tensor de índices mundiais.

MNIST

A seguir está o código de amostra para o conjunto de dados MNIST -

dset.MNIST(root, train = TRUE, transform = NONE, 
target_transform = None, download = FALSE)

Os parâmetros são os seguintes -

  • root - diretório raiz do conjunto de dados onde existem os dados processados.

  • train - Verdadeiro = Conjunto de treinamento, Falso = Conjunto de teste

  • download - Verdadeiro = baixa o conjunto de dados da Internet e o coloca na raiz.

COCO

Isso requer que a API COCO seja instalada. O exemplo a seguir é usado para demonstrar a implementação COCO do conjunto de dados usando PyTorch -

import torchvision.dataset as dset
import torchvision.transforms as transforms
cap = dset.CocoCaptions(root = ‘ dir where images are’, 
annFile = ’json annotation file’,
transform = transforms.ToTensor())
print(‘Number of samples: ‘, len(cap))
print(target)

O resultado obtido é o seguinte -

Number of samples: 82783
Image Size: (3L, 427L, 640L)

O objetivo do Convents é construir o modelo da CNN do zero. A arquitetura da rede conterá uma combinação das seguintes etapas -

  • Conv2d
  • MaxPool2d
  • Unidade Linear Retificada
  • View
  • Camada Linear

Treinando o modelo

Treinar o modelo é o mesmo processo que os problemas de classificação de imagens. O seguinte snippet de código completa o procedimento de um modelo de treinamento no conjunto de dados fornecido -

def fit(epoch,model,data_loader,phase 
= 'training',volatile = False):
   if phase == 'training':
      model.train()
   if phase == 'training':
      model.train()
   if phase == 'validation':
      model.eval()
   volatile=True
   running_loss = 0.0
   running_correct = 0
   for batch_idx , (data,target) in enumerate(data_loader):
      if is_cuda:
         data,target = data.cuda(),target.cuda()
         data , target = Variable(data,volatile),Variable(target)
      if phase == 'training':
         optimizer.zero_grad()
         output = model(data)
         loss = F.nll_loss(output,target)
         running_loss + = 
         F.nll_loss(output,target,size_average = 
         False).data[0]
         preds = output.data.max(dim = 1,keepdim = True)[1]
         running_correct + = 
         preds.eq(target.data.view_as(preds)).cpu().sum()
         if phase == 'training':
            loss.backward()
            optimizer.step()
   loss = running_loss/len(data_loader.dataset)
   accuracy = 100. * running_correct/len(data_loader.dataset)
   print(f'{phase} loss is {loss:{5}.{2}} and {phase} accuracy is {running_correct}/{len(data_loader.dataset)}{accuracy:{return loss,accuracy}})

O método inclui lógicas diferentes para treinamento e validação. Existem duas razões principais para usar modos diferentes -

  • No modo de trem, o dropout remove uma porcentagem dos valores, o que não deveria acontecer na fase de validação ou teste.

  • Para o modo de treinamento, calculamos gradientes e alteramos o valor dos parâmetros do modelo, mas a retropropagação não é necessária durante as fases de teste ou validação.

Neste capítulo, vamos nos concentrar em criar um convento do zero. Isso infere na criação do respectivo convento ou rede neural de amostra com a tocha.

Passo 1

Crie uma classe necessária com os respectivos parâmetros. Os parâmetros incluem pesos com valor aleatório.

class Neural_Network(nn.Module):
   def __init__(self, ):
      super(Neural_Network, self).__init__()
      self.inputSize = 2
      self.outputSize = 1
      self.hiddenSize = 3
      # weights
      self.W1 = torch.randn(self.inputSize, 
      self.hiddenSize) # 3 X 2 tensor
      self.W2 = torch.randn(self.hiddenSize, self.outputSize) # 3 X 1 tensor

Passo 2

Crie um padrão de feed forward de função com funções sigmóides.

def forward(self, X):
   self.z = torch.matmul(X, self.W1) # 3 X 3 ".dot" 
   does not broadcast in PyTorch
   self.z2 = self.sigmoid(self.z) # activation function
   self.z3 = torch.matmul(self.z2, self.W2)
   o = self.sigmoid(self.z3) # final activation 
   function
   return o
   def sigmoid(self, s):
      return 1 / (1 + torch.exp(-s))
   def sigmoidPrime(self, s):
      # derivative of sigmoid
      return s * (1 - s)
   def backward(self, X, y, o):
      self.o_error = y - o # error in output
      self.o_delta = self.o_error * self.sigmoidPrime(o) # derivative of sig to error
      self.z2_error = torch.matmul(self.o_delta, torch.t(self.W2))
      self.z2_delta = self.z2_error * self.sigmoidPrime(self.z2)
      self.W1 + = torch.matmul(torch.t(X), self.z2_delta)
      self.W2 + = torch.matmul(torch.t(self.z2), self.o_delta)

etapa 3

Crie um modelo de treinamento e predição conforme mencionado abaixo -

def train(self, X, y):
   # forward + backward pass for training
   o = self.forward(X)
   self.backward(X, y, o)
def saveWeights(self, model):
   # Implement PyTorch internal storage functions
   torch.save(model, "NN")
   # you can reload model with all the weights and so forth with:
   # torch.load("NN")
def predict(self):
   print ("Predicted data based on trained weights: ")
   print ("Input (scaled): \n" + str(xPredicted))
   print ("Output: \n" + str(self.forward(xPredicted)))

As redes neurais convolucionais incluem uma característica principal, extraction. As etapas a seguir são usadas para implementar a extração de recursos da rede neural convolucional.

Passo 1

Importe os respectivos modelos para criar o modelo de extração de recursos com “PyTorch”.

import torch
import torch.nn as nn
from torchvision import models

Passo 2

Crie uma classe de extrator de recursos que pode ser chamada quando necessário.

class Feature_extractor(nn.module):
   def forward(self, input):
      self.feature = input.clone()
      return input
new_net = nn.Sequential().cuda() # the new network
target_layers = [conv_1, conv_2, conv_4] # layers you want to extract`
i = 1
for layer in list(cnn):
   if isinstance(layer,nn.Conv2d):
      name = "conv_"+str(i)
      art_net.add_module(name,layer)
      if name in target_layers:
         new_net.add_module("extractor_"+str(i),Feature_extractor())
      i+=1
   if isinstance(layer,nn.ReLU):
      name = "relu_"+str(i)
      new_net.add_module(name,layer)
   if isinstance(layer,nn.MaxPool2d):
      name = "pool_"+str(i)
      new_net.add_module(name,layer)
new_net.forward(your_image)
print (new_net.extractor_3.feature)

Neste capítulo, iremos nos concentrar no modelo de visualização de dados com a ajuda de conventos. As etapas a seguir são necessárias para obter uma imagem perfeita da visualização com a rede neural convencional.

Passo 1

Importe os módulos necessários que são importantes para a visualização de redes neurais convencionais.

import os
import numpy as np
import pandas as pd
from scipy.misc import imread
from sklearn.metrics import accuracy_score

import keras
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Flatten, Activation, Input
from keras.layers import Conv2D, MaxPooling2D
import torch

Passo 2

Para interromper a aleatoriedade potencial com dados de treinamento e teste, chame o respectivo conjunto de dados conforme fornecido no código abaixo -

seed = 128
rng = np.random.RandomState(seed)
data_dir = "../../datasets/MNIST"
train = pd.read_csv('../../datasets/MNIST/train.csv')
test = pd.read_csv('../../datasets/MNIST/Test_fCbTej3.csv')
img_name = rng.choice(train.filename)
filepath = os.path.join(data_dir, 'train', img_name)
img = imread(filepath, flatten=True)

etapa 3

Trace as imagens necessárias para obter os dados de treinamento e teste definidos de maneira perfeita usando o código abaixo -

pylab.imshow(img, cmap ='gray')
pylab.axis('off')
pylab.show()

A saída é exibida conforme abaixo -

Neste capítulo, propomos uma abordagem alternativa que, em vez disso, depende de uma única rede neural convolucional 2D em ambas as sequências. Cada camada de nossa rede recodifica os tokens de origem com base na sequência de saída produzida até agora. As propriedades do tipo atenção são, portanto, difundidas em toda a rede.

Aqui, vamos nos concentrar em creating the sequential network with specific pooling from the values included in dataset. Esse processo também é mais bem aplicado no “Módulo de reconhecimento de imagem”.

As etapas a seguir são usadas para criar um modelo de processamento de sequência com conventos usando PyTorch -

Passo 1

Importe os módulos necessários para desempenho de processamento de sequência usando conventos.

import keras 
from keras.datasets import mnist 
from keras.models import Sequential 
from keras.layers import Dense, Dropout, Flatten 
from keras.layers import Conv2D, MaxPooling2D 
import numpy as np

Passo 2

Realize as operações necessárias para criar um padrão na respectiva sequência usando o código abaixo -

batch_size = 128 
num_classes = 10 
epochs = 12
# input image dimensions 
img_rows, img_cols = 28, 28
# the data, split between train and test sets 
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000,28,28,1) 
x_test = x_test.reshape(10000,28,28,1)
print('x_train shape:', x_train.shape) 
print(x_train.shape[0], 'train samples') 
print(x_test.shape[0], 'test samples')
y_train = keras.utils.to_categorical(y_train, num_classes) 
y_test = keras.utils.to_categorical(y_test, num_classes)

etapa 3

Compile o modelo e ajuste o padrão no modelo de rede neural convencional mencionado, conforme mostrado abaixo -

model.compile(loss = 
keras.losses.categorical_crossentropy, 
optimizer = keras.optimizers.Adadelta(), metrics = 
['accuracy'])
model.fit(x_train, y_train, 
batch_size = batch_size, epochs = epochs, 
verbose = 1, validation_data = (x_test, y_test)) 
score = model.evaluate(x_test, y_test, verbose = 0) 
print('Test loss:', score[0]) 
print('Test accuracy:', score[1])

A saída gerada é a seguinte -

Neste capítulo, entenderemos o famoso modelo de incorporação de palavras - word2vec. O modelo Word2vec é usado para produzir incorporação de palavras com a ajuda de um grupo de modelos relacionados. O modelo Word2vec é implementado com código C puro e o gradiente é calculado manualmente.

A implementação do modelo word2vec em PyTorch é explicada nas etapas abaixo -

Passo 1

Implemente as bibliotecas em incorporação de palavras conforme mencionado abaixo -

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F

Passo 2

Implemente o modelo Skip Gram de incorporação de palavras com a classe chamada word2vec. Incluiemb_size, emb_dimension, u_embedding, v_embedding tipo de atributos.

class SkipGramModel(nn.Module):
   def __init__(self, emb_size, emb_dimension):
      super(SkipGramModel, self).__init__()
      self.emb_size = emb_size
      self.emb_dimension = emb_dimension
      self.u_embeddings = nn.Embedding(emb_size, emb_dimension, sparse=True)
      self.v_embeddings = nn.Embedding(emb_size, emb_dimension, sparse = True)
      self.init_emb()
   def init_emb(self):
      initrange = 0.5 / self.emb_dimension
      self.u_embeddings.weight.data.uniform_(-initrange, initrange)
      self.v_embeddings.weight.data.uniform_(-0, 0)
   def forward(self, pos_u, pos_v, neg_v):
      emb_u = self.u_embeddings(pos_u)
      emb_v = self.v_embeddings(pos_v)
      score = torch.mul(emb_u, emb_v).squeeze()
      score = torch.sum(score, dim = 1)
      score = F.logsigmoid(score)
      neg_emb_v = self.v_embeddings(neg_v)
      neg_score = torch.bmm(neg_emb_v, emb_u.unsqueeze(2)).squeeze()
      neg_score = F.logsigmoid(-1 * neg_score)
      return -1 * (torch.sum(score)+torch.sum(neg_score))
   def save_embedding(self, id2word, file_name, use_cuda):
      if use_cuda:
         embedding = self.u_embeddings.weight.cpu().data.numpy()
      else:
         embedding = self.u_embeddings.weight.data.numpy()
      fout = open(file_name, 'w')
      fout.write('%d %d\n' % (len(id2word), self.emb_dimension))
      for wid, w in id2word.items():
         e = embedding[wid]
         e = ' '.join(map(lambda x: str(x), e))
         fout.write('%s %s\n' % (w, e))
def test():
   model = SkipGramModel(100, 100)
   id2word = dict()
   for i in range(100):
      id2word[i] = str(i)
   model.save_embedding(id2word)

etapa 3

Implemente o método principal para exibir o modelo de incorporação de palavras de maneira adequada.

if __name__  ==  '__main__':
   test()

As redes neurais profundas têm um recurso exclusivo para permitir avanços no aprendizado de máquina, entendendo o processo da linguagem natural. Observa-se que a maioria desses modelos trata a linguagem como uma sequência plana de palavras ou caracteres, e utiliza um tipo de modelo que é denominado rede neural recorrente ou RNN.

Muitos pesquisadores chegam à conclusão de que a linguagem é mais bem compreendida em relação à árvore hierárquica de frases. Esse tipo está incluído em redes neurais recursivas que levam em consideração uma estrutura específica.

O PyTorch tem um recurso específico que ajuda a tornar esses modelos complexos de processamento de linguagem natural muito mais fáceis. É uma estrutura completa para todos os tipos de aprendizado profundo com forte suporte para visão computacional.

Características da rede neural recursiva

  • Uma rede neural recursiva é criada de tal forma que inclui a aplicação do mesmo conjunto de pesos com diferentes estruturas semelhantes a grafos.

  • Os nós são percorridos em ordem topológica.

  • Este tipo de rede é treinado pelo modo reverso de diferenciação automática.

  • O processamento de linguagem natural inclui um caso especial de redes neurais recursivas.

  • Esta rede de tensores neurais recursivos inclui vários nós funcionais de composição na árvore.

O exemplo de rede neural recursiva é demonstrado abaixo -