机器学习期末复习 BP神经网络的推导,4X4X3,激活函数变为Logistic函数,其他不变

news2024/11/25 10:09:10

刚写完了bp神经网络的实验课代码,对这个比较熟悉(后面给出实现代码)

Logistic函数也就是sigmod函数,表达式是这样的:

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

sigmod函数是隐层和输出层的激活函数(sigmod函数记作f(x),它的导数记作f `(x)),它有一个特点是f `(x)=f(x)*(1 - f(x)),这个特点在推导参数更新公式中有用到。

本题中题干给出的是4X4X3的神经网络,也就是输入层为4,隐层为4,输出层为3。

首先是前向传播过程:

我这里层与层之间的权值只画出了一部分,这里面的某些变量的值和我给出的代码不是一一对应的。

输入层的大小为d=4,输入层下标的变量用i表示

隐层的大小为q=4,隐层下标的变量用h表示

输出层的大小为l=3,输出层下标的变量用j表示

X[i]代表输入的特征

 V[i][h]代表输入层和隐层之间的权值

p[h]代表与这个结点相连的4个输入层结点与对应权值v相乘再相加的结果

sitah是隐层结点

b[h]是经过激活函数之后输出的值,即b[h]=sigmod(p[h]-sitah)

W[h][j]是隐层与输出层的权值

m[j]代表与这个结点相连的4个隐层结点与对应权值w相乘再相加的结果

sitay是输出层结点

Y[j]是经过激活函数之后输出的值,即Y[j]=sigmod(m[j]-sitay)

最后我们通过Ek来评估模型输出的好坏:

 (括号里面是我们通过训练集计算得的结果减去训练集给出的正确的结果)

推导过程中的注意事项是一个w[h][j]或一个sitay只会影响一个输出值y[j];

每一个w[h][j]仅会影响与他相连的那唯一一个输出值y[j],其实上面那个公式中的Ek是对全部输出值y[j]来说的,但是我们求的偏导是关于w[h][j],w[h][j]只与y[j]有关系,这样其他的y[1],y[2]啥的无关项就是常数,求偏导就消去了。

 sitay同理。

但是一个v[i][h]或者sitah会影响全部的输出值y;

v[i][h]影响所有输出值y的原因是通过v[i][h]计算并激活(用到sitah)得到的b[h],这个b[h]参与到了所有的y的运算中,sitah同理。

所以推导中w和sitay有共同之处,v和sitah有共同之处。

参考文章:

详解BP神经网络

实现代码:

Iris训练集网上一搜就有

import math
import random
import numpy as np


def readFile(filename, nums, len):
    """
    读取iris.txt
    iris.txt为150行,每行有5个数据,前4个数据为特征,第五个为所属的类
    训练分为全训练和部分训练(打乱顺序)
    训练时传入某一行的四个参数,即输入层为4
    因为有3类,所以输出层为3,当读入类别时,需要额外做一些处理,不能只读入数值
    所以读取数据时全读入,保存到列表中,再根据要求划分出训练集和测试集
    流程:
    全读入--打乱--按nums划分训练集和测试集--返回
    参数
    len:文件的行数
    nums:范围为(0-1]的数,1 代表全训练,全为测试集,2/3 代表2/3为训练集,1/3为测试集
    filename:读取的文件的地址
    返回值
    train:训练集
    test:测试集
    """
    train_part = int(len * nums)
    test_part = len - train_part
    if nums == 1:  # 初始化训练集和测试集
        train = [[] for i in range(len)]
        test = [[] for i in range(len)]
    else:
        train = [[] for i in range(train_part)]
        test = [[] for i in range(test_part)]

    f = open(filename, 'r')
    filesave = [[] for i in range(len)]  # 初始化全集
    for i in range(len):
        s = f.readline()
        s = s.strip('\n')
        s = s.strip(' ')
        x = s.split('\t')

        for j in range(4):
            filesave[i].append(eval(x[j]))

        if eval(x[-1])==1:
            filesave[i].append([1,0,0])
        elif eval(x[-1])==2:
            filesave[i].append([0,1,0])
        else:
            filesave[i].append([0,0,1])

    numbers = [i for i in range(len)]  # 进行打乱处理
    random.shuffle(numbers)

    if nums == 1:
        for i in range(len):
            train[i] = filesave[numbers[i]]
        test = train[:]
    else:
        j = 0
        for i in range(train_part):
            train[i] = filesave[numbers[i]]
        for i in range(train_part, len):
            test[j] = filesave[numbers[i]]
            j += 1

    return train, test


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


class bp_network:
    def __init__(self, train, test, cycles=1200,key=100,node_input=4, node_hide=4, node_output=3):
        """
        初始化:
        输入层到隐层的权值v 4*4
        隐层到输出层的权值w 4*3
        隐层的阈值sitah 4
        输出层的阈值sitay 3
        学习率n

        :param train: 训练集
        :param test: 测试集
        :param cycles: 总训练轮数
        :param key: 每隔多少轮测试一次错误率
        :param node_input: 输入层结点个数
        :param node_hide: 隐层结点个数
        :param node_output: 输出层结点个数
        """
        self.node_input = node_input
        self.node_hide = node_hide
        self.node_output = node_output
        self.train = train
        self.test = test
        self.n = 0.01
        self.cycles=cycles
        self.key=key

        self.sitay = []  # 输出层阈值
        self.sitah = []  # 隐藏层阈值
        self.w = [[] for i in range(node_hide)]  # 隐藏层到输出层权值4*3
        self.v = [[] for i in range(node_input)]  # 输入层到隐藏层权值4*4

        #w[h][j] 4*3
        for j in range(self.node_output):
            self.sitay.append(random.random())  # 输出层阈值
            for h in range(self.node_hide):
                self.w[h].append(random.random())
        #v[i][h] 4*4
        for h in range(self.node_hide):
            self.sitah.append(random.random())  # 隐藏层阈值
            for i in range(self.node_input):
                self.v[i].append(random.random())

    def bp_predict(self,p):
        """
        预测函数,用于测试错误率
        思路:遍历测试集,计数错误预测个数
        :param p: 第几轮
        :return: 无
        """
        wrong = 0
        for k in range(len(self.test)):
            bi = [0 for i in range(self.node_hide)]  # 隐层激活后输出
            yi = [0 for i in range(self.node_output)]  # 输出层输出

            for h in range(self.node_hide):
                for i in range(self.node_input):
                    bi[h] += self.v[i][h] * self.test[k][i]
                bi[h] = sigmoid(bi[h] - self.sitah[h])

            for j in range(self.node_output):  # 3
                for h in range(self.node_hide):  # 4
                    yi[j] += self.w[h][j] * bi[h]
                yi[j] = sigmoid(yi[j] - self.sitay[j])

            if test[k][-1][yi.index(max(yi))] ==0:
                wrong += 1
        print("第",int(p/self.key),"轮正确率:", (1-wrong / len(test)) * 100, "%")

    def bp_train(self):
        """
        训练函数,用于训练
        :return: 无
        """
        for p in range(self.cycles):
            for k in range(len(self.train)):
                bi = [0 for i in range(self.node_hide)]  # 隐层激活后输出6
                yi = [0 for i in range(self.node_output)]  # 输出层输出
                gi = []#输出层梯度
                eh = []#隐层梯度
                # w[h][j] 4*3  v[i][h] 4*4
                for h in range(self.node_hide):
                    for i in range(self.node_input):
                        bi[h] += self.v[i][h] * self.train[k][i]
                    bi[h] = sigmoid(bi[h] - self.sitah[h])

                for j in range(self.node_output):  # 3
                    for h in range(self.node_hide):  # 4
                        yi[j] += self.w[h][j] * bi[h]
                    yi[j] = sigmoid(yi[j] - self.sitay[j])

                for i in range(self.node_output):
                    gi.append(yi[i] * (1 - yi[i]) * (train[k][-1][i] - yi[i]))

                for h in range(self.node_hide):
                    temp = 0
                    for j in range(self.node_output):
                        temp += self.w[h][j] * gi[j]
                    eh.append(bi[h] * (1 - bi[h]) * temp)

                for h in range(self.node_hide):
                    for j in range(self.node_output):
                        self.w[h][j] += self.n * gi[j] * bi[h]
                for j in range(self.node_output):
                    self.sitay[j] += -self.n * gi[j]
                for h in range(self.node_hide):
                    for i in range(self.node_input):
                        self.v[i][h] += self.n * eh[h] * train[k][i]
                for h in range(self.node_hide):
                    self.sitah[h] += -self.n * eh[h]

            if p % self.key == 0:
                self.bp_predict(p)

if __name__ == "__main__":
    train, test = readFile("D:\\PythonProject_Class\\test_Data\\iris.txt", 2/3, 150)
    bp = bp_network(train, test,node_hide=5,cycles=2400)
    bp.bp_train()

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

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

相关文章

如何本地搭建Plex私人影音云盘教程,实现Plex家庭影音中心,打造超级多媒体中心

文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 转发自CSDN远程穿透的文章:免费搭建Plex家庭影音中心 - 打造超级多媒体中心【公网远程访问…

WEBPACK、VITE 常用配置(对照)及迁移指南

文中 Webpack 版本为 5.x,Vite 版本为 4.3.x webpack 是新一代构建工具里面的老大哥了,从 2013 年发布已经持续升级 10 年,形成完备的生态环境。vite 则是下一代前端开发与构建工具,2019年发布,最新发布版本 4.3.3&…

文件操作安全之-文件上传告警运营篇

本文从文件上传的定义,文件上传的IDS规则,文件上传的示例,文件上传的告警研判,文件上传的处置建议等几个方面阐述如何通过文件上传类型的告警的线索,开展日常安全运营工作,从而挖掘有意义的安全事件。 文件…

rtl仿真器-iverilog icarus安装和测试

Icarus Verilog是一个轻量、免费、开源的Verilog编译器,基于C实现,开发者是 Stephen Williams ,遵循 GNU GPL license 许可证,安装文件中已经包含 GTKWave支持Verilog/VHDL文件的编译和仿真,命令行操作方式&#xff0c…

C语言函数大全-- _w 开头的函数(1)

C语言函数大全 本篇介绍C语言函数大全-- _w 开头的函数 1. _waccess 1.1 函数说明 函数声明函数功能int _waccess(const wchar_t* path, int mode);用于测试文件或目录是否存在,并检查程序是否具有对它们的访问权限 参数: path : 待测试的…

Elasticsearch(三)

Elasticsearch(三) 数据聚合 聚合的分类 文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html 聚合可以实现对文档数据的统计、分析、运算。聚合常见的有三类: 桶聚合:用来对文档做分组 Te…

【P22】JMeter 调试后置处理程序(Debug PostProcessor)

&#xff08;1&#xff09;、测试计划右键 <<< 添加 <<< 线程&#xff08;用户&#xff09;<<< 线程组 默认参数即可 &#xff08;2&#xff09;、线程组右键 <<< 添加 <<< 取样器 <<< 调试取样器 默认参数即可 &…

SQL复习(一)——安装

1 mysql卸载 reference&#xff1a;https://blog.csdn.net/m0_67392273/article/details/126066580 Step1:停止MySql服务 在卸载之前&#xff0c;先停止MySQL8.0的服务 搜索“服务”&#xff0c;找到“MySQL”&#xff0c;右键点击选择“停止” Step2&#xff1a;软件的卸…

Unittest自动化测试之unittestunittest_生成测试报告

unittest_生成测试报告 测试报告为测试结果的统计即展示&#xff0c;是自动化测试不可或缺的一部分&#xff0c;利用unittest 可以生成测试报告 方式一、使用第三方 HTMLTestRunner 执行测试用例集&#xff0c;生成网页版测试报告&#xff08;推荐&#xff09; HTMLTestRunn…

5年软测经验去面试25k测试岗,看到这样的面试题我还是心虚了....

我是着急忙慌的准备简历——5年软件测试经验&#xff0c;可独立测试大型产品项目&#xff0c;熟悉项目测试流程...薪资要求&#xff1f;5年测试经验起码能要个25K吧 我加班肝了一页半简历&#xff0c;投出去一周&#xff0c;面试电话倒是不少&#xff0c;自信满满去面试&#…

系统掌握入河排污口设置论证技术、方法及报告编制框架

在短时间内较系统的掌握入河排污口设置论证技术、方法及报告编制框架&#xff0c;学习内容以城镇生活污水厂、造纸项目、石化项目、制药项目案例为线索&#xff0c;系统讲解入河排污口设置论证报告书编制过程&#xff0c;并以水质模型为手段&#xff0c;讲解水质影响预测模型的…

Voice Control for ChatGPT 沉浸式的与ChatGPT进行交流学习。

Voice Control for ChatGPT 日常生活中&#xff0c;我们与亲人朋友沟通交流一般都是喜欢语音的形式来完成的&#xff0c;毕竟相对于文字来说语音就不会显的那么的苍白无力&#xff0c;同时最大的好处就是能解放我们的双手吧&#xff0c;能更快实现两者间的对话&#xff0c;沟通…

华为OD机试真题 Java 实现【简单的自动曝光】【2023Q1 100分】

一、题目描述 一个图像有 n 个像素点&#xff0c;存储在一个长度为 n 的数组 img 里&#xff0c;每个像素点的取值范围[0,255]的正整数。 请你给图像每个像素点值加上一个整k(可以是负数)&#xff0c;得到新图 newlmg&#xff0c;使得新图 newlmg 的所有像素平均值最接近中位…

响应式设计和移动端优化:如何实现页面在不同设备上的适配和优化

章节一&#xff1a;介绍响应式设计和移动端优化 响应式设计是一种使网页能够自适应不同设备和屏幕尺寸的设计方法。它通过使用流式网格布局、媒体查询和弹性图片等技术&#xff0c;使得网页能够在不同分辨率和设备上呈现出最佳的布局和用户体验。 移动端优化则是针对移动设备…

青训营 x 训练营结营测试题目(前端方向)

文章目录 &#x1f4cb;前言&#x1f3af;选择题&#xff08;含多选&#xff09;&#x1f4dd;最后 &#x1f4cb;前言 这篇文章的内容是23年6月青训营 x 训练营结营题目&#xff0c;题目一共有25题&#xff0c;题目类型为选择题&#xff0c;包括了单选题和多选题&#xff0c;…

WiFi(Wireless Fidelity)基础(十二)

目录 一、基本介绍&#xff08;Introduction&#xff09; 二、进化发展&#xff08;Evolution&#xff09; 三、PHY帧&#xff08;&#xff08;PHY Frame &#xff09; 四、MAC帧&#xff08;MAC Frame &#xff09; 五、协议&#xff08;Protocol&#xff09; 六、安全&#x…

VHDL直流电机模糊控制器的设计与实现

在直流电机控制策略方面,属于智能控制理论的模糊控制其突出优点在于它不依赖于被控对象的模型,因此本设计尝试将模糊控制理论应用于直流电机转速控制,并将模糊控制器实现于FPGA(Field Programmable Gate Array)芯片上。在实现方法上本设计采用模糊查表控制法实现模糊控制器…

【C++】-static在类和对象中的作用和细节(下)

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树 ❤️‍&#x1fa79;作者宣言&#xff1a;认真写好每一篇博客 &#x1f4a8;作者gitee:gitee &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 文章目录 前言 前言 今天我们来讲一个static对类的对象的作用…

安全基础第十二天:nginx相关配置和nginx-host绕过

目录 一、nginx的动静分离 1.动静分离的原理 2.动静分离实验&#xff08;centos做为放置静态资源的服务器&#xff0c;ubuntu做为请求的web服务器&#xff09; &#xff08;1&#xff09;在centos的/usr/local/nginx/html下创建一个静态文件static &#xff08;2&#xff09…