Нейронная сеть для начинающих - PullRequest
0 голосов
/ 02 декабря 2018

Я готов создать нейронную сеть на python, используя Keras, которая сообщает, является ли число четным или нечетным.Я знаю, что это можно сделать разными способами, и использование NN для этого является излишним, но я хочу сделать это в образовательных целях.

Я сталкиваюсь с проблемой: точность моей модели составляет около 50%, чтоозначает, что он не может определить, является ли число четным или нечетным.

Я подробно опишу вам шаг, который я прошел, и, надеюсь, мы вместе найдем решение:)

Шагодно создание данных и меток: в основном мои данные представляют собой числа от 0 до 99 (двоичные), а метки - 0 (нечетные) и 1 (четные)

for i in range(100):
    string = np.binary_repr(i,8)
    array = []
    for k in string:
        array.append(int(k))
    array = np.array(array)
    labels.append(-1*(i%2 - 1)) 

Затем я создаю модельэто сделано из 3 слоев.-Слой 1 (вход): один нейрон, который принимает любой массив numly размером 8 (8-битное представление целых чисел) -Слой 2 (скрытый): два нейрона -Слой 3 (выход): один нейрон

# creating a model

model = Sequential()
model.add(Dense(1, input_dim=8, kernel_initializer='uniform', activation='relu'))
model.add(Dense(2, kernel_initializer='uniform', activation='relu'))
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))

затем я обучаю модель, используя binary_cross_entropy как функцию потерь, так как я хочу двоичную классификацию целых чисел:

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

, затем я обучаю модель и оцениваю ее:

#training
model.fit(data, labels, epochs=10, batch_size=2)

#evaluate the model
scores = model.evaluate(data, labels)
print("\n%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))

И вот где я потерялся из-за этой 50% точности.

Я думаю, что я что-то упустил из-за реализации NN или Keras, поэтому любая помощь будет принята.

Спасибо за чтение

редактировать: я изменил свой код в соответствии с комментарием Стефана Фалька

1 Ответ

0 голосов
/ 02 декабря 2018

Следующее дает мне точность на тестовом наборе 100%:

import numpy as np
from tensorflow.contrib.learn.python.learn.estimators._sklearn import train_test_split
from tensorflow.python.keras import Sequential
from tensorflow.python.keras.layers import Dense

# Number of samples (digits from 0 to N-1)
N = 10000
# Input size depends on the number of digits
input_size = int(np.log2(N)) + 1

# Generate data
y = list()
X = list()

for i in range(N):
    binary_string = np.binary_repr(i, input_size)
    array = np.zeros(input_size)
    for j, binary in enumerate(binary_string):
        array[j] = int(binary)
    X.append(array)
    y.append(int(i % 2 == 0))

X = np.asarray(X)
y = np.asarray(y)

# Make train/test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1)

# Create the model
model = Sequential()
model.add(Dense(2, kernel_initializer='uniform', activation='relu'))
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))

model.compile(loss='mse', optimizer='adam', metrics=['accuracy'])

# Train
model.fit(X_train, y_train, epochs=3, batch_size=10)

# Evaluate    
print("Evaluating model:")
scores = model.evaluate(X_test, y_test)
print("\n%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))

Почему это так хорошо работает?

Ваша проблема очень проста.Сеть должна знать только, установлен ли первый бит (1) или нет (0).Для этого вам на самом деле не нужен скрытый слой или любые нелинейности.Проблема может быть решена с помощью простой линейной регрессии.

Эта

model = Sequential()
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))

также сделает эту работу.Далее, по теме функция разработки ,

X = [v % 2 for v in range(N)]

также достаточно.Вы увидите, что X в этом случае будет иметь тот же контент, что и y.


Возможно, попробуйте нелинейный пример, такой как XOR .Обратите внимание, что у нас нет тестового набора здесь, потому что нет ничего для обобщения или каких-либо «невидимых» данных, которые могут удивить сеть.

import numpy as np
from tensorflow.python.keras import Sequential
from tensorflow.python.keras.layers import Dense

X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])

model = Sequential()
model.add(Dense(5, input_dim=2, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

model.fit(X, y, batch_size=1, nb_epoch=1000)

print(model.predict_proba(X))

print(model.predict_proba(X) > 0.5)

Посмотрите на эту ссылку и поиграйтес примером.

...