Сделал даже странный классификатор, используя ANN в керасе, не получили хорошие результаты? - PullRequest
0 голосов
/ 23 января 2019

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

Я написал этот код:

# -*- coding: utf-8 -*-

import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense


X = np.zeros(1000, dtype=int)
y = np.zeros(1000, dtype=int)

for number in range(1000):
    X[number] = number
    y[number] = (number+1) % 2

classifier = Sequential()
classifier.add(Dense(units = 3, activation = 'relu', input_dim = 1))
classifier.add(Dense(units = 1, activation = 'sigmoid'))
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy',metrics = ['accuracy'])
classifier.fit(X, y, epochs = 100, batch_size  = 50)

Но я могу достичь точности только 0,5.Может кто-нибудь помочь мне выяснить, что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Один из способов заставить такой классификатор работать, изменив представление ваших входных данных.Простые целые числа в этом случае не будут работать.Один из способов - преобразовать целые числа в их двоичный эквивалент, а затем закодировать их в список битов.

import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense


X = np.zeros(1000, dtype=int)
y = np.zeros(1000, dtype=int)

for number in range(1000):
    X[number] = number
    y[number] = (number+1) % 2

binaries = ["{0:b}".format(x) for x in X] #convert integers in binary
max_len = max([len(x) for x in binaries])
same_len_bin = ['0'*(max_len-len(x))+x for x in binaries] #all inputs must have same len
X = np.array([[int(n) for n in x] for x in same_len_bin]) #list of bits

classifier = Sequential()
classifier.add(Dense(units = 3, activation = 'relu', input_dim = 10))
classifier.add(Dense(units = 1, activation = 'sigmoid'))
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy',metrics = ['accuracy'])
classifier.fit(X, y, epochs = 100, batch_size  = 50)

Обратите внимание, что я использовал форматирование строк для создания двоичного аналога каждого целого числа.Затем я добавил достаточно 0 s перед каждой строкой, чтобы обеспечить одинаковую длину всех входов.В этот момент входные данные являются строками, поэтому последний шаг преобразования составляет список целых чисел из каждой строки.

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

Вот как выглядят числа после преобразования:

for n in X[:5]:
    print(n)

[0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 1]
[0 0 0 0 0 0 0 0 1 0]
[0 0 0 0 0 0 0 0 1 1]
[0 0 0 0 0 0 0 1 0 0]

Результат обучения будет:

Epoch 1/100
1000/1000 [==============================] - 0s 320us/step - loss: 0.6780 - acc: 0.5500
Epoch 2/100
1000/1000 [==============================] - 0s 22us/step - loss: 0.6712 - acc: 0.5680
...
...
Epoch 100/100
1000/1000 [==============================] - 0s 24us/step - loss: 0.0294 - acc: 1.0000
0 голосов
/ 23 января 2019

Проблема в том, что представление вашего ввода не подходит для этой проблемы.Вы можете найти обсуждение этого здесь

...