贪玩ML系列之一个BP玩一天

手写串行BP算法,可调batch_size

既要:1、输入层f(x)=x  隐藏层sigmoid 输出层f(x)=x

2、run函数实现单条数据的一次前馈

3、train函数读入所有数据for循环处理每条数据。

循环中:

首先调用run函数,得到各层的值

self.input_nodes_value

self.hidden_nodes_value

self.output_nodes_value

然后计算输出层误差和delta

4、关键函数:用于前馈的sigmoid和用于反馈的sigmoid的导数

 self.activation_function = lambda x : 1/(1+np.exp(-x))  # sigmoid函数,用于正向传播
 self.delta_activation_function = lambda x: x-x**2 # sigmoid一阶导,用于反向传播
inputs = np.array([[0.5, -0.2, 0.1]])
targets = np.array([[0.4]])
test_w_i_h = np.array([[0.1, -0.2],
                       [0.4, 0.5],
                       [-0.3, 0.2]])
test_w_h_o = np.array([[0.3],
                       [-0.1]])
batch_size=1

# 输入层没有激活函数f(x)=x,隐藏层激活函数sigmoid,输出层激活函数f(x)=x
class NeuralNetwork(object):
    def __init__(self, input_nodes, hidden_nodes, output_nodes, learning_rate):

        # Set number of nodes in input, hidden and output layers.
        self.input_nodes = input_nodes
        self.hidden_nodes = hidden_nodes
        self.output_nodes = output_nodes

#         创建三个一维数组存放三层节点的值
#         print(str(self.input_nodes)+" "+str(self.hidden_nodes)+" "+str(self.output_nodes))
        self.input_nodes_value=[1.0]*input_nodes
        self.hidden_nodes_value=[1.0]*hidden_nodes
        self.output_nodes_value=[1.0]*output_nodes

        # Initialize weights
        self.weights_input_to_hidden = np.random.normal(0.0, self.input_nodes**-0.5,
                                       (self.input_nodes, self.hidden_nodes))

        self.weights_hidden_to_output = np.random.normal(0.0, self.hidden_nodes**-0.5,
                                       (self.hidden_nodes, self.output_nodes))
        self.learning_rate = learning_rate

        #### TODO: Set self.activation_function to your implemented sigmoid function ####

        self.activation_function = lambda x : 1/(1+np.exp(-x))  # sigmoid函数,用于正向传播
        self.delta_activation_function = lambda x: x-x**2 # sigmoid一阶导,用于反向传播

        self.change_to_fix_weights_h2o=[[0.0]*self.output_nodes]*self.hidden_nodes
        self.change_to_fix_weights_i2h=[[0.0]*self.hidden_nodes]*self.input_nodes
#         print("xxxx")
#         print(self.change_to_fix_weights_h2o)
#         print(self.change_to_fix_weights_i2h)

    def train(self, features, targets):#完成n条数据的一次前向传递
        ‘‘‘ Train the network on batch of features and targets. 

            Arguments
            ---------

            features: 2D array, each row is one data record, each column is a feature
            targets: 1D array of target values

        ‘‘‘

        ####################modify by zss###############################################

        n=features.shape[0]#数据条数
#         print(features)
#         print(targets)

        counter=batch_size
        for ii in range(0,n):
            print("######",ii)
            print(self.weights_input_to_hidden)
            print(self.weights_hidden_to_output)
