Нейронная сеть неправильно корректирует веса или обучение - PullRequest
0 голосов
/ 11 июля 2020

Я сделал очень простую нейронную сеть с нуля, но она почему-то не работает ... Есть мысли? Я неправильно понял свои уравнения для обратного распространения, потому что это, кажется, единственное место, где что-то могло пойти не так. Я проверил это с помощью простой задачи XOR. Следовал руководству Coding Train (хотя он написан на javascript) (извините за беспорядочный код, я новичок в python, также странные отступы связаны только с моей неспособностью скопировать и прошить код)

Библиотека матриц:

import numpy as np

class Matrix():
def __init__ (self, rows, columns):
    self.rows =  rows
    self.columns = columns
    self.matrix = np.full([rows, columns], 0)          

def sigmoid(x):
    return 1/(1 + np.exp(-x))
def relu(x):
    for i in range(len(x)):
        for j in range(len(x[0])):
            x[i][j] = max(0, x[i][j])
    return x
def tanh(x):
    return np.tanh(x)
def tanhp(x):
    return 1 - np.square(Matrix.tanh(x))
def relup(x):
    for i in range(len(x)):
        for j in range(len(x[0])):
            if x[i][j] > 0:
                x[i][j] = 1
            else:
                x[i][j] = 0  
    return x
    
def simgoidp(x):
    return Matrix.sigmoid(x) * (1 - Matrix.sigmoid(x))

def fromArray(arr):
    m = Matrix(arr.shape[0], arr.shape[1])
    
    for i in range(len(arr)):
        for j in range(len(arr[0])):
            m.matrix[i][j] = arr [i][j]
    return m

def randomize(self):
    self.matrix = np.random.randn(self.rows, self.columns)
    return self.matrix


def matTranspose(matrix):
    return np.transpose(matrix)

def add (self, a):
    self.matrix = np.add(self.matrix, a)
    return np.add(self.matrix, a)

#element wise
def elAdd(a, b):
    return np.add(a, b)
def elSub(a, b):
    return np.subtract(a, b)
def elMul(a, b):
    return np.multiply(a, b)
#matrix
def matMul(a, b):
    return np.matmul(a, b)
#scalar
def scaleMul(a, b):
    return b * a
def scaleAdd(a, b):
    return b + a
def scaleSubtract(a, b):
    return a - b

#apply a function to all values
def mapFunc(a, func):
    for i in range(len(a)):
        for j in range(len(a[0])):
            val = a[i][j]
            a[i][j] = func(val)
    return a

Нейронная сеть:

import MatrixLib as m
from MatrixLib import Matrix as mm
import numpy as np
class NeuralNetwork():
def __init__(self, numI, numH, numO, learnRate):
    self.inpNodes = numI
    self.hidNodes = numH
    self.outNodes = numO
    
    self.iHWeights = m.Matrix(numH, numI)
    self.hOWeights = m.Matrix(numO, numH)
    self.hBias = m.Matrix(numH, 1)
    self.oBias = m.Matrix(numO, 1)
    
    self.iHWeights.randomize()
    self.hOWeights.randomize()
    self.hBias.randomize()
    self.oBias.randomize()
    self.learnRate = learnRate
    
    
def train(self, inputs, targets):
   
    #feedforwardCode
    inpu = m.Matrix.fromArray(inputs)
    hidden = np.matmul(self.iHWeights.matrix, inpu.matrix)
    hidden = np.add(hidden, self.hBias.matrix)
    hidden = mm.sigmoid(hidden)
    
    out = np.matmul(self.hOWeights.matrix, hidden)
    out = np.add(out, self.oBias.matrix)
    out = mm.sigmoid(out)
    
    #actual code
    inp = inpu.matrix
    
    #calculate tranposed stuff
    wHOT = mm.matTranspose(self.hOWeights.matrix)
    hT = mm.matTranspose(hidden)
    iT = mm.matTranspose(inp)
    #error calculations
    error = mm.elSub(targets, out)
    hError = np.matmul(wHOT, error)
    
    #calculate gradients
    gradient = mm.simgoidp(out)
    gradient = mm.elMul(error, gradient)
    gradient = mm.scaleMul(gradient, self.learnRate)
    
    hGradient = mm.simgoidp(hidden)
    hGradient = mm.elMul(hError, hGradient)
    hGradient = mm.scaleMul(hGradient, self.learnRate)

    #calculate deltas
    hOWeightDelta = np.matmul(gradient, hT)
    iHWeightDelta = np.matmul(hGradient, iT)
    
    hOBiasDelta = gradient
    iHBiasDelta = hGradient
    #get new weights
    print(self.hBias.matrix)
    self.hOWeights.add(hOWeightDelta)
    self.iHWeights.add(iHWeightDelta)
    self.hBias.add(hGradient)
    self.oBias.add(gradient)
    print(self.hBias.matrix)
    
def feedforward(self, inp):
    
    inp = m.Matrix.fromArray(inp)
    hidden = mm.matMul(self.iHWeights.matrix, inp.matrix)
    hidden = mm.elAdd(hidden, self.hBias.matrix)
    hidden = mm.sigmoid(hidden)
    
    out = mm.matMul(self.hOWeights.matrix, hidden)
    out = mm.elAdd(out, self.oBias.matrix)
    out = mm.sigmoid(out)
    
    return out

Основная:

import MatrixLib as m
from MatrixLib import Matrix as mm
import nn as nn
import numpy as np
from keras.datasets import mnist

iterations = 10000

net = nn.NeuralNetwork(2, 2, 1,.1)
inpu = np.array([[[0],[ 1]], [[0],[0]], [[1],[0]], [[1],[1]]])
targets = np.array([[1],[0],[1],[0]])


for i in range(10):
ri = np.random.randint(4)
inp = inpu[ri]
target = targets[ri]
net.train(inp, target)

a = net.feedforward(inpu[0])
b = net.feedforward(inpu[1])
c = net.feedforward(inpu[2])
d = net.feedforward(inpu[3])

print(a, b, c, d)
...