手把手教你使用Python从零开始搭建感知器

news2024/11/30 2:44:10

大家好,今天本文将展示如何从零开始实现神经网络的最基本要素(感知器),以及人工智能的基本模块背后的数学原理。

虽然人工智能和机器学习等术语已经成为流行词汇,每天都会听到或谈论这些概念,但它们背后的数学概念已经存在了很长时间(从40年代起就有介绍人工神经网络-ANN的论文)。其有几个很好的优势:

  • 现在有大量的数据可用于训练神经网络,而且在处理大型、复杂的问题上,人工神经网络经常优于其他机器学习技术。

  • 自20世纪90年代以来,计算能力大幅增加,现在可以在合理的时间内训练大型神经网络。这在一定程度上归功于摩尔定律,但在另一方面也要感谢游戏行业,他们生产了数以百万计功能强大的GPU卡。

  • 训练算法已经得到改进。平心而论,它们与20世纪90年代使用的算法只有细微的不同,但这些相对较小的调整产生了巨大的积极影响。

一、简介

感知器是神经网络的基本构建模块,为我们提供了对机器学习和人工智能世界的简单而强大的了解。本文将探索感知器的本质,并学习如何从零开始实现它们。感知器在人工智能的发展中具有重要的历史意义,为现代深度学习模型奠定了基础。感知器在概念上的简单性使其成为任何希望掌握神经网络基础知识的人的理想起点。

接下来,本文将深入探讨感知器的架构和内部工作原理,提供代码示例和实用见解,以确保你对这一基本概念有扎实的理解。因此,接下来将使用以下Python软件包来实现感知器。

import numpy as np
import matplotlib.pyplot as plt
import random
import math

二、感知器架构

感知器由以下核心部件组成:

1. 输入特征

输入特征代表感知器用于做出决策的原始数据,本文将定义两个具有固定值的输入(X1X2),以简化神经网络。然而在实际应用中,神经元可能会使用多个输入来表示不同的输入信息。

X = [1, 0]

2. 权重

在此本文将生成用于组成神经网络的权重,我们将首先生成较小的随机权重,但需要注意的是,这些权重将在网络训练时更新。下面的代码展示了如何生成两个介于-11之间的随机权重(每个输入一个)。

w = []
nInputs = 2
for i in range(nInputs):
    w.append(random.uniform(-1, 1))   

3. 偏置

偏置项是感知器的附加输入项,用作可调节的阈值,它允许感知器在所有输入特征为零时也能做出决策。偏置有助于控制感知器的激活,本文将初始偏置设置为一个小的随机数。

b = random.uniform(-1,1)

4. 激活函数

激活函数将加权输入的总和转换为二进制输出,该输出是感知器的预测结果,表示一个决策或分类,通常我们希望激活函数的输出为01。另一个关键属性是其可微分性,这在网络训练中起着至关重要的作用。函数的可微分性是在训练过程中调整网络权重的不可或缺的要求,使网络能够从数据中学习并随着时间的推移进行改进。

用于此目的的一个非常常见的函数是sigmoid函数,因为它具有可微分性、平滑性和简单的梯度。

def sigmoid(x):
    return 1/(1+math.exp(-x))

5. 前馈

现在我们已经掌握了设计感知器的基本元素,我们必须将输入数据传递给感知器,这一步称为前馈。首先我们计算输入数据的加权和,然后将结果通过激活函数传递给感知器。

加权和只是权重向量和输入之间的点积,然后将其传递给sigmoid函数:

# 加权和 = w1*x1 + w2*x2 ... + b
z = sigmoid(np.dot(X, w) + b)

最后必须应用激活函数来预测输出为0还是1:

def activation(z):
    return 1 if z >0.5 else 0

 三、训练感知器

到目前为止,我们只能将输入数据传递给感知器,而不知道感知器是否正确。训练阶段对于提高感知器的准确性至关重要,其过程包括对感知器的权重进行多次迭代(epochs)更新。在每个迭代中,我们都要计算输出相对于目标实际值的误差,以便更新权重并使误差最小化:

