python实现单隐层神经网络基本模型

应朋友之请写了一份python实现单隐层BP Ann model的code,好久没写博客,就顺便发上来。这篇代码比较干净利落,比较纯粹的描述了Ann的基本原理,初学机器学习的同学可以参考。

模型中几个比较重要的参数:

1.学习率

学习率是影响模型收敛的重要因素,一般来说要根据具体场景灵活调整,过高的学习率会使得函数快速发散。

2.隐元数量

一般来说,增加隐层中神经元的数量比直接增加隐层更加有效,这也是单隐层神经网络的特点。对于复杂程度不算太高的问题而言,单隐层的效果优于多隐层。

3.随机种子位数

代码中增加了这一参数,来控制初始化连接权与阈值的精度。由于神经网络中初始权重与阈值是随机生成的,那么其随机精度会对结果产生一定的影响。在输入元、隐元的数量较多时,调整随机精度会起到减小误差的作用。

代码中举了一个非常简单的训练示例,笔者自拟了一个规则:

输入两个变量,当变量A = 变量B时,返回类型1,矩阵化为[1,0]。当变量A != 变量B时,返回类型2,矩阵化为[0,1]。

让神经网络去学习这个simple的规则,并给出20条测试数据去验证。最终使用了5000条训练数据,就获得了100%的正确分类能力。

#---Author:伍思磊---
#---Mail:[email protected]
#---2015/7/27---

import random
import math

#---神经网络Model---
class Ann:
    #构造函数 初始化模型参数
    def __init__(self, i_num, h_num, o_num):
        #可调参数
        self.learn_rate = 0.1    #学习率
        self.num_long = 2        #输出结果位数
        self.random_long = 10    #随机种子位数

        #输入参数
        self.input_num = i_num   #输入层 数量
        self.hidden_num = h_num  #隐层 数量
        self.output_num = o_num  #输出层 数量

        #模型参数
        self.input = []          #输入层
        self.hidden = []         #隐层
        self.output = []         #输出层
        self.error = []          #误差
        self.expectation = []    #期望
        self.weight_ih = self.__ini_weight(self.input_num, self.hidden_num)   #输入层->隐层 连接权
        self.weight_ho = self.__ini_weight(self.hidden_num, self.output_num)  #隐层->输出层 连接权
        self.threshold_h = self.__ini_threshold(self.hidden_num)              #隐层 阈值
        self.threshold_o = self.__ini_threshold(self.output_num)              #输出层 阈值
        

    #初始连接权生成器
    def __ini_weight(self, x, y):
        result = []
        long = math.pow(10, self.random_long)
        for i in range(0, x, 1):
            res = []
            for j in range(0, y, 1):
                num = round(random.randint(-1*long,long)/long, self.random_long)
                res.insert(j, num)
            result.insert(i, res)
        return result

    #初始阈值生成器
    def __ini_threshold(self, n):
        result = []
        long = pow(10, self.random_long)
        for i in range(0, n, 1):
            num = round(random.randint(-1*long,long)/long, self.random_long)
            result.insert(i, num)
        return result

    #激励函数 sigma
    def excitation(self, value):
        sigma = 1/(1+(math.exp(-1*value)))
        return sigma

    #输入数据
    def input_param(self, data, expectation = []):
        self.input = []
        for value in data:
            self.input.append(value)
        if(expectation):
            self.expectation = []
            for value in expectation:
                self.expectation.append(value)

    #隐层计算
    def count_hidden(self):
        self.hidden = []
        for h in range(0, self.hidden_num, 1):
            Hval = 0
            for i in range(len(self.input)):
                Hval += self.input[i] * self.weight_ih[i][h]
            Hval = self.excitation(Hval+self.threshold_h[h])
            self.hidden.insert(h, Hval)

    #输出层计算
    def count_output(self):
        self.output = []
        for o in range(0, self.output_num, 1):
            Oval = 0
            for h in range(len(self.hidden)):
                Oval += self.hidden[h] * self.weight_ho[h][o]
            Oval += self.threshold_o[o]
            Oval = round(Oval, self.num_long)
            self.output.insert(o, Oval)

    #误差计算
    def count_error(self):
        self.error = []
        for key in range(len(self.output)):
            self.error.insert(key, self.expectation[key] - self.output[key])

    #连接权反馈训练 输入层->隐层
    def train_weight_ih(self):
        for i in range(len(self.weight_ih)):
            for h in range(len(self.weight_ih[i])):
                tmp = 0
                for o in range(0, self.output_num, 1):
                    tmp += self.weight_ho[h][o] * self.error[o]
                self.weight_ih[i][h] = self.weight_ih[i][h] + self.learn_rate * self.hidden[h] * (1 - self.hidden[h]) * self.input[i] * tmp
            

    #连接权反馈训练 隐层->输出层
    def train_weight_ho(self):
        for h in range(len(self.weight_ho)):
            for o in range(len(self.weight_ho[h])):
                self.weight_ho[h][o] = self.weight_ho[h][o] + self.learn_rate * self.hidden[h] * self.error[o]
                
    #阈值反馈训练 隐层
    def train_threshold_h(self):
        for h in range(len(self.threshold_h)):
            tmp = 0
            for o in range(0, self.output_num, 1):
                tmp += self.weight_ho[h][o] * self.error[o]
            self.threshold_h[h] = self.threshold_h[h] + self.learn_rate * self.hidden[h] * (1 - self.hidden[h]) * tmp
            

    #阈值反馈训练 输出层
    def train_threshold_o(self):
        for o in range(len(self.threshold_o)):
            self.threshold_o[o] = self.threshold_o[o] + self.error[o]

    #反馈训练
    def train(self):
        self.train_weight_ih()
        self.train_weight_ho()
        self.train_threshold_h()
        self.train_threshold_o()

    #归一化函数
    def normal_num(self, max, min, data):
        data = (data - min)/(max - min)
        return data

    #寻找集合的最大值和最小值

