You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何训练含两层及以上的神经网络?

如何修改神经网络训练函数以支持多层网络?

我已经用Python从零实现了神经网络,定义了Neuron、Layer和NeuralNetwork类,成功训练并使用了含1层、1个神经元、3个输入的网络。现在想构建两层及以上、每层神经元数量任意的网络,但不知道怎么修改train函数来训练这类网络。目前已经实现了前向传播:第0层输入网络输入,非0层输入前一层的输出,但后续训练步骤不清楚。

以下是当前代码:

import numpy as np
from numpy import exp, random
import math

from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt

np.random.seed(1)

class Neuron:
    def __init__(self, weights, bias):
        self.weights = weights
        self.bias = bias

    def sigmoid(self, x):
        output = 1/(1+exp(-x))
        return output

    def compute(self, inputs):
        self.output = self.sigmoid(np.dot(inputs, self.weights) + self.bias)
        return self.output

class Layer: 
    def __init__(self, numberOfNeurons, numberOfInputs):
        self.neurons = []
        self.outputs = []
        self.numberOfNeurons = numberOfNeurons
        self.numberOfInputs = numberOfInputs

        self.initialiseWeightsAndBiases()

        for i in range(0,numberOfNeurons):
            self.neurons.append(Neuron(self.weights, self.biases))

    def initialiseWeightsAndBiases(self):
        self.weights = 2 * random.random((self.numberOfInputs, self.numberOfNeurons)) - 1
        self.biases = 2 * random.random((1, self.numberOfNeurons)) - 1
    
    def forward(self, inputs):
        self.outputs = np.array([])
        for i in self.neurons:
            self.outputs = np.append(self.outputs, i.compute(inputs))

class NeuralNetwork:
    def __init__(self, layers):
        self.layers = layers

    def forwardPass(self, inputs):
        for i in range(0,len(layers)):
            if i == 0:
                layers[i].forward(inputs)   
            else:
                layers[i].forward(layers[i-1].outputs)
        return layers[-1].outputs

    def calculateError(self, predictedOutputs, trueOutputs):
        error = (trueOutputs - predictedOutputs) * predictedOutputs * (1 - predictedOutputs)
        return error

    def trainNetwork(self, trainingDataInputs, trainingDataOutputs, numberOfIterations):
        for y in range(0, numberOfIterations):
            predictedOutputs = self.forwardPass(trainingDataInputs)
            error = self.calculateError(predictedOutputs, trainingDataOutputs)
            for i in layers[0].neurons:             
                i.weights += np.dot(trainingDataInputs.T, error.T)

    def visualiseNetwork(self):
        pass

# 测试单层网络
inputLayer = Layer( 1, 3)
layers = [inputLayer]
network1 = NeuralNetwork(layers)

inputTrainingData = np.array([[0, 0, 1], [1, 1, 1], [1, 0, 1], [0, 1, 1]])
outputTrainingData = [[0, 1, 1, 0]]

network1.trainNetwork(inputTrainingData, outputTrainingData, 10000)
outputs = network1.forwardPass([[0,1,1]])
print(outputs)

核心修改方案:实现反向传播算法

要支持多层网络训练,必须实现反向传播——从输出层反向计算每一层的误差项,再基于误差更新对应层的权重和偏置。以下是具体修改步骤:

1. 修正forwardPass的变量引用问题

原代码直接使用全局变量layers,改为引用类成员self.layers,避免多层网络时出现逻辑错误:

def forwardPass(self, inputs):
    current_input = inputs
    for layer in self.layers:
        layer.forward(current_input)
        current_input = layer.outputs
    return self.layers[-1].outputs

2. 修复Layer类的神经元权重初始化问题

原代码中同一层所有神经元共享一组权重,这是错误的——每个神经元需要独立的权重和偏置:

class Layer: 
    def __init__(self, numberOfNeurons, numberOfInputs):
        self.neurons = []
        self.outputs = []
        self.numberOfNeurons = numberOfNeurons
        self.numberOfInputs = numberOfInputs

        # 为每个神经元初始化独立的权重和偏置
        for _ in range(numberOfNeurons):
            weights = 2 * random.random((numberOfInputs, 1)) - 1
            bias = 2 * random.random(1) - 1
            self.neurons.append(Neuron(weights, bias))
    
    def forward(self, inputs):
        self.outputs = np.array([])
        for neuron in self.neurons:
            self.outputs = np.append(self.outputs, neuron.compute(inputs))
        self.outputs = self.outputs.reshape(-1)  # 统一维度方便后续计算

3. 重写trainNetwork函数,实现完整反向传播

添加学习率参数,从输出层到输入层依次计算误差,再更新权重和偏置:

def trainNetwork(self, trainingDataInputs, trainingDataOutputs, numberOfIterations, learning_rate=0.1):
    # 调整输出数据维度,匹配网络输出格式
    trainingDataOutputs = np.array(trainingDataOutputs).T
    
    for _ in range(numberOfIterations):
        # 前向传播获取预测结果
        predictedOutputs = self.forwardPass(trainingDataInputs).reshape(-1, 1)
        
        # 初始化误差列表,从输出层开始计算
        errors = []
        # 输出层误差:结合真实值、预测值和sigmoid导数
        output_error = (trainingDataOutputs - predictedOutputs) * predictedOutputs * (1 - predictedOutputs)
        errors.append(output_error)
        
        # 反向计算隐藏层误差
        for i in reversed(range(len(self.layers)-1)):
            next_layer = self.layers[i+1]
            next_error = errors[0]
            # 基于下一层的误差和权重,推导当前层误差
            current_error = np.dot(next_error, next_layer.weights.T) * self.layers[i].outputs.reshape(-1,1) * (1 - self.layers[i].outputs.reshape(-1,1))
            errors.insert(0, current_error)
        
        # 更新每一层的权重和偏置
        for i in range(len(self.layers)):
            layer = self.layers[i]
            # 获取当前层的输入:输入层用训练数据,隐藏层用前一层输出
            layer_input = trainingDataInputs if i == 0 else self.layers[i-1].outputs.reshape(-1, layer.numberOfInputs)
            
            # 计算权重和偏置的更新量
            delta_weights = learning_rate * np.dot(layer_input.T, errors[i])
            delta_biases = learning_rate * np.mean(errors[i], axis=0)
            
            # 更新参数
            layer.weights += delta_weights
            layer.biases += delta_biases.reshape(layer.biases.shape)

4. 测试多层网络

现在可以创建两层及以上的网络进行测试:

# 构建两层网络:输入层(2个神经元,3输入)+ 输出层(1个神经元,2输入)
input_layer = Layer(2, 3)
output_layer = Layer(1, 2)
layers = [input_layer, output_layer]
network = NeuralNetwork(layers)

inputTrainingData = np.array([[0, 0, 1], [1, 1, 1], [1, 0, 1], [0, 1, 1]])
outputTrainingData = [[0, 1, 1, 0]]

# 训练网络
network.trainNetwork(inputTrainingData, outputTrainingData, 10000, learning_rate=0.2)
# 测试预测
outputs = network.forwardPass([[0,1,1]])
print(outputs)  # 输出应接近0

内容的提问来源于stack exchange,提问作者Matthew Haywood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:35:44