我是Deep-Learning
的新手,所以我正在阅读Deep Learning with Keras by Antonio Gulli并学习很多东西。我想开始使用一些概念。我想尝试实现一个带有一维卷积层的神经网络,该卷进入双向复发层(如下面的论文)。我遇到的所有教程或代码片段都没有实现与此类似的任何远程(例如图像识别)或使用具有不同功能和用法的旧版keras
。
我想要做的是this paper的变化:
(1)将DNA序列转换为one-hot encoding
载体; ✓
(2)使用一维卷积神经网络; ✓
(3)最大合并; ✓
(4)将输出发送到bidirectional RNN
; ⓧ
(5)对输入进行分类;
我无法弄清楚如何让形状与Bidirectional RNN
相匹配。我甚至无法让普通的RNN
在这个阶段工作。如何重组传入层以使用双向RNN?
注意:原始代码来自https://github.com/uci-cbcl/DanQ/blob/master/DanQ_train.py,但我将输出层简化为二进制分类。这个处理在https://github.com/fchollet/keras/issues/3322中描述(种类),但我无法使用更新的keras
。原始代码(和第二个链接)在一个非常大的数据集上工作,所以我生成一些假数据来说明这个概念。他们还使用旧版本的keras
,从那时起,关键功能发生了变化。
# Imports
import tensorflow as tf
import numpy as np
from tensorflow.python.keras._impl.keras.layers.core import *
from tensorflow.python.keras._impl.keras.layers import Conv1D, MaxPooling1D, SimpleRNN, Bidirectional, Input
from tensorflow.python.keras._impl.keras.models import Model, Sequential
# Set up TensorFlow backend
K = tf.keras.backend
K.set_session(tf.Session())
np.random.seed(0) # For keras?
# Constants
NUMBER_OF_POSITIONS = 40
NUMBER_OF_CLASSES = 2
NUMBER_OF_SAMPLES_IN_EACH_CLASS = 25
# Generate sequences
https://pastebin.com/GvfLQte2
# Build model
# ===========
# Input Layer
input_layer = Input(shape=(NUMBER_OF_POSITIONS,4))
# Hidden Layers
y = Conv1D(100, 10, strides=1, activation="relu", )(input_layer)
y = MaxPooling1D(pool_size=5, strides=5)(y)
y = Flatten()(y)
y = Bidirectional(SimpleRNN(100, return_sequences = True, activation="tanh", ))(y)
y = Flatten()(y)
y = Dense(100, activation='relu')(y)
# Output layer
output_layer = Dense(NUMBER_OF_CLASSES, activation="softmax")(y)
model = Model(input_layer, output_layer)
model.compile(optimizer="adam", loss="categorical_crossentropy", )
model.summary()
# ~/anaconda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/layers/recurrent.py in build(self, input_shape)
# 1049 input_shape = tensor_shape.TensorShape(input_shape).as_list()
# 1050 batch_size = input_shape[0] if self.stateful else None
# -> 1051 self.input_dim = input_shape[2]
# 1052 self.input_spec[0] = InputSpec(shape=(batch_size, None, self.input_dim))
# 1053
# IndexError: list index out of range
您无需重构任何内容即可将Conv1D图层的输出转换为LSTM图层。
所以,问题只是Flatten
层的存在,它破坏了形状。
这些是Conv1D和LSTM使用的形状:
(batch, length, channels)
(batch, timeSteps, features)
长度与timeSteps相同,通道与功能相同。
使用Bidirectional
包装器也不会改变任何东西。它只会复制您的输出功能。
如果您要将整个序列整体分类,那么您的最后一个LSTM必须使用return_sequences=False
。 (或者你可以使用一些压扁+密集后)
如果您要对序列的每个步骤进行分类,那么所有LSTM都应该有return_sequences=True
。您不应该在它们之后展平数据。