1D канал свертки Кераса независимо, [образцы, временные шаги, особенности], набор данных ветряных турбин - PullRequest
0 голосов
/ 25 мая 2018

Я работаю над набором данных о ветряных турбинах, который имеет обычный матричный формат: [строка: дата / время, столбец: функции]

Но я хочу, чтобы сверткой зафиксировать прогресс каждой из этих функций, таких каксделано в LSTM.Итак, я сгенерировал новый набор данных со следующими измерениями:

[datetime, 15 временных шагов, 128 функций]: теперь в каждой исходной строке datetime есть 15 сцепленных регистров (t-0, t-1, ..., t-14) для каждого объекта.

Мой план состоит в том, чтобы свернуть в измерении временного шага для каждого объекта (канала) отдельно с ядром размером 1x5 и шагом 5. Получение для каждого DateTime (пакета),3 фильтра длиной 5 из 128 объектов, выходная форма которых (Нет, 3128).

Затем я применяю максимальное объединение к предыдущему результату второго измерения (3), чтобы получить "самый важныйсвернутый временной шаг », ожидающий выходной размер: (Нет, 1,128)

И, наконец, я подключаю плотный слой для двоичной классификации.

Текущая сетевая архитектура реализована в кератах следующим образом:

model.add( Conv1D(padding = 'valid',filters = nfeatures,strides = 5,kernel_size = 5, 
                  activation = 'relu',input_shape = (timesteps,nfeatures)) )
model.add( MaxPooling1D() )
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

Проблема заключается в том, что при проверке весов на первом слое (conv1d) весы имеют следующие размеры: [5,128,128] и смещение [128].

Ожидаемый весФормат s: [5,1,128], почему 5x128x128?Я хочу только 5 весов (размер ядра) для каждой функции / канала.

Спасибо!

1 Ответ

0 голосов
/ 25 мая 2018

Стандартные сверточные фильтры:

Чтобы получить отличные результаты, нейронные сети редко рассматривают функцию в одиночку, наоборот, они способствуют корреляции между функциями для извлечения более точных результатов.

Именно поэтому стандартные формы фильтра свертки:

(width, input_features, output_features)   

В этой свертке все входные объекты считаются для создания новых выходных объектов.

Как полностью индивидуализировать функции?

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

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

Эти группы затем могут обрабатываться параллельно со слоем TimeDistributed.

model = Sequential()

#reordering data and adding 1 dummy feature per group    
model.add(Permute((2,1), input_shape = (timesteps,nfeatures))) #(batch, feat, steps)    
model.add(Lambda(lambda x: K.expand_dims(x))) #(batch, feat, steps, 1)

#applying the 1 filter convolution for each group
model.add(TimeDistributed(Conv1D(padding = 'valid',filters = 1,strides = 5,
                                 kernel_size = 5, activation = 'relu')))
model.add( TimeDistributed(MaxPooling1D()) )

#restoring to (batch,features)    
model.add(Reshape((nfeatures,)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

Честно говоря, ваша модель будет намного более мощной при использовании стандартной свертки, но у вас могут быть особые причины дляделая это.

Один отдельный фильтр для каждой функции

Это требует больше работы.Нам понадобится либо пользовательский слой, который реализует deepwise_conv1d (который не предлагает Keras), либо мы создадим 128 отдельных слоев conv1D с 1 фильтром (проще).

Используя второй подход (несколько слоев сверток),нам понадобится функциональная модель API для создания параллельных ветвей.

from keras.model import Model

#function to split the input in multiple outputs
def splitter(x):
    return [x[:,:,i:i+1] for i in range(nfeatures)]


#model's input tensor 
inputs = Input((timesteps,nfeatures))

#splitting in 128 parallel tensors - 128 x (batch,15,1)
multipleFeatures = Lambda(splitter)(inputs)

#applying one individual convolution on each parallel branch
multipleFeatures = [
   Conv1D(padding = 'valid',filters = 1,strides = 5, kernel_size = 5)(feat) 
   for feat in multipleFeatures ]

#joining the branches into (batch, 3, 128)
joinedOutputs = Concatenate()(multipleFeatures)
joinedOutputs = Activation('relu')(joinedOutputs)

outputs = MaxPooling1D()(joinedOutputs)
outputs = Lambda(lambda x: K.squeeze(x,axis=1))(outputs)
outputs = Dropout(0.5)(outputs)
outputs = Dense(1, activation='sigmoid')(outputs)

model = Model(inputs,outputs)
...