神经网络实战前言

news2024/11/17 7:41:29

应用广泛

  • 从人脸识别到网约车,在生活中无处不在

未来可期

  • 无人驾驶技术便利出行
  • 医疗健康改善民生

产业革命

  • 第四次工业革命——人工智能

机器学习概念

  • 机器学习不等价与人工智能
  • 20世纪50年代,人工智能是说机器模仿人类行为的能力

符号人工智能

  • 基于符号,将人类的知识声明为一种计算机可以处理的形式
  • 专家系统发展于人工智能
  • 模拟人类的决策
  • 缺点是:依赖人类专家的知识,解决问题的规则和认知是被编程的

机器学习

  • 通俗讲,机器从已有的数据中学习并对其他数据做预测

机器学习的基础条件

  • 海量的数据存储能力
  • 强大的运算能力

刚开始科学家使用符号人工智能,但是发现研究进展不顺,随着计算机硬件的提升,机器学习的基础条件得到满足后,AI发展迎来春天。

机器学习算法

有监督分类

  • 标记过的训练数据
  • 学习从输入变量映射到目标变量的规则
  • 例如:降雨(目标变量),温度、时间、气压、风速等等就是输入变量

无监督分类

  • 未经标记过的训练数据
  • 学习数据中的关联规则、模式及类别
  • 常见案例是聚类分析

监督分类的案例

  • 区分两种动物,兔子和大象
  • 收集到的数据有速度和体重
  • 兔子的特征是,体重小,速度快
  • 大象的特征是,体重大,速度慢
  • 机器学习算法的任务就是,找到分割兔子和大象的区别,生成决策边界线,将海量的数据一分为二,线就是决策边界。
  • 有了决策边界,就可以对未知的数据集进行预测,判断类型
  • 不同的学习算法会对最终的结果有影响

常用的机器学习方法包括:

  • 神经网络
  • 线性回归
  • 对数概率回归
  • 支持向量机
  • 决策树

机器学习的工作流程

  1. 输入数据
    1. 多个数据源
  2. 数据预处理
    1. 数据整合
    2. 数据编码
    3. 数据换算和标准化
    4. 补充缺失数据
      1. 均值替换缺失值
      2. 基于存在数据预测缺失值
    5. 训练测试数据分割
  3. 数据分析
    1. 数据可视化
    2. 探索性数据分析
      1. 特征工程
      2. 领域知识加入机器学习
  4. 模型构建
    1. 选择学习模型
    2. 调参
    3. 训练模型
    4. 评估模型
  5. 输出结果
    1. 输出未知数据集的预测结果

神经网络

模拟人类大脑神经元

单层神经网络——感知机

核心:数学函数
过程:输入+运算+输出

为什么神经网络好?

通用函数逼近器

现实生活中的问题总能用数学函数来表征,不论函数有多复杂,神经网络都能对这个函数无限逼近(前提:理想的算力)

可扩展性好且灵活

神经网络的不同堆叠方式和排列组合可以解决各种问题,好的程序员对网络的编排更为熟悉。

神经网络的内部工作原理

  • 输入层
  • 一个或者多个的隐藏层
  • 输出层
  • 每层之间包含权重W和偏差b
  • 为每个隐藏层所选择的激活函数σ

Python中训练神经网络

import numpy as np

class NeuralNetwork:
    def__init__(self,x,y):
        self.input=x
        self.weights1=np.random.rand(self.input.shape[1],4)
        self.weights2=np.random.rand(4,1)
        self.y=y
        self.output=np.zeros(self.y.shape)
  1. import numpy as np:导入NumPy库并将其重命名为np,用于处理数组和矩阵等数学运算。

  2. class NeuralNetwork::定义了一个名为NeuralNetwork的类,用于表示神经网络。

  3. def __init__(self, x, y)::定义了类的构造函数,用于初始化神经网络的参数。

  4. self.input = x:将输入数据x保存到类的属性input中。

  5. self.weights1 = np.random.rand(self.input.shape[1], 4):随机初始化输入层到隐藏层之间的权重矩阵,矩阵大小为输入数据的特征数(x的列数)乘以隐藏层的神经元数(这里设定为4)。

  6. self.weights2 = np.random.rand(4, 1):随机初始化隐藏层到输出层之间的权重矩阵,矩阵大小为隐藏层的神经元数(4)乘以输出值。

  7. self.y = y:将输出数据y保存到类的属性y中。

  8. self.output = np.zeros(self.y.shape):初始化一个和输出数据y相同大小的零矩阵,用于保存神经网络的输出值。

