Fronteira de decisão: Perceptron
Clique no gráfico para adicionar um ponto à classe selecionada.
Classe AClasse BFronteira de decisão
Épocas0
Acertos—
Erro médio—
LABORATÓRIO DE FRONTEIRAS
Monte grupos A e B, treine uma rede e veja como a fronteira de decisão muda entre um Perceptron e uma MLP.
Clique no gráfico para adicionar um ponto à classe selecionada.
O primeiro ponto do conjunto percorre a rede abaixo.
Última amostra usada no treinamento.
Treine uma época para visualizar as contas.
Veja o erro médio diminuir enquanto a taxa de acerto aumenta.
Em um perceptron de camada única, qualquer ativação é aplicada depois da mesma soma linear. Ela muda a forma da saída, mas a fronteira continua sendo uma reta. Para separar este cenário, selecione MLP · camada oculta e uma ativação diferenciável.
CÓDIGO DIDÁTICO
O exemplo abaixo treina um Perceptron com pontos A e B e também devolve a equação da reta aprendida.
// Pontos com duas coordenadas e uma classe conhecida.
const pontos = [
{ x: [-0.8, 0.6], classe: "B" },
{ x: [-0.4, 0.2], classe: "B" },
{ x: [0.3, 0.5], classe: "A" },
{ x: [0.7, -0.2], classe: "A" }
];
// Converte os nomes A e B nos alvos numéricos usados no treino.
function normalizarClasse(classe) {
return classe === "A" ? 1 : 0;
}
// Calcula o potencial de ativação u para um ponto do plano.
function calcularPotencial(entradas, modelo) {
return modelo.w1 * entradas[0] + modelo.w2 * entradas[1] + modelo.bias;
}
// O degrau escolhe o lado da fronteira em que o ponto está.
function ativacaoStep(u) {
return u >= 0 ? 1 : 0;
}
// Produz a resposta ŷ sem modificar o modelo.
function classificar(entradas, modelo) {
const u = calcularPotencial(entradas, modelo);
return { u, yChapeu: ativacaoStep(u) };
}
// Aplica a regra de aprendizagem em somente um ponto.
function ajustarPesos(ponto, modelo, taxa) {
const y = normalizarClasse(ponto.classe);
const { yChapeu } = classificar(ponto.x, modelo);
const erro = y - yChapeu;
modelo.w1 += taxa * erro * ponto.x[0];
modelo.w2 += taxa * erro * ponto.x[1];
modelo.bias += taxa * erro;
return erro;
}
// Uma época apresenta todos os pontos uma vez.
function treinarEpoca(pontos, modelo, taxa) {
return pontos.reduce(
(erros, ponto) => erros + Math.abs(ajustarPesos(ponto, modelo, taxa)),
0
);
}
// Repete épocas até não haver erros ou o limite ser atingido.
function treinar(pontos, limiteEpocas, taxa) {
const modelo = { w1: 0.2, w2: -0.1, bias: 0 };
for (let epoca = 1; epoca <= limiteEpocas; epoca++) {
const erros = treinarEpoca(pontos, modelo, taxa);
if (erros === 0) break;
}
return modelo;
}
// Converte u = 0 na forma x₂ = inclinação·x₁ + intercepto.
function obterFronteira(modelo) {
return {
inclinacao: -modelo.w1 / modelo.w2,
intercepto: -modelo.bias / modelo.w2
};
}
const modelo = treinar(pontos, 100, 0.15);
console.log(modelo, obterFronteira(modelo));
// Limitação importante:
// se A e B não forem separáveis por uma reta, esse treino não converge.
// Nesse caso usamos uma MLP, como no laboratório XOR.