我试图将一维卷积网络用于通常使用MLP的大噪声数据分类问题,但在CNN中得到的结果要差得多。我试图通过将CNN网络简化为MLP的结构来找出问题所在。这就是我所做的。 MLP的结构是(192、60、60、163),其具有两个具有tanh活化功能的尺寸为60的隐藏的致密层。简化的CNN仅包含一个conv1d层,其内核大小和步幅都设置为输入层(192)的大小,并具有60个要素。这样的设置将每个功能的输入收敛到一个节点。因此,该转换层实际上包含60个节点,然后被展平并连接到大小为60的密集层,然后连接到输出层。我认为这样的CNN具有与上述MLP相同的结构。 这是CNN的代码:
input = tf.placeholder(shape=[192, 1], dtype=tf.float32)
targets = tf.placeholder(shape=[163], dtype=tf.float32)
layer = tf.layers.conv1d(input, filters=60, kernel_size=192, strides=192, activation=tf.nn.tanh, kernel_initializer=tf.truncated_normal_initializer(), bias_initializer=tf.zeros.initializer())
layer = tf.layers.flatten(layer)
layer = tf.layers.dense(layer, units=60, activation=tf.nn.tanh, kernel_initializer=tf.truncated_normal_initializer(), bias_initializer=tf.zeros.initializer())
logits = tf.layers.dense(layer, units=163, kernel_initializer=tf.truncated_normal_initializer(), bias_initializer=tf.zeros.initializer())
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=targets, logits=logits), name='cross_entropy')
这是MLP的代码
input = tf.placeholder(shape=[192], dtype=tf.float32)
targets = tf.placeholder(shape=[163], dtype=tf.float32)
layer = tf.layers.dense(input, units=60, activation=tf.nn.tanh, kernel_initializer=tf.truncated_normal_initializer(), bias_initializer=tf.zeros.initializer())
layer = tf.layers.dense(layer, units=60, activation=tf.nn.tanh, kernel_initializer=tf.truncated_normal_initializer(), bias_initializer=tf.zeros.initializer())
logits = tf.layers.dense(layer, units=163, kernel_initializer=tf.truncated_normal_initializer(), bias_initializer=tf.zeros.initializer())
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=targets, logits=logits), name='cross_entropy')
在相同的训练参数下,MLP的准确性约为8%,而CNN的准确性仅为1%。根据我的理解,这种转换层与MLP中的第一个密集层执行相同的矩阵运算。卷积运算只是输入和内核按元素相乘的总和,因此conv1d层的内核或过滤器实际上充当MLP中第一个密集层的权重。并且由于它们使用相同的激活函数(tanh),因此梯度应该相同。那么,为什么CNN的结果如此糟糕?