y_pred = activation(z)
error = y - y_pred

lr = 0.1
w_new = []
for wi, xi in zip(w, X):
    w_new.append(wi + lr*error*xi)

b_new = b + lr*error

其中,lr是学习率,我们将其值设置为0.1,但也可以根据问题的不同设置为其他值。

因此我们现在拥有更新的权重,重复执行前馈步骤多个周期。通过根据梯度反复调整权重和偏置,网络会逐渐学会做出更好的预测,并随着时间的推移减少误差,这一步骤也被称为反向传播。

四、应用于鸢尾花数据集

到目前为止,大家已经了解感知器的各个部分以及它们的工作原理。接下来,本文将汇总所有学到的知识,创建感知器类,并使用真实数据集来验证感知器的工作原理。

【鸢尾花数据集】https://scikit-learn.org/stable/auto_examples/datasets/plot_iris_dataset.html

class Perceptron():
    
    def __init__(self,input_size = 2, lr = 0.01, epochs = 20):
        # 设置默认参数
        self.lr = lr
        self.epochs = epochs
        self.input_size = input_size
        self.w = np.random.uniform(-1, 1, size=(input_size))
        self.bias = random.uniform(-1,1)
        self.misses = []
        
    def predict(self, X):
        w = self.w
        b = self.bias
        z = sigmoid(np.dot(X,self.w) + b)
        
        if z > 0.5:
            return 1
        else:
            return 0
        
    def fit(self, X, y):
        
        for epoch in range(self.epochs):
            miss = 0
            for yi, xi in zip(y, X):
                y_pred = self.predict(xi)
                # 更新权重以最小化误差
                error = yi - y_pred
                self.w += self.lr*error*xi
                self.bias += self.lr*error
                miss += int(error != 0.0)
            # 获取每个时期的错误分类数
            self.misses.append(miss)

从上面的代码中可以看出:

  • lr:学习率

  • input_size:输入数据的特征数量

  • epochs:训练的迭代次数

  • X:输入数据(样本,特征)

  • y:目标数据(标签0或1)

现在,我们将使用scikit-learn库中鸢尾花数据集的感知器实现:

from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target

该数据集由4个特征(花萼长度、花萼宽度、花瓣长度和花瓣宽度)组成,共有150个样本,分为3个分类(山鸢尾、变色鸢尾和维吉尼亚鸢尾)。为了简化起见,本示例只使用2个特征(花萼长度和花瓣长度)以及山鸢尾和变色鸢尾的样本:

X = X[:100, [0,2]]
y = y[y<2]

# 绘制数据
plt.figure(figsize=(16,8))
plt.scatter(X[:50,0], X[:50,1], marker='o', label='setosa')
plt.scatter(X[50:,0], X[50:,1], marker='x', label='virginica')
plt.ylabel('sepal length')
plt.xlabel('petal length')
plt.show()

接下来,我们需要使用标记的数据(X,y)来训练感知器,并查看其性能表现如何:

perceptron = Perceptron()
perceptron.fit(X,y)
print(perceptron.w, perceptron.bias)
#(array([0.09893529, 0.09323132]), -0.763184789232628)

这样,我们就得到了训练的最优权重和偏置。那么感知器在错误分类方面表现如何呢?为此,我们将绘制感知器类别的错误参数:

感知器在训练过程中的错误分类次数

从上图可以看出,感知器在第一个时期出现了12次失误,并持续学习,直到在训练结束时不再犯错。

五、总结

本文成功地实现并训练了一个感知器,并使用真实数据集对其性能进行了评估。

尽管感知器是神经网络的基础模块,但正如我们在文章中所看到的,它也有其局限性:

  • 它在二分类数据集上表现良好;

  • 问题是线性可分的。换句话说,它们只能对可以通过直线或超平面将数据分为两类的数据进行分类;

  • 本文处理的是一个干净的数据集,几乎没有噪声,这使得感知器能够轻松收敛。