#             print(self.run(features[ii]))
#             print(targets[ii])

            error_o=[0.0]*self.output_nodes#输出层误差
            error_h=[0.0]*self.hidden_nodes#隐藏层误差
            output_deltas=[0.0]*self.output_nodes
            hidden_deltas=[0.0]*self.hidden_nodes

            for o in range(self.output_nodes): # 输 出 层
                error_o[o]=targets[ii][o]-self.output_nodes_value[o]#计算输出层误差
                output_deltas[o]=self.delta_activation_function(self.output_nodes_value[o])*error_o[o]

            for h in range(self.hidden_nodes): # 隐 藏 层
                for o in range(self.output_nodes):
                    error_h[h]+=output_deltas[o]*self.weights_hidden_to_output[h][o]
                hidden_deltas[h]=self.delta_activation_function(self.hidden_nodes_value[h])*error_h[h]

            for h in range(self.hidden_nodes):
                for o in range(self.output_nodes):
                    self.change_to_fix_weights_h2o[h][o]+=output_deltas[o]*self.hidden_nodes_value[h]

            for i in range(self.input_nodes):
                for h in range(self.hidden_nodes):
                    self.change_to_fix_weights_i2h[i][h]+=hidden_deltas[h]*self.input_nodes_value[i]

            counter-=1
            if counter==0:#当counter=0,进行一次权重修改
                #调整隐藏层--输出层权重
                for h in range(self.hidden_nodes):
                    for o in range(self.output_nodes):
                        self.weights_hidden_to_output[h][o] += self.learning_rate*self.change_to_fix_weights_h2o[h][o]

                #调整输入层--隐藏层权重
                for i in range(self.input_nodes):
                    for h in range(self.hidden_nodes):
                        self.weights_input_to_hidden[i][h] += self.learning_rate*self.change_to_fix_weights_i2h[i][h]

                self.change_to_fix_weights_h2o=[[0.0]*self.output_nodes]*self.hidden_nodes
                self.change_to_fix_weights_i2h=[[0.0]*self.hidden_nodes]*self.input_nodes
                counter=batch_size
        return self.weights_hidden_to_output

    def run(self, features):#完成一条数据的一次前向传递
        ‘‘‘
            features: 1D array of feature values
        ‘‘‘        

        print(features)

        for i in range(self.input_nodes):
            self.input_nodes_value[i]=features[i]
#             self.input_nodes_value[i]=self.activation_function(features[i])

        for h in range(self.hidden_nodes):
            temp=0
            for i in range(self.input_nodes):
                temp+=self.input_nodes_value[i]*self.weights_input_to_hidden[i][h]
            temp=self.activation_function(temp)
            self.hidden_nodes_value[h]=temp

        for o in range(self.output_nodes):
            temp=0
            for h in range(self.hidden_nodes):
                temp+=self.hidden_nodes_value[h]*self.weights_hidden_to_output[h][o]
#             temp=self.activation_function(temp)
            self.output_nodes_value[o]=temp
        return

def test_run():
    # Test correctness of run method
    network = NeuralNetwork(3, 2, 1, 0.5)
    network.weights_input_to_hidden = test_w_i_h.copy()
    network.weights_hidden_to_output = test_w_h_o.copy()

    print("#####"+str(network.run(np.array([0.5, -0.2, 0.1]))))
    print(np.allclose(network.run(np.array([0.5, -0.2, 0.1])), 0.09998924))
    return

def test_train():
    # Test that weights are updated correctly on training
    network = NeuralNetwork(3, 2, 1, 0.5)
    network.weights_input_to_hidden = test_w_i_h.copy()
    network.weights_hidden_to_output = test_w_h_o.copy()
    network.train(inputs, targets)

    print(np.allclose(network.weights_hidden_to_output,
                                np.array([[ 0.37275328],
                                            [-0.03172939]])))
    print(np.allclose(network.weights_input_to_hidden,
                                np.array([[ 0.10562014, -0.20185996],
                                            [0.39775194, 0.50074398],
                                            [-0.29887597, 0.19962801]])))
test_train()

可以看出结果比较接近,但是还是不满足allclose 5%的要求,因为只迭代了一次,多迭代几次精确率就会进一步上升,未完待续

allclose结果为false

原文地址:https://www.cnblogs.com/zealousness/p/9351799.html

时间: 2024-10-21 20:21:47

贪玩ML系列之一个BP玩一天的相关文章

随心篇第七期:我是一个爱玩游戏的孩子

我是一个爱玩游戏的孩子,从小时记事起到现在,从没离开过游戏 你可能会问:你爸爸妈妈不管你吗? 好吧,爸爸妈妈有管,但是家里做买卖,比较忙,哪里有空呢 多亏爸爸妈妈没有管我玩游戏,要不然真的会阻止我游戏方面天赋成长的啊 最近正在玩的游戏是炉石和D3,当然了,有一起玩的可以随时来叫我哦 我的战网账号:[email protected] 我玩游戏的时候很认真的,就像我平常做事情一样,很少溜号的,因为那些是不好的习惯,所以我们要抵制才好 我喜欢调研,在游戏中,我擅长玩一些单机游戏,经常会去思考,而不是无

怎样才能成为一个电玩程序员(转)

电玩游戏广受青少年们欢迎,其中不少年轻人专注于此,甚至想到要自己编写一个游戏.另外一方面电玩游戏工程师被大多数人认为是大有"钱"途的.如果你做的游戏走红了,成为百万富翁也是分分钟的事情.要是你果真对电玩有着持续的热情,且立志成为电玩工程师,我这里有心得可以分享.如果你够努力,够诚心,就一定没问题!关键是要对自己有信心. 1.资讯灵通: 经常和相关同行啊前辈们交流,走访校园,多阅读些关于电玩编程的杂志书籍,电子书什么的.这样就能更加了解你将要进入的领域究竟是什么样儿的.同时还能了解到要成

