Модель нейросетей Keras для бинарной классификации с 3D-тензорными временными рядами в качестве входных данных - PullRequest
0 голосов
/ 29 августа 2018

Я строю модель NN, используя керасы и тензорный поток для двоичной классификации по временным рядам. Вот так выглядит мой вклад в форме (124,4591):

      |      Col 1      |    Col 2        |    Col 3        |    Col 4        |
Row 1 | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] |
Row 2 | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] |
Row 3 | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] | [x1, ..., x591] |

Я разделил свои данные на X_train, X_test, y_train и y_test. Я также закодировал свои метки из ['True', 'False'] в [0, 1], используя LabelEncoder() и OneHotEncoder().

x = np.stack((np.vstack(x[:,0]),np.vstack(x[:,1]),np.vstack(x[:,2]),np.vstack(x[:,3])))
x = x.reshape((124,4,591))
y = table_raw_ptpt['Binding Known']
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size = 0.3, random_state = 0)

X_train.shape возвращает (86, 4, 591) . Кодировка для этикеток:

label_encoder = LabelEncoder()
integer_encoded_train = label_encoder.fit_transform(array(y_train))
integer_encoded_test = label_encoder.fit_transform(array(y_test))

onehot_encoded_y_train = OneHotEncoder(sparse=False)
integer_encoded_train = integer_encoded_train.reshape(len(integer_encoded_train), 1)
onehot_encoded_y_train = onehot_encoded_y_train.fit_transform(integer_encoded_train)

onehot_encoded_y_test = OneHotEncoder(sparse=False)
integer_encoded_test = integer_encoded_test.reshape(len(integer_encoded_test), 1)
onehot_encoded_y_test = onehot_encoded_y_test.fit_transform(integer_encoded_test)

onehot_encoded_y_train.shape возвращает (86, 2) .

Вот мой NN:

model = Sequential()
model.add(Dense(86, activation='relu', input_shape=(4,591)))
model.add(Dense(43, activation='relu'))
model.add(Dense(20, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

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

Это работает. Но когда я пытаюсь соответствовать X_train, я получаю ошибку:

Ошибка при проверке цели: ожидается, что dens_227 будет иметь форму (1,), но получил массив с формой (2,)

Упомянутый слой является выходным слоем. Насколько я понял, форма вывода неверна. Я попытался использовать Flattern() между слоями, и даже попытался Reshape(1,). Но так как я новичок в этом, я не до конца понимаю, что мне нужно добавить, чтобы контролировать свою форму данных в NN, чтобы получить нужный мне вывод.

Мне удалось заставить его работать с softmax, но мне нужно, чтобы sigmoid тоже работал, чтобы потом можно было получить окончательный прогноз (True или False / 1 или 0).

Спасибо.

1 Ответ

0 голосов
/ 29 августа 2018

Проблема в том, как вы обрабатываете свои данные истинной земли y. Следующая модель работает со случайными данными с вашими реальными данными, вы должны закодировать y как one-hot с 4 значениями и присвоить этому горячему кодированию вектор истинности земли y, который должен иметь форма (124, 4 , 1), обратите внимание на 4 (здесь я использую 124 образца)

Итак, y должен иметь 4 измерения y1, y2, y3, y4. Ниже показано, как должны быть закодированы и присвоены 4-мерному целевому вектору y ваши логические истинные истинные значения 00, 01, 10,11, которые являются парами:

0 0 ->      0001  -> y1=0, y2=0, y3=0, y4=1
0 1 ->      0010  -> y1=0, y2=0, y3=1, y4=0
1 0 ->      0100  -> y1=0, y2=1, y3=0, y4=0
1 1 ->      1000  -> y1=1, y2=0, y3=0, y4=0

эта обработка логических значений может быть проиллюстрирована с помощью карты Карно-Вейча (https://en.wikipedia.org/wiki/Karnaugh_map), каждый квадрат на карте эквивалентен одному логически закодированному значению в горячем виде.

вам нужно написать функцию, которая преобразует комбинацию ваших логических значений 00,01,10,11 в закодированную в одну горячую точку функцию вектор измерения 4, как указано выше

с y, закодированным таким образом, модель может быть построена как

from random import randint
from random import seed
import math
import numpy as np
from keras.models import Sequential
from keras.layers import Dense


# generating random data, replace this with your data

X = np.random.rand(124,4,591)

y = np.random.randint(2,size=(124,4)) # replace this with your ground truth feature vector

y=y.reshape(124,4,1)



# https://stackoverflow.com/questions/44704435/error-when-checking-model-input-expected-lstm-1-input-to-have-3-dimensions-but


model = Sequential()
model.add(Dense(86, activation='relu', input_shape=(4,591)))
model.add(Dense(43, activation='relu'))
model.add(Dense(20, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()

model.fit(X, y, epochs=1, batch_size=10)

Критическим является то, что y имеет то же второе измерение, что и X здесь, а именно 4, это может быть достигнуто путем кодирования логических значений вашей основной истины, как указано выше

это не сделано в коде выше, потому что я не знаю ваших данных, в коде используются случайные данные правильной размерности

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