Maxout激活函数原理及实现

1、原理简介

maxout激发函数,则其隐含层节点的输出表达式为:

这里的W是3维的,尺寸为d*m*k,其中d表示输入层节点的个数,m表示隐含层节点的个数,k表示每个隐含层节点对应了k个”隐隐含层”节点,这k个”隐隐含层”节点都是线性输出的,而maxout的每个节点就是取这k个”隐隐含层”节点输出值中最大的那个值。因为激发函数中有了max操作,所以整个maxout网络也是一种非线性的变换。

下图可以帮你直观的认识什么是maxout激活函数(下图中k=3):

maxout的拟合能力是非常强的,它可以拟合任意的的凸函数。最直观的解释就是任意的凸函数都可以由分段线性函数以任意精度拟合,而maxout又是取k个隐隐含层节点的最大值,这些”隐隐含层"节点也是线性的,所以在不同的取值范围下,最大值也可以看做是分段线性的(分段的个数与k值有关)。论文中的图如下(它表达的意思就是可以拟合任意凸函数,当然也包括了ReLU了):

2、Maxout与Dropout

Dropout是一种网络规则化技巧,其实它就是相当于在训练很多个不同的网络结构,尽管如此,推理阶段所有不同结构的参数依然是共享的,因为实际上只有一个网络存在。

在机器学习算法中,有一个概念叫做bagging,bagging就相当于提供了一种投票机制,对于一个任务,我们不是仅仅使用一个模型来做出决策,而是通过多个模型的平均来决定最终的决策。

由于在Dropout中仅仅只有一个模型,因此无法进行平均操作,取而代之的是将模型的权重乘以Dropout比率p,这个做法在线性激活函数中表现尚可,但是如果是经过非线性激活函数那就不准确了。而Maxout模型的仿射变换中没有非线性激活函数,因此我们也可以在此变换中引入Dropout技巧,并且实验表明Maxout与Dropout的结合效果比较好。

3、Maxout的tensorflow实现

import tensorflow as tf


x = tf.random_normal([1,3])
m = 4
k = 3

d = x.get_shape().as_list()[-1]

W = tf.Variable(tf.random_normal(shape=[d, m, k]))
b = tf.Variable(tf.random_normal(shape = [m, k]))
dot_z = tf.tensordot(x, W, axes=1) + b
z = tf.reduce_max(dot_z, axis=2)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run([x,dot_z,z]))

推荐阅读更多精彩内容