Aniversário
Alura 12 anos

20% OFF

Falta pouco!

00

DIAS

00

HORAS

00

MIN

00

SEG

Alura > Cursos de Inteligência Artificial > Cursos de IA para Dados > Conteúdos de IA para Dados > Primeiras aulas do curso Live coding: completando códigos com o Pytorch

Live coding: completando códigos com o Pytorch

Completador de código - Apresentação

Introdução ao Curso de Completadores de Texto e Código

Olá! Já nos perguntamos como funciona o completador de textos no WhatsApp ou mesmo o completador de código no editor de código? Neste curso, vamos compreender e implementar uma pequena solução que se propõe a resolver esse problema. Assim, entenderemos os princípios de construção de uma rede neural que visa solucionar esse tipo de questão.

Apresentação do Instrutor

Olá! Meu nome é Alan Spadini e irei acompanhar vocês neste curso.

Audiodescrição: Alan é um homem branco, com cabelos castanhos. Ele está no estúdio da Alura, com uma parede colorida ao fundo e uma estante.

Pré-requisitos para o Curso

Para acompanhar este curso, é interessante que já tenhamos algum conhecimento de Machine Learning (aprendizado de máquina). Além disso, é recomendável seguir a formação de PyTorch, pois utilizaremos essa ferramenta para resolver o problema proposto.

Encerramento

Nos vemos nos próximos vídeos do curso. Até mais!

Completador de código - Tokenizando o texto

Introdução ao Completador de Código SQL

Para criar um completador de código SQL personalizado, começamos com a ideia de usar um corpus de comandos SQL previamente utilizados. A meta é desenvolver uma rede neural que possa sugerir a continuação de comandos SQL, como completar SELECT * FROM com CUSTOMERS.

Pré-processamento do Texto

A primeira etapa é pré-processar o texto para que ele possa ser utilizado pela rede neural. Isso envolve a tokenização, que é a divisão do texto em palavras. Vamos começar importando as bibliotecas necessárias:

import torch
import torch.nn as nn
from torch.utils.data import Dataset, Dataloader
from collections import Counter

Com as bibliotecas importadas, definimos nosso corpus de comandos SQL:

corpus = [
    "SELECT * FROM customers WHERE active = 1;",
    "INSERT INTO products (name, price) VALUES ('laptop', 1200);",
    "UPDATE employees SET salary = 5000 WHERE department = 'HR';",
    "DELETE FROM orders WHERE order_date < '2023-01-01';",
    "CREATE TABLE users (id INT PRIMARY KEY, username VARCHAR(50));",
    "ALTER TABLE invoices ADD COLUMN total DECIMAL(10, 2);",
    "DROP TABLE IF EXISTS temp_data;",
    "SELECT name, COUNT(*) AS total FROM sales GROUP BY name;",
    "JOIN addresses ON customers.id = addresses.customer_id;",
    "ORDER BY created_at DESC LIMIT 10;",
    "WHERE status = 'pending' AND priority > 5;",
    "HAVING SUM(amount) > 1000;",
    "GRANT SELECT, INSERT ON database.* TO 'user'@'localhost';",
    "REVOKE ALL PRIVILEGES ON employees FROM 'intern'@'%';",
    "BEGIN TRANSACTION; COMMIT;",
    "ROLLBACK TO SAVEPOINT before_update;",
    "EXPLAIN SELECT * FROM logs WHERE type = 'error';",
    "INDEX idx_name ON employees (last_name);",
    "PRIMARY KEY (order_id, product_id);",
    "FOREIGN KEY (customer_id) REFERENCES customers(id);"
]

Agora, vamos tokenizar o corpus dividindo-o em palavras:

tokens = [word.lower() for sentence in corpus for word in sentence.split()]

Ao executar o código acima, obtemos uma lista de palavras em minúsculas, que são os tokens do nosso corpus.

Construção do Vocabulário

Com os tokens em mãos, o próximo passo é criar um vocabulário que conte a frequência de cada palavra:

vocab = Counter(tokens)

Podemos visualizar o vocabulário para ver a frequência de cada palavra:

vocab

Para facilitar o uso, ordenamos o vocabulário pela frequência das palavras:

vocab = sorted(vocab, key=vocab.get, reverse=True)

E verificamos o vocabulário ordenado:

vocab

Mapeamento de Índices

Precisamos também mapear cada palavra para um índice único, o que é essencial para o treinamento da rede neural:

word_to_idx = {word: i for i, word in enumerate(vocab)}

E o mapeamento inverso, de índices para palavras:

idx_to_word = {i: word for word, i in word_to_idx.items()}

