Нейронная сеть набора данных MNIST, почему сеть не может классифицировать изображения? - PullRequest
1 голос
/ 20 января 2020

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

Вот пример гипотезы во время градиентного спуска:

Iter 1: [0,5123, 0,5492, 0,5329, 0,5281, ...]

Iter 2: [0,3294, 0,3239, 0,3985, 0,3283, ...]

Iter 3: [0,1313, 0,1123, 0,1233, 0,1231, ...]

Iter 4: [0,0112, 0,0123, 0,0123, 0,0123, ...]

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

Вот код:

Обработка изображения:

    def processImg(self):

        with open("binaryMNIST.pkl", "br") as fh:
            data = pc.load(fh)


        img_dim = 28;
        features = 784;
        m = 60000
        test_m = 10000;

        fullX = (np.asfarray(data[0]))
        bias = np.ones((60000, 1))
        fullX = np.hstack((bias, fullX))

        fullY = np.asfarray(data[1])

        testX = (np.asfarray(data[2]))
        bias2 = np.ones((10000, 1))
        testX = np.hstack((bias2, testX))

        testY = np.asfarray(data[3])

        fullY = fullY.astype(int)
        testY = testY.astype(int)

        iden = np.identity(10, dtype = np.int)
        oneHot = np.zeros((m, 10), dtype = np.int)
        oneHot_T = np.zeros((test_m, 10), dtype = np.int)

        #creates m number of one, zeros vector indicating the class
        for i in range(test_m):
            oneHot_T[i] = iden[testY[i], :]

        for i in range(m):
            oneHot[i] = iden[fullY[i], :]

        trainX = fullX[:40000, :]
        trainY = oneHot[:40000, :]

        valX = np.asfarray(fullX[40000:, :])
        valY = np.asfarray(oneHot[40000:, :])


        self.trainX = trainX
        self.trainY = trainY
        self.valX = valX
        self.valY = valY
        self.testX = testX
        self.oneHot_T = oneHot_T

Настройка тета:

    def setThetas(self):
        #784 features
        #5 nodes per layer (not including bias)
        #(nodes in previous layer, nodes in next layer)
        #theta1(785, 5) theta2(6, 5) theta3(6, 10)

        #after finishing, do big 3d matrix of theta and vectorize backprop

        params = np.random.rand(4015)
        self.params = params

вперед и назад:

    def fbProp(self, theta1, theta2, theta3):

        #after calculating a w/sig(), add bias
        m = np.shape(self.trainY)[0]
        z1 = np.array(np.dot(self.trainX, theta1), dtype = np.float64)

        a1 = self.sig(z1)
        bias = np.ones((40000, 1))
        a1 = np.hstack((bias, a1))
        z2 = np.dot(a1, theta2)
        a2 = self.sig(z2)
        a2 = np.hstack((bias, a2))
        z3 = np.dot(a2, theta3)
        hyp = self.sig(z3)

        g3 = 0
        g2 = 0
        g1 = 0

        for i in range(m):
            dOut = hyp[i, :] - self.trainY[i, :]
            #switch
            d2 = np.dot(np.transpose(dOut), np.transpose(theta3))
            d2 = d2[1:] * self.sigG(z2[i, :])
            d1 = np.dot(d2, np.transpose(theta2))
            d1 = d1[1:] * self.sigG(z1[i, :])

            g3 = g3 + np.dot(np.transpose(np.array(a2[i, :], ndmin = 2)), np.array(dOut, ndmin = 2))
            g2 = g2 + np.dot(np.transpose(np.array(a1[i, :], ndmin = 2)), np.array(d1, ndmin = 2))
            g1 = g1 + np.dot(np.transpose(np.array(self.trainX[i, :], ndmin = 2)), np.array(d1, ndmin = 2))

        self.theta1G = (1/m) * g1
        self.theta2G = (1/m) * g2
        self.theta3G = (1/m) * g3

Градиентный спуск:

    def gradDescent(self):

        params = np.array(self.params)
        theta1 = params[0:3925]
        theta1 = np.resize(theta1, (785, 5))
        theta2 = params[3925:3955]
        theta2 = np.resize(theta2, (6, 5))
        theta3 = params[3955:4015]
        theta3 = np.resize(theta3, (6, 10))

        for i in range(self.steps):
            J = self.error(theta1, theta2, theta3, self.trainX, self.trainY)
            print("Iteration: ", i+1, " | error: ", J)
            self.fbProp(theta1, theta2, theta3)
            theta1 = theta1 - (self.alpha * self.theta1G)
            theta2 = theta2 - (self.alpha * self.theta2G)
            theta3 = theta3 - (self.alpha * self.theta3G)

Функция ошибки:

    def error(self, theta1, theta2, theta3, X, y):
        bias = np.ones((np.shape(y)[0], 1))
        a1 = self.sig(np.dot(X, theta1))
        a1 = np.hstack((bias, a1))
        a2 = self.sig(np.dot(a1, theta2))
        a2 = np.hstack((bias, a2))
        hyp = self.sig(np.dot(a2, theta3))
        print(hyp[0, :])

        #10 classes
        pt1 = ((np.log(hyp) * y) + (np.log(1-hyp) * (1-y))).sum()
        J = - (1/(40000)) * pt1.sum()

        return J

Сигмовидный градиент и сигмовидная кишка:

    def sigG(self, z):
        return (self.sig(z) * (1-self.sig(z)))


    def sig(self, z):
        return 1/(1+(np.exp(-z)))
...