当前位置: 首页 > article >正文

neuroph建立简单BP网络

在神经网络中,激活函数扮演着至关重要的角色,它们为网络引入了非线性因素,使得网络能够学习和模拟复杂的非线性关系。下面列出的各种激活函数及其特点如下:

  1. LINEAR ("Linear"):
    • 线性激活函数实际上就是恒等函数,即 f(x)=x。
    • 它不会给网络带来任何非线性特性,因此在实际应用中很少使用(除了在某些特殊情况下,如回归问题或某些层作为输出层时)。
  2. RAMP ("Ramp"):
    • Ramp函数是一种分段线性函数,通常定义为当 x<0 时 f(x)=0,当 x≥0 时 f(x)=x。
    • 它与ReLU(Rectified Linear Unit)类似,但Ramp函数在 x<0 时保持输出为0,而不是像ReLU那样保持不变。Ramp函数有时被认为是一个更平滑的ReLU版本。
  3. STEP ("Step"):
    • Step函数是一种简单的二值激活函数,通常定义为当 x<0 时 f(x)=0,当 x≥0 时 f(x)=1。
    • 它将任意输入值映射到两个输出值之一,这种非连续性使得它在大多数现代神经网络中不太实用。
  4. SIGMOID ("Sigmoid"):
    • Sigmoid函数是一个S形曲线,定义为 f(x)=1+e−x1​。
    • 它将任意实值压缩到区间(0, 1)内,非常适合用于二分类问题的输出层。然而,由于梯度消失问题和计算量较大,它在深度神经网络中的使用已经减少。
  5. TANH ("Tanh"):
    • Tanh函数是双曲正切函数,定义为 f(x)=ex+e−xex−e−x​。
    • 它将输入值压缩到区间(-1, 1)内,并且是零中心的(即,输出的均值为0)。这有助于加快收敛速度,因此它比Sigmoid函数更受欢迎。然而,梯度消失问题仍然存在。
  6. GAUSSIAN ("Gaussian"):
    • 高斯(或称为高斯)激活函数使用高斯(或正态)分布函数,形式可能因具体实现而异,但通常与标准正态分布相关。
    • 它将输入值映射到一个钟形曲线,但这种激活函数在神经网络中不太常见,因为其他激活函数通常能提供更好的性能。
  7. TRAPEZOID ("Trapezoid"):
    • 梯形激活函数是一种非线性函数,其形状类似于梯形。
    • 它结合了线性和非线性的部分,但在实际应用中不太常见,可能是因为它缺乏足够的理论依据或优势。
  8. SGN ("Sgn"):
    • Sgn(符号)函数根据输入值的正负输出+1、-1或0(取决于具体定义)。
    • 它是一种简单的二值激活函数,但在神经网络中并不常用,因为它的梯度在大部分输入上都是0(除了0点附近的微小区域),这会导致梯度消失问题。
  9. SIN ("Sin"):
    • Sin函数是正弦函数,将输入值映射到[-1, 1]区间的正弦波上。
    • 它是一个周期性的非线性函数,但在神经网络中不常用,因为神经网络通常希望激活函数具有单调递增或递减的特性,以便进行有效的梯度下降。
  10. LOG ("Log"):
    • Log函数(可能指的是自然对数或其他对数)将输入值映射到对数尺度上。
    • 它在某些特定领域(如机器学习中的某些损失函数)中很有用,但在作为神经网络的激活函数时并不常见。
  11. RECTIFIED ("RectifiedLinear", ReLU):
    • ReLU(Rectified Linear Unit)函数是当前深度学习中使用最广泛的激活函数之一。
    • 它定义为 f(x)=max(0,x),即将所有负值置为0,保持正值不变。
    • ReLU函数简单、计算效率高,且有助于缓解梯度消失问题(在正值区域内)。然而,它也存在死亡ReLU问题(即某些神经元在训练过程中永远不会被激活)。

为了分析1个y和3个自变量(x,z,  k) (0为训练集,1为测试集) 的回归问题使用java的BP网络激活函数使用RECTIFIED如下:

private static void poly3UseBpn(Double[] x0, Double[] z0, Double[] k0, Double[] y, Double[] x1, Double[] z1, Double[] k1, Double[] y0, Double[] y1) {
    // 归一化数据
    double minX = Arrays.stream(x0).min(Double::compareTo).get();
    double maxX = Arrays.stream(x0).max(Double::compareTo).get();
    double rangeX = maxX - minX;
    double minZ = Arrays.stream(z0).min(Double::compareTo).get();
    double maxZ = Arrays.stream(z0).max(Double::compareTo).get();
    double rangeZ = maxZ - minZ;
    double minK = Arrays.stream(k0).min(Double::compareTo).get();
    double maxK = Arrays.stream(k0).max(Double::compareTo).get();
    double rangeK = maxK - minK;
    // 创建数据集 (3 个输入,1 个输出)
    DataSet trainingSet = new DataSet(3, 1);
    for (int i = 0; i < x0.length; i++) {
        double normalizedInputX = (x0[i] - minX) / rangeX;
        double normalizedInputZ = (z0[i] - minZ) / rangeZ;
        double normalizedInputK = (k0[i] - minK) / rangeZ;
        trainingSet.add(new DataSetRow(new double[]{normalizedInputX, normalizedInputZ, normalizedInputK}, new double[]{y[i]}));
    }
    // 创建一个具有 3 个输入层神经元,10 个隐藏层神经元,1 个输出层神经元的神经网络
    MultiLayerPerceptron neuralNet = new MultiLayerPerceptron(TransferFunctionType.RECTIFIED, 3, 10, 1);
    //使用固定的权重
    neuralNet.randomizeWeights(new Random(1));
    // 设置学习率和迭代次数
    double currentLearningRate = 0.01;
    int iterations = 10000;
    double errorThreshold = 0.001;
    double minLearningRate = 1e-5;
    double decay = 0.9;
    // 训练网络
    BackPropagation backPropagation = new BackPropagation();
    backPropagation.setLearningRate(currentLearningRate);
    neuralNet.setLearningRule(backPropagation);
    for (int i = 0; i < iterations; i++) {
        neuralNet.learn(trainingSet);
        // 获取当前误差
        double error = backPropagation.getTotalNetworkError();
        if (error < errorThreshold) {
            System.out.println("error:" + error + "---->" + (error < errorThreshold) + "====>" + i);
            break;
        }
        // 更新学习率(指数衰减)
        currentLearningRate = Math.max(minLearningRate, currentLearningRate * decay);
        backPropagation.setLearningRate(currentLearningRate);
    }

    // 在 x0 和 z0 上评估拟合值,并将结果存储在 y0 中
    for (int i = 0; i < x0.length; i++) {
        double normalizedInputX = (x0[i] - minX) / rangeX;
        double normalizedInputZ = (z0[i] - minZ) / rangeZ;
        double normalizedInputK = (k0[i] - minK) / rangeZ;
        neuralNet.setInput(normalizedInputX, normalizedInputZ, normalizedInputK);
        neuralNet.calculate();
        y0[i] = neuralNet.getOutput()[0];
    }
    // 在 x1 和 z1 上评估拟合值,并将结果存储在 y1 中
    for (int i = 0; i < x1.length; i++) {
        double normalizedInputX = (x1[i] - minX) / rangeX;
        double normalizedInputZ = (z1[i] - minZ) / rangeZ;
        double normalizedInputK = (k1[i] - minK) / rangeZ;
        neuralNet.setInput(normalizedInputX, normalizedInputZ, normalizedInputK);
        neuralNet.calculate();
        y1[i] = neuralNet.getOutput()[0];
    }


http://www.kler.cn/a/312134.html

相关文章:

  • windows C#-LINQ概述
  • ODOO学习笔记(1):ODOO的SWOT分析和技术优势是什么?
  • Oracle RAC的thread
  • C++数据结构算法学习
  • 希尔排序(C语言)
  • (十)Python字典基本操作
  • windows消息机制
  • Spring Boot 项目中整合 RabbitMQ,使用死信队列(Dead Letter Exchange, DLX)实现延迟队列功能
  • 设计模式 组合模式(Composite Pattern)
  • 【HTTP】认识 URL 和 URL encode
  • KL散度(Kullback-Leibler)
  • java框架
  • 深入理解 MySQL MVCC:多版本并发控制的核心机制
  • vmware,centos8(虚拟机) 的安装
  • Python Web开发中的持续集成与持续交付(CI/CD)
  • cassandra指定配置文件的docker启动方法
  • 【学术会议征稿】第四届计算机、信息工程与电子材料国际学术会议 (CTIEEM 2024)
  • 微信小程序能不能有一种公共的分包,能被普通的分包引用其资源?(内有解决方案)
  • 【测试】博客系统测试报告
  • docker面经
  • 【Mac】系统环境配置
  • mybatisplus分页查询学习
  • QT应用开发的C++功能框架以及实战入门开发项目场景
  • 计算机网路(应用层)
  • 中台架构下的数据仓库与非结构化数据整合
  • Nuxt Kit 中的插件:创建与使用