一 介绍
Maxout网络可以理解为单个神经元的扩展,主要是扩展单个神经元里面的激活函数。
Maxout是将激活函数变成一个网络选择器,原理就是将多个神经元并列地放在一起,从它们的输出结果中找到最大的那个,代表对特征相应最敏感,然后取这个神经元的结果参与后面的运算。
下图是单个神经元和Maxout网络的对比
它的公式可以理解成:
z1=w1*x+b1
z2=w2*x+b2
z3=w3*x+b3
z4=w4*x+b4
...
out=max(z1,z3,z3,z4,...)
为什么要这样做呢。神经元的作用,类似人类的神经细胞,不同的神经元会因为输入的不同而产生不同的输出,即不同的细胞关心的信号不同。依赖于这个原理,现在的做法就是相当于同时将多个神经元放在一起,哪个效果更好就用哪个。所以这样的网络会有更好的拟合效果。
二 实例描述
Maxout网络的构建方法:通过reduce_max函数对多个神经元的输出来计算Max值,将Max值当作输入按照神经元正反传播方向进行计算。
三 代码
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/")
print ('输入数据:',mnist.train.images)
print ('输入数据打shape:',mnist.train.images.shape)
import pylab
im = mnist.train.images[1]
im = im.reshape(-1,28)
pylab.imshow(im)
pylab.show()
print ('输入数据打shape:',mnist.test.images.shape)
print ('输入数据打shape:',mnist.validation.images.shape)
import tensorflow as tf #导入tensorflow库
tf.reset_default_graph()
# tf Graph Input
x = tf.placeholder(tf.float32, [None, 784]) # mnist data维度 28*28=784
y = tf.placeholder(tf.int32, [None]) # 0-9 数字=> 10 classes
# Set model weights
W = tf.Variable(tf.random_normal([784, 10]))
b = tf.Variable(tf.zeros([10]))
z= tf.matmul(x, W) + b
maxout = tf.reduce_max(z,axis= 1,keep_dims=True)
# Set model weights
W2 = tf.Variable(tf.truncated_normal([1, 10], stddev=0.1))
b2 = tf.Variable(tf.zeros([1]))
# 构建模型
pred = tf.nn.softmax(tf.matmul(maxout, W2) + b2)
# 构建模型
#pred = tf.nn.softmax(z) # Softmax分类
# Minimize error using cross entropy
#cost = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred), reduction_indices=1))
cost = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=z))
#参数设置
learning_rate = 0.04
# 使用梯度下降优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
training_epochs = 200
batch_size = 100
display_step = 1
# 启动session
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())# Initializing OP
# 启动循环开始训练
for epoch in range(training_epochs):
avg_cost = 0.
total_batch = int(mnist.train.num_examples/batch_size)
# 遍历全部数据集
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
# Run optimization op (backprop) and cost op (to get loss value)
_, c = sess.run([optimizer, cost], feed_dict={x: batch_xs,
y: batch_ys})
# Compute average loss
avg_cost += c / total_batch
# 显示训练中的详细信息
if (epoch+1) % display_step == 0:
print ("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(avg_cost))
print( " Finished!")
四 运行结果
......
Epoch: 0189 cost= 0.298605501
Epoch: 0190 cost= 0.298417259
Epoch: 0191 cost= 0.297975748
Epoch: 0192 cost= 0.297584648
Epoch: 0193 cost= 0.297219502
Epoch: 0194 cost= 0.296815876
Epoch: 0195 cost= 0.296571933
Epoch: 0196 cost= 0.296303167
Epoch: 0197 cost= 0.295947715
Epoch: 0198 cost= 0.295588067
Epoch: 0199 cost= 0.295275190
Epoch: 0200 cost= 0.294988065
五 说明
可以看到损失值下降到0.29,随着迭代次数的增加还会继续下降
Maxout的拟合功能很强大,但是也会有节点过多,参数过多,训练过慢的缺点。