Выход нейронной сети приближается к постоянному значению в процессе обучения - PullRequest
0 голосов
/ 28 октября 2018

Я написал простую нейронную сеть в Python 3, и я пытаюсь обучить ее на наборе данных, но кажется, что чем больше итераций или данных, на которых она обучается, тем ближе результат к 1.

Я также пытался обучить сеть на меньшем наборе данных и случайном наборе данных, но происходит то же самое.Кроме того, использование функции активации ReLU приводит к тому, что весовые коэффициенты переходят в бесконечность, что заставляет меня полагать, что по какой-то причине весовые значения приближаются к максимальному значению, которое может вывести функция активации, или что сеть обучается в обратном направлении или что-то в этом роде.

Я должен упомянуть, что я впервые пытаюсь написать скрипт машинного обучения.

Вот код:

import numpy as np

class Neural_Network(object):
    def __init__(self, inputSize, outputSize, hiddenLayerCount, hiddenSize, learningRate):
        self.inS = inputSize
        self.outS = outputSize
        self.hiddenS = hiddenSize
        self.layerC = hiddenLayerCount
        self.lr = learningRate
        self.weights = {}
        self.biases = {}
        self.matricies = {}
        self.zmatricies = {}

        self.weights[0] = np.random.randn(self.inS, self.hiddenS)
        self.biases[0] = np.random.randn(1, self.hiddenS)
        for i in range(1, self.layerC+1):
            self.weights[i] = np.random.randn(self.hiddenS, self.hiddenS)
            self.biases[i] = np.random.randn(1, self.hiddenS)

        self.weights[self.layerC+1] = np.random.randn(self.hiddenS, self.outS)
        self.biases[self.layerC+1] = np.random.randn(1, self.outS)

    def activationFunc(self, matrix):
        ex = np.exp(matrix)
        enx = np.exp((-1)*matrix)
        return (ex-enx)/(ex+enx)

    def DActivationFunc(self, matrix):
        return (1-np.power(self.activationFunc(matrix), 2)) #tanh

    '''def activationFunc(self, matrix):
        print(matrix)
        return matrix * (matrix >= 0)

    def DActivationFunc(self, matrix):
        return 1 * (matrix >= 0)''' #relu

    '''def activationFunc(self, matrix):
        return 1/(1+np.exp(-matrix))

    def DActivationFunc(self, matrix):
        return matrix*(1-matrix)''' #sigmoid

    def propagate(self, inMatrix):
        prevm = inMatrix
        for i in range(0, self.layerC+2):
            z = np.add(np.dot(prevm, self.weights[i]), self.biases[i])
            self.zmatricies[i] = z
            nextm = self.activationFunc(z)
            self.matricies[i] = nextm
            prevm = nextm
        return prevm

    def backpropagate(self, inMatrix, matricies, zmatricies, output, expectedOut):
        error = 0.5*np.power(expectedOut-output, 2)
        prevdelta = (error)*self.DActivationFunc(zmatricies[self.layerC+1])
        self.weights[self.layerC+1] += self.lr*np.dot(self.matricies[self.layerC].T, prevdelta)
        self.biases[self.layerC+1] += self.lr*prevdelta

        for i in range(self.layerC, 1, -1):
            cdelta = np.dot(prevdelta, self.weights[i+1].T)*self.DActivationFunc(zmatricies[i])
            self.weights[i] += self.lr*np.dot(cdelta, matricies[i-1].T)
            self.biases[i] += self.lr*cdelta
            prevdelta = cdelta

        cdelta = np.dot(prevdelta, self.weights[1].T)*self.DActivationFunc(zmatricies[0])
        self.weights[0] += self.lr*np.dot(inMatrix.T, cdelta)
        self.biases[0] += self.lr*cdelta
        return error

    def train(self, inputData, expectedOutputData):
        return self.backpropagate(inputData, self.matricies, self.zmatricies, self.propagate(inputData), expectedOutputData)

    def dumpData(self):
        np.savetxt("3iterations.txt", [self.weights, self.biases], fmt="%s")

