Algoritmos, Inteligência Artificial e... esse ano vou começar uma academia
sexta-feira, 7 de janeiro de 2022
Atualizado às 07:35
Preliminares
De certa forma, o ano de 2022 começa do mesmo modo que 2021, 2020, 2019 e outros anos pregressos, ou seja, começa sempre pelas resoluções para o Ano Novo. Que me conteste quem não tem as suas. "Esse ano vou emagrecer!", "Não vou mais faltar na academia!", "Vou me apaixonar!", "Vou aplicar minhas economias!". Talvez essas sejam algumas das mais comuns e que, ao passar do ano, tendem a desvanecer. Não vou tentar aqui explicar os eventuais motivos e porquês destas resoluções não vingarem, mas lanço uma dica "computacional" que talvez ajude a explicar esse fenômeno. Vou usar essa dica como um gancho para tentar clarear uma das dúvidas mais frequentes sobre tecnologia que é a definição de algoritmo. "Estico a corda" um pouco para nos aventurarmos pelo tópico do momento, IA, Inteligência Artificial. Comecemos 2022 pelo paço número um.
Algoritmo
"Um algoritmo é uma sequência de passos bem definidos que leva a execução de uma tarefa". Não me lembro mais de quem seria essa frase, mas tenho essa definição "grafada em pedra" na minha memória, do mesmo modo como todo cientista da computação tem também essa mesma ou uma outra frase bem semelhante. Frases como essa são repetidas como um mantra desde os primeiros dias de aula de disciplinas de Programação de Computadores. Penso que para a maioria dos techno people, essa frase mística só é perfeitamente entendida depois que implementamos e criamos dezenas, centenas de algoritmos. Acreditem, ninguém entende frases assim do dia para a noite e, por isso, é sempre providencial reforçar o que sabemos sobre esse tema.
Comecemos com um algoritmo clássico, também comentado nos primeiros dias de aula: fritar um ovo. Todos nós sabemos como fritar um ovo, mas experimentem "escrever uma sequência de passos bem definidos que leva a execução" de um ovo frito. Essas instruções devem ser seguidas por qualquer pessoa que não saiba fritar um ovo e devem alcançar o objetivo. "Coloque óleo numa panela e frite o ovo." Esse não é um algoritmo pois não tem os passos bem definidos. Não define o tipo de panela (frigideira), a quantidade de óleo, a altura da chama, o tempo de fritura e tampouco que devemos tirar a casca do ovo. Sério? Tirar a casca? Acreditem, essa etapa deve ser explicada para muita gente.
Vamos a um exemplo mais techno: um algoritmo para um carro autônomo fazer curvas. "Ligue a seta para a direção desejada. Confira nos retrovisores se o trânsito atrás de você está livre. Desloque o veículo para a direção desejada". Acho que o leitor percebeu que eu não esqueci da seta, no entanto não mencionei se é uma curva para esquerda ou para direita, como também o que fazer se tiver um outro veículo ao lado, qual deve ser a velocidade para fazer a curva, se é só uma curva leve ou se é uma conversão... Vejam, esse algoritmo simples acima não funciona. Não é específico. Não é genérico para todas as situações. Como escrever um algoritmo que aborde todas as possibilidades?
Então, caro leitor, será que nossas resoluções de Ano Novo não poderiam ser mais específicas? Será que não deveríamos trocar a frase "Não vou mais faltar na academia!" para a seguinte: "Irei a academia semanalmente às segundas e quartas-feiras entre 7 e 8h, a partir do dia 3 de janeiro", por exemplo? Será que esse não é um motivo pelo qual nossas resoluções de Ano Novo falham?
A objetividade e, por vezes, o baixo nível de detalhamento, são dois grandes desafios para a Computação e obviamente transformaram-se em grandes fontes de trabalho também. Objetividade de detalhamento "são as praias" dos programadores. Escrever algoritmos é uma das tarefas mais importantes e complexas da Computação: a programação de computadores. Mesmo os algoritmos mais simples podem ser fontes de exceção que, se não tratadas, impedem o software de funcionar. Merece destaque, por exemplo, o algoritmo de Ronald Fagin (IBM Research), Amnon Lotem, e Moni Naor (Weizmann Institute of Science), de apenas 12 linhas, que recebeu uma das maiores honrarias da Computação, o Gödel Prize de 2014. Hoje esse pequeno e poderoso código, responsável pela agregação de múltiplas fontes de dados, serve a milhares de sistemas e aplicações que manipulam big data, ou seja, grandes repositórios de dados complexos. São 12 linhas que incrivelmente bem boladas que geram uma riqueza tremenda na indústria tech.
Algoritmos são como receitas culinárias. Quando implementados no computador recebem o nome de programas ou softwares. Esses softwares devem normalmente responder a um domínio amplo de situações, obviamente, sem causar erros. Falhas nos programas (algoritmos) são normalmente atribuídas a falhas nos testes destes softwares. Talvez o primeiro exemplo de uma falha perigosa de programação que impactou a mídia foi uma falha no sistema de alerta de segurança soviético em 1983. Foi um software bug que quase causou a terceira guerra mundial [Wired]. O sistema russo acusou o deslocamento de cinco mísseis balísticos, provenientes dos EUA, em direção a antiga União Soviética; isso em meio a Guerra Fria. Na ocasião, o Ten. Cel. Stanislav Petrov, evitou a retaliação russa julgando que o alerta só poderia ter sido causado por um erro no sistema. O erro foi proveniente de reflexos solares de nuvens no satélite espião e que foram confundidos pelo software como mísseis intercontinentais. Hoje falhas graves de software ocorrem com grande frequência e tendem a aumentar dada a dependência tecnológica das instituições e também das pessoas nos vários tipos de software.
No imaginário da população o computador tem, muitas vezes, poderes e capacidades semelhantes aos do ser humano, os quais poderiam, por exemplo, responder a problemas com mais eficiência e com mais "sabedoria" que nós, mas isso certamente não é verdade. Os algoritmos devem prever e serem programados, codificados, para atuar a cada situação diferente. Para cada tarefa automatizada existe um código escrito por humanos que detalha todas as situações. Por exemplo, a tela que você vê agora no seu computador tem, aproximadamente, 2.500X1.500 pontos luminosos, os pixels. Ou seja, são mais de 3,7 milhões de pontos que, por meio de software (códigos escritos manualmente) são coloridos, um a um. Imagine quantas tarefas de colorir pontos são executadas numa simples varredura do mouse pela tela?
Uma das medidas de referência para a complexidade de software é a quantidade de linhas de códigos usadas. Nestes casos a medida SLOC (Software Lines Of Code) é usada. Essa medida oferece uma dimensão da quantidade de pessoas-hora que trabalharam escrevendo esses algoritmos. Segundo o website Information is Beatiful [Information], o navegador Google Chrome tem aproximadamente 6,7 milhões de linhas de código, o sistema operacional Android que equipa 70% de todos os telefones móveis [Statcounter] 12 milhões, o Facebook 62 milhões, enquanto que um carro de luxo, como o Mercedes-Benz S-Class tem mais de 30 milhões de linhas. E quanto é isso? Para se ter uma ideia da demanda temporal para produzir esses softwares, um excelente programador pode produzir 6 mil linhas de código pronto ao ano. Isso sem contar todos os testes que ele deve ter feito sobre seu próprio código além de todos os códigos descartados que, eventualmente, não funcionaram ou não foram usados. Ou seja, para produzir essas 30M de linhas em um ano seriam necessárias 500 pessoas trabalhando.
Outra situação que normalmente atenta contra essa Caixa de Pandora que podem ser os algoritmos é a complexa hierarquia de tarefas envolvida na produção de software. Desde a sua concepção, da ideia de uma tarefa, estão envolvidas várias pessoas e equipes. As pessoas que concebem o problema, as que concebem a sua solução (o algoritmo), o Lider de Projeto, o Engenheiro de Software e sua equipe, o Lider de Produção e os programadores. Isso sem contar as equipes de Bancos de Dados, de teste de software, de interface com o usuário, entre outras. Nessa longa cadeia de produção de software certamente o que foi solicitado no início do projeto poderá não ser atendido na sua conclusão.
"Mas eu pensei que a Inteligência Artificial evitasse todo esse trabalho de programar as situações possíveis, de antever todos os potenciais problemas...". Pois é ... seria bom mesmo se isso acontecesse, mas a IA também precisa ser programada, embora os níveis de programação sejam diferentes. Vejamos...
IA e Algoritmos
O que atualmente chamamos de IA pouco tem de inteligência e muito tem de aprendizado e repetição de situações anteriores. A abordagem que domina a IA atualmente é a que chamamos de aprendizado de máquina (AM), ou seja, ensinamos os computadores o que já conhecemos e eles repetem. Sim, já é um grande avanço, mas que ainda em nada se assemelha a uma máquina inteligente, pois as máquinas definitivamente ainda nada criam de novo e, além disso, não são facilmente adaptáveis a contextos diferentes. Por exemplo, sobre contexto: as redes sociais mostram os mesmos tipos de mensagens dos mesmos autores, seja numa segunda-feira à tarde, ou num domingo pela manhã. Oras, não seria mais interessante se num domingo recebêssemos notícias mais amenas, por exemplo, de eventos culturais, menos notícias de assuntos relacionados ao nosso trabalho e mais notícias de lazer?
Para entendermos melhor essa relação da IA com os algoritmos iremos fazer uma viagem aos principais estágios de desenvolvimento das abordagens de IA. Divido essa aventura épica em 3 fases: 1) a fase das regras; 2) a fase do aprendizado de máquina e; 3) a fase das redes neurais. Essas três fases também alteram o modo de construção de software, o modo de programação.
IA baseada em regras
Um sistema que realiza IA por meio de um modelo baseado em regras é conhecido como sistemas de IA baseados em regras. Um sistema de IA baseado em regras produz resultados predefinidos que são baseados em regras codificadas por humanos. Normalmente essas regras são declarações codificadas no modelo "se-então". Ou seja, se acontecer tal coisa então faça essa tarefa. Para exemplificarmos a utilidade desta abordagem, muitos sistemas de diálogos homem-máquina foram implementados como sistemas baseados em regras. Por exemplo, sistemas de telefonia que oferecem opções ao usuário; o usuário responde; o sistema capta palavras-chave e gera outras opções, em níveis mais específicos, segundo esse novo status. Esses sistemas conversacionais, também chamados de chatbots, são muito usados no atendimento ao usuário de websites. Sistemas que usam regras são classificados como sistemas determinísticos, ou seja, eles sempre devem ter uma mesma e única resposta para cada opção. Os antigos sistemas especialistas foram um marco para os sistemas de regras. Esses sistemas funcionam bem para situações de domínio fechado em que o número de regras é pequeno. Conforme os sistemas ficam mais complexos há necessidade de criação de novas regras e a possibilidade dessas regras entrarem em conflito entre si aumenta. Essas duas situações são impeditivas para essa forma de IA abarcar problemas complexos e, consequentemente, os projetos de IA que usam sistemas de regras não são escaláveis e não são mais o tipo dominante.
IA baseada em Aprendizado de Máquina
Diferentemente dos sistemas baseados em regras, os sistemas baseados em aprendizado de máquina buscam seu conhecimento em fontes de dados e não em regras propostas e codificadas por humanos. Nos sistemas de IA realizados por meio de aprendizado de máquina são criados modelos (de classificação, de inferência, de reconhecimento, de fala, etc.) a partir de computações feitas sobre grandes conjuntos de dados. Por exemplo, se uma imobiliária tiver cadastrado um grande número de imóveis, com todos os detalhes de tipos de cômodos, valores dos alugueres e dados dos inquilinos, um sistema computacional poderá organizar esses imóveis em grupos, por exemplo, que mostrem que numa determinada região um imóvel de três quartos deve estar numa determinada faixa de aluguel, diferente, por exemplo, de um imóvel do mesmo tamanho noutra região. Esse é um exemplo simples, inclusive dominado por humanos, mas compradores usuais de mercados online sabem bem como os sistemas varejistas usam seus perfis de consumidores para oferecer produtos de potencial interesse para cada perfil de consumidor. Algoritmos de classificação são uma grande força motriz nos sistemas que usam aprendizado de máquina. Nestes sistemas, um grande volume de dados é usado para treinar um classificador, para criar um modelo. Classificador treinado, quando um novo dado chega ao sistema ele o classifica. Classifica sempre de acordo com o que aprendeu. AM resolve muita coisa, mas, por vezes, gera confusão. O aprendizado enviesado é uma dessas fontes de problemas [SRINIVASAN, CHANDER 2021]. O aprendizado de um classificador deve ser feito sobre uma base de dados que reflita o universo de aplicação. Imaginemos, por exemplo, um sistema de agenciamento de empregos específicos para a área de Enfermagem. Se um gênero específico, A, tem uma quantidade maior de cadastros, esse gênero poderá ter mais ofertas de emprego e, provavelmente, maior estabilidade no trabalho apenas devido a uma diferença numérica com outro gênero, B. Assim, o sistema mal equilibrado e mal treinado, poderá aprender que recrutar pessoas do gênero A é preferível a recrutar pessoas do gênero B pois a rotatividade seria maior. Percebam como os problemas de programação persistem. Estes problemas talvez pareçam mais complexos na abordagem de AM, mas definitivamente estão presentes, como nos sistemas baseados em regras. Uma vantagem da abordagem de AM sobre os sistemas de regras é que estes sistemas são escaláveis e não são determinísticos, ou seja, podem apresentar graus distintos de certeza sobre a resposta dada. Normalmente são sistemas que usam de recursos estatísticos ou probabilísticos, oferecendo assim uma segurança extra do vínculo matemático com a certeza do resultado. Outra característica interessante do AM é que para os vários algoritmos usados nos vários tipos de aprendizagem existem diversas implementações possíveis, como se fossem vários motores distintos, que você adapta às necessidades dos seus problemas. Ou seja, o mundo de AM é composto por programas pré-fabricados, mas que precisam de ajustes antes de serem usados. É uma pena que nesta área existam poucos "mecânicos" que sabem ajustar esses motores.
IA baseada em Redes Neurais
Para completar, temos a "febre" do momento: os sistemas de IA por meio de redes neurais. Essas redes são hoje grandes arranjos formados de simulações computacionais de neurônios. As ciências do cérebro já mostraram como nossos neurônios funcionam. A Computação se apropriou desse conhecimento e os modelou em software. As redes neurais surgiram como arranjos de dezenas, centenas de neurônios programados em software. Os vários tipos de arranjo destes neurônios dão origem a vários tipos de redes, tais como: Perceptrons, Feed Forward Network, Redes de Hopfield e Rede Neural Convolucional. Estes são alguns modelos, entre vários outros mais recentes. Em tese, esses modelos de redes têm os neurônios de entrada, os neurônios de saída, além de outros numa camada intermediária que fazem a maior parte do processamento trocando informações entre si. Recentemente tivemos a expansão destes modelos com redes que hoje acomodam milhões de neurônios. Essas são as chamadas redes neurais profundas, deep neural networks. Se já era difícil acompanhar a troca de informações entre os neurônios de modelos mais simples, imaginem acompanhar a troca de informações nessas redes profundas, com milhões de neurônios. A explicabilidade dessas redes é hoje um dos temas de pesquisa da Computação [POPE et al. 2019].
Por meio dessa jornada algorítmica podemos perceber que a programação de computadores nos desafia em vários níveis de abstração, do nível mais elementar da criação de comandos simples, incluindo aqui entidades modulares de média complexidade (tais como os neurônios), até níveis mais complexos que contam com a interligação de vários destes módulos e modelos formando uma cascata de software por vezes composta de milhões de linhas de código. Se toda essa complexidade tende a afastar o usuário desta caixa de Pandora, para nós, cientistas da Computação, essa complexidade apresenta-se como um desafio para a explicabilidade destes sistemas. Desafio esse que trará maior confiabilidade ao código e, consequentemente, um crescimento do uso destas metodologias.
Ooops! 22h15... lá se foi mais um dia sem academia. Melhor definir essas resoluções de Ano Novo com mais objetividade e... segui-las à risca.
Referências bibliográficas
Wired. Set. 26, 1983: The Man Who Saved the World by Doing ... Nothing. Disponível aqui de 26 de setembro de 2007. Último acesso em 30 de dezembro de 2020.
Information. Codebases: Milions lines of code. Disponível aqui. Último acesso em 30 de dezembro de 2020.
Statcounter. Mobile Operating System Market Share Worldwide. Disponível aqui. Último acesso em 30 de dezembro de 2020.
Gödel. Disponível aqui. Último acesso em 30 de dezembro de 2020.
SRINIVASAN, Ramya; CHANDER, Ajay. Biases in AI systems. Communications of the ACM, v. 64, n. 8, p. 44-49, 2021.
POPE, Phillip E. et al. Explainability methods for graph convolutional neural networks. In: Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition. 2019. p. 10772-10781.
*Evandro Eduardo Seron Ruiz é professor associado do Departamento de Computação e Matemática, FFCLRP - USP, onde é docente em dedicação exclusiva. Atua também como orientador no Programa de Pós-graduação em Computação Aplicada do DCM-USP. Bacharel em Ciências de Computação pela USP, mestre pela Faculdade de Engenharia Elétrica da UNICAMP, Ph.D. em Electronic Engineering pela University of Kent at Canterbury, Grã-Bretanha, professor Livre-docente pela USP com estágios sabáticos na Columbia University, NYC e no Instituto de Estudos Avançados da USP (IEA-USP). Coordenador do Grupo de Pesquisa "Tech Law" do IEA-USP. Membro fundador do Instituto Avançado de Proteção de Dados - IAPD.