【2022.8.14】

今天完成神经网络的bp算法

其实从上周就开始看别人博客怎么实现,然后手动实现一下,自己动手确实可以加深印象
记录一下:
在这里插入图片描述

import math
import random

import numpy


def getDeviation(errOut, corOut):
    x = 0
    for i in range(len(errOut)):
        x += (errOut[i] - corOut[i]) ** 2
    return x / 2


class backpropagation:
    def __init__(self, hideLen, studyRate):
        inLen = len(inputs[0])
        outLen = len(outputs[0])

        # self.inToHide = numpy.ndarray((inLen, hideLen))
        self.inToHide = numpy.zeros((inLen, hideLen))
        # self.hideToOut = numpy.ndarray((hideLen, outLen))
        self.hideToOut = numpy.zeros((hideLen, outLen))
        self.b = numpy.zeros(hideLen)
        for j in range(hideLen):
            for i in range(inLen):
                self.inToHide[i][j] = random.random()
            for i in range(outLen):
                self.hideToOut[j][i] = random.random() * 10

        for y in range(100):
            for i in range(len(outputs)):
                for x in range(10):
                    tempHide = neural(inputs[i], self.inToHide, self.b)
                    tempOut = matrixMultiply([tempHide], self.hideToOut)[0]
                    bp(inputs[i], self.inToHide, tempHide, self.hideToOut, tempOut, outputs[i], studyRate, self.b)
                tempHide = neural(inputs[i], self.inToHide, self.b)
                tempOut = matrixMultiply([tempHide], self.hideToOut)[0]
                print(tempOut)
            print("-----------------------------")
        print(self.inToHide)
        print(self.hideToOut)
        print(self.b)
        print("-----------------------------")

    def test(self, inp):
        outs = numpy.ndarray((len(inp), len(inp[0])))
        for i in range(len(inp)):
            tempHide = neural(inp[i], self.inToHide, self.b)
            outs[i] = matrixMultiply([tempHide], self.hideToOut)[0]
        return outs


def neural(inp, inToHide, inherent):
    tempHide = matrixMultiply([inp], inToHide)[0]
    for i in range(len(inherent)):
        tempHide[i] += inherent[i]
    # 神经元固有值,也可以优化,暂时不动
    sigmoid(tempHide)
    return tempHide


def bp(inp, inToHide, hide, hideToOut, errOut, corOut, studyRate, b):
    deviation = getDeviation(errOut, corOut)
    if deviation < 0.00001:
        return deviation
    # print(deviation)
    d_deviation_o = numpy.zeros(len(corOut))
    for i in range(len(corOut)):
        d_deviation_o[i] = errOut[i] - corOut[i]

    d_ho_h = numpy.zeros(len(hide))
    for i in range(len(hide)):
        d_ho_h[i] = hide[i] * (1 - hide[i])

    d_deviation_h = numpy.zeros(len(hide))
    for i in range(len(hide)):
        for j in range(len(corOut)):
            d_deviation_h[i] += d_deviation_o[j] * hideToOut[i][j] * d_ho_h[j]

    # 先修正inToHide
    for i in range(len(inp)):
        for j in range(len(hide)):
            inToHide[i][j] -= d_deviation_h[j] * inp[i] * studyRate
            b[j] -= d_deviation_h[j] * inp[i] * studyRate

    # 再修正hideToOut
    for i in range(len(hide)):
        for j in range(len(corOut)):
            hideToOut[i][j] -= d_deviation_o[j] * hide[i] * studyRate
    return deviation


def matrixMultiply(leftMatrix, rightMatrix):
    lXLen = len(leftMatrix)
    lYlen = len(leftMatrix[0])
    rXLen = len(rightMatrix)
    rYLen = len(rightMatrix[0])
    if lYlen != rXLen:
        return None
    outMatrix = numpy.zeros((lXLen, rYLen))
    for i in range(lXLen):
        for j in range(rYLen):
            for k in range(lYlen):
                outMatrix[i][j] += leftMatrix[i][k] * rightMatrix[k][j]
    return outMatrix