#---业务部分(示例)---

#要训练的规则,输入两个值,如果两值相等返回[1,0],反之返回[0,1]
def testFunc(val):
    if(val[0] == val[1]):
        return [1,0]
    else:
        return [0,1]

#构造神经网络模型
ann = Ann(2,3,2)

#生成训练数据,随机生成5000组[0,1][1,0][1,1][0,0]随机数组
data = []
for i in range(0, 10000, 1):
    x = random.randint(0,1)
    y = random.randint(0,1)
    data.append([x,y])

#取得训练数据中的最大值和最小值
for i in range(len(data)):
    for j in range(len(data[i])):
        if(i == 0 and j == 0):
            max = min = data[i][j]
        elif(data[i][j] > max):
            max = data[i][j]
        elif(data[i][j] < min):
            min = data[i][j]

#训练数据归一化
dataNormal = []
for i in range(len(data)):
    dataNormal.insert(i, [])
    for j in range(len(data[i])):
        dataNormal[i].append(ann.normal_num(max, min, data[i][j]))

#计算训练数据期望值,并进行反馈训练
for i in range(len(data)):
    #计算期望值
    exp = testFunc(data[i])
    #输入训练数据与期望
    ann.input_param(dataNormal[i], exp)
    #计算隐层
    ann.count_hidden()
    #计算输出层
    ann.count_output()
    #计算误差
    ann.count_error()
    #反馈训练
    ann.train()

#生成测试数据,随机生成20组
testdata = []
for i in range(0, 20, 1):
    x = random.randint(0,1)
    y = random.randint(0,1)
    testdata.append([x,y])

#进行测试,同时输出神经网络预测值与实际期望值
for i in range(len(testdata)):
    exp = testFunc(testdata[i])
    ann.input_param(testdata[i])
    ann.count_hidden()
    ann.count_output()
    print("Ann:")
    print(ann.output)
    print("Exp:")
    print(exp)
    print("\r")
时间: 2024-10-29 15:17:32

python实现单隐层神经网络基本模型的相关文章

用C实现单隐层神经网络的训练和预测(手写BP算法)

