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

从零实现C#神经网络遇异常:输出恒为0或无因变化求助

问题分析与修复方案

你的神经网络代码存在几个关键问题,导致输出异常:

1. 神经元状态未重置,多次预测结果累加

Prediction方法中,后续层的神经元值是直接累加的,没有在每次预测前重置为0。第一次预测后神经元保留了计算值,第二次预测会基于旧值继续计算,导致结果每次不同。

修复代码:

public float[] Prediction(float[] inputs)
{
    int biasIndex = 0;
    neurons[0] = inputs;

    for (int i = 1; i < layers; i++)
    {
        // 重置当前层神经元为0
        Array.Clear(neurons[i], 0, neurons[i].Length);
        for (int j = 0; j < neurons[i].Length; j++)
        {
            for (int k = 0; k < weights[i - 1][j].Length; k++)
            {
                neurons[i][j] += neurons[i - 1][k] * weights[i - 1][j][k];
            }
            neurons[i][j] += bias[biasIndex];
            // 应用激活函数
            neurons[i][j] = ActivationFunction(neurons[i][j]);
            biasIndex++;
        }
    }

    return neurons[neurons.Length - 1];
}

2. 未调用激活函数

你定义了sigmoid激活函数,但在预测过程中完全没有使用,导致输出只是输入与权重的线性组合,无法体现神经网络的非线性能力,甚至在权重偏置未初始化时输出全0。

修复:在每个神经元计算完加权和与偏置后,调用ActivationFunction,如上面代码所示。

3. Mathf依赖问题(非Unity环境)

如果不是在Unity中运行,Mathf类不存在,需要替换为System.Math,同时注意整数除法问题:1 / (1 + ...)中1是整数,会导致结果为0,要改为1f。

修复激活函数:

private float ActivationFunction(float prediction)
{
    return 1f / (1f + (float)Math.Exp(-prediction));
}

4. 权重与偏置未初始化时输出全0

如果没有调用GiveRandomNumbers方法,权重和偏置数组默认初始化为0,此时所有神经元的计算结果都是0,输出自然全0。确保在使用网络前调用GiveRandomNumbers初始化参数:

// 使用示例
var nn = new NeuralNetwork(3, new int[] {2,3,1});
nn.GiveRandomNumbers(); // 必须调用初始化权重偏置
var output = nn.Prediction(new float[] {0.5f, 0.8f});

5. Evaluation方法逻辑错误

原方法只预测了testingDataSet[0](第一个输入),没有遍历所有测试数据,而且判断预测是否正确的阈值(0.0001)对于sigmoid输出(0-1之间)来说过于严格,实际应该根据任务调整。

修复后的Evaluation方法:

public float Evaluation(float[][] testingInputs, float[][] testingOutputs)
{
    int correctCount = 0;
    int totalPredictions = 0;

    for (int i = 0; i < testingInputs.Length; i++)
    {
        float[] prediction = Prediction(testingInputs[i]);
        float[] correctOutput = testingOutputs[i];

        for (int j = 0; j < prediction.Length; j++)
        {
            totalPredictions++;
            // 调整阈值,比如允许0.1的误差
            if (Math.Abs(prediction[j] - correctOutput[j]) < 0.1f)
            {
                correctCount++;
            }
        }
    }

    return (float)correctCount / totalPredictions * 100f;
}

其他潜在问题

  • bias数组的计算可以简化:bias的长度应该是所有隐藏层和输出层的神经元总数,即layerSize.Skip(1).Sum(),原代码的biasLength - layerSize[0]逻辑正确,但可以更直观。
  • TrainingAlgorithm和TrainingLoop未实现,网络无法训练,当前只能用随机初始化的参数预测。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:54:56