Почему точность всегда 0,00% с большими потерями на Keras для глубокого обучения - PullRequest
0 голосов
/ 05 апреля 2019

enter image description here Я создал код в Keras для обучения нейронных сетей, чтобы имитировать поведение системы, которую я разработал в MATLAB. Я экспортировал выходные и входные данные из MATLAB в Keras. Всякий раз, когда я тренируюсь, точность составляет 0,00%, а потери всегда составляют 382,9722 ....

Я перепробовал все (увеличение скрытых слоев, функции активации, размеры пакетов, эпохи и т. Д.), Кажется, ничего не решило проблему. Буду признателен, если кто-нибудь скажет мне, если что-то не так с кодом или моими данными.

data = pd.read_csv('testkeras.txt')
print(data.head())

Y = data.output
X = data.drop('output', axis=1)

xtrain, xtest, ytrain, ytest = train_test_split(X,Y,test_size=0.5)


model = Sequential()
model.add(Dense(units = 64, input_dim = 6, init = 'uniform',             
activation='relu'))
model.add(Dense(units = 32, activation='relu'))
model.add(Dense(units = 16, activation='relu'))
model.add(Dense(1, activation='sigmoid')) #output layer


model.compile(optimizer = 'rmsprop', loss = 'mean_absolute_error', 
metrics=['acc'])


history = model.fit(xtrain, ytrain, batch_size = 2048, epochs = 20,      
validation_split= 0.2, verbose=1)


score = model.evaluate(xtest, ytest, batch_size=2048)
print(score)

Пример исходных данных из matlab (первые 6 столбцов являются входными, а последний столбец - выходными)

2,2,2,2,2,2,2.5404e+05
2,2,2,2,2,2,2.5404e+05
2,2,1.9998,1.9998,1.9998,1.9998,2.5404e+05
2,2,1.9988,1.9988,1.9988,1.9988,2.5404e+05
2,2,1.9938,1.9938,1.9938,1.9938,2.5404e+05
2,2,1.9687,1.9687,1.9687,1.9687,2.5403e+05
2,2,1.8431,1.8431,1.8431,1.8431,2.5401e+05
2,2,1.2153,1.2153,1.2153,1.2153,2.5388e+05
2,2,-1.9186,-1.9186,-1.9186,-1.9186,2.5324e+05
2,2,-17.469,-17.469,-17.469,-17.469,2.5007e+05
2,1.9997,-92.331,-92.331,-92.331,-92.331,2.3481e+05
2,1.9936,-402.94,-402.94,-402.94,-402.94,1.7135e+05
2,1.9724,-723.02,-723.02,-723.02,-723.02,1.0558e+05
2,1.9373,-938.65,-938.65,-938.65,-938.65,60759
1.9999,1.8683,-1105.7,-1105.7,-1105.7,-1105.7,24988
1.9999,1.8212,-1152.8,-1152.8,-1152.8,-1152.8,14210
1.9997,1.7097,-1190.6,-1190.6,-1190.6,-1190.6,3712
1.9996,1.6936,-1192.1,-1192.1,-1192.1,-1192.1,3012.4
1.9994,1.6126,-1192.5,-1192.5,-1192.5,-1192.5,898.37
1.9992,1.5645,-1189.5,-1189.5,-1189.5,-1189.5,291.6
1.9987,1.4363,-1176.9,-1176.9,-1176.9,-1176.9,-362.02
1.9981,1.3097,-1161.9,-1161.9,-1161.9,-1161.9,-523.72
1.9974,1.1848,-1146.5,-1146.5,-1146.5,-1146.5,-564.79
1.9965,1.0615,-1131.1,-1131.1,-1131.1,-1131.1,-576.24
1.9955,0.93983,-1115.8,-1115.8,-1115.8,-1115.8,-580.39
1.9944,0.81985,-1100.6,-1100.6,-1100.6,-1100.6,-582.7
1.9931,0.70149,-1085.6,-1085.6,-1085.6,-1085.6,-584.53
1.9918,0.58475,-1070.7,-1070.7,-1070.7,-1070.7,-586.19
1.9903,0.46962,-1055.9,-1055.9,-1055.9,-1055.9,-587.78
1.9887,0.35607,-1041.3,-1041.3,-1041.3,-1041.3,-589.31
1.987,0.2441,-1026.8,-1026.8,-1026.8,-1026.8,-590.78
1.9852,0.13368,-1012.4,-1012.4,-1012.4,-1012.4,-592.21
1.9833,0.024813,-998.22,-998.22,-998.22,-998.22,-593.58
1.9813,-0.082527,-984.13,-984.13,-984.13,-984.13,-594.9
1.9791,-0.18835,-970.17,-970.17,-970.17,-970.17,-596.17
1.9769,-0.29267,-956.34,-956.34,-956.34,-956.34,-597.4
1.9745,-0.39551,-942.64,-942.64,-942.64,-942.64,-598.57
1.9721,-0.49687,-929.07,-929.07,-929.07,-929.07,-599.7
1.9695,-0.59677,-915.62,-915.62,-915.62,-915.62,-600.78

Данные X-поезда

3492 -0.49055   2.0     2.0     2.0     2.0     2.0
9730 -0.49055   2.0     2.0     2.0     2.0     2.0
3027 -0.49055   2.0     2.0     2.0     2.0     2.0
4307 -0.49055   2.0     2.0     2.0     2.0     2.0
3364 -0.49055   2.0     2.0     2.0     2.0     2.0
(5008, 6)

и данные Y-поезда:

3492   -1.333700e-06
9730    5.215400e-08
3027    4.209600e-06
4307    5.215400e-08
3364    5.215400e-08
Name: output, dtype: float64
(5008,) 

1 Ответ

1 голос
/ 05 апреля 2019

Как уже упоминалось в комментариях, это проблема регрессии, поэтому точность не имеет смысла.

Но в вашем коде есть другая проблема. Ваша функция активации последних слоев сигмовидная:

model.add(Dense(1, activation='sigmoid')) #output layer

Функция Sigmoid определяется между 0 и 1, это означает, что выход вашей сети никогда не будет меньше 0 или больше единицы. Таким образом, вы никогда не приблизитесь даже к своим отрицательным результатам. Я вижу 2 варианта решения этой проблемы

  • Масштабируйте ваши выходные данные от 0 до 1, например, с Sklearns MinMaxScaler
  • Используйте функцию активации, которая может выводить любое число, например, линейное, или если вы уверены, что ваши данные находятся в диапазоне от -1 до 1, что-то вроде tanh.

Это также может улучшить вашу производительность (меньше ошибок, быстрее учиться), если вы масштабируете свои входные данные. Обычно его масштабируют таким образом, что среднее значение равно 0, а дисперсия равна 1. Это называется стандартизацией. Вы можете сделать это, например с sklearns StandardScaler

Также ваши тренировочные данные кажутся как-то неправильными:

3492 -0.49055   2.0     2.0     2.0     2.0     2.0
9730 -0.49055   2.0     2.0     2.0     2.0     2.0
3027 -0.49055   2.0     2.0     2.0     2.0     2.0
4307 -0.49055   2.0     2.0     2.0     2.0     2.0
3364 -0.49055   2.0     2.0     2.0     2.0     2.0

каждая строка здесь идентична, в то время как ваши метки (y) отличаются. Вы не можете построить сеть, которая отображает идентичные входы на разные выходы.

...