with open('data.csv', 'r') as rawf:
    data = rawf.readlines()

terms = {'workclass': ['Private', 'Self-emp-not-inc', 'Self-emp-inc', 'Federal-gov', 'Local-gov', 'State-gov', 'Without-pay', 'Never-worked'],
         'education': ['Bachelors', 'Some-college', '11th', 'HS-grad', 'Prof-school', 'Assoc-acdm', 'Assoc-voc', '9th', '7th-8th', '12th', 'Masters', '1st-4th', '10th', 'Doctorate', '5th-6th', 'Preschool'],
         'marital-status': ['Married-civ-spouse', 'Divorced', 'Never-married', 'Separated', 'Widowed', 'Married-spouse-absent', 'Married-AF-spouse'],
         'occupation': ['Tech-support', 'Craft-repair', 'Other-service', 'Sales', 'Exec-managerial', 'Prof-specialty', 'Handlers-cleaners', 'Machine-op-inspct', 'Adm-clerical', 'Farming-fishing', 'Transport-moving', 'Priv-house-serv', 'Protective-serv', 'Armed-Forces'],
         'relationship': ['Wife', 'Own-child', 'Husband', 'Not-in-family', 'Other-relative', 'Unmarried'],
         'race': ['White', 'Asian-Pac-Islander', 'Amer-Indian-Eskimo', 'Other', 'Black'],
         'sex': ['Female', 'Male'],
         'native-country': ['United-States', 'Cambodia', 'England', 'Puerto-Rico', 'Canada', 'Germany', 'Outlying-US(Guam-USVI-etc)', 'India', 'Japan', 'Greece', 'South', 'China', 'Cuba', 'Iran', 'Honduras', 'Philippines', 'Italy', 'Poland', 'Jamaica', 'Vietnam', 'Mexico', 'Portugal', 'Ireland', 'France', 'Dominican-Republic', 'Laos', 'Ecuador', 'Taiwan', 'Haiti', 'Columbia', 'Hungary', 'Guatemala', 'Nicaragua', 'Scotland', 'Thailand', 'Yugoslavia', 'El-Salvador', 'Trinadad&Tobago', 'Peru', 'Hong', 'Holand-Netherlands']}



def parse(cdata):
    global terms
    cdata = cdata.split(', ')
    formattedData = []
    formattedData.append(int(cdata[0])/100)
    formattedData.append(terms['workclass'].index(cdata[1])/len(terms['workclass']))
    formattedData.append(int(cdata[2])/1000000)
    formattedData.append(int(cdata[4])/16)
    formattedData.append(terms['marital-status'].index(cdata[5])/len(terms['marital-status']))
    formattedData.append(terms['occupation'].index(cdata[6])/len(terms['occupation']))
    formattedData.append(terms['relationship'].index(cdata[7])/len(terms['relationship']))
    formattedData.append(terms['race'].index(cdata[8])/len(terms['race']))
    formattedData.append(terms['sex'].index(cdata[9])/len(terms['sex']))
    formattedData.append(int(cdata[12])/168)
    formattedData.append(terms['native-country'].index(cdata[13])/len(terms['native-country']))
    return np.array([formattedData], dtype=float)

NN = Neural_Network(11, 1, 3, 22, 0.001) #inputsize, outputsize, hiddenLayerCount, hiddenLayerSize, learningRate

for iterations in range(0, 3):
    for i in range(0, len(data)):
        cdata = data[i]
        if '?' not in data[i]:
            NN.train(parse(cdata), np.array([(cdata[14]==">50K")+0], dtype=float))
    print("done " + str(iterations))
    for i in range(0, 5):                       #outputs for first 5 inputs
        cdata = data[i]                         #
        if '?' not in data[i]:                  #
            print(NN.propagate(parse(cdata)))   #
    print("done")

NN.dumpData()

Данные бесплатны для использования и могут быть найдены здесь:

Описание данных Фактические данные

Я не включал категории прибылей и убытков, поскольку данные кажутся неоднозначными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...