Pergunta para agilistas: como a presença de redes neurais impacta o ciclo de vida do desenvolvimento?
Eu vi o tweet do Grady recentemente e li o artigo que referenciou, e ele me fez pensar. O treinamento de uma rede neural é uma espécie de programação? É o tipo de atividade que uma equipe ágil poderia planejar, estimar e executar em iterações? Ou é algo completamente diferente?
Antes de tentar responder a essa pergunta, vamos estabelecer nossas definições. O que é programação?
Alan Turing definiu a programação de computadores em seu artigo de 1936. Desde então, utilizamos sua definição sem alteração significativa. De acordo com Turing, um programa de computador é uma sequência de declarações simples da seguinte forma:
Dado que o sistema está no estado S1,
Quando ocorre o evento E,
Então, defina o sistema para declarar o estado S2 e invocar o comportamento B.
Essa declaração é obviamente uma transição de uma máquina de estado finito (finite state machine – FSM). E, na verdade, cada programa já escrito pode ser reduzido a uma sequência linear de tais declarações. Podemos, de fato, afirmar que o ato de programar computadores é simplesmente a enumeração de todas as transições dentro da máquina de estado finito que expressa o comportamento desejado pelo programador.
É claro que não usamos muito a linguagem FSM para escrever nosso código. Em vez disso, usamos a linguagem de Dijkstra: Sequência, Seleção e Iteração. No entanto, não é muito difícil provar que essas duas formas de expressão são equivalentes.
Como uma prova não matemática, considere que o formato da transição acima usa a mesma trinca Dado/Quando/Então que se tornou tão popular para a especificação de comportamento em Desenvolvimento Orientado a Comportamentos (Behaviour Driven Development – BDD). Poder-se-ia, portanto, fazer a afirmação de que BDD é simplesmente o ato de especificar as transições da máquina de estado que os programadores implementarão usando Sequência, Seleção e Iteração.
Como prova adicional, poderíamos olhar para a disciplina de Test Driven Development (TDD) em que nenhum código de produção pode ser escrito a menos que seja para satisfazer um teste unitário falho.
Esses testes unitários seguem sempre o padrão conhecido como Organizar, Agir e Afirmar (Arrange, Act, e Assert – AAA). Primeiro, organizamos o sistema para o estado apropriado para o teste. Então, agimos sobre o sistema. Em seguida, afirmamos que os resultados dessa ação estavam corretos.
Se você pensar cuidadosamente sobre isso, vai perceber que AAA é simplesmente uma expressão alternativa para o Dado/Quando/Então do BDD.
Dado que nós organizamos o sistema no estado testável,
Quando nós agimos sobre esse sistema,
Então esperamos que nossas afirmações sejam aprovadas.
E, claro, isso significa que TDD é apenas uma maneira de enumerar completamente todas as transições do FSM que expressam o comportamento desejado do programa que estamos escrevendo.
Portanto, não deveria ser surpresa que o ato de programar um computador seja o ato de definir uma máquina de estado finito. O que os programadores fazem é definir os estados, eventos e comportamentos necessários. Cada programa de computador, não importa quão simples ou complexo, nada mais é do que uma rede de estados, transições e comportamentos.
E isso é verdade, mesmo se o programa for uma rede neural.
Nossas expectativas são altas
Os últimos chavões são tipos como machine learning e deep learning. Esses termos representam o problema maciço de projetar e treinar uma rede neural. Mas se uma rede neural é realmente apenas um FSM, então por que nós temos que treiná-la? Por que simplesmente não especificamos todos os estados e transições como qualquer programador faria?
A resposta é que nós não conhecemos todos os estados e transições. Não temos como enumerá-los todos. E, assim, esperamos que o treinamento da rede neural faça com que ela infira esses estados e transições.
Na verdade, isso não está de todo certo. A rede neural pode não saber em que estado está. Também pode não saber que eventos está recebendo. Ela pode conhecer apenas os estados e eventos em um sentido estatístico. E esperamos que ela infira o comportamento correto dessas estatísticas.
Eu posso explicar isso usando uma rede neural com a qual você está intimamente familiarizado – seu cérebro.
Imagine que você está dirigindo um carro por uma rodovia em um momento em que há muito pouco tráfego. O que você vê à sua frente é estrada vazia. Sua velocidade é estável. O tempo está bom. O sol está brilhando acima. Você conhece seu estado. Você vê a estrada curva à frente. Você percebe que, dado o seu estado atual, você deve ajustar o ângulo da roda ligeiramente. Isso coloca você em um novo estado, e você sabe qual é esse estado. Seu comportamento é quase totalmente determinista. Você poderia escrever o FSM.
Agora imagine que você está dirigindo em uma rua movimentada da cidade na chuva. Há carros brigando por posição em torno de você. Os semáforos, as ruas de sentido único, a construção, os pedestres, as motos etc. A quantidade de dados que você deve processar em uma base de segundo a segundo é assustadora. Você deve continuar olhando para a esquerda e para a direita, verificando o carro à frente, o carro atrás, os semáforos e as placas. Você nunca sabe realmente em que estado você está. Você tem uma percepção estatística do seu estado. Você pode atribuir uma probabilidade aos estados nos quais você pode estar. O carro à sua frente dá um solavanco por alguma razão inesperada. Você rapidamente aumenta a pressão no seu freio. “Não”, você decide, “não estava parando… Apenas bateu em um buraco”.
De alguma forma, no caos de todos aqueles dados conflitantes, é esperado que você tome boas decisões de condução e execute comportamentos concretos. É o seu trabalho, como da rede neural responsável pelo carro, extrair e expressar ordem a partir do caos. Nenhum programador poderia escrever o FSM para fazer isso.
Treinando
Então, como você treina uma rede neural? A resposta simples a essa pergunta é que você apresenta a rede neural com uma sequência de eventos e, em seguida, “recompensa” ou “pune” o seu comportamento. Nesse caso, as palavras “recompensa” e “castigo” equivalem a incrementar ou decrescer um valor de “adequação”. A rede neural aprende a maximizar a “adequação” com base em eventos atuais e anteriores. Na verdade, a rede neural acumula dentro de sua memória uma máquina de estado finito difusa. Eu digo com efeito, porque você não pôde encontrar aquele FSM na memória da rede neural. Ele está oculto dentro das variáveis e coeficientes, e interconexões do programa. Está lá, mas está codificado de uma maneira que é muito difícil de decodificar.
Então, para responder à pergunta de Grady. O treinamento é uma programação de rede neural? O treinamento de uma rede neural é uma história ou um conjunto de histórias, para uma equipe ágil priorizar e executar? Você pode estimar quanto tempo levará para treinar uma rede neural?
A resposta para isso, pelo menos no momento, é claramente “Não”. Treinar redes neurais é algo de uma arte obscura. Pode haver uma ciência por trás disso, mas essa ciência ainda não é particularmente rigorosa.
Treinar uma rede neural não é nada parecido com programar. Não é a enumeração das transições em uma máquina de estado finito. Em vez disso, é uma tentativa de encontrar eventos suficientes para apresentar à rede neural, e uma correspondente tentativa de medir o quão apropriadamente a rede neural se comporta. E é essa última medida que é a mais repleta de incerteza e perigo.
Expectativas muito altas?
Será que vamos ter carros autônomos em breve? Vamos ver uma verdadeira inteligência de máquina num futuro próximo? Táxis autônomos estarão nos levando de um ponto arbitrário a outro em uma década?
Bem, vamos fazer um pouco de matemática.
O cérebro humano tem cerca de 1E14 neurônios. Cada neurônio se conecta a cerca de 1E3 outros neurônios. Se considerarmos cada conexão para corresponder aproximadamente a um bit de memória, então nossos cérebros têm na ordem de 1E17 bits de memória. Isso corresponde aproximadamente a 10 petabytes de RAM. Não confunda isso com disco ou SSD. Estamos falando de memória de acesso instantâneo. RAM.
Além disso, cada uma dessas 1E17 conexões pode mudar a cada 10ms ou mais. Isso significa que o cérebro humano pode processar aproximadamente 1E19 bits por segundo. Meu laptop, com 4 núcleos rodando em 2.8ghz, e um buss de 64 bits pode processar apenas 1E15 bits por segundo. Assim, o cérebro humano pode superar o meu laptop por quatro ordens de magnitude em pura capacidade de processamento.
Para imitar a capacidade de processamento do cérebro humano, eu precisaria de 10.000 laptops apple powerbook que estivessem intimamente conectados uns aos outros e 10 petabytes de RAM. Isso não é uma tecnologia de hardware que possuímos atualmente.
Na verdade, a estrutura de nossos computadores é tão vastamente diferente da estrutura do cérebro, que fazer a comparação é ridículo. O cérebro humano não é um computador em qualquer sentido que nós reconheceríamos a palavra. Ele não tem endereços, não tem instruções, ele não tem pilhas, números inteiros, números de ponto flutuante, busses, relógios mestres ou qualquer outra coisa que reconheceríamos como parte de um computador. Na verdade, o cérebro humano não é nem mesmo digital. É um processador de dados analógico composto de 100 bilhões de componentes que são maciçamente interligados.
Então, não. Não vamos ver Hal 9000 em breve. Johnny #5 não estará vivo em breve. Discando MycroftXXX no seu telefone não irá conectá-lo com Mike, o líder da revolução. Collossus e Guardian não vão coconspirar para assumir o mundo. Não espere encontrar Neo na Matrix. Não espere Kit falar no rádio de seu carro. Nossos computadores simplesmente não vão acordar em breve.
Táxis autônomos
Mas nossos computadores podem dirigir carros? Podemos fazer redes neurais suficientemente poderosas para conduzir com segurança passageiros humanos de qualquer ponto arbitrário para qualquer outro?
Vamos fazer um pouco mais de matemática. Meu cérebro pesa cerca de 1 libra. Como ele é 10.000 vezes mais poderoso do que o meu laptop, eu infiro que se o meu laptop fosse feito de neurônios, pesaria 0.0001 libra, ou um vigésimo de um grama. Essa é aproximadamente a massa do cérebro de uma abelha.
Na verdade, o milhão de neurônios no cérebro da abelha está embalado dez vezes mais densamente do que o nosso e opera muito mais rápido do que o nosso. O que significa que o cérebro da abelha é significativamente mais poderoso do que o meu laptop.
Então, você acredita que você poderia treinar o cérebro de uma abelha para dirigir seu carro? Com segurança? Legalmente? De qualquer ponto arbitrário para qualquer outro?
Talvez essa não seja uma pergunta justa. Então, vamos multiplicar esse tamanho de cérebro por um fator de 600. O cérebro de um gato pesa 30 gramas. Precisaria de 600 de meus laptops, intimamente conectados uns aos outros e terabytes de RAM a fim de imitar o cérebro de um gato. Você acredita que você poderia treinar seu gato para dirigir de um lugar para outro? Com segurança?
Ou é possível que, para treinar adequadamente uma rede neural para conduzir com segurança um carro, será necessária uma rede neural com as capacidades do cérebro humano?
***
Uncle Bob faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://blog.cleancoder.com/uncle-bob/2017/03/16/DrCalvin.html.