Керас: Создание нейронной сети, чтобы найти модуль числа - PullRequest
4 голосов
/ 30 мая 2019

Я опытный разработчик Python, но я новичок в машинном обучении.Это моя первая попытка использовать Keras.Можете ли вы сказать, что я делаю неправильно?

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

В приведенном ниже коде я определяю сеть и обучаю ее 10 000 случайных чисел.Затем я проверяю его на 500 случайных числах.

По какой-то причине точность, которую я получаю, составляет около 1/7, то есть точности, которую вы ожидаете от совершенно случайного алгоритма, т.е. моя нейронная сеть неделать что-либо.

Может кто-нибудь помочь мне разобраться в чем дело?

import keras.models
import numpy as np
from python_toolbox import random_tools

RADIX = 7

def _get_number(vector):
    return sum(x * 2 ** i for i, x in enumerate(vector))

def _get_mod_result(vector):
    return _get_number(vector) % RADIX

def _number_to_vector(number):
    binary_string = bin(number)[2:]
    if len(binary_string) > 20:
        raise NotImplementedError
    bits = (((0,) * (20 - len(binary_string))) +
            tuple(map(int, binary_string)))[::-1]
    assert len(bits) == 20
    return np.c_[bits]


def get_mod_result_vector(vector):
    return _number_to_vector(_get_mod_result(vector))


def main():
    model = keras.models.Sequential(
        (
            keras.layers.Dense(
                units=20, activation='relu', input_dim=20
            ),
            keras.layers.Dense(
                units=20, activation='relu'
            ),
            keras.layers.Dense(
                units=20, activation='softmax'
            )
        )
    )
    model.compile(optimizer='sgd',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])

    data = np.random.randint(2, size=(10000, 20))
    labels = np.vstack(map(get_mod_result_vector, data))

    model.fit(data, labels, epochs=10, batch_size=50)
    def predict(number):
        foo = model.predict(_number_to_vector(number))
        return _get_number(tuple(map(round, foo[0])))
    def is_correct_for_number(x):
        return bool(predict(x) == x % RADIX)
    predict(7)
    sample = random_tools.shuffled(range(2 ** 20))[:500]
    print('Total accuracy:')
    print(sum(map(is_correct_for_number, sample)) / len(sample))
    print(f'(Accuracy of random algorithm is {1/RADIX:.2f}')


if __name__ == '__main__':
    main()
...