как настроить сеть LSTM? - PullRequest
0 голосов
/ 14 апреля 2020

Я пытаюсь реализовать сеть LSTM с использованием Keras для прогнозирования перемещения ограничивающего прямоугольника с учетом действия.

Набор данных, который я использую, выглядит следующим образом: (ограничивающий прямоугольник для прогнозирования сделан из столбцы b0, b1, b2, b3)

act b0  b1  b2  b3  id  score

0   85  238 129 256 69  0.9289865493774414
1   -1  -1  -1  -1  -1  -1
1   -1  -1  -1  -1  -1  -1
2   -1  -1  -1  -1  -1  -1
3   -1  -1  -1  -1  -1  -1
0   46  136 256 245 73  0.9369892477989197
1   18  18  256 252 73  0.8203921318054199
1   144 212 169 223 10  0.9630357623100281
1   13  9   252 199 73  0.9374213814735413
3   -1  -1  -1  -1  -1  -1
0   215 141 255 233 72  0.9941028952598572
2   199 116 243 183 74  0.8685483932495117
3   215 141 255 233 72  0.9941184520721436
1   189 78  215 95  76  0.8610376119613647
3   206 50  255 169 72  0.8224002122879028
0   -1  -1  -1  -1  -1  -1
3   19  129 249 253 73  0.8635225892066956
2   -1  -1  -1  -1  -1  -1
2   0   78  13  91  10  0.9488454461097717
3   -1  -1  -1  -1  -1  -1
0   206 123 255 189 62  0.9980332255363464
2   221 197 256 255 62  0.9782524704933167
2   -1  -1  -1  -1  -1  -1
2   -1  -1  -1  -1  -1  -1
1   -1  -1  -1  -1  -1  -1
0   184 78  243 169 72  0.9953457713127136
2   191 139 254 246 72  0.9929528832435608
3   184 78  243 169 72  0.9953963160514832
3   197 1   254 91  72  0.9956125020980835
2   184 78  243 169 72  0.9953963160514832

Я создаю новый столбец с ограничивающим прямоугольником в одном входе с:

b_box = ['b0', 'b1', 'b2', 'b3']
df['b_box'] = df[b.box].apply(tuple, axis=1).apply(list)

Проблема, с которой я сталкиваюсь :

Это означает, что форма значения, которое я передаю в сеть LSTM, представляет собой массив 4D (3994, 5, 1, 4), который не может быть использован.

Полный код:

import pandas as pd
import os

from sklearn.model_selection import train_test_split

import numpy as np

PATH = "./csv/"

filename = os.path.join(PATH, "test.csv")
names = ['act', 'b0', 'b1', 'b2', 'b3', 'id', 'score']
df = pd.read_csv(filename, sep=',')

# print("Starting file:")
# print(df[0:10])
# print("Ending file:")
# print(df[-10:])
b_box = ['b0', 'b1', 'b2', 'b3']


df['b_box'] = df[b_box].apply(tuple, axis=1).apply(list)

# print(df.head())

train, test = train_test_split(df, test_size=0.2)

boxes_train = train['b_box'].tolist()
boxes_test = test['b_box'].tolist()

# print("Training set has {} observations".format(len(boxes_train)))
# print("Test set has {} observations".format(len(boxes_test)))

def to_sequences(seq_size, obs):
    x = []
    y = []

    for i in range(len(obs)-SEQUENCE_SIZE-1):
        window = obs[i:(i+SEQUENCE_SIZE)]
        after_window = obs[i+SEQUENCE_SIZE]
        window = [[x] for x in window]
        x.append(window)
        y.append(after_window)

    return np.array(x), np.array(y)

SEQUENCE_SIZE = 5
x_train, y_train = to_sequences(SEQUENCE_SIZE, boxes_train)
x_test, y_test = to_sequences(SEQUENCE_SIZE, boxes_test)

print(x_train)
# print("Shape of training set: {}".format(x_train.shape))
# print("Shape of test set: {}".format(x_test.shape))

from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Embedding
from keras.layers import LSTM
from keras.datasets import imdb

print("Build model...")
model = Sequential()
model.add(LSTM(64, dropout=0.2, recurrent_dropout=0.2, input_dim=1))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
print('Train...')

model.fit(x_train, y_train, validation_data=(x_test, y_test), verbose=2, epochs=100)

1 Ответ

0 голосов
/ 14 апреля 2020

Вам необходимо подготовить данные, используя TimeSeriesGenerator . Вот быстрый пример с 2 функциями.

import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.preprocessing.sequence import TimeseriesGenerator

dim = 1000

# 2 features 
x1 = np.random.normal(size=dim).reshape(1000,1)
x2 = np.random.normal(size=dim).reshape(1000,1)
data = np.hstack((x1,x2))

# target is simply the sum
targets = x1 + x2 
targets = np.insert(targets,0,0)[0:dim]

data_gen = TimeseriesGenerator(data, targets,length=1,batch_size=1)

model = Sequential()
model.add(LSTM(128, input_shape=(1,2), dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(1))
model.compile(loss='mse',optimizer='adam')

# Please note 'fit_generator' instead of 'fit'
model.fit_generator(generator=data_gen,steps_per_epoch=32,epochs=5)

Out:

Epoch 1/5
32/32 [==============================] - 3s 89ms/step - loss: 2.6368
Epoch 2/5
32/32 [==============================] - 0s 4ms/step - loss: 1.8943
Epoch 3/5
32/32 [==============================] - 0s 3ms/step - loss: 1.0667
Epoch 4/5
32/32 [==============================] - 0s 3ms/step - loss: 1.1214
Epoch 5/5
32/32 [==============================] - 0s 3ms/step - loss: 0.5821

EDIT

В вашем случае, поскольку вы используете pandas, вам нужно просто извлечь объекты и цель ( Я предполагаю, что целью является «оценка», и передаю их в TimeseriesGenerator. Шаг insert необходим для смещения меток на один шаг в будущем. Также параметры length и batch_size равны 1, так как я предполагаю, что каждый временной шаг помечен (т. Е. Вы не используете всю последовательность временных шагов для каждого прогноза). Проверьте в документации, действительно ли эти параметры вам нужны для вашей модели.

dim = 1000
# the columns are the same but I filled the df with random values 
train_cols = ['act','b0','b1','b2','b3','id']
df = pd.DataFrame(np.random.randint(0,100,size=(dim, 6)), columns=train_cols)

df['score'] = df.mean(axis=1)
targets = np.insert(np.asarray(df['score']),0,0)[0:dim]

data_gen = TimeseriesGenerator(df[train_cols].values, targets,length=1,batch_size=1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...