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

使用Accord.NET构建波士顿房价回归神经网络的技术咨询

波士顿房价回归问题Accord.NET代码答疑

问题概述

我是一名新手学生,想要尝试构建神经网络解决波士顿房价(Boston Housing)数据集的回归问题,但对Accord.NET中适用的函数及网络设置不太理解。以下是我编写的代码,请帮忙检查数据预处理、训练数据提交是否正确,以及应该选择何种激活函数?

我希望得到medv的预测值。目前代码中似乎所有层(包括输出层)都使用了LinearFunction,在Python的Keras中可以为每层设置不同的激活函数,请问在Accord.NET中该如何实现?

抱歉,我的代码还很粗糙,我刚开始学习...

用户提供的代码:

System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
customCulture.NumberFormat.NumberDecimalSeparator = ".";
System.Threading.Thread.CurrentThread.CurrentCulture = customCulture;

string Boston_FileName = @"Boston.csv";
DataTable tab = new CsvReader(Boston_FileName, true).ToTable();

medv = tab.Columns["medv"].ToArray();
medv_train = medv.Get(0, 404);//80%
medv_test = medv.Get(404, 506);//20%

double[][] out_medv = medv.ToJagged();
double[][] out_medv_train = medv_train.ToJagged();
double[][] out_medv_test = medv_test.ToJagged();

tab.Columns.Remove("medv");

int signs = tab.Columns.Count;

double[][] in_x = tab.ToJagged();
double[][] in_train = in_x.Get(0, 404); //80%
double[][] in_test = in_x.Get(404, 506);//20%

to_standart( in_train, in_test); 

ActivationNetwork netw = new ActivationNetwork(
    new LinearFunction(), 
    13,                      
    13,
    1);              

netw.Randomize();

var teacher = new BackPropagationLearning(netw);

for (int epoch = 0; epoch < 100; epoch++)
{
    var error = teacher.RunEpoch(in_train, out_medv_train);
    WriteLine($"Эпоха {epoch}  ошибка {error}");
}

int count= 0, correct= 0;

for (int i = 0; i < in_test.Length; i++)
{
    var prediction = netw.Compute(in_test[i]);
    double outputResult = prediction.First();

    WriteLine($"   {outputResult}");
}

ReadLine();

一、数据预处理与训练数据拆分检查

  • 拆分逻辑正确性:波士顿数据集共506条样本,按80%/20%拆分训练集(404条)和测试集(102条)的比例合理,代码中Get(0,404)和Get(404,506)的调用符合预期。
  • 标准化操作注意点:to_standart函数必须仅基于训练集的均值和标准差转换测试集,避免数据泄露。如果你的函数是用训练集统计量统一处理两组数据,逻辑正确;如果是分别计算两组数据的统计量,需要修改。
  • 目标变量处理:回归问题中目标变量medv无需分类编码,直接转为二维数组的操作符合Accord.NET的输入要求,是正确的。

二、训练代码的问题修正

  • 学习率与动量设置:BackPropagationLearning默认学习率偏低,建议手动配置加速收敛:
    var teacher = new BackPropagationLearning(netw)
    {
        LearningRate = 0.01,
        Momentum = 0.9 // 添加动量缓解震荡,加速收敛
    };
    
  • 迭代次数调整:100次迭代不足以让神经网络充分学习,建议增加到1000次以上,或添加早停机制(当连续多轮训练误差下降阈值低于设定值时停止)。
  • 测试集误差评估:当前仅输出训练误差,建议添加测试集均方误差(MSE)计算,直观评估模型泛化能力:
    // 计算测试集MSE
    double testMse = 0;
    for (int i = 0; i < in_test.Length; i++)
    {
        var prediction = netw.Compute(in_test[i]);
        testMse += Math.Pow(prediction[0] - out_medv_test[i][0], 2);
    }
    testMse /= in_test.Length;
    WriteLine($"测试集均方误差: {testMse:F4}");
    

三、激活函数选择与分层设置

1. 激活函数选择建议

  • 隐藏层:回归问题的隐藏层需要非线性激活函数来学习复杂特征映射,推荐选择:
    • RectifierFunction()(ReLU):输出范围(0,+∞),缓解梯度消失问题,收敛速度快
    • TanHFunction():输出范围(-1,1),梯度消失问题比Sigmoid轻微
    • SigmoidFunction():输出范围(0,1),适合已归一化的数据场景
  • 输出层:回归问题需要预测连续值,输出层必须用LinearFunction,你当前的设置是正确的。

2. Accord.NET分层设置不同激活函数

ActivationNetwork默认给所有层用同一个激活函数,要实现分层设置,需手动创建ActivationLayer并添加到网络中,示例如下:

// 手动构建网络,支持分层配置激活函数
var netw = new ActivationNetwork(inputCount: 13);

// 添加隐藏层:13个神经元,使用ReLU激活
netw.Layers.Add(new ActivationLayer(13, new RectifierFunction()));
// 可选:添加第二层隐藏层,比如10个神经元用Tanh激活
// netw.Layers.Add(new ActivationLayer(10, new TanHFunction()));
// 添加输出层:1个神经元,使用线性激活
netw.Layers.Add(new ActivationLayer(1, new LinearFunction()));

// 初始化网络权重
netw.Randomize();

四、其他优化建议

  • 权重初始化优化:替换默认的Randomize(),使用高斯初始化让初始权重更合理:
    new GaussianWeightsInitializer().Initialize(netw);
    
  • 训练集洗牌:训练前打乱训练集样本顺序,避免模型学习到样本顺序的无关规律:
    // 同时打乱输入和目标变量,保证对应关系
    in_train.Shuffle(out_medv_train);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:12:46