Curso Aberto de Inteligência Artificial

Bem vindo ao curso aberto de inteligência artificial. Nesse curso, vamos aprender sobre processamento de linguagem natural, aprendizado de máquina, aprendizado profundo, entre outros tópicos.

Introdução à Inteligência Artificial (IA)

A inteligência artificial (IA) é uma área da ciência da computação dedicada à criação de sistemas capazes de realizar tarefas que normalmente requerem inteligência humana. Isso inclui a capacidade de raciocinar, aprender, perceber, tomar decisões e, em alguns casos, demonstrar criatividade ou emoções. Desde sua concepção, a IA evoluiu de meras teorias e experimentos em laboratórios para se tornar uma parte integrante do tecido tecnológico e social do século 21.

Panorama do Século 20

A ideia de máquinas pensantes remonta a mitologias antigas, mas a concepção moderna de IA começa no século 20. Alan Turing, matemático britânico, é frequentemente citado como um dos pais da computação e da IA, especialmente por seu trabalho durante a Segunda Guerra Mundial e pela publicação do artigo "Computing Machinery and Intelligence" em 1950, no qual propõe o que agora é conhecido como o Teste de Turing.

Desenvolvimento Inicial e Desafios

Nas décadas de 1950 e 1960, o otimismo era alto, e muitos cientistas acreditavam que a IA alcançaria a capacidade humana em poucas décadas. Essa época viu o nascimento de programas que podiam realizar tarefas específicas, como jogar xadrez ou resolver problemas de álgebra. No entanto, os avanços iniciais enfrentaram obstáculos significativos, principalmente devido à limitação da capacidade de processamento dos computadores da época e à complexidade não antecipada de problemas aparentemente simples.

"Invernos" da IA

A história da IA no século 20 é marcada por períodos de grande entusiasmo seguidos por desilusões, conhecidos como "invernos" da IA. Durante esses invernos, o financiamento e o interesse na pesquisa de IA diminuíram significativamente devido às expectativas infladas não atendidas. Apesar desses desafios, o final do século 20 testemunhou avanços fundamentais, incluindo o desenvolvimento de algoritmos de aprendizado de máquina e redes neurais, que pavimentaram o caminho para o ressurgimento da IA.

Avanços e Descobertas no Século 21

O século 21 trouxe uma revolução na IA, alimentada por enormes avanços em poder computacional, disponibilidade de grandes conjuntos de dados (big data) e o desenvolvimento de algoritmos sofisticados de aprendizado de máquina e aprendizado profundo. Esses avanços permitiram que máquinas aprendessem a partir de dados, melhorassem com a experiência e realizassem tarefas complexas com precisão cada vez maior.

Hoje, a IA está em toda parte, de assistentes virtuais em smartphones a sistemas avançados de recomendação, diagnósticos médicos assistidos por IA, veículos autônomos e além. A IA também desempenha um papel crucial na ciência de dados, análise preditiva e na automação de processos de negócios, transformando indústrias inteiras.

Desafios Éticos e Futuros

Com os avanços da IA, surgem questões éticas e desafios significativos, incluindo preocupações com privacidade, segurança, viés algorítmico e o impacto no mercado de trabalho. A governança e regulamentação da IA tornaram-se tópicos de debate global, visando assegurar que seu desenvolvimento e aplicação beneficiem a sociedade como um todo.

Rumo ao Futuro

O campo da IA continua a avançar a um ritmo acelerado, com pesquisas focadas em tornar os sistemas de IA mais eficientes, transparentes e alinhados com valores humanos. A fronteira entre a inteligência artificial e a inteligência humana está se tornando cada vez mais difusa, prometendo um futuro onde a IA não apenas aumenta nossas capacidades mas também nos desafia a redefinir nossa compreensão da inteligência e da consciência.

Processamento de Linguagem

O Processamento de Linguagem Natural (PLN) é um campo da inteligência artificial que se concentra em tornar as máquinas capazes de entender e interpretar a linguagem humana da forma como é falada e escrita. A ideia é que as máquinas possam ler, decifrar, entender e até mesmo fazer sentido do idioma humano.

A linguagem humana é complexa, repleta de nuances, ambiguidades, expressões idiomáticas, e variações culturais. O processamento de linguagem busca abordar essas complexidades através de diversas subáreas, incluindo a análises baseadas em regras, análises estatisticas e aplicação de inteligência artificial.