net core天马行空系列: 一个接口多个实现类,利用mixin技术通过自定义服务名,实现精准属性注入

系列目录 1.net core天马行空系列:原生DI+AOP实现spring boot注解式编程 2.net core天马行空系列: 泛型仓储和声明式事物实现最优雅的crud操作 哈哈哈哈,大家好,我就是高产似母猪的三合.日常开发中,我们常会遇到这样的场景,一个接口,有多个实现类,在某个业务中,我们希望指定某个实现类,如今网络上常见的解决方案,就是注入一个委托或者利用工厂模式,这些方式虽然能实现功能,但使用起来还是不够优雅,如何才称得上优雅呢?自然是在添加服务的时候给服务指定名称,注入的时候根据

NET中小型企业项目开发框架系列(一个)

当时的前端,我们开发了基于Net一组结构sprint.NET+NHibernate+MVC+WCF+EasyUI等中小型企业级系统开发平台,如今把整个开发过程中的步步进展整理出来和大家分享,这个系列可能有点长.多多指导学习.        我们的底层开发平台是sprint.NET+NHibernate+MVC+WCF+EasyUI方式开发,顺便加点Spring.net注入的部分,当然我们最基本的关于权限设计.业务设计,而架构.咱们没有学过太复杂的架构.我们还是以最经常使用的MVC架构開始拓展 參

漫谈程序员系列:一个老程序员的2014年终总结

人生天地之间,若白驹过隙,忽然而已.蓦然回首,头上似霜雪,脸上似山川.我的 2014 啊,你就这么毫无眷恋地离我而去了.既然往事已不可追,未来尚未到来,在这年末岁首的间隙,就让我来回忆一下余烟尚存的 2014 吧. 2014 年,对我而言,发生了很多事,不管怎样,我还是一个程序员,这是工作.生活,以及我自己,给我的标签.也许很快这个标签会泛黄.蝶化.零落成泥碾作尘,不过不论怎样,它是我青春的纪念,它仍将伴随着我继续前行. 坚持技术博客写作 看到这里,也许你笑了. 是啊,这一年我不务正业,虽然每周

写一下自己一个星期玩树莓派的经验,如何安装系统,如何在树莓派中安装opencv,如何运行代码。

在树莓派上安装opencv最简单的方法是: sudo apt-get update sudo apt-get install libopencv-dev sudo apt-get install python-opencv 如果你还想了解更多,下面提供的那么多链接中你一定找到方法的,饭都送到你面前你不会吃,那么你活该饿着. 平时自己习惯用vim 所以在树莓派上安装了vim编辑器 安装命令  sudo apt-get  install  vim 就可以了. 好了,可以运行一个opencv的例子来检

Appium自动化测试系列2- 写一个Python测试脚本来测试一下YY语音

我们在<Appium自动化测试系列1-Appium环境的安装和配置>里已经搭好了Appium的基本环境,这一章,我们就来真刀真枪使用一下Appium, 看看Appium是如果来实现自动化测试的.在写测试脚本之前,我们先安装几个必要的Python三方库. 1 安装Python的setuptools库 (因为安装Python的Selenium库需要用到它) 1) 下载setuptools文件并解压 https://pypi.python.org/pypi/setuptools/12.0.4#dow

JavaWeb学习系列——第一个JavaWeb程序

Eclipse中新建一个Dynamic Web Project 指定项目名称.依赖环境 勾选生成web.xml选项 更改项目编译输出目录,项目右键 ->properties ->Java Build Path ->source ->Default output folder,修改为JavaWeb01/WebContent/WEB-INF/classes 在WebContent文件夹下新建一个index.jsp文件,修改其代码如下 <%@ page language="

【给你一个承诺 - 玩转 AngularJS 的 Promise】

了解Promise 在谈论Promise之前我们要了解一下一些额外的知识:我们知道JavaScript语言的执行环境是"单线程",所谓单线程,就是一次只能够执行一个任务,如果有多个任务的话就要排队,前面一个任务完成后才可以继续下一个任务. 这种"单线程"的好处就是实现起来比较简单,容易操作:坏处就是容易造成阻塞,因为队列中如果有一个任务耗时比较长,那么后面的任务都无法快速执行,或导致页面卡在某个状态上,给用户的体验很差. 当然JavaScript提供了"异