Нейронная сеть регрессии синусоидальной волны требует сотни скрытых единиц, чтобы быть эффективными? - PullRequest
0 голосов
/ 28 апреля 2019

В настоящее время я пытаюсь реализовать прямую нейронную сеть с 1 скрытым слоем, используя numpy в качестве проекта для университета.Мы должны использовать функции активации гиперболического тангенса для скрытого слоя, а функция для выходного слоя не определена.NN - это регресс синусоидальной волны.

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

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

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

Единственная вещь, которая заставляет эту работу работать, - это добавлять чрезмерное количествоюниты к скрытому слою (Hn в функции обучения).Скорость обучения .1-.2, количество эпох 2000-5000 и 100-200 скрытых юнитов, похоже, регрессируют синусоидальную волну.

Я баловался с этим часами и откровенноУ меня нет идей.Любая помощь будет принята с благодарностью.

Вот код:

import numpy as np
import matplotlib.pyplot as plt

__name__ = "partB"


class partB:
    def __init__(self):
        pass

    def propegate(self, Xs):
        self.A1 = np.dot(self.W1, Xs)
        self.Z1 = np.tanh(self.A1) + self.b1
        self.A2 = np.dot(self.W2, self.Z1)
        self.Z2 = np.power(1 + np.exp(-1 * self.A2), -1) + self.b2

        predictions = self.Z2
        return predictions

    def backProp(self, momentumFac):
        # Get gradients
        dA2 = self.Z2 - self.targets
        dW2 = (1 / self.m) * np.dot(dA2, self.A1.T)
        db2 = (1 / self.m) * np.sum(dA2, axis = 1, keepdims = True)
        dA1 = np.multiply(np.dot(self.W2.T, dA2), 1 - np.power(self.Z1, 2))
        dW1 = (1 / self.m) * np.dot(dA1, self.data.T)
        db1 = (1 / self.m) * np.sum(dA1, axis = 1, keepdims = True)

        # print("dW2: ", dW2, " dA1: ", dA1)

        self.W1 = momentumFac * self.W1 - self.learnRate * dW1
        self.W2 = momentumFac * self.W2 - self.learnRate * dW2
        self.b1 = self.b1 - self.learnRate * db1
        self.b2 = self.b2 - self.learnRate * db2

    def logLoss(self):
        #prob = np.multiply(np.log(self.Z2), self.targets) + np.multiply(np.log(1 - self.Z2), (1 - self.targets))
        cost = (1 / self.m) * np.sqrt(np.sum(np.square(self.Z2 - self.targets)))
        #cost = - np.sum(prob) / self.m
        return cost

    def sigmoid(self, Z):
        return np.float64(1) / (np.float64(1) + np.exp(-Z))

    def learnBitch(self, learnRate, epochs, moment):
        # Make data
        perm = np.random.permutation(50)
        dat = 2 * np.random.random_sample((1, 50)) - 1
        targ =  .5 * np.sin(2 * np.pi * dat) + .5 + .3 * np.random.random_sample((1, 50))
        self.data = dat[:,perm]
        self.targets = targ[:,perm]
        # Make Ns
        Xn = self.data.shape[0]
        Yn = self.targets.shape[0]
        Hn = 200
        self.m = self.data.shape[1]
        # Initialize Ws and bias vectors
        cost = np.float64(0)
        while (cost == 0):
            self.W1 = np.random.random_sample((Hn, Xn))
            self.W2 = np.random.random_sample((Yn, Hn))
            self.b1 = np.zeros([Hn, 1])
            self.b2 = np.zeros([Yn, 1])


            self.learnRate = learnRate
            itt = np.intc(0)

            costArr = []
            costXs = []

            plt.clf()
            costGraph = plt.figure()
            costGraph.show()
            costGraph.canvas.draw()

            for itt in range(epochs):
                self.propegate(self, self.data)
                cost = self.logLoss(self)
                self.backProp(self, moment)
                print('cost: ', cost)

                if itt % 25 == 0:
                    costArr.append(cost)
                    costXs.append(itt)

                    plt.plot(costXs, costArr)

                    costGraph.canvas.draw()


        self.xVals = [np.linspace(-1, 1, 50)]
        self.yVals = self.propegate(self, self.xVals)

        print(self.xVals)
        print(self.yVals)

        plt.clf()
        plt.scatter(self.data, self.targets)
        plt.plot(np.squeeze(self.xVals), np.squeeze(self.yVals))
        plt.show()

        #self.plot_decision_boundary(self, lambda x: self.propegate(self, x), self.data, self.targets)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...