两层神经网络的数学内核

\hat{y} = \sigma\left[W_2\sigma(W_1x + b_1) + b_2\right]

其中:
x 是输入向量,
W_1是第一个隐藏层的权重矩阵,b_1是第一个隐藏层的偏置向量,
\sigma是激活函数(如 Sigmoid 函数),
W_2是第二个隐藏层到输出层的权重矩阵,b_2 是输出层的偏置向量,
\hat{y}是神经网络的输出向量。

神经网络的训练包括2个步骤

  1. 前馈:计算预测输出\hat{y}

  2. 反向传播(Backward Propagation):更新权重和偏差

前馈

进行前向传播计算,假设偏差都为0

import numpy as np

class NeuralNetwork:
    def__init__(self,x,y):
        self.input=x
        self.weights1=np.random.rand(self.input.shape[1],4)
        self.weights2=np.random.rand(4,1)
        self.y=y
        self.output=np.zeros(self.y.shape)
    def feedforward(self):
        self.layer1=sigmoid(np.dot(self.input,self.weights1))
        self.layer2=sigmoid(np.dot(self.input,self.weights2))

1. `self.layer1 = sigmoid(np.dot(self.input, self.weights1))`:将输入数据 `self.input` 与第一层的权重矩阵 `self.weights1` 相乘,并通过 Sigmoid 激活函数进行非线性变换,得到第一层的输出 `self.layer1`。这一步表示输入数据经过第一层的处理后的输出。

2. `self.layer2 = sigmoid(np.dot(self.input, self.weights2))`:将输入数据 `self.input` 与第二层的权重矩阵 `self.weights2` 相乘,并通过 Sigmoid 激活函数进行非线性变换,得到第二层的输出 `self.layer2`。这一步表示第一层的输出经过第二层的处理后的输出。

这段代码的目的是计算神经网络的前向传播过程中各层的输出,以便后续计算损失函数和进行反向传播更新权重。值得注意的是,这里的 `sigmoid` 函数是一个自定义的激活函数,用于将神经网络的输出限制在0到1之间。

损失函数

损失函数有多种,目前以平方和误差为例

SSE = \sum_{i=1}^{n} (y_i - \hat{y}_i)^2

平方和误差就是对实际值和预测值之间的差值求和

目标是实现训练神经网络并找到是损失函数最小化的最优权重

反向传播

计算出预测结果的误差(损失),需要找到一种方法将误差在网络中反向传导以便更新权重和偏差。

要找合适的权重和偏差矫正量,需要知道损失函数关于权重及偏差的导数

函数的导数就是函数的斜率

根据导数就可以根据导数的值增加或者减少导数值的方式来调节权重和偏差,这种方法也称为梯度下降法

使用链式法则求损失函数的导数,链式法则封装在keras等机器学习的库中

关键点:由损失函数关于权重的导数(斜率),帮助调整权重

import numpy as np

def sigmoid(x):
    return 1.0/(1+np.exp(-x))
def sigmoid_derivative(x):
    return x*(1.0-x)
