AI e Machine Learning: como aprendê-los visualmente

JavaScript Teacher Blocked Desbloquear Seguir Seguindo 7 de janeiro

Eu criei este tutorial como uma peça de nível básico em Inteligência Artificial .

Qualquer assunto novo deve ser apresentado em uma linguagem que corresponda ao nível de habilidade do aluno naquele momento. Portanto, não espere fórmulas matemáticas loucas ainda.

Confira meu livro CSS na Amazon (referência a todas as propriedades CSS)

Em particular, vamos dar uma olhada no Aprendizado Profundo do Machine Learning .

A profundidade de uma rede neural é determinada pelo número de camadas de entrada .

Os algoritmos de Aprendizado de Máquina avaliam a probabilidade de um determinado conjunto de dados em relação a um padrão específico.

Pensando em intervalos

Os neurônios em seu cérebro definitivamente não são digitais, mas se assemelham à lógica binária como estado ligado ou desligado . Mas no software, usamos um intervalo de valores .

O resultado de um ciclo de cálculo em uma operação AI é uma estimativa de precisão no intervalo entre 0,0 – 1,0 . Em última análise – um valor de saída é produzido com base em quão bem os dados de entrada correspondem a um padrão específico com 1,0 sendo 100% compatível (você raramente alcança isso, mas 0,95 – 0,97 é bom).

Esse padrão é geralmente treinado antes que resultados significativos possam ser produzidos. Mais sobre isso um pouco mais adiante neste tutorial. Mas primeiro, aqui está ML no seu mais básico.

Tudo começa com redes neurais – uma imitação de software da estrutura física dos neurônios em um cérebro.

Estrutura de Rede Neural Simples

Machine Learning na sua forma mais básica – uma rede neural muito simples.

Neste exemplo minimalista 1 camada de entrada consiste em 3 nós de entrada é mostrada.

Um conjunto múltiplo de entradas por camada é normalmente fornecido. Cada entrada é coletada de algum tipo de fonte. Como uma matriz de pixels de uma imagem usada para reconhecimento de rosto , por exemplo / ou qualquer outro dado. Depende do propósito do que você está tentando realizar com o seu algoritmo de IA .

Ambos os valores de entrada e saída são flutuantes pt. números entre 0,0 e 1,0 .

Logisticamente, durante a operação da rede, os dados são alimentados da esquerda para a direita. No entanto… A propagação de retrocesso é algumas vezes usada para otimizar a Rede Neural. É quando viajamos pela rede em sentido inverso. Mas, por enquanto, não precisamos nos preocupar com isso.

Soma

A soma de vários nós de entrada é exatamente o que parece. É a soma total dos pesos de todos os nós da camada de entrada anterior. Depois de calcular a soma, ela é passada para a função de ativação para processamento.

Função de Ativação

A função de ativação converte a soma dos valores de entrada em um valor de saída .

Mas como exatamente isso funciona?

Precisamos dar uma olhada em outro aspecto do Machine Learning.

Lembre-se dessas equações matemáticas do ensino médio? Parábolasalguém?

Fonte da imagem: https://pl.wikipedia.org/wiki/Plik:Catenary-pm.svg

Uma função de ativação é literalmente apenas uma equação matemática . Então, para aqueles com um fundo de matemática, isso pode ser um pouco mais fácil de entender. Se não, leia os diagramas visuais e o restante deste tutorial para que ele comece a afundar!

A razão pela qual não podemos usar equações lineares simples é devido às suas limitações.

Eles não são suficientes para a criação de redes neurais úteis .

As redes neurais são projetadas em torno de equações mais complexas. Por exemplo, a função Sigmoid (também conhecida como Logistic ) é bastante comum. ( Vamos dar uma olhada em alguns dos diferentes na seção abaixo. )

Todos eles assumem a forma de f (x) = … e depois trituram o valor de x de uma maneira única para essa função. Por que isso é importante e por que temos funções AF diferentes que se tornarão mais aparentes um pouco mais tarde.

