Простая ошибка нейронной сети уменьшается, а затем увеличивается - PullRequest
1 голос
/ 15 июня 2019

Написал нейронную сеть на python, просто для забавы, хочу, чтобы это работало, а не использовал уже существующие пакеты, которые работают проще / лучше.

Я на данный момент только регулирую смещение выходного узла с обратным распространением. Корректировка выглядит примерно так:

смещение - = (истинное значение - выходное значение) * (дельта выходного узла) * (скорость обучения)

это делается в последней строке функции backprop.

При 20-кратном прогоне выборки данных абсолютная ошибка уменьшается, затем увеличивается и продолжает расти бесконечно, но с уменьшающейся скоростью. Ошибка (истинное значение - выходное значение) изначально очень отрицательная и увеличивается с каждой последовательной итерацией.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#getting sample data
df = pd.read_csv('City_of_Seattle_Staff_Demographics.csv')
df = df.sample(frac=0.1)
df = pd.get_dummies(df)
df = (df - df.min()) / (df.max() - df.min())
df.reset_index(inplace=True)
inputdata = np.array(df.drop(columns=['Hourly Rate', 'index'])) #index by inputs 2d array
outputdata = np.array(df[['Hourly Rate']])    #1 by index 2d array

#initialising variables
inn = len(inputdata[0])    #number of input nodes
hnn = 16    #number of hidden nodes
onn = len(outputdata[0])    #number of output nodes
inodes = np.empty((1, inn))    #value of input nodes
hi = np.empty((1, hnn))    #value of hidden nodes before logistic function is applied
oi = np.empty((1, onn))    #value of output nodes before logistic function is applied
ho = np.empty((1, hnn))    #value of hidden nodes after logistic function is applied
oo = np.empty((1, onn))    #value of output nodes after logistic function is applied
hdelta = np.empty((1, hnn))    #deltas of each node, given by delta(ho)
odelta = np.empty((1, onn))    #deltas of each node, given by delta(oo)
hbias = np.random.rand(1, hnn)    #node biases
obias = np.random.rand(1, onn)    #node biases
syn1 = np.random.rand(inn, hnn)    #synapse layers
syn2 = np.random.rand(hnn, onn)    #synapse layers

lrate = 0.01
error = 0.0

def sigmoid (x):
    return 1/(1+np.exp(-x))

def delta (x):
    return x*(1-x)

def forwardprop (index):
    global inodes, hi, oi, ho, oo, hbias, obias, syn1, syn2
    inodes = np.array([inputdata[index]])
    hi = np.matmul(inodes, syn1) + hbias
    ho = sigmoid(hi)
    oi = np.matmul(ho, syn2) + obias
    oo = sigmoid(oi)

def backprop (index):
    #backprop is only trying to adjust the output node bias
    global inodes, hi, oi, ho, oo, hbias, obias, syn1, syn2
    oo = np.array([outputdata[index]]) - oo
    odelta = delta(oo)
    hdelta = delta(ho)
    obias -= oo * odelta * lrate

def errorcalc ():
    global onn, oo, error
    for x in range(onn):
        error += oo[0][x]

def fullprop (index):
    forwardprop(index)
    backprop(index)
    errorcalc()

def fulliter ():    #iterate over whole sample
    global error
    error = 0
    for x in range(len(inputdata)):
        fullprop(x)
    print('error: ', error)

for x in range(20):
    fulliter()

Я ожидаю, что ошибка уменьшится в абсолютном значении, например: -724, -267, -84, -21, 12, -10, 9, -7, ... вместо этого это происходит примерно так: -724, -267, -84, -21, 33, 75, 114, 162, 227, 278, 316 ... 376, 378, 379, 380

...