Однократное векторное предсказание всегда возвращает одно и то же значение
Моя глубинная нейронная сеть возвращает один и тот же результат для каждого входа. Я попробовал (безуспешно) различные варианты:
- потеря
- оптимизатор
- топология сети / типы слоев
- число эпох (1-100)
У меня есть 3 выхода (один-горячий), и для каждого входного выхода они похожи (он меняется после каждой тренировки):
4.701869785785675049 e-01 4.793547391891479492 e-01 2.381391078233718872 e-01
Эта проблема возникает вероятно, из-за крайне случайного характера моих тренировочных данных (прогнозирование запасов).
Набор данных также сильно смещен в сторону одного из ответов (именно поэтому я использовалsample_weight
- вычисленный пропорционально).
Я думаю, что могу исключить переобучение (это происходит даже для 1 эпохи, и у меня есть выпадающие слои).
Один из примеров моей сети:
xs_conv = xs.reshape(xs.shape[0], xs.shape[1], 1)
model_conv = Sequential()
model_conv.add(Conv1D(128, 15, input_shape=(input_columns,1), activation='relu'))
model_conv.add(MaxPooling1D(pool_size=3))
model_conv.add(Dropout(0.4))
model_conv.add(Conv1D(64, 15, input_shape=(input_columns,1), activation='relu'))
model_conv.add(MaxPooling1D(pool_size=3))
model_conv.add(Dropout(0.4))
model_conv.add(Flatten())
model_conv.add(Dense(128, activation='relu'))
model_conv.add(Dropout(0.4))
model_conv.add(Dense(3, activation='sigmoid'))
model_conv.compile(loss='mean_squared_error', optimizer='nadam', metrics=['accuracy'])
model_conv.fit(xs_conv, ys, epochs=10, batch_size=16, sample_weight=sample_weight, validation_split=0.3, shuffle=True)
Я бы понял, если бы выходы были случайными, но то, что происходит, кажется очень странным. Есть идеи?
Данные: вычислено.csv
Весь код:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from keras.layers import Input, Dense, Conv1D, Dropout, MaxPooling1D, Flatten
from keras.models import Model, Sequential
from keras import backend as K
import random
DATA_DIR = '../../Data/'
INPUT_DATA_FILE = DATA_DIR + 'computed.csv'
def get_y(row):
profit = 0.010
hot_one = [0,0,0]
hot_one[0] = int(row.close_future_5 >= profit)
hot_one[1] = int(row.close_future_5 <= -profit)
hot_one[2] = int(row.close_future_5 < profit and row.close_future_10 > -profit)
return hot_one
def rolling_window(window, arr):
return [np.array(arr[i:i+window]).transpose().flatten().tolist() for i in range(0, len(arr))][0:-window+1]
def prepare_data(data, widnow, test_split):
xs1 = data.iloc[:,1:26].as_matrix()
ys1 = [get_y(row) for row in data.to_records()]
xs = np.array(rolling_window(window, xs1)).tolist()
ys = ys1[0:-window+1]
zipped = list(zip(xs, ys))
random.shuffle(zipped)
train_size = int((1.0 - test_split) * len(data))
xs, ys = zip(*zipped[0:train_size])
xs_test, ys_test = zip(*zipped[train_size:])
return np.array(xs), np.array(ys), np.array(xs_test), np.array(ys_test)
def get_sample_weight(y):
if(y[0]): return ups_w
elif(y[1]): return downs_w
else: return flats_w
data = pd.read_csv(INPUT_DATA_FILE)
window = 30
test_split = .9
xs, ys, xs_test, ys_test = prepare_data(data, window, test_split)
ups_cnt = sum(y[0] for y in ys)
downs_cnt = sum(y[1] for y in ys)
flats_cnt = sum(y[0] == False and y[1] == False for y in ys)
total_cnt = ups_cnt + downs_cnt + flats_cnt
ups_w = total_cnt/ups_cnt
downs_w = total_cnt/downs_cnt
flats_w = total_cnt/flats_cnt
sample_weight = np.array([get_sample_weight(y) for y in ys])
_, input_columns = xs.shape
xs_conv = xs.reshape(xs.shape[0], xs.shape[1], 1)
model_conv = Sequential()
model_conv.add(Conv1D(128, 15, input_shape=(input_columns,1), activation='relu'))
model_conv.add(MaxPooling1D(pool_size=3))
model_conv.add(Dropout(0.4))
model_conv.add(Conv1D(64, 15, input_shape=(input_columns,1), activation='relu'))
model_conv.add(MaxPooling1D(pool_size=3))
model_conv.add(Dropout(0.4))
model_conv.add(Flatten())
model_conv.add(Dense(128, activation='relu'))
model_conv.add(Dropout(0.4))
model_conv.add(Dense(3, activation='sigmoid'))
model_conv.compile(loss='mean_squared_error', optimizer='nadam', metrics=['accuracy'])
model_conv.fit(xs_conv, ys, epochs=1, batch_size=16, sample_weight=sample_weight, validation_split=0.3, shuffle=True)
xs_test_conv = xs_test.reshape(xs_test.shape[0], xs_test.shape[1], 1)
res = model_conv.predict(xs_test_conv)
plotdata = pd.concat([pd.DataFrame(res, columns=['res_up','res_down','res_flat']), pd.DataFrame(ys_test, columns=['ys_up','ys_down','y_flat'])], axis = 1)
plotdata[['res_up', 'ys_up']][3000:3500].plot(figsize=(20,4))
plotdata[['res_down', 'ys_down']][3000:3500].plot(figsize=(20,4))
1 ответ:
Я запустил вашу модель с вложенными данными и до сих пор могу сказать, что самая большая проблема-это отсутствие очистки данных.
Например, в строке 623 есть значениеinf
в.csv
. После того, как я отфильтровал их все с помощьюxs1 = xs1[np.isfinite(xs1).all(axis=1)]
... Я собрал некоторую статистику по
xs
, а именно min, max и mean. Они получились довольно примечательными:-43.0049723138 32832.3333333 # !!! 0.213126234391
В среднем значения близки к
Но даже с их помощью модель оказалась с точностью проверки 71-79%. Распределение результатов немного смещено в сторону 3-го класса, но в целом довольно разнообразно, чтобы назвать его своеобразным: 19% для класса 1, 7% для класса 2, 73% для класса 3. Пример вывода теста:0
, но некоторые из них на 6 порядков выше. Эти строки определенно повредит нейронной сети, поэтому вы должны либо фильтровать их, либо придумать умный способ нормализации функций.[[ 1.93120316e-02 4.47684433e-04 9.97518778e-01] [ 1.40607255e-02 2.45630667e-02 9.74113524e-01] [ 3.07740629e-01 4.80920941e-01 2.28664145e-01] ..., [ 5.72797097e-02 9.45571139e-02 8.07634115e-01] [ 1.05512664e-01 8.99530351e-02 6.70437515e-01] [ 5.24505274e-03 1.46622911e-01 9.42657173e-01]]