O que acontece quando recebemos o nosso resultado?

O AF passa o valor calculado para o próximo nó e essencialmente como uma entrada parcial em uma das funções de ativação em um nó no próximo conjunto de entrada .

Você pode pensar nisso como um conjunto de múltiplas entradas. E passando o valor calculado para o próximo nó. É o gateway de valor entre os conjuntos de entrada.

Tipos diferentes de funções de ativação

Assim como existem diferentes tipos de equações matemáticas … existem diferentes tipos de funções de ativação.

Exatamente como eles processam os números para chegar ao valor final de saída está estreitamente relacionado ao treinamento de uma rede existente primeiro. Então, não podemos ir tão longe no assunto ainda, porque, em geral, o sistema não é baseado em algo tão simples como calcular e retornar um resultado numérico.

Mas o que podemos fazer – para aprofundar nossa compreensão, até agora – é dar uma olhada na representação visual de cada equação matemática por trás de diferentes funções de ativação!

Este é um tutorial visual . E para lhe dar uma idéia básica do que você vai enfrentar aqui está uma tabela do conjunto clássico de equações matemáticas nas quais muitas Funções de Ativação clássicas podem ser baseadas.

A AF mais básica é representada por f (x) = x ou a função de identidade .

Algumas fórmulas matemáticas básicas bem conhecidas.

Existem vários outros. Mas eles são um pouco mais complexos.

Essencialmente, essas funções são usadas para determinar o valor do nó resultante.

Como exatamente uma função de ativação determina seu valor?

Bem, isso é o que é um AF. Ele recebe uma entrada na forma de um número e produz um valor de retorno entre 0.0 e 1.0 ( às vezes, o intervalo é +/- infinito ). As fórmulas reais são descritas acima. Você pode reescrever essas equações como funções em Python , JavaScript ou qualquer outra linguagem de programação.

Se você gosta de matemática e tem muito tempo em mãos, vai adorar escrever essas funções em código! Mas muitas vezes você não precisa. E isso porque bibliotecas de AI já existentes cuidam disso para você. Dessa forma, você pode se concentrar em construir sua Rede Neural e treiná-la para um propósito específico.

Cada nó carrega um peso calculado

Então, essas funções de ativação produzem um valor.

A coisa mais importante a notar neste momento – cada ponto é um peso .

Esse peso mede a probabilidade de um determinado padrão ser correspondido.

Mas várias camadas de conjuntos de entrada são possíveis, conforme mostrado no próximo exemplo.

Nós em uma Rede Neural ligeiramente mais avançada conectada uns aos outros.

Cada nó único se comunica com cada nó único na próxima camada de entrada que compõe essa rodovia de comunicação conectada em cruz.

O número de itens em cada camada é arbitrário. Não precisa ser o mesmo número mostrado no diagrama acima. Dependendo do problema que você está tentando resolver.

Será preciso alguma intuição e criatividade para determinar o número de nós de entrada que você deseja usar em cada camada. Mas até mesmo resolver o mesmo problema pode ser realizado por diferentes estruturas de redes neurais.

Devido à natureza não linear dos cálculos, esse processo é ambíguo.

Camadas Ocultas

Acabamos de discutir como uma rede neural pode ter várias camadas de entrada . Eles podem ser considerados linhas verticais de nós.

Todas as camadas internas entre a primeira linha de entrada e o nó de saída são geralmente chamadas de camadas ocultas . Isso faz sentido porque é aqui que a maior parte do trabalho de processamento do AI é feito. Basicamente é a caixa de mistério da IA.

Diferentes tipos de padrões de rede neural

Às vezes, ML pode parecer muito com a criação de um padrão de rede para corresponder aos padrões.

Redes neurais vêm em diferentes formas e formas.

Diferentes tipos de estruturas de redes neurais são mais aptos a resolver tipos específicos de problemas associados à sua estrutura.

OK – Mas como escrevemos o código?

Isso foi muita teoria.

Mas como podemos implementá-lo no código?