实验要求:?实现10以内的非负双精度浮点数加法,例如输入4.99和5.70,能够预测输出为10.69?使用Gprof测试代码热度 代码框架?随机初始化1000对数值在0~10之间的浮点数,保存在二维数组a[1000][2]中.?计算各对浮点数的相加结果,保存在数组b[1000]中,即b[0] = a[0][0] + a[0][1],以此类推.数组a.b即可作为网络的训练样本.?定义浮点数组w.v分别存放隐层和输出层的权值数据,并随机初始化w.v中元素为-1~1之间的浮点数.?将1000组输入(a

Neural Networks and Deep Learning(week3)Planar data classification with one hidden layer(基于单隐层的平面数据分类)

Planar data classification with one hidden layer 你会学习到如何: 用单隐层实现一个二分类神经网络 使用一个非线性激励函数,如 tanh 计算交叉熵的损失值 实现前向传播和后向传播 原文地址:https://www.cnblogs.com/douzujun/p/10289799.html

可变多隐层神经网络的python实现

说明:这是我对网上代码的改写版本(基于win7 + python34) 一.先说说改动的部分 1) 改写了NetStruct类初始化函数 原来: 1 class NetStruct: 2 '''神经网络结构''' 3 def __init__(self, x, y, hidden_layers, activ_fun_list, performance_function = 'mse'): 现在: 1 class NetStruct: 2 '''神经网络结构''' 3 def __init__(s

神经网络入门-用python实现一个两层神经网络并在CIFAR10数据集上调参

下面是我从cs231n上整理的神经网络的入门实现,麻雀虽小,五脏俱全,基本上神经网络涉及到的知识点都有在代码中体现. 理论看上千万遍,不如看一遍源码跑一跑. 源码上我已经加了很多注释,结合代码看一遍很容易理解. 最后可视化权重的图: 主文件,用来训练调参 two_layer_net.py 1 # coding: utf-8 2 3 # 实现一个简单的神经网络并在CIFAR10上测试性能 4 5 import numpy as np 6 import matplotlib.pyplot as pl

CS224d 单隐层全连接网络处理英文命名实体识别tensorflow

什么是NER? 命名实体识别(NER)是指识别文本中具有特定意义的实体,主要包括人名.地名.机构名.专有名词等.命名实体识别是信息提取.问答系统.句法分析.机器翻译等应用领域的重要基础工具,作为结构化信息提取的重要步骤. NER具体任务 1.确定实体位置 2.确定实体类别 给一个单词,我们需要根据上下文判断,它属于下面四类的哪一个,如果都不属于,则类别为0,即不是实体,所以这是一个需要分成 5 类的问题: ? Person (PER) ? Organization (ORG) ? Locatio

TensorFlow基础入门(五)--单隐层与双隐层的神经网络结构

注意:本部分的ppt来源于中国大学mooc网站:https://www.icourse163.org/learn/ZUCC-1206146808?tid=1206445215&from=study#/learn/content?type=detail&id=1211168244&cid=1213754001 原文地址:https://www.cnblogs.com/byczyz/p/12079731.html

1.4激活函数-带隐层的神经网络tf实战

激活函数 激活函数----日常不能用线性方程所概括的东西 左图是线性方程,右图是非线性方程 当男生增加到一定程度的时候,喜欢女生的数量不可能无限制增加,更加趋于平稳 在线性基础上套了一个激活函数,使得最后能得到输出结果 常用的三种激活函数: 取值不同时得到的结果也不同 常见激活函数图形 tensorflow中自带的激活函数举例: 添加隐层的神经网络 #添加隐层的神经网络结构 import tensorflow as tf def add_layer(inputs,in_size,out_size

神经网络进阶-用python实现一个完整的神经网络框架并在CIFAR10数据集上调参

上一个博客中讲解了用python实现一个简单的两层神经网络,我们是把所有的网络层都直接写在了类中.但是作为一个神经网络框架,网络的结构应该是可以由使用者自定义的,这样一来也就不用为每个网络结构都重写所有代码,我们把每一层模块化,在神经网络的类中定义结构时使用这些模块化的层堆叠形成一个完整的神经网络.每一种层,分别实现forward和password两个函数,用来正向计算和反向传播. 这里我们实现的网络层和功能有:全连层.激活层.计算loss.自动训练 1.全连层 全连层的正向计算很简单,f(W,

[翻译博文]线性隐层单元并不存在

译自:Don't Interpret Linear Hidden Units, they do not exist! http://building-babylon.net/2016/10/19/dont-interpret-linear-hidden-units-they-dont-exist/ 已经训练好了模型,很自然的想到该如何理解该模型.数据点最大化隐层单元的激活函数,将数据点输入特征视为指示哪个单元来重组.下面是对隐层单元的误解: 隐层没有非线性单元: 层间权重无约束: 采用(随机)梯