Многослойный персептрон не сходится - PullRequest
0 голосов
/ 25 апреля 2018

Это простой MLP, который я пишу для двоичной классификации изображений, с обратным распространением:

class MLP:
    def __init__(self, size, epochs = 1000, learning_rate = 1):
        self.l1weights = numpy.random.random((size + 1, 3))
        self.l2weights = numpy.random.random(3)
        self.epochs = epochs
        self.learning_rate = learning_rate

    def predict(self, _input_):
        #Append bias at the beginning of input
        l1output = self.sigmoid(numpy.dot(numpy.append([1], _input_), self.l1weights))
        l2output = self.sigmoid(numpy.dot(l1output, self.l2weights))
        return l1output, l2output

    def train(self, training_set, training_goal):
        for epoch in range(self.epochs):
            l1squared_error = 0
            l2squarederror = 0
            for set_index in range(training_goal.shape[0]):
                set = training_set[set_index]
                l1output, l2output = self.predict(set)

                l2error = training_goal[set_index] - l2output
                l1error = l2error * self.dsigmoid(l2output) * self.l2weights

                self.l1weights[0] = self.l1weights[0] + self.learning_rate * l1error
                for index in range(len(self.l1weights) - 1):
                    self.l1weights[index + 1] += self.learning_rate * l1error * self.dsigmoid(l1output)
                for index in range(len(self.l2weights)):
                    self.l2weights[index] += self.learning_rate * l2error * self.dsigmoid(l2output)

                l1squared_error += sum(l1error ** 2)
                l2squarederror += l2error ** 2
            print("Squared error at epoch " + str(epoch) + " : " + str(l1squared_error) + ", " + str(l2squarederror))

    def sigmoid(self, _input_):
        #Sigmoid sigmoid function
        return 1 / (1 + numpy.exp(-_input_))

    def dsigmoid(self, _input_):
        return _input_ * (1 - _input_)

При запуске иногда все выходные данные сходятся в 1, но по какой-то причине прогнозы для 0 сходятся в 0,5, в то время как прогнозы для 1 остаются около 0,75, при этом ошибка в слое 2 остается такой же после ~ 1000 эпох, если это происходит относительно более успешно. Это из тестирования с 2x2 классификацией изображения с кодом ниже:

def image_class(input):
    return 1 if input >= 2 else 0

training_set = ((numpy.arange(2**4)[:,None] & (1 << numpy.arange(4))) != 0)
training_goals = numpy.array([image_class(sum(i)) for i in training_set])

mlp = MLP(size=4)
mlp.train(training_set, training_goals)

1 Ответ

0 голосов
/ 25 апреля 2018

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

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