Aplicações de Processamento de Linguagem

Classificação de Textos

Na classificação de textos o objetivo é classificar um texto em uma ou mais categorias. Por exemplo, classificar um e-mail como spam ou não spam, classificar um texto como positivo ou negativo, classificar um texto como notícia ou artigo de opinião, entre outros. Por meio da classificação de textos podemos seguir com diversas outras atividades como a análise de dados, por exemplo, saber quantas opiniões sobre um produto são positivas ou negativas, filtrar conteúdos trazendo apenas textos de um determinado tema, entre inúmeras outras possibilidades.

graph LR
    A[/Texto/] --> |Classificador| Classe

Exemplos:

graph LR
    A[/Email: Você ganhou um prêmio em dinheiro!!/] --> |Classificador| C[Spam]
    B[/Email: Você conseguiu finalizar o relatório solicitado?/] --> |Classificador| D[Não Spam]

graph LR
    D[/Eu gostei do filme./] --> |Classificador| Positivo
    E[/Eu achei o filme ruim./] --> |Classificador| Negativo

Clusterização

A clusterização é uma técnica de agrupamento de dados que visa dividir um conjunto de dados em grupos, ou clusters, de forma que os dados dentro de um cluster sejam mais semelhantes entre si do que com os dados de outros clusters. No contexto do processamento de linguagem, a clusterização pode ser usada para agrupar textos semelhantes, como notícias sobre o mesmo tópico, ou para agrupar palavras ou frases semelhantes.

graph LR
    t1[/Texto1/] -->|Clusterizador| C1((Cluster1))
    t2[/Texto2/] -->|Clusterizador| C1
    t3[/Texto3/] -->|Clusterizador| C1
    t4[/Texto4/] -->|Clusterizador| C2((Cluster2))
    t5[/Texto5/] -->|Clusterizador| C2

Identificação de Entidades

A identificação de entidades é o processo de identificar e classificar entidades nomeadas em um texto, como nomes de pessoas, organizações, locais, datas, e outras informações relevantes. Isso é útil para extrair informações de documentos, identificar tópicos em textos. Com essas informações estruturadas é possível realizar análises mais profundas, como por exemplo, identificar quais são as pessoas mais mencionadas em um conjunto de notícias, ou quais são os locais mais citados em um conjunto de documentos, entre outros

graph LR
    A[/Texto/] --> B([Identificador de Entidades]) --> Entidade1
    B --> Entidade2

Exemplo:

graph LR
    A[/Luiz viajou para a Austrália./] --> B([Identificador de Entidades]) --> C[Entidade: Luiz - Pessoa]
    B --> D[Entidade: Austrália - Local]

Tradução

A tradução é uma das aplicações mais conhecidas do processamento de linguagem, e envolve a conversão de texto de um idioma para outro. A tradução automática é uma ferramenta valiosa para a comunicação global, permitindo que as pessoas compreendam e se comuniquem em diferentes idiomas.

graph LR
    A[/Texto em Português/] --> B([Tradutor]) --> C[Texto em Inglês]

Exemplo:

graph LR
    A[/Eu gosto de estudar./] --> B([Tradutor]) --> C[I like to study.]

Sumarização

A sumarização é o processo de resumir um texto longo em um texto mais curto, mantendo as informações mais importantes. Isso é útil para extrair os principais pontos de um texto, permitindo que as pessoas obtenham uma visão geral do conteúdo sem precisar ler o texto completo.

graph LR
    A[/Texto Longo/] --> B([Sumarizador]) --> C[Texto Resumido]

Exemplo:

graph TD
    A["O artigo discute os efeitos das mudanças climáticas na biodiversidade.
    Ele aborda a perda de habitat, a extinção de espécies 
    e os impactos nas comunidades locais."] --> B([Sumarizador]) --> C[O artigo discute os efeitos das mudanças climáticas na biodiversidade.]

Busca de Respostas

A busca de respostas é uma aplicação que envolve encontrar respostas para perguntas em um texto. Isso é útil para encontrar informações específicas em documentos, artigos, ou páginas da web, sem a necessidade de ler o texto completo.

graph LR
    A[Pergunta] --> B([Buscador de Respostas]) --> C[Resposta]

Exemplo:

graph LR
    A[Quem foi o primeiro presidente do Brasil?] --> B([Buscador de Respostas]) --> C[Deodoro da Fonseca]

Geração de Textos

A geração de textos é o processo de geração automática de texto. Essa geração pode ser condicionada a uma entrada inicial, por exemplo especificação de um tema ou não, neste caso gerando um texto aleatório. Isso é útil para criar conteúdo automatizado, como notícias, respostas de chatbots, ou até mesmo obras de ficção.

graph LR
    B([Gerador de Textos]) --> C[Texto Gerado]

Exemplo:

graph LR
    B([Gerador de Textos]) --> C[O Brasil é um país localizado na América do Sul.]

Desafios do Processamento de Linguagem

Apesar das aplicações de processamento de linguagem serem simples de compreender, algumas delas envolvem desafios significativos.

Podemos criar um sistema de classificação de sentimento de textos (positivo, negativo ou neutro) por abordagens simples como a contagem de palavras positivas e negativas. Vejamos os exemplos abaixo:

  • Eu gostei muito do filme.
  • Eu achei o filme ruim.

A primeira frase contém a palavra "gostei" que é uma palavra positiva, enquanto a segunda contém a palavra "ruim" que é uma palavra negativa. Por meio de uma abordagem trivial podemos dizer que a primeira frase é positiva e a segunda é negativa. No entanto vejamos as duas frases abaixo:

  • Eu não gostei do filme.
  • Eu achei o filme ruim, mas o ator principal foi ótimo.

A primeira frase contém a palavra "gostei" que é uma palavra positiva, porém precedida pela palavra "não" que inverte o seu sentido. A segunda frase contém a palavra "ruim" que é uma palavra negativa, porém seguida pela palavra "ótimo" que é uma palavra positiva. Nos dois exemplos verificamos que contar as palavras positivas e negativas pode não é suficiente para determinar o sentimento da frase.

A área de processamento de linguagem é repleta de problemas deste e de muitos outros tipos, sendo que estes desafios crescem a medida que o problema tratado se torna mais complexo. Por isso é necessário fazer o uso de técnicas mais robustas que possam lidar com toda essa complexidade. Entre estas técnicas estão o uso de aprendizado de máquina (machine learning) e sua subárea aprendizado profundo (deep learning).

Aprendizado de Máquina

O aprendizado de máquina (machine learning, ML) é um ramo da inteligência artificial que permite que sistemas aprendam e melhorem a partir de experiências sem serem explicitamente programados para isso. Esta capacidade de aprender e adaptar-se torna o aprendizado de máquina uma ferramenta poderosa para aplicações complexas.

Supondo que fossemos escrever uma função para nos dizer se uma determinada frase possui um sentimento negativo, positivo ou neutro. Uma abordagem possível seria escrever um programa que analisasse a frase em busca de palavras negativas ou positivas. Uma implementação em python seria algo como:

def analisar_sentimento(frase):
    palavras_negativas = ["ruim", "horrível", "péssimo"]
    palavras_positivas = ["bom", "ótimo", "excelente"]
    
    palavras = frase.split()
    
    for palavra in palavras:
        if palavra in palavras_negativas:
            return "negativo"
        elif palavra in palavras_positivas:
            return "positivo"
    
    return "neutro"

Para alguns poucos exemplos essa abordagem poderia funcionar, como

  • O jantar foi bom.
  • O filme foi horrível.

No entanto podemos criar facilmente inúmeros exemplos que não seriam corretamente classificados, como

  • O jantar foi agradável. (palavra não existe na lista)
  • O jantar não foi bom. (negação)

Para resolver este problema teríamos que prever todas as palavras e combinações possíveis, o que seria inviável. Podemos dar exemplos desse tipo em diversos contextos diferentes:

  • Identificar se uma imagem é de um cachorro ou de um gato (teriamos que programar todas as combinações de pixels possíveis para cachorros e gatos)
  • Identificar as palavras que uma pessoa está falando (teriamos que programar todas as combinações de sons possíveis para cada palavra)

Uma forma de solucionar este problema é ao invés de criarmos regras explícitas para classificar os dados, utilizarmos um algoritmo que possa aprender essas regras automaticamente. Este é o princípio do aprendizado de máquina.

Conceitos Fundamentais

O aprendizado de máquina é baseado em algoritmos que recebem e analisam dados de entrada para fazer previsões ou decisões, sem intervenção humana. Os principais conceitos incluem:

  • Dados: Conjunto de exemplos usados para treinar, validar e testar o modelo. Os dados podem ser rotulados ou não rotulados.
  • Modelo: Uma representação matemática ou estatística dos dados. O modelo é ajustado durante o treinamento e usado para fazer previsões.
  • Treinamento: Processo de ajuste dos parâmetros do modelo usando dados de treinamento.
  • Validação e Teste: Avaliação da performance do modelo em um conjunto de dados separado do treinamento para verificar sua generalização.
graph TD
    Dados --> Treinamento
    Treinamento --> Modelo
    Modelo --> Previsões
    Modelo --> Validação
    Modelo --> Teste

Tipos de Aprendizado de Máquina

Aprendizado Supervisionado

No aprendizado supervisionado, os algoritmos aprendem a partir de dados rotulados, tentando prever a saída para dados novos baseando-se no aprendizado anterior. Este tipo de aprendizado é comumente utilizado em tarefas de classificação e regressão. Alguns exemplos de algoritmos de aprendizado supervisionado:

  • Regressão Linear
  • Regressão Logística
  • K-Nearest Neighbors
  • Support Vector Machines
  • Árvores de Decisão
  • Redes Neurais
  • Naive Bayes
  • Random Forests
  • Gradient Boosting

Aprendizado Não Supervisionado

No aprendizado não supervisionado, os algoritmos analisam e agrupam dados não rotulados baseando-se em semelhanças e diferenças, sem um objetivo específico de previsão. Este tipo de aprendizado é comumente utilizado em tarefas de agrupamento e redução de dimensionalidade. Alguns exemplos de algoritmos de aprendizado não supervisionado:

  • K-means
  • DBSCAN
  • Análise de Componentes Principais (PCA)
  • Autoencoders

Aprendizado por Reforço

No aprendizado por reforço, o modelo aprende a tomar decisões através de tentativas e erros, recebendo recompensas por ações corretas. Este tipo de aprendizado é comumente utilizado em tarefas de controle e otimização. Alguns exemplos de algoritmos de aprendizado por reforço:

  • Q-learning
  • Deep Q-Networks (DQN)
  • Policy Gradients
  • Actor-Critic
  • Proximal Policy Optimization (PPO)

Redes Neurais Vs Outros Algoritmos

Embora exista uma grande diversidade de algoritmos de aprendizado de máquina, as redes neurais têm se destacado em muitas aplicações devido à sua alta capacidade de aprender representações complexas e não-lineares dos dados em relação a outros algoritmos. Se corretamente treinadas, as redes neurais conseguem continuar aprendendo indefinidamente quanto mais dados são fornecidos. Devido a isso, redes neurais tem sido a principal escolha para muitas aplicações de aprendizado de máquina, como processamento de texto, reconhecimento de fala, visão computacional, entre outros.

Aprendizado Profundo

O campo do aprendizado de máquina tem evoluído rapidamente nos últimos anos, impulsionado em grande parte pelo desenvolvimento e aplicação de aprendizado profundo por meio de redes neurais. Estas são sistemas computacionais vagamente inspirados na estrutura neural do cérebro humano, projetados para reconhecer padrões e resolver problemas complexos de forma semelhante a como os humanos fazem. Este texto explora os conceitos fundamentais, tipos e aplicações das redes neurais no contexto do aprendizado de máquina.

Regressão Linear

A regressão linear é um modelo estatístico que examina a relação linear entre duas variáveis. É uma das formas mais simples de aprendizado de máquina e é frequentemente usada para prever o valor de uma variável dependente com base no valor de uma variável independente.

graph LR;
    x1(x1) -->|ω1| B((∑)) --> D(y);
    x2(x2) -->|ω2| B;

Regressão Logística

A regressão logística é um modelo estatístico usado para modelar a probabilidade de uma variável dependente categórica. Ela é uma extensão da regressão linear e é usada para prever a probabilidade de uma observação pertencer a uma classe específica.

graph LR;
    x1(x1) -->|ω1| B((∑)) --> C[σ] --> D(y);
    x2(x2) -->|ω2| B;

Redes Neurais Tradicionais

A regressão linear e a regressão logística são importantes modelos de aprendizado de máquina que podem lidar com uma diversidade lineares. No entanto, a maioria dos problemas do mundo real não é linear e, portanto, requer modelos mais complexos. Uma forma de resolver este problema é agregar multiplas regressões logísticas em um único modelo de forma a aprender diferentes padrões dentro de um mesmo conjunto de dados.

graph LR;

    x1(x1);
    x2(x2);
    x1 --> |ω11| s1;
    x2 --> |ω12| s1;
    x1 --> |ω21| s2;
    x2 --> |ω22| s2;

    subgraph Regressão Logística 2
        direction LR
        s2((∑)) --> sig2[σ] --> y2(y2);
    end

    subgraph Regressão Logística 1
        direction LR
        s1((∑)) --> sig1[σ] --> y1(y1);
    end
    

Aqui, ao utilizar duas regressões logísticas, acabamos tendo dois outputs y1 e y2. Como podemos resumir esses dois outputs em apenas um? Colocamos mais uma regressão logística:

graph LR;
    x1(x1);
    x2(x2);

    subgraph Regressão Logística 1
        direction LR
        s1((∑)) --> sig1[σ] --> h1(h1);
    end

    subgraph Regressão Logística 2
        direction LR
        s2((∑)) --> sig2[σ] --> h2(h2);
    end

    subgraph Regressão Logística 3
        direction LR
        s3((∑)) --> sig3[σ] --> y(ŷ);
    end
    
    x1 --> |ω11| s1;
    x2 --> |ω12| s1;
    x1 --> |ω21| s2;
    x2 --> |ω22| s2;
    h1 --> |ω31| s3;
    h2 --> |ω32| s3;

Este é o princípio das redes neurais tradicionais.

Aprendizado e Treinamento

O processo de treinamento de uma rede neural envolve a ajustagem dos pesos das conexões entre os neurônios. Isso é feito através de um processo iterativo chamado backpropagation, onde o erro entre a saída prevista e a real é calculado e usado para atualizar os pesos, a fim de minimizar esse erro ao longo do tempo.

graph LR;
    entradas("Entradas (x1, x2, ..., xn)");
    rede["Rede (ω11, ω12, ..., ωmn)"];
    saidas("Saídas (ŷ1, ŷ2, ..., ŷn)");
    erro("Erro");
    
    entradas --> rede --> saidas --> erro --> rede;

    subgraph rede["Rede (ω11, ω12, ..., ωmn)"]
        direction LR
        n1((" "));
        n2((" "));
        n3((" "));
        n4((" "));
        n5((" "));
        n6((" "));
        n7((" "));

        n1 --> n3;
        n1 --> n4;
        n1 --> n5;
        
        n2 --> n3;
        n2 --> n4;
        n2 --> n5;

        n3 --> n6;
        n4 --> n6;
        n5 --> n6;

        n3 --> n7;
        n4 --> n7;
        n5 --> n7;
    end


Desafios em Redes Neurais

As redes neurais tradicionais são capaz de trabalhar com varios tipos de relações não lineares em tarefas mais simples envolvendo imagens e textos. No entanto para tarefas mais complexas, as redes tradicionais enfrentam várias limitações devido à sua estrutura simples e à forma como processam as informações. Listamos abaixo algumas destas limitações

  • Flexibilidade no Tamanho da Entrada: Lidar com entradas de tamanho variável é problemático, pois as redes neurais tradicionais requerem um tamanho de entrada fixo.

  • Dependência Temporal e Sequencial: Dificuldade em processar sequências de dados ou dados temporais, como séries temporais ou linguagem natural, devido à sua incapacidade de manter estados ou informações de entradas anteriores.

  • Memória de Longo Prazo em Sequências Longas: Dificuldade em capturar dependências de longo prazo em sequências longas devido ao problema de dissipação do gradiente, que afeta a capacidade de aprendizado da rede.

  • Processamento de Dados Espaciais: Incapacidade de eficientemente processar dados com uma forte componente espacial, como imagens, devido à falta de consideração da localização espacial e da estrutura dos dados.

  • Eficiência Computacional com Dados de Alta Dimensão: Tratar eficientemente dados de alta dimensão, como imagens, pode ser computacionalmente custoso e ineficaz devido ao grande número de parâmetros necessários

  • Reconhecimento de Padrões Complexos: Identificar padrões complexos ou hierárquicos em dados, especialmente em grandes volumes de dados ou dados altamente dimensionais

Devido a estes e outros problemas foi necessário o desenvolvimento de novas arquiteturas de redes neurais, como as redes neurais convolucionais e as redes neurais recorrentes. Enquanto as redes convolucionais são capazes de lidar com problemas relacionados a dados espaciais, como imagens, as redes recorrentes são capazes de lidar com problemas relacionados a sequências temporais, como textos.