我正在跟随Vincent Vanhoucke的Udacity深度学习视频并尝试理解最大池的(实际的或直观的或明显的)效果。
让我们说我当前的模型(没有合并)使用带有步幅2的卷积来减少维数。
def model(data):
conv = tf.nn.conv2d(data, layer1_weights, [1, 2, 2, 1], padding='SAME')
hidden = tf.nn.relu(conv + layer1_biases)
conv = tf.nn.conv2d(hidden, layer2_weights, [1, 2, 2, 1], padding='SAME')
hidden = tf.nn.relu(conv + layer2_biases)
shape = hidden.get_shape().as_list()
reshape = tf.reshape(hidden, [shape[0], shape[1] * shape[2] * shape[3]])
hidden = tf.nn.relu(tf.matmul(reshape, layer3_weights) + layer3_biases)
return tf.matmul(hidden, layer4_weights) + layer4_biases
现在我介绍了池:用步幅2和内核大小2的最大池操作(nn.max_pool())替换步幅。
def model(data):
conv1 = tf.nn.conv2d(data, layer1_weights, [1, 1, 1, 1], padding='SAME')
bias1 = tf.nn.relu(conv1 + layer1_biases)
pool1 = tf.nn.max_pool(bias1, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')
conv2 = tf.nn.conv2d(pool1, layer2_weights, [1, 1, 1, 1], padding='SAME')
bias2 = tf.nn.relu(conv2 + layer2_biases)
pool2 = tf.nn.max_pool(bias2, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')
shape = pool2.get_shape().as_list()
reshape = tf.reshape(pool2, [shape[0], shape[1] * shape[2] * shape[3]])
hidden = tf.nn.relu(tf.matmul(reshape, layer3_weights) + layer3_biases)
return tf.matmul(hidden, layer4_weights) + layer4_biases
除了提高准确性之外,我们使用后期模型而不是无池模型的理由是什么?很想从已经多次使用过cnn的人那里获得一些见解!
答案 0 :(得分:4)
两种方法(步幅和汇集)都降低了输入的维数(对于步幅/池大小> 1)。这本身就是一件好事,因为它减少了计算时间,参数数量并且可以防止过度拟合。
他们以不同的方式实现它:
您还提到“除了提高的准确度”。但是人们在机器学习中几乎所做的一切都是为了提高准确性(其他一些损失函数)。因此,如果明天有人会证明sum-square-root pool在许多bechmarks上取得了最好的结果,那么很多人都会开始使用它。
答案 1 :(得分:1)
在分类任务中,提高准确性是目标。
但是,汇集允许您:
减少输入维度是您想要的,因为它迫使网络将其学习的表示投影到不同的维度空间中。这在计算上是好的,因为你必须分配更少的内存,因此你可以有更大的批次。但它也是令人满意的东西,因为通常高维空间有很多冗余,并且是所有abjects看起来稀疏和不相似的空间(见The curse of dimensionality)
此外,您决定用于池操作的功能可以强制网络更加重视某些功能。
例如,最大池化被广泛使用,因为允许网络对输入图像的小变化具有鲁棒性。
在实践中会发生的事情是,只有具有最高激活的特征才能通过最大池化门。 如果输入图像移位了一小部分,那么尽管输入被移位(最大移位等于内核大小),但最大池操作会产生相同的输出。
没有合并的CNN也能够学习这种功能,但在参数和计算时间方面的成本更高(参见Striving for Simplicity: The All Convolutional Net)