0

0

使用 Python 和 NumPy 为神经网络创建简单高效的遗传算法

碧海醫心

碧海醫心

发布时间:2024-12-11 08:30:15

|

351人浏览过

|

来源于dev.to

转载

使用 python 和 numpy 为神经网络创建简单高效的遗传算法

这是有关 ml 进化算法课程的第一篇文章。

当你知道神经网络的参数,但不知道输出应该是什么时,就需要遗传算法,例如,这个算法可以用来玩 google dinosaur 或 flappy bird,因为你不知道输出应该是什么,但您有能力对最可行的选项进行排序,例如按时间,这称为适应度函数。

我一直没能找到这样一个有效、简单且可用的算法,所以我开始创建自己的轻量级、简单、完美运行的遗传算法。

我的目的不是拖拖拉拉地写这篇文章,也不是用它的篇幅来折磨读者,所以我们直接上代码吧。正如已经提到的,代码很简单,所以大部分内容不需要在整篇文章中描述。

立即学习Python免费学习笔记(深入)”;

首先我们需要导入模块:

import numpy as np
import random

然后我们添加dataset及其答案,但不使用反向传播算法,而只是统计正确答案的数量。然后你可以在其他变体上进行测试,这些变体现在已被注释掉

银河易创
银河易创

一站式AIGC创作平台,集成GPT-3.5、GPT-4、文心一言等对话模型、Midjourney、DallE等绘画工具、AI音乐、AI视频和AI PPT等功能!

下载
x = np.array([[1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0], [0, 1, 1], [1, 1, 1]])
y = np.array([[0],[1],[1], [0], [0], [0], [0], [1], [1]])

#x = np.array([[0, 1, 1], [0, 0, 1], [1, 0, 1], [0, 1, 0], [1, 0, 0], [1, 1, 0], [0, 0, 0], [1, 1, 0], [1, 1, 1]])
#y = np.array([[1],[0], [0], [1], [0], [1], [0], [1], [1]])

#x = np.array([[1, 1, 0], [0, 0, 1], [1, 0, 1], [0, 1, 0], [1, 0, 0], [0, 0, 0], [1, 1, 0], [0, 1, 1], [1, 1, 1]])
#y = np.array([[1],[0],[1], [0], [1], [0], [1], [0], [1]])

添加列表和激活函数。这些列表的含义稍后将会变得清晰。第一个激活函数是 sigmoid,第二个是阈值。

listnet = []
newnet = []
goodnet = []
goodnet0 = []
goodnet1 = []
goodnet2 = []
goodnet3 = []
goodnet4 = []
goodnet5 = []
goodnet6 = []
good = 0
epoch = 0

good = 0
epoch = 0

def sigmoid(x):
    return 1/(1 + np.exp(-x)) 
def finfunc(x):
    if x[0] >= 0.5:
        x[0] = 1
        return x[0]

    else:
        x[0] = 0
        return x[0]

接下来,我们需要创建两个类,第一个类用于创建初始群体,第二个类用于所有后续群体,因为第一次我们需要随机创建权重,然后仅交叉和使它们变异。 init() 函数用于创建或添加权重,predict() 是算法本身和计算最佳选项所必需的,fredict() 函数的不同之处在于它返回答案和适应度函数来显示数字在屏幕上查看训练阶段。在输出层,首先使用 sigmoid 函数使答案更接近其中一个选项,然后才使用阈值函数。

class network():
    def __init__(self):
        self.h1 = np.random.randn(3, 6)
        self.o1 = np.random.randn(6, 1)

    def predict(self, x, y):
        t1 = x @ self.h1
        t1 = sigmoid(t1)
        t2 = t1 @ self.o1
        t2 = sigmoid(t2)
        t2 = finfunc(t2)
        if t2 == y[0]:
            global good
            good += 1

    def fpredict(self, x, y):
        t1 = x @ self.h1
        t1 = sigmoid(t1)
        t2 = t1 @ self.o1
        t2 = sigmoid(t2)
        t2 = finfunc(t2)
        if t2 == y[0]:
            global good
            good += 1
        return t2, good
class network1():
    def __init__(self, h1, o1):
        self.h1 = h1
        self.o1 = o1


    def predict(self, x, y):
        t1 = x @ self.h1
        t1 = sigmoid(t1)
        t2 = t1 @ self.o1
        t2 = sigmoid(t2)
        t2 = finfunc(t2)
        if t2 == y[0]:
            global good
            good += 1
    def fpredict(self, x, y):
        t1 = x @ self.h1
        t1 = sigmoid(t1)
        t2 = t1 @ self.o1
        t2 = sigmoid(t2)
        t2 = finfunc(t2)
        if t2 == y[0]:
            global good
            good += 1
        return t2, good

