神经网络正弦波回归需要数百个隐藏单元才能有效?

时间:2019-04-27 21:20:04

标签: machine-learning neural-network regression

我目前正在尝试使用numpy作为大学项目来实现具有1个隐藏层的前馈神经网络。我们将对隐藏层使用双曲正切激活函数,而对输出层的函数未指定。 NN将使正弦波消退。

我已经为XOR分类问题实现了此代码,并且看起来工作正常。正弦波回归码只有很小的变化。

我几个小时以来一直在修改超级参数,增加了动力(这似乎只会使情况变得更糟),并且在使其正常工作方面未见成功。

对于该项目,我们将使用3个隐藏单位然后使用20个隐藏单位进行回归。这两个选项似乎都极大地拟合了数据。大约有一半的时间,它只会产生一条水平线,有时还会绘制出看起来是单个tanh函数的图。

唯一使该事情起作用的方法是向隐藏层(学习功能中的Hn)添加过多的单位。学习速度为.1-2.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)

0 个答案:

没有答案