Керас: Как связать модель CNN с деревом решений - PullRequest
0 голосов
/ 29 апреля 2019

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

электрокардиограф (электрокардиография)

Я хочу использовать архитектуру CNN для извлечения функций из данных, а затем использовать эти извлеченные функции для подачи классического «Классификатора дерева решений» . Ниже вы можете увидеть мой подход к CNN без дерева решений;

model = Sequential()
model.add(Conv1D(15,60,padding='valid', activation='relu',input_shape=(18000,1), strides = 1,  kernel_regularizer=regularizers.l1_l2(l1=0.1, l2=0.1)))
model.add(MaxPooling1D(2,data_format='channels_last'))
model.add(Dropout(0.6))
model.add(BatchNormalization())
model.add(Conv1D(30, 60, padding='valid', activation='relu',kernel_regularizer = regularizers.l1_l2(l1=0.1, l2=0.1), strides=1))
model.add(MaxPooling1D(4,data_format='channels_last'))
model.add(Dropout(0.6))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(3, activation = 'softmax'))

Я хочу отредактировать этот код так, чтобы в выходном слое работало дерево решений вместо model.add(Dense(3, activation = 'softmax')). Я попытался сохранить выходные данные последнего сверточного слоя, как этот;

output = model.layers[-6].output

И когда я распечатал переменную output, результат был такой;

ВЫХОД: Тензор ("conv1d_56 / Relu: 0", форма = (?, 8971, 30), DTYPE = float32)

Полагаю, переменная output содержит извлеченные объекты. Теперь, как я могу передать свою модель классификатора дерева решений этими данными, которые хранятся в переменной output? Вот дерево решений от scikit learn;

from sklearn.tree import DecisionTreeClassifier

dtc = DecisionTreeClassifier(criterion = 'entropy')
dtc.fit()

Как мне кормить метод fit()? Заранее спасибо.

1 Ответ

2 голосов
/ 29 апреля 2019

Чтобы извлечь вектор объектов, которые вы можете передать другому алгоритму, вам нужен полностью связанный слой перед слоем softmax.Нечто подобное добавит 128-мерный слой непосредственно перед слоем softmax:

model = Sequential()
model.add(Conv1D(15,60,padding='valid', activation='relu',input_shape=(18000,1), strides = 1,  kernel_regularizer=regularizers.l1_l2(l1=0.1, l2=0.1)))
model.add(MaxPooling1D(2,data_format='channels_last'))
model.add(Dropout(0.6))
model.add(BatchNormalization())
model.add(Conv1D(30, 60, padding='valid', activation='relu',kernel_regularizer = regularizers.l1_l2(l1=0.1, l2=0.1), strides=1))
model.add(MaxPooling1D(4,data_format='channels_last'))
model.add(Dropout(0.6))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(3, activation = 'softmax'))

Если вы затем запустите model.summary(), вы увидите название слоев:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv1d_9 (Conv1D)            (None, 17941, 15)         915       
_________________________________________________________________
max_pooling1d_9 (MaxPooling1 (None, 8970, 15)          0         
_________________________________________________________________
dropout_10 (Dropout)         (None, 8970, 15)          0         
_________________________________________________________________
batch_normalization_9 (Batch (None, 8970, 15)          60        
_________________________________________________________________
conv1d_10 (Conv1D)           (None, 8911, 30)          27030     
_________________________________________________________________
max_pooling1d_10 (MaxPooling (None, 2227, 30)          0         
_________________________________________________________________
dropout_11 (Dropout)         (None, 2227, 30)          0         
_________________________________________________________________
batch_normalization_10 (Batc (None, 2227, 30)          120       
_________________________________________________________________
flatten_6 (Flatten)          (None, 66810)             0         
_________________________________________________________________
dense_7 (Dense)              (None, 128)               8551808   
_________________________________________________________________
dropout_12 (Dropout)         (None, 128)               0         
_________________________________________________________________
dense_8 (Dense)              (None, 3)                 387       
=================================================================
Total params: 8,580,320
Trainable params: 8,580,230
Non-trainable params: 90
_________________________________________________________________

После того, как ваша сеть будет обучена, вы можете создать новую модель, в которой выходной слой станет «плотность_7», и он сгенерирует 128 векторов пространственных объектов:

feature_vectors_model = Model(model.input, model.get_layer('dense_7').output)
dtc_features = feature_vectors_model.predict(your_X_data)  # fit your decision tree on this data
...