克服这些局限性的一种方法是使用更复杂的模型,如具有非线性激活函数的多层感知器(MLP),MLP可以学习非线性决策边界,从而能够解决更复杂的问题。

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

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

相关文章

软件开发介绍

一、软件开发整体介绍 作为一名软件开发工程师&#xff0c;我们需要了解在软件开发过程中的开发流程&#xff0c;以及软件开发过程中涉及到的岗位角色&#xff0c;角色的分工、职责&#xff0c;并了解软件开发中涉及到的三种软件环境。 1.1 软件开发流程 第一阶段&#xff1a…

MQTT解读【全网最易懂】

目录 前言 一、MQTT相比于TCP长连接的优势 1、协议更标准 2、MQTT协议制定好了很多利于物联网的功能 3、理解数据内容&#xff0c;用数据产生价值 二、选择MQTT还是TCP长连接透传 1、原始的业务场景 2、端对端M2M场景——无人汽车 3、APP控制设备端场景——智能家居、智…

RK3588的GPU驱动和桌面环境

这里主要是以orange pi 5 plus为对象作一个简单的笔记 首先看rk3588的gpu介绍&#xff0c;它用的是ARM的GPU&#xff0c;支持openGL ES和openCL&#xff08;支持什么其实跟GPU驱动有关&#xff0c;arm官方闭源GPU驱动就只支持这两个&#xff09; opi官方提供了debian的xfce和…

Linux网络编程系列之服务器编程——多路复用模型

Linux网络编程系列 &#xff08;够吃&#xff0c;管饱&#xff09; 1、Linux网络编程系列之网络编程基础 2、Linux网络编程系列之TCP协议编程 3、Linux网络编程系列之UDP协议编程 4、Linux网络编程系列之UDP广播 5、Linux网络编程系列之UDP组播 6、Linux网络编程系列之服务器编…

ROS-6.参数的使用

参数的使用 参数服务结构命令行的使用方式运行小海龟命令介绍查看参数获取参数值设置参数保存参数到文件从文件导入参数 通过程序操作创建节点修改cmake编译运行 参数服务结构 ros中存在参数服务管理服务&#xff0c;管理这所有参数&#xff0c;所有节点剋订阅和发布这些节点 …

第三章 内存管理 三、覆盖与交换

目录 一、覆盖技术 二、交换技术 三、总结 一、覆盖技术 1、在覆盖技术中&#xff0c;我们要找到程序的调用结构。 2、因为这些程序不可能同时被调用&#xff08;互斥调用&#xff09;&#xff0c;所以我们只需要选出需要空间最大的程序。 3、在物理内存中开拓一片与最大程…

ABB机器人关于重定位移动讲解

关于机器人如何重定位移动&#xff0c;首先来看一下示教器上的重定位移动是在哪。 从图中所示的坐标位置和操纵杆方向得知&#xff0c;重定位的本质是绕X、Y、Z轴的旋转。那么实现跟摇杆一样的操作&#xff0c;就可以通过改变当前位置的欧拉角来实现&#xff0c;参考Rapid指令…

小米笔记本Pro 15.6“频繁蓝屏解决办法

一、事情的缘起 2020年3月&#xff0c;我在小米官网购买这个笔记本&#xff0c;型号为&#xff1a;小米笔记本Pro 15.6" 2019款 四核i5 8G MX250 深灰。当时买这款笔记本&#xff0c;也是考虑到它屏幕比较大&#xff0c;而且配置也不错&#xff0c;四核8G的内存也足够我办…

测试需要写测试用例吗?

如何理解软件的质量 我们都知道&#xff0c;一个软件从无到有要经过需求设计、编码实现、测试验证、部署发布这四个主要环节。 需求来源于用户反馈、市场调研或者商业判断。意指在市场行为中&#xff0c;部分人群存在某些诉求或痛点&#xff0c;只要想办法满足这些人群的诉求…

并行Stream的性能测试

final long count 200_000_000;Random random new Random();//创建2亿条的listList<Integer> list Stream.generate(() -> random.nextInt(20)).limit(count).collect(Collectors.toList());// 顺序处理long startTime System.currentTimeMillis();list.stream().…