Você pode usar uma biblioteca como Tensorflow.js para começar.

Mas isso não vai adiantar, porque ainda há muito para cobrir.

OK – Mas como isso produz resultados significativos?

Nós discutimos a estrutura de uma rede neural até este ponto.

Nós conversamos sobre funções de ativação , entradas de dados e camadas ocultas .

Também falamos sobre pesos passados para lá e para cá das conexões simuladas.

Para que um algoritmo de Aprendizado de Máquina não-linear produza qualquer resultado sensato, primeiro ele precisa ser treinado em um conjunto de dados preexistentes.

Você sempre começa escolhendo dados para treinar seu algoritmo de IA.

Isso depende do problema que você está tentando resolver.

Se você quiser reconhecer números em uma imagem, comece com imagens de dígitos.

Reconhecendo números de uma captura de tela

O exemplo clássico da IA é ensinar uma rede neural a reconhecer números entre 0 e 9 . Da mesma forma que você pode treinar um algoritmo de máquina para reconhecer letras AZ ou mesmo partes de um rosto humano – um olho ou boca em uma fotografia também representa um tipo particular de forma ou padrão que é comum a todos os humanos, mas pode aparecem ligeiramente diferentes.

Lembre-se de que tudo o que estamos lidando aqui são padrões .

Quando o algoritmo reconhece um padrão, nunca é uma correspondência de 100%. Mas quanto mais nos aproximamos de 1,0 (100%), maior a probabilidade de que a forma que procuramos represente aquilo que foi treinado para reconhecer.

Se usássemos uma fonte padrão, nem precisaríamos fazer nenhum trabalho de IA. Poderíamos simplesmente digitalizar cada dígito para o padrão exato de pixels. Mas o ponto chave da IA é reconhecer um padrão na obscuridade .

Primeiro, precisamos ter algum tipo de meio que será usado como um dado de treinamento. Cada dígito pode ser representado por uma imagem:

Os mesmos dígitos escritos várias vezes produzem um padrão ligeiramente diferente. Imagem tirada da demonstração do AI do JavaScript localizada em http://myselph.de/neuralNet.html

Você pode reconhecer facilmente cada dígito de vista. Mas um algoritmo de IA precisa ser treinado para reconhecer padrões similares, porque, embora sejam semelhantes, ainda não são 100% idênticos.

Para conseguir isso, podemos dividir o padrão primário em blocos menores e implementar algo conhecido como extração de recursos .

Extração de recursos

Para identificar um dígito, o algoritmo implementa um sistema de extração de características que divide padrões comuns em contrapartes relevantes para a construção do dígito completo / símbolo / letra / etc.

A essência de um padrão permanece a mesma. Por exemplo, 0 é principalmente um círculo – você pode dividi-lo em padrões menores com um arco em cada um dos lados:

Se apenas pudermos treinar nosso algoritmo para reconhecer esses 4 padrões únicos e verificar sua presença dentro da área localizada de uma imagem, podemos calcular a quantidade de certeza com a qual se pode dizer que pode ser um zero .

É o mesmo para outros dígitos. O dígito 1, por exemplo, é uma barra vertical única. Ou talvez com uma linha menor em um leve ângulo no topo.

O número 2 é metade de um círculo no topo, uma linha diagonal e uma linha horizontal .

O número 3 pode ser dividido em dois padrões semi-arqueados .

O número 4 pode ser considerado como 3 linhas: vertical , horizontal e diagonal .

…e assim por diante.

E se for um dígito escrito à mão ? Ainda tem as mesmas propriedades daquele dígito: as mesmas arestas , os mesmos loops .

E se o dígito aparecer em uma placa de limite de velocidade na rua, de um ângulo indireto em uma fotografia? Muito parecido com a nossa própria visão, a IA deveria ser capaz de acomodar algum tipo de termo de erro.

Isso é cinco , três ou oito ?

Experimente esta demo AI JavaScript que permite desenhar algo na tela e fazer com que o algoritmo pré-treinado lhe diga o que você acabou de desenhar.