def sigmoid(arr):
    for i in range(len(arr)):
        arr[i] = 1 / (1 + math.e ** -arr[i])


if __name__ == '__main__':
    inputs = [[0, 0], [0, 1], [1, 0], [1, 1]]
    outputs = [[0, 0], [0, 1], [0, 4], [0, 9]]
    shit = backpropagation(4, 0.3)
    print(shit.test([[1, 2]]))

'''
正向计算:
h1 = i1*a11 + i2*a21 + 0.5
ho1 = sigmoid(h1)
o1 = ho1 * b11 + ho2 * b21
o2 = ho1 * b12 + ho2 * b22
deviation = 1/2(O1 - o1)^2 + 1/2(O2 - o2)^2


计算偏导数,用于更新权值和固定值:
$(a, b)表示a对b的偏导数
$(deviation, o1) = (O1 - o1) * -1 = o1 - O1
$(deviation, o2) = (O2 - o2) * -1 = o2 - O2
$(o1, b11) = ho1
    $(deviation, b11) = $(deviation, o1) * $(o1, b11) = (o1 - O1) * ho1   
    $(deviation, b12) = (o2 - O2) * ho1    
    $(deviation, b21) = (o1 - O1) * ho2
    $(deviation, b22) = (o2 - O2) * ho2
$(o1, ho1) = b11
$(o2, ho1) = b12
$(deviation, ho1) = $(deviation, o1) * $(o1, ho1) + $(deviation, o2) * $(o2, ho1) = (o1 - O1) * b11 + (o2 - O2) * b12
$(deviation, ho2) = $(deviation, o1) * $(o1, ho2) + $(deviation, o2) * $(o2, ho2) = (o1 - O1) * b21 + (o2 - O2) * b22
$(ho1, h1) = ho1 - ho1^2
$(ho2, h2) = ho2 - ho2^2
$(deviation, h1) = [(o1 - O1) * b11 + (o2 - O2) * b12] * (ho1 - ho1^2)
$(deviation, h2) = [(o1 - O1) * b21 + (o2 - O2) * b22] * (ho2 - ho2^2)

更新w:
$(h1, a11) = i1
    $(deviation, a11) = $(deviation, h1) * $(h1, a11) = [(o1 - O1) * b11 + (o2 - O2) * b12] * (ho1 - ho1^2) * i1
    $(deviation, a21) = [(o1 - O1) * b11 + (o2 - O2) * b12] * (ho1 - ho1^2) * i2
    $(deviation, a12) = [(o1 - O1) * b21 + (o2 - O2) * b22] * (ho2 - ho2^2) * i1
    $(deviation, a22) = [(o1 - O1) * b21 + (o2 - O2) * b22] * (ho2 - ho2^2) * i2

更新b:
$(deviation, b1) = $(deviation, h) * $(h, b1) = $(deviation, h1)
'''

贴结果

[6.32587583e-07 6.33213280e-04]
[-0.00268672 1.00111571]
[3.99775448e-03 4.00182551e+00]
[-7.02548284e-04 8.99848403e+00]

[[-6.94880581 0.67494424 23.90272794 2.64975556]
[-0.34046229 -0.27877047 -0.04787937 -0.74671243]]
[[ 0.77230955 -5.19829496]
[-4.1884299 0.42527155]
[ 2.16351037 6.70760107]
[ 1.25660785 2.06724707]]
[-8.75129545 -1.08167547 22.65811574 0.99926829]

[[2.13356514 8.67763353]]

个人观点

效果不是很理想,需要进一步优化,调参数,一个是中间节点数,一个是学习速度,一个是循环次数
但是很开心,因为一种新的编程方法诞生,不用写if else,直接以矩阵运算作为程序
这对于无法用if else写的程序来说是必须的方法,比如图像识别,你无法构造if else的条件
c语言一类的程序的if else是可以转化为矩阵运算的,但是反过来很难

例子

if (x > 1)
	return 22 * x
else
	return 88

上面的if else可以用激活函数代替
有没有人能设计出这个矩阵和激活函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值