C语言联合体和枚举

C语言联合体和枚举 文章目录 C语言联合体和枚举一、联合体①联合体简介②联合体大小的计算 二、枚举 一、联合体 ①联合体简介 union Un {char c;int i; };像结构体一样&#xff0c;联合体也是由⼀个或者多个成员构成&#xff0c;这些成员可以不同的类型。但是编译器只为最大…

【Python数据分析工具】

文章目录 概要整体架构流程技术名词解释 概要 数据分析是一种通过收集、处理、分析和解释大量数据&#xff0c;以发现有价值信息、洞察趋势、制定决策并解决问题的过程。在现代科技和互联网的推动下&#xff0c;数据分析变得日益重要。它不仅仅是对数字和图表的简单解释&#…

GCOV覆盖率分析

安全之安全(security)博客目录导读 覆盖率分析汇总 目录 一、GCOV简介 二、GCOV使用示例 三、GCOV编译命令 四、运行并生成覆盖率报告 五、覆盖率报告分析 一、GCOV简介 因为动态代码分析可能只覆盖部分代码&#xff0c;所以我们需要一个代码覆盖工具&#xff0c;以了解…

APP备案避坑指南,值得收藏

目录 什么时间节点前需完成备案&#xff1f; APP/小程序一定要做备案吗&#xff1f; 涉及前置审批的APP有哪些&#xff1f; APP 支持安卓、IOS 多个运行平台&#xff0c;应该备案多少次&#xff1f; 企业是自有服务器&#xff0c;该如何进行APP备案&#xff1f; APP备案可…

探索服务器的无限潜能:创意项目、在线社区与更多可能

文章目录 1. 创意项目的孵化器1.1 托管你的应用1.2 测试和开发1.3 制定和实施你的计划 2. 构建在线社区2.1 自定义社交网络2.2 数据控制2.3 扩展和改进 3. 其他创意可能性3.1 博客和媒体网站3.2游戏服务器3.3 云存储3.4 数据分析3.5 远程办公 结论 &#x1f389;欢迎来到Java学…

你不一定知道的七种进程间通信方式

一、前言 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到&#xff0c;所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷贝到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信…

Easysearch压缩模式深度比较:ZSTD+source_reuse的优势分析

引言 在使用 Easysearch 时&#xff0c;如何在存储和查询性能之间找到平衡是一个常见的挑战。Easysearch 具备多种压缩模式&#xff0c;各有千秋。本文将重点探讨一种特别的压缩模式&#xff1a;zstd source_reuse&#xff0c;我们最近重新优化了 source_reuse,使得它在吞吐量…

【ROS2RUN源码解析:解决ROS2 run命令找不到问题的详细流程】

文章目录 概要整体架构流程技术名词解释小结 概要 当你在使用ROS2时遇到找不到可执行文件的错误时&#xff0c;首先需要执行以下步骤来诊断问题。首先&#xff0c;使用命令printenv AMENT_PREFIX_PATH&#xff08;或者ros2 pkg prefix加上包的名称&#xff09;来检查你的功能包…

AI :微软推出 AutoGen 框架,帮开发者创建基于大语言模型的复杂应用

本心、输入输出、结果 文章目录 AI :微软推出 AutoGen 框架,帮开发者创建基于大语言模型的复杂应用前言AutoGen 简介快速入门AutoGen 安装相关支持相关代码相关架构图弘扬爱国精神AI :微软推出 AutoGen 框架,帮开发者创建基于大语言模型的复杂应用 编辑:简简单单 Online z…

Chrome 浏览器关闭后再打开,需要重新登录账号,解决办法

最近&#xff08;2023-10-15&#xff09;每次打开 Chrome 浏览器&#xff0c;Chrome 自身账号以及各个网站账号都需要重新登录&#xff0c;电脑本身为家用&#xff0c;使用时间不多的情况下&#xff0c;频繁登录账号很痛苦&#xff0c;也很迷惑。现找到解决办法&#xff0c;记录…