我们输出第一个答案和变量good,这是这里的适应度函数,然后我们为下一个神经网络重置它,打印“wait0”(你可以在这里写任何你想要的东西)是必要的,以免对不同神经网络的答案从哪里开始感到困惑。

s = network()
print(s.fpredict(x[0], y[0]))
print(s.fpredict(x[1], y[1]))
print(s.fpredict(x[2], y[2]))
print(s.fpredict(x[3], y[3]))
print("wait0")
good = 0

第一个周期过去了,在这里以及随后的所有周期中,我们只给出了六个问题来检查它如何处理任务,而它还没有满足,也就是说,我们检查它是否临时抱佛脚,这种情况有时会发生。现在让我们更详细地讨论一下:根据它正确回答了多少个答案,我们将其分配给其中一个类,如果大量答案是正确的,那么我们必须支持这样的神经网络并增加其数量,以便随着随后的变异将会出现更多更聪明的人,要理解这一点,你可以想象100个人中有一个天才,但这对于每个人来说是不够的,这意味着他的天才将在下一代中消失,这意味着神经网络要么学习速度非常慢,要么根本不存在,为了避免这种情况,我们增加了循环中具有大量正确答案的神经网络的数量。最后,我们清空主 listnet 列表,按照从最好到最差的顺序为其分配 goodnet 列表的新值,筛选出 100 个最佳个体,用于后续突变。

for s in range (1000):
    s = network()
    good = 0
    s.predict(x[0], y[0])
    s.predict(x[1], y[1])
    s.predict(x[2], y[2])
    s.predict(x[3], y[3])
    s.predict(x[4], y[4])
    s.predict(x[5], y[5])
    if good == 6:
        goodnet6.append(s)
        for r in range(15):
            goodnet4.append(s)
    elif good == 5:
        goodnet5.append(s)
        for r in range(10):
            goodnet4.append(s)
    elif good == 4:
        goodnet4.append(s)
        for r in range(5):
            goodnet4.append(s)
    elif good == 3:
        goodnet3.append(s)
    elif good == 2:
        goodnet2.append(s)
    elif good == 1:
        goodnet1.append(s)
    elif good == 0:
        goodnet0.append(s)
    good = 0
listnet = []
listnet.extend(goodnet6)
listnet.extend(goodnet5)
listnet.extend(goodnet4)
listnet.extend(goodnet3)
listnet.extend(goodnet2)
listnet.extend(goodnet1)
goodnet1 = []
goodnet2 = []
goodnet3 = []
goodnet4 = []
goodnet5 = []
goodnet6 = []
goodnet = listnet[:100]
listnet = goodnet
goodnet = []

交叉和变异本身:我们从第一个亲本中取出一部分,从第二个中取出第二部分,进行变异,然后我们在 newnet 列表中得到一个孩子,所以 1000 次。

for g in range(1000):
    parent1 = random.choice(listnet)
    parent2 = random.choice(listnet)
    ch1h = np.vstack((parent1.h1[:1], parent2.h1[1:])) * random.uniform(-0.2, 0.2)
    ch1o = parent1.o1 * random.uniform(-0.2, 0.2)
    g = network1(ch1h, ch1o)
    newnet.append(g)
listnet = newnet
newnet = []

从代码的前一部分开始,我们使用 network1(),因为我们现在是交叉和变异,而不是随机创建。所以我们需要重复 1000 次(这是一个超参数,所以你可以自己选择 epoch 的数量,15 对我来说就足够了),我们在第一个 epoch 上显示答案,第 1000 个是最终版本(如果你有,例如,20,然后指定 20)。这里代码是重复的,所以我就不描述了,一切都很清楚了。

