如何用javaScript实现多层神经网络

378 阅读2分钟

神经网络是一种模拟人脑的计算模型。它由许多互相连接的神经元层组成,并且可以通过训练来学习复杂的模式。多层神经网络是一种常见的体系结构,其中输入信号经过多个隐藏层,最终输出一个预测结果。

实现步骤

步骤1:初始化权重和偏差

在创建神经网络之前,我们需要初始化权重和偏差。我们可以使用随机值来初始化它们。

function initializeParameters(layerDims) {
  const parameters = {};
  for (let l = 1; l < layerDims.length; l++) {
    // 随机初始化权重
    parameters[`W${l}`] = Math.random();
    // 初始化偏差为0
    parameters[`b${l}`] = 0;
  }
  return parameters;
}

步骤2:前向传播

在前向传播过程中,将输入信号传递给神经网络,并计算输出结果。将在每个隐藏层使用激活函数来引入非线性性。

function dotProduct(A, B) {
    let result = 0;
    for (let i = 0; i < A.length; i++) {
        result += A[i] * B[i];
    }
    return result;
}
function sigmoid(Z) {
    return 1 / (1 + Math.exp(-Z));
}
function forwardPropagation(X, parameters) {
  const A = { A0: X };
  let Z, A_prev, W, b;
  for (let l = 1; l < layerDims.length; l++) {
    A_prev = A[`A${l - 1}`];
    W = parameters[`W${l}`];
    b = parameters[`b${l}`];
    Z = dotProduct(W, A_prev) + b;
    A[`A${l}`] = sigmoid(Z);
  }
  return A[`A${layerDims.length - 1}`];
}

步骤3:成本函数

需要定义成本函数来衡量神经网络的准确性。在这个例子中,将使用平均方差误差(Mean Squared Error)作为成本函数。

function computeCost(AL, Y) {
  const m = AL.length;
  let cost = 0;
  for (let i = 0; i < m; i++) {
    cost += (AL[i] - Y[i]) ** 2;
  }
  cost /= m;
  return cost;
}

步骤4:反向传播

在反向传播过程中,将计算神经网络中每个参数对成本函数的偏导数。将使用这些偏导数来更新参数,以使成本函数最小化。

function sum(arr) {
    let result = 0;
    for (let i = 0; i < arr.length; i++) {
        result += arr[i];
    }
    return result;
}
function sigmoidDerivative(Z) {
    const S = sigmoid(Z);
    return S * (1 - S);
}
function backwardPropagation(AL, Y, parameters, cache) {
  const grads = {};
  let dZ, dA, dW, db, A_prev, m;
  m = AL.length;
  dZ = AL - Y;
  A_prev = cache[`A${cache.length - 2}`];
  dW = dotProduct(dZ, A_prev.T) / m;
  db = sum(dZ) / m;
  dA_prev = dotProduct(parameters[`W${parameters.length - 1}`].T, dZ);
  grads[`dW${parameters.length - 1}`] = dW;
  grads[`db${parameters.length - 1}`] = db;
  for (let l = parameters.length - 2; l >= 0; l--) {
    dZ = dA_prev * sigmoidDerivative(cache[`Z${l}`]);
    A_prev = cache[`A${l}`];
    dW = dotProduct(dZ, A_prev.T) / m;
    db = sum(dZ) / m;
    dA_prev = dotProduct(parameters[`W${l}`].T, dZ);
    grads[`dW${l}`] = dW;
    grads[`db${l}`] = db;
  }
  return grads;
}

步骤5:更新参数

将使用梯度下降法来更新神经网络中的参数。将使用步长(learning rate)来控制每次迭代的更新量。

function updateParameters(parameters, grads, learningRate) {
  for (let l = 1; l < layerDims.length; l++) {
    parameters[`W${l}`] -= learningRate * grads[`dW${l}`];
    parameters[`b${l}`] -= learningRate * grads[`db${l}`];
  }
  return parameters;
}

步骤6:训练神经网络

现在,使用实现的函数来训练神经网络。使用随机生成的数据来训练这个神经网络。

const layerDims = [2, 4, 1];
const learningRate = 0.01;
const epochs = 1000;
const X = [[0, 0], [0, 1], [1, 0], [1, 1]];
const Y = [[0], [1], [1], [0]];
let parameters = initializeParameters(layerDims);
for (let i = 0; i < epochs; i++) {
  const AL = forwardPropagation(X, parameters);
  const cost = computeCost(AL, Y);
  const cache = {
    A0: X,
    Z1: dotProduct(parameters.W1, X) + parameters.b1,
    A1: sigmoid(Z1),
    Z2: dotProduct(parameters.W2, A1) + parameters.b2,
    A2: sigmoid(Z2),
  };
  const grads = backwardPropagation(AL, Y, parameters, cache);
  parameters = updateParameters(parameters, grads, learningRate);
  console.log(`Epoch ${i+1}: Cost = ${cost}`);
}