O algoritmo tentará oferecer a melhor correspondência, mesmo que o que você desenhe não seja realmente um número. Ainda assim, você pode ver o intelecto artificial em ação tentando fornecer a aproximação mais próxima possível.

O que o conjunto treinado parece?

Aqui está um trecho dos dados de treinamento do algoritmo. É apenas uma lista de pesos armazenados em uma matriz muito longa ( milhares de valores ):

 // Os pesos da rede neural (pesos unitários e desvios unitários) // o treinamento foi feito em Matlab com o conjunto de dados MNIST. 
// este dado é para uma unidade 784-200-10, com não linearidade logística
// no oculto e softmax na camada de saída. A entrada é uma
// [-1; 1] imagem de nível de cinza, plano de fundo == 1, 28x28 pixels linearizados
// na ordem das colunas (isto é, coluna1 (:); coluna2 (:); ...) saída i-ésima
// sendo o máximo significa que a rede acha que a entrada codifica
// (i-1) os pesos abaixo mostraram uma taxa de erro de 1,92% no teste
// conjunto de dados (9808/10000 dígitos reconhecidos corretamente).
 seja w12 = [[-0,00718674, 0,00941102, -0,0310175, -0,00121102, -0,00978546, -4,65943e-05, 0,0150367, 0,0101846, 0,0482145, 0,00291535, -0,00172736, 0,0234746, 0,0416268, 0,0315077, -0,00252011, 0,0163985, 0,00853601, 0,00836308 , 0,00692898, 0,0215552, 0,0540464, 0,0393167, 0,0668207, 0,0232665, 0,031598, 0,0143047, 0,0156885, -0,0269579, -0,00777022, 0,0397823, -0,00825727, 0,0212889, -0,00755215, 0,0353843, 0,0297246, ... 
 / * ... Milhares de pesos seguem mais ... * / 

O código-fonte completo não caberia neste artigo. Mas os conjuntos são geralmente muito longos, mesmo para o que parece ser testes triviais.

Entrada de imagem em pintura na rede neural

Este código foi retirado da função recognise () escrita em JavaScript.

Foi tirado da demonstração em http: // myselph.de

Você pode conferir todo o código-fonte aqui.

 // para visualização / depuração: pinte a entrada para a rede neural. if (document.getElementById ('preprocessing'). checked == true) 
{
ctx.clearRect (0, 0, canvas.width, canvas.height);
ctx.drawImage (copyCtx.canvas, 0, 0);
para (var y = 0; y <28; y ++) {
para (var x = 0; x <28; x ++) {
var block = ctx.getImageData (x * 10, y * 10, 10, 10);
var newVal = 255 * (0,5 - nnInput [x * 28 + y] / 2);
para (var i = 0; i <4 * 10 * 10; i + = 4) {
block.data [i] = newVal;
block.data [i + 1] = newVal;
block.data [i + 2] = newVal;
block.data [i + 3] = 255;
}
ctx.putImageData (bloco, x * 10, y * 10);
}
}
}

Esse trecho parcial de código “cola” a entrada de imagem (um desenho à mão livre) que foi anteriormente dividido em blocos de 10 x 10, armazenando valores médios de escala de cinza para essa área da imagem.

Ele irá então verificá-lo contra o conjunto treinado e depois de analisar as somas e comparações de médias contra ele retornará a probabilidade do resultado em termos de quão próximo o seu desenho de tela HTML corresponde a um dígito específico.

Palavras finais

Inteligência Artificial é um assunto vasto. Existem diferentes tipos de padrões de aprendizado de máquina e tutoriais saindo todos os dias. Este tutorial deve servir apenas como uma introdução para alguém que está apenas começando!

Siga-me no Twitter para brindes de livros gratuitos

Siga- me no @ js_tut onde eu postar tutoriais freemium JavaScript, ferramentas de CSS on-line e brindes de livros grátis de host!

A conta do Tidal Wave é a que dá meus livros gratuitamente.