for i in range(1000):
    good = 0
    epoch += 1
    for s in listNet:
      good = 0
      s.predict(x[0], y[0])
      s.predict(x[1], y[1])
      s.predict(x[2], y[2])
      s.predict(x[3], y[3])
      s.predict(x[4], y[4])
      s.predict(x[5], y[5])
      if good == 6:
          GoodNet6.append(s)
          for r in range(15):
              GoodNet4.append(s)
      elif good == 5:
          GoodNet5.append(s)
          for r in range(10):
              GoodNet4.append(s)
      elif good == 4:
          GoodNet4.append(s)
          for r in range(5):
              GoodNet4.append(s)
      elif good == 3:
          GoodNet3.append(s)
      elif good == 2:
          GoodNet2.append(s)
      elif good == 1:
          GoodNet1.append(s)
      elif good == 0:
          GoodNet0.append(s)
      good = 0
    listNet = []
    listNet.extend(GoodNet6)
    listNet.extend(GoodNet5)
    listNet.extend(GoodNet4)
    listNet.extend(GoodNet3)
    listNet.extend(GoodNet2)
    listNet.extend(GoodNet1)
    GoodNet1 = []
    GoodNet2 = []
    GoodNet3 = []
    GoodNet4 = []
    GoodNet5 = []
    GoodNet6 = []
    goodNET = listNet[:100]
    listNet = goodNET
    goodNET = []
    if epoch == 1000:

        print(listNet[0].Fpredict(x[0], y[0]))
        print(listNet[0].Fpredict(x[1], y[1]))
        print(listNet[0].Fpredict(x[2], y[2]))
        print(listNet[0].Fpredict(x[3], y[3]))
        print(listNet[0].Fpredict(x[4], y[4]))
        print(listNet[0].Fpredict(x[5], y[5]))
        print(listNet[0].Fpredict(x[6], y[6]))
        print(listNet[0].Fpredict(x[7], y[7]))
        print(listNet[0].Fpredict(x[8], y[8]))

        good = 0
        print('wait')
    elif epoch == 1:

        good = 0
        print(listNet[0].Fpredict(x[0], y[0]))
        print(listNet[0].Fpredict(x[1], y[1]))
        print(listNet[0].Fpredict(x[2], y[2]))
        print(listNet[0].Fpredict(x[3], y[3]))
        print('wait1')
    for g in range(1000):
        parent1 = random.choice(listNet)

        parent2 = random.choice(listNet)
        ch1H = np.vstack((parent1.H1[:1], parent2.H1[1:])) * random.uniform(-2, 2)
        ch1O = parent1.O1 * random.uniform(2, 2)
        g = Network1(ch1H, ch1O)
        NewNet.append(g)
    listNet = NewNet

这就是神经网络应该找到的模式,这就是最终版本所依赖的数字(第一,第二,第三)并忽略其余的。例如,您可以执行逻辑运算(xor、not、and ...),仅在这种情况下,在网络类中将输入数据更改为 2,我还遵循隐藏层中的神经元等于输入的规则数据乘以二,它起作用了,但是你可以尝试你的选择,向神经网络提供相同数量的一些答案和其他答案也很重要,以便正确答案的数量,例如“a”,将等于“b”,否则神经网络将回答所有答案同样的方式,也就是说,如果有更多的 a,那么它会回答所有问题,但不会有任何结果,也在训练样本中给它完全不同的选项,以便它理解模式,例如,如果你一个xor块,那么你必须添加一个带有两个1的选项,但是在逻辑运算的情况下,你必须给出所有选项,因为它们太少了,它不会理解任何东西。
就是这样!!!下一篇文章(必读!):很快……
代码:https://github.com/lanskoykirill/gennumpy.git

我的网站(可能正在重新设计):selfrobotics.space

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
github中文官网入口 github中文版官网网页进入
github中文官网入口 github中文版官网网页进入

github中文官网入口https://docs.github.com/zh/get-started,GitHub 是一种基于云的平台,可在其中存储、共享并与他人一起编写代码。 通过将代码存储在GitHub 上的“存储库”中,你可以: “展示或共享”你的工作。 持续“跟踪和管理”对代码的更改。

4085

2026.01.21

自建git服务器
自建git服务器

git服务器是目前流行的分布式版本控制系统之一,可以让多人协同开发同一个项目。本专题为大家提供自建git服务器相关的各种文章、以及下载和课程。

978

2023.07.05

git和svn的区别
git和svn的区别

git和svn的区别:1、定义不同;2、模型类型不同;3、存储单元不同;4、是否拥有全局版本号;5、内容完整性不同;6、版本库不同;7、克隆目录速度不同;8、分支不同。php中文网为大家带来了git和svn的相关知识、以及相关文章等内容。

579

2023.07.06

git撤销提交的commit
git撤销提交的commit

Git是一个强大的版本控制系统,它提供了很多功能帮助开发人员有效地管理和控制代码的变更,本专题为大家提供git 撤销提交的commit相关的各种文章内容,供大家免费下载体验。

275

2023.07.24

git提交错误怎么撤回
git提交错误怎么撤回

git提交错误撤回的方法:git reset head^:撤回最后一次提交,恢复到提交前状态。git revert head:创建新提交,内容与之前提交相反。git reset :使用提交的 sha-1 哈希撤回指定提交。交互式舞台区:标记要撤回的特定更改,然后提交,排除已撤回更改。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

568

2024.04.09

git怎么对比两个版本的文件内容
git怎么对比两个版本的文件内容

要对比两个版本的 git 文件,请使用 git diff 命令:git diff 比较工作树和暂存区之间的差异。git diff 比较两个提交或标签之间的差异。git diff 输出显示差异块,其中 + 表示添加的行,- 表示删除的行, 表示修改的行。可使用 gitkraken、meld、beyond compare 等可视化工具更直观地查看差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

532

2024.04.09

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

494

2023.08.14

http与https有哪些区别
http与https有哪些区别

http与https的区别:1、协议安全性;2、连接方式;3、证书管理;4、连接状态;5、端口号;6、资源消耗;7、兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2903

2024.08.16

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号