Com esses mapeamentos, temos a base necessária para alimentar uma rede neural que aprenderá a completar comandos SQL. No próximo passo, desenvolveremos a classe da rede neural que utilizará essas informações para gerar sugestões de código.

Completador de código - Construindo a rede

Introdução à Construção da Rede Neural

Agora, vamos construir a rede neural necessária para lidar com este problema. Vamos criar uma classe, pois o PyTorch, a biblioteca que estamos utilizando para trabalhar com redes neurais, normalmente opera com classes. Assim, criaremos uma classe chamada SQLLM. Em seguida, abriremos e fecharemos parênteses e utilizaremos o nn.Module, que é algo do PyTorch que estamos importando.

class SQLLM(nn.Module):

Definição do Método __init__

Dentro dessa classe, criaremos o método __init__, que conterá as principais estruturas da rede neural. Para isso, definiremos o método __init__ com self e algumas entradas que a classe receberá. Passaremos o vocab_size, embedding_dim e hidden_dim, que será igual a 128.

    def __init__(self, vocab_size, embedding_dim=64, hidden_dim=128):

Dentro do método __init__, utilizaremos o comando super().__init__() para chamar algumas estruturas necessárias para a rede neural.

        super().__init__()

Criação do Embedding

Em seguida, criaremos self.embedding, que será igual a nn.Embedding. Este método embedding receberá o tamanho do vocabulário e a dimensão do embedding, ou seja, vocab_size e embedding_dim.

        self.embedding = nn.Embedding(vocab_size, embedding_dim)

A ideia do embedding é transformar as palavras do vocabulário em uma representação vetorial. Ele recebe o vocabulário e converte as palavras do conjunto de dados em uma representação numérica vetorial, facilitando o aprendizado da rede neural sobre o problema.

Implementação da Camada LSTM

Após essa etapa, também precisaremos de uma camada de rede neural. Quando trabalhamos com frases ou sentenças, lidamos com informações sequenciais e queremos prever a próxima palavra. Por isso, utilizaremos uma camada de rede neural específica para informações sequenciais, que são as camadas LSTM.

        self.lstm = nn.LSTM(embedding_dim, hidden_dim, batch_first=True)

Nós vamos definir os parâmetros embedding_dim, hidden_dim, batch_first=True. Estamos passando as informações de forma que precisamos especificar o tamanho da dimensão que a camada da rede neural vai receber. O parâmetro batch_first refere-se ao fato de que a rede neural normalmente recebe a informação em blocos, e não todas as sentenças de uma única vez. Ela processa sentença por sentença para realizar um treinamento mais eficiente.

Adição da Camada Linear

Agora, queremos adicionar uma camada linear que será a última camada da nossa rede neural.

        self.fc = nn.Linear(hidden_dim, vocab_size)

Criação do Método forward

Criamos o método __init__ e, agora, vamos criar a rede neural que utilizaremos para propagar as informações. Passaremos uma sentença ou um conjunto de sentenças, e queremos que a saída seja a próxima palavra prevista.

Com todos esses elementos e blocos que compõem nossa rede neural, vamos criar a rede neural que consumirá esses blocos. Vamos definir o método forward(self, x, hidden=None):. A informação que entra é x, que representa nosso vocabulário. O vocabulário será transformado em uma representação numérica vetorial, gerando a saída x, que passará para a próxima camada da rede.

    def forward(self, x, hidden=None):
        x = self.embedding(x)

Na próxima camada, teremos out, hidden saindo da camada LSTM.

        out, hidden = self.lstm(x, hidden)

Em seguida, passamos out = self.fc(out).

        out = self.fc(out)

Temos, assim, uma camada de rede LSTM seguida por uma camada linear. Com isso, conseguimos retornar essa informação.

        return out, hidden

Conclusão e Próximos Passos

Construímos nossa estrutura de rede neural, onde a informação entra, é transformada por embeddings, passa por uma camada de rede neural que lida com informações sequenciais e, depois, por uma camada linear. Por fim, geramos a saída diretamente.

No próximo vídeo, vamos discutir como passar essas informações. Já vimos o tipo de estrutura e pré-processamento necessário para a rede neural, mas no próximo vídeo veremos como passar efetivamente essas informações, considerando que normalmente são passadas em blocos. Até o próximo vídeo.

Sobre o curso Live coding: completando códigos com o Pytorch

O curso Live coding: completando códigos com o Pytorch possui 45 minutos de vídeos, em um total de 9 atividades. Gostou? Conheça nossos outros cursos de IA para Dados em Inteligência Artificial, ou leia nossos artigos de Inteligência Artificial.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Escolha a duração
do seu plano

Conheça os Planos para Empresas