Точность двоичного классификатора ДНН не увеличивается - PullRequest
2 голосов
/ 10 мая 2019

Точность моего двоичного классификатора DNN кажется застрявшей со времен 1-й. Я думаю, это означает, что модель не обучается. Любое понимание того, почему это происходит?

Постановка задачи: я хотел бы классифицировать заданную последовательность показаний для датчиков (например, [0 1 15 1 0 3]) либо в 0, либо в 1 (0 эквивалентно состоянию «холостой ход», 1 эквивалентно «активному») состояние).

О наборе данных: Набор данных доступен здесь Столбец «состояние» является целью, а остальные столбцы являются объектами.

Я пытался использовать SGD вместо Адама, пытался использовать различные инициализации ядра, пытался изменить количество скрытых слоев и количество нейронов на слой и пытался использовать StandardScaler из sklearn вместо MinMaxScaler. Ни один из этих подходов, казалось, не изменил результат.

Это код:

import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.callbacks import EarlyStopping
from keras.optimizers import Adam
from keras.initializers import he_uniform
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import OneHotEncoder

seed = 7
random_state = np.random.seed(seed)

data = pd.read_csv('Dataset/Reformed/Model0_Dataset.csv')
X = data.drop(['state'], axis=1).values
y = data['state'].values

#min_max_scaler = MinMaxScaler()
std_scaler = StandardScaler()

# X_scaled = min_max_scaler.fit_transform(X)
X_scaled = std_scaler.fit_transform(X)

X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=random_state)

# One Hot encode targets
y_train = y_train.reshape(-1, 1)
y_test = y_test.reshape(-1, 1)

enc = OneHotEncoder(categories='auto')
y_train_enc = enc.fit_transform(y_train).toarray()
y_test_enc = enc.fit_transform(y_test).toarray()

epochs = 500    
batch_size = 100
model = Sequential()
model.add(Dense(700, input_shape=(X.shape[1],), kernel_initializer=he_uniform(seed)))
model.add(Dropout(0.5))
model.add(Dense(1400, activation='relu', kernel_initializer=he_uniform(seed)))
model.add(Dropout(0.5))
model.add(Dense(700, activation='relu', kernel_initializer=he_uniform(seed)))
model.add(Dropout(0.5))
model.add(Dense(800, activation='relu', kernel_initializer=he_uniform(seed)))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))
model.summary()

early_stopping_monitor = EarlyStopping(patience=25)
# model.compile(SGD(lr=.01, decay=1e-6, momentum=0.9, nesterov=True), loss='binary_crossentropy', metrics=['accuracy'])
model.compile(Adam(lr=.01, decay=1e-6), loss='binary_crossentropy', metrics=['accuracy'], )

history = model.fit(X_train, y_train_enc, validation_split=0.2, batch_size=batch_size,
                    callbacks=[early_stopping_monitor], epochs=epochs, shuffle=True, verbose=1)
eval = model.evaluate(X_test, y_test_enc, batch_size=batch_size, verbose=1)

Ожидаемые результаты: точность увеличивается (и убыток уменьшается) с каждой эпохой (по крайней мере, для ранних эпох).

Фактические результаты: следующие значения фиксируются на протяжении всего процесса обучения:

loss: 8.0118 - acc: 0.5001 - val_loss: 8.0366 - val_acc: 0.4987

1 Ответ

0 голосов
/ 10 мая 2019

Вы используете неправильную потерю, с softmax с двумя выходами, вы должны использовать categorical_crossentropy, и вы должны в горячем виде кодировать свои метки. Если вы хотите использовать binary_crossentropy, то выходной слой должен быть одним модулем с сигмовидной активацией.

...