Я сделал очень простую нейронную сеть с нуля, но она почему-то не работает ... Есть мысли? Я неправильно понял свои уравнения для обратного распространения, потому что это, кажется, единственное место, где что-то могло пойти не так. Я проверил это с помощью простой задачи 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)