class NeuralNetwork:
    def __init__(self,x,y):
        self.input=x
        self.weights1=np.random.rand(self.input.shape[1],4)
        self.weights2=np.random.rand(4,1)
        self.y=y
        self.output=np.zeros(self.y.shape)
    def feedforward(self):
        self.layer1=sigmoid(np.dot(self.input,self.weights1))
        self.output =sigmoid(np.dot(self.layer1,self.weights2))
    def backprop(self):
        #Find the derivative of the loss function with respect to weight2 and weight1 using the chain rule
        d_weights2=np.dot(self.layer1.T,(2*(self.y-self.output)*sigmoid_derivative(self.output)))
        d_weights1=np.dot(self.input.T,(np.dot(2*(self.y-self.output)*sigmoid_derivative(self.output),self.weights2.T)*sigmoid_derivative(self.layer1)))
        self.weights1 +=d_weights1
        self.weights2 +=d_weights2
if __name__=="__main__":
    X=np.array([[0,0,1],
               [0,1,1],
               [1,0,1],
               [1,1,1]])
    y=np.array([[0],[1],[1],[0]])
    nn=NeuralNetwork(X,y)
    
    for i in range(1500):
        nn.feedforward()
        nn.backprop()
    print(nn.output)

这段代码实现了一个简单的神经网络,包括一个输入层、一个隐藏层和一个输出层。以下是每个模块的描述:

  1. import numpy as np: 导入NumPy库,用于处理数组和矩阵等数值计算。

  2. def sigmoid(x): 定义sigmoid激活函数,用于将输入值转换为0到1之间的值。

  3. def sigmoid_derivative(x): 定义sigmoid激活函数的导数,用于反向传播中计算梯度。

  4. class NeuralNetwork: 定义神经网络类,包括初始化方法__init__、前向传播方法feedforward和反向传播方法backprop

    • __init__(self, x, y): 初始化神经网络,包括输入数据x、目标输出y、第一层到第二层的权重weights1和第二层到输出层的权重weights2

    • feedforward(self): 执行神经网络的前向传播,计算输入经过权重后得到的输出。

    • backprop(self): 执行神经网络的反向传播,根据损失函数的梯度更新权重,以减小预测输出与实际输出之间的差距。

  5. if __name__=="__main__"::主程序入口,创建神经网络对象并进行训练。

    • 创建输入数据X和目标输出y

    • 创建神经网络对象nn

    • 循环执行1500次训练迭代,每次迭代包括前向传播和反向传播。

    • 打印训练后的输出结果nn.output

重要点:Sigmoid是激活函数,将函数值压缩到0~1,对于二元问题,就是将预测结果位于0~1

结果精度检验

x1x2x3Y
0010
0111
1011
1110

迭代神经网络1500次,给出了最后的预测结果,与真实值进行对照,同时给出损失迭代-次数图

if __name__=="__main__":
    X=np.array([[0,0,1],
               [0,1,1],
               [1,0,1],
               [1,1,1]])
    y=np.array([[0],[1],[1],[0]])
    nn=NeuralNetwork(X,y)

    losses = []  # 用于记录每次迭代后的损失值

    for i in range(1500):
        nn.feedforward()
        nn.backprop()
        loss = np.mean(np.square(nn.y - nn.output))  # 计算均方误差损失
        losses.append(loss)

    plt.plot(range(1, 1501), losses)  # 绘制损失-迭代次数图
    plt.xlabel('Iterations')
    plt.ylabel('Loss')
    plt.title('Loss vs. Iterations')
    plt.show()

为什么要求平均,不平均代码报错?

在计算损失时,我们通常会计算所有样本的损失值的平均值。这是因为损失是所有样本预测值与真实值之间差值的函数,我们希望损失值能够反映整个数据集的预测准确程度,而不仅仅是单个样本的准确程度。因此,对所有样本的损失值取平均可以更好地衡量整个模型的性能。

预测值       实际值
0.009240
0.972571
0.972011
0.034340

由图片和图表可以看出来,前馈和反向传播算法成功训练的神经网络,且预测值收敛于真实值,且预测值与真实值有一定的误差,这个是在允许范围之内的。

最后

    for i in range(1500):
        nn.feedforward()
        nn.backprop()
        loss = np.mean(np.square(nn.y - nn.output))  # 计算均方误差损失
        losses.append(loss)

这块代码可以在类中进行分装,代码简洁,迁移性、可读性好

def train(self, epochs):
        for i in range(epochs):
            self.feedforward()
            self.backprop()
            loss = np.mean(np.square(self.y - self.output))  # 计算均方误差损失
            self.losses.append(loss)
if __name__=="__main__":
    X=np.array([[0,0,1],
               [0,1,1],
               [1,0,1],
               [1,1,1]])
    y=np.array([[0],[1],[1],[0]])
    nn=NeuralNetwork(X,y)
    
    nn.train(1500)  # 进行1500次训练迭代
    
    plt.plot(range(1, 1501), nn.losses)  # 绘制损失-迭代次数图
    plt.xlabel('Iterations')
    plt.ylabel('Loss')
    plt.title('Loss - Iterations')
    plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1506942.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

官方安装配置要求服务器最低2核4G

官方安装配置要求服务器至少2核、4G。 如果服务器低于这个要求,就没有必要安装,因为用户体验超级差。 对于服务器CPU来说,建议2到4核就完全足够了,太多就浪费了,但是内存越大越好,最好是4G以上。 如果服务器…

XSS攻击场景分析

XSS攻击场景分析 在目前这个时间节点还是属于一个排位比较高的漏洞,在OWASP TOP10 2021中隶属于注入型漏洞,高居TOP3的排位,可见这个漏洞的普遍性。跨站脚本攻击的学习中我们主要需要明白的是跨站的含义,以及XSS的核心。XSS主流分…

CentOS 7安装MySQL及常见问题与解决方案(含JDBC示例与错误处理)

引言 MySQL是一个流行的开源关系型数据库管理系统,广泛应用于各种业务场景。在CentOS 7上安装MySQL后,我们通常需要使用JDBC(Java Database Connectivity)连接MySQL进行后端操作。 目录 引言 CentOS 7安装MySQL 使用JDBC连接My…

LLM Drift(漂移), Prompt Drift Cascading(级联)

原文地址:LLM Drift, Prompt Drift & Cascading 提示链接可以手动或自动执行;手动需要通过 GUI 链构建工具手工制作链。自治代理在执行时利用可用的工具动态创建链。这两种方法都容易受到级联、LLM 和即时漂移的影响。 2024 年 2 月 23 日 在讨论大型…

Java对接(BSC)币安链 | BNB与BEP20的开发实践(二)BNB转账、BEP20转账、链上交易监控

上一节我们主要是环境搭建,主要是为了能够快速得去开发,有些地方只是简单的介绍,比如ETH 、web3j等等这些。 这一节我们来用代码来实现BNB转账、BEP20转账、链上交易监控 话不多说,我们直接用代码实现吧 1. BNB转账 /*** BNB转…

Python判断语句+循环语句

一、Python判断语句 1.1 布尔类型和比较运算符 # 定义变量存储布尔类型的数据 bool_1 True bool_2 False print( f"bool_1变量的内容是:{ bool_1 },类型为:{ type( bool_1 ) }" ) print( f"bool_2变量的内容是:{…

打卡--MySQL8.0 一(单机部署)

一路走来,所有遇到的人,帮助过我的、伤害过我的都是朋友,没有一个是敌人。如有侵权,请留言,我及时删除! MySQL 8.0 简介 MySQL 8.0与5.7的区别主要体现在:1、性能提升;2、新的默认…

ELFK 分布式日志收集系统

ELFK的组成: Elasticsearch: 它是一个分布式的搜索和分析引擎,它可以用来存储和索引大量的日志数据,并提供强大的搜索和分析功能。 (java语言开发,)logstash: 是一个用于日志收集,处理和传输的…

04hive数仓内外部表复杂数据类型与分区分桶

hive内部表和外部表 默认为内部表,外部表的关键字 :external内部表:对应的文件夹就在默认路径下 /user/hive/warehouse/库名.db/外部表:数据文件在哪里都行,无须移动数据 # students.txt 1,Lucy,girl,23 2,Tom,boy,2…

2023年终总结——跌跌撞撞不断修正

目录 一、回顾1.一月,鼓足信心的开始2.二月,焦躁不安3.三月,路还是要一步一步的走4.四月,平平淡淡的前行5.五月,轰轰烈烈的前行6.六月,看事情更底层透彻了7.七月,设计模式升华月8.八月&#xff…

加速 Webpack 构建:提升效率的秘诀

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

LCR 112. 矩阵中的最长递增路径【leetcode】/dfs+记忆化搜索

LCR 112. 矩阵中的最长递增路径 给定一个 m x n 整数矩阵 matrix ,找出其中 最长递增路径 的长度。 对于每个单元格,你可以往上,下,左,右四个方向移动。 不能 在 对角线 方向上移动或移动到 边界外(即不允…

【C语言基础】:深入理解指针(终篇)

文章目录 深入理解指针一、函数指针变量4.1 函数指针变量的创建4.2 函数指针变量的使用4.3 typedef关键字 二、函数指针数组三、转移表四、回调函数4.1 什么是回调函数4.2 qsort使用举例4.2.1 使用qsort函数排序整形数据4.2.2 使用qsort排序结构数据4.2.3 qsort函数的模拟实现 …

贝叶斯优化的门控循环神经网络BO-GRU(时序预测)的Matlab实现

贝叶斯优化的门控循环神经网络(BO-GRU)是一种结合了贝叶斯优化(Bayesian Optimization, BO)和门控循环单元(Gated Recurrent Unit, GRU)的模型,旨在进行时序预测。这种模型特别适用于时间序列数…

python文件组织:包(package)、模块(module)、文件(file)

包: 模块所在的包,创建一个包用于组织多个模块,包文件夹中必须创建一个名为’__init__.py’的文件,以将其识别为包,否则只能算作是一个普通的目录。在使用该包时,init自动执行。 包可以多层嵌套&#xff…

C++变参模板

从c11开始&#xff0c;模板可以接受一组数量可变的参数&#xff0c;这种技术称为变参模板。 变参模板 下面一个例子&#xff0c;通过变参模板打印一组数量和类型都不确定的参数。 #include <iostream> #include <string>void print(void) {std::cout<<&quo…

数据结构小记【Python/C++版】——散列表篇

一&#xff0c;基础概念 散列表&#xff0c;英文名是hash table&#xff0c;又叫哈希表。 散列表通常使用顺序表来存储集合元素&#xff0c;集合元素以一种很分散的分布方式存储在顺序表中。 散列表是一个键值对(key-item)的组合&#xff0c;由键(key)和元素值(item)组成。键…

探索云原生数据库技术:构建高效可靠的云原生应用

数据库是应用开发中非常重要的组成部分&#xff0c;可以进行数据的存储和管理。随着企业业务向数字化、在线化和智能化的演进过程中&#xff0c;面对指数级递增的海量存储需求和挑战以及业务带来的更多的热点事件、突发流量的挑战&#xff0c;传统的数据库已经很难满足和响应快…

OpenCV filter2D函数详解

OpenCV filter2D函数简介 OpenCV filter2D将图像与内核进行卷积&#xff0c;将任意线性滤波器应用于图像。支持就地操作。当孔径部分位于图像之外时&#xff0c;该函数根据指定的边界模式插值异常像素值。 该函数实际上计算相关性&#xff0c;而不是卷积&#xff1a; filter…

【Spark编程基础】实验一Spark编程初级实践(附源代码)

文章目录 一、实验目的二、实验平台三、实验内容和要求1. 计算级数2. 模拟图形绘制3.统计学生成绩 一、实验目的 1.掌握 Scala 语言的基本语法、数据结构和控制结构&#xff1b; 2.掌握面向对象编程的基础知识&#xff0c;能够编写自定义类和特质&#xff1b; 3.掌握函数式编程…