Рубрики
Без рубрики

Как я иду от 70 строк кода только 26, используя Numpy Library

Замена ручных рукописных математических функций с Numpy. Помечено с Depleperning, Python, Numpy.

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

К счастью, мне не нужно делать это вперед в будущем. Numpy Библиотека сделает это все для меня. Numpy является одним из фунтовых библиотек в научной вычислительной экосистеме Python. Он обеспечивает высокопроизводительный, многомерный объект массива, который делает его быстро и легко работать с матрицами.

В этом посте я покажу вам, как я использую Numpy, чтобы заменить ручную рукописные функции математики, которые я написал.

Ниже приведен исходный код с моими собственными функциями умножения матрицы.

def flatten_image(image):
    return list(itertools.chain.from_iterable(image))

def weighted_sum(a, b):
    assert(len(a) == len(b))
    output = 0
    for i in range(len(a)):
        output += (a[i] * b[i])
    return output

def vector_matrix_multiplication(a, b):
    output = [0 for i in range(10)]
    for i in range(len(output)):
        assert(len(a) == len(b[i]))
        output[i] = weighted_sum(a, b[i])
    return output

def zeros_matrix(rows, cols):
    output = []
    for r in range(rows):
        output.append([0 for col in range(cols)])
    return output

def outer_product(a, b):
    output = zeros_matrix(len(a), len(b))
    for i in range(len(a)):
        for j in range(len(b)):
            output[i][j] = a[i] * b[j]
    return output

class NeuralNet:
    def __init__(self):
        self.weights = [
            [0.0000 for i in range(784)],
            [0.0001 for i in range(784)],
            [0.0002 for i in range(784)],
            [0.0003 for i in range(784)],
            [0.0004 for i in range(784)],
            [0.0005 for i in range(784)],
            [0.0006 for i in range(784)],
            [0.0007 for i in range(784)],
            [0.0008 for i in range(784)],
            [0.0009 for i in range(784)]
        ]
        self.alpha = 0.0000001

    def predict(self, input):
        return vector_matrix_multiplication(input, self.weights)

    def train(self, input, labels, epochs):
        for i in range(epochs):
            for j in range(len(input)):
                pred = self.predict(input[j])

                label = labels[j]
                goal = [0 for k in range(10)]
                goal[label] = 1

                error = [0 for k in range(10)]
                delta = [0 for k in range(10)]

                for a in range(len(goal)):
                    delta[a] = pred[a] - goal[a]
                    error[a] = delta[a] ** 2

                weight_deltas = outer_product(delta, input[j])

                for x in range(len(self.weights)):
                    for y in range(len(self.weights[0])):
                        self.weights[x][y] -= (self.alpha * weight_deltas[x][y])

Чтобы помочь мне лучше понять, как Numpy Slots в этот код, я собираюсь сохранить свои функции помощника, но реализуйте их, используя Numpy. Например, у меня все еще есть функция взвешенной суммы, но вместо руки рассчитывая взвешенную сумму, я использую Numpy Dot Function.

def flatten_image(image):
    return image.reshape(1, 28*28)

def weighted_sum(a, b):
    return a.dot(b)

def vector_matrix_multiplication(a, b):
    return np.matmul(input, weights.T)

def zeros_matrix(rows, cols):
    return np.zeros((rows, cols))

def outer_product(a, b):
    return np.outer(a, b)

class NeuralNet:
    def __init__(self):
        self.weights = np.random.random((10, 28 * 28)) * 0.0001
        self.alpha = 0.0000001

    def predict(self, input):
        return vector_matrix_multiplication(input, self.weights)

    def train(self, input, labels, epochs):
        for i in range(epochs):
            for j in range(len(input)):
                pred = self.predict(input[j])

                label = labels[j]
                goal = np.zeros(10)
                goal[label] = 1                       

                delta = pred - goal
                error = delta ** 2

                weight_deltas = outer_product(delta, input[j])

                self.weights -= (self.alpha * weight_deltas)

Уже вы можете увидеть код многоочистителя.

Если мы удалим эти помощники и делаем все встроенные, код сокращается еще больше. Оригинальная реализация длиной 70 строк, и эта только 26 строк.

Numpy Library делает много работы для меня.

def flatten_image(image):
    return image.reshape(1, 28*28)

class NeuralNet:
    def __init__(self):
        self.weights = np.random.random((10, 28 * 28)) * 0.0001
        self.alpha = 0.0000001

    def predict(self, input):
        return np.matmul(input, self.weights.T)

    def train(self, input, labels, epochs):
        for i in range(epochs):
            for j in range(len(input)):
                pred = self.predict(input[j])

                label = labels[j]
                goal = np.zeros(10)
                goal[label] = 1

                delta = pred - goal
                error = delta ** 2

                weight_deltas = np.outer(delta, input[j])

                self.weights -= (self.alpha * weight_deltas)

import itertools
import numpy as np

from keras.datasets import mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()

images = x_train
labels = y_train

prepared_images = [flatten_image(image) for image in images]
prepared_labels = np.array(labels)

nn = NeuralNet()
nn.train(prepared_images, prepared_labels, 5)

test_set = x_test
test_labels = y_test
num_correct = 0
for i in range(len(test_set)):
    prediction = nn.predict(flatten_image(test_set[i]))
    correct = test_labels[i]
    if np.argmax(prediction) == int(correct):
        num_correct += 1

print(str(num_correct/len(test_set) * 100) + "%")
76.05%

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

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

Оригинал: “https://dev.to/leogau/how-i-go-from-70-lines-of-code-to-only-26-using-the-numpy-library-nm3”