四时宝库

程序员的知识宝库

人工智能基础:MLP实现,sigmoid和softmax的差别

一个更复杂高效的架构是多层感知器MLP。典型的学习算法是后向传播算法。

后向传播算法比较系统的输出值和期望输出值,根据他们之间的差值(或者称为error),修改神经网络的突触的权值。需要强调的是,虽然你不知道隐藏层神经元的期望输出,依然可以通过梯度下降技术来进行监督学习。

输入层的数量需要根据输入的数量来决定。例如mnist的每个输入有28*28个,因此输入层必须有784个。最终的输出有10中可能性,因此输出层可以是10个。隐藏层的层数和每层的神经元数量没有严格的准则,仅有以写经验供参考

当增加隐藏层的数量时,我们也需要增加训练集的大小和连接的数量,这回导致训练时间增加。

如果隐藏层的神经元太多,一方面更多权重需要更新,另一方面需要的训练集数量跟多。这会导致较差的一般化能力,毕竟训练集仅仅时真实情况的一个样本,拟合得太接近了,当输入一个不在训练集中的数据时,容易出错。但如果隐藏的神经元太少,可能没有能力完成训练集的学习。

#import MNIST data

import input_data

mnist=input_data.read_data_sets("MNIST_data/",one_hot=True)

import tensorflow as tf

import matplotlib.pyplot as plt

#Parameters

learning_rate=0.01

training_epochs=20

batch_size=100

display_step=1

n_hidden_1 = 256 #the number of neurons for the first layer

n_hidden_2 = 256 # the second hidden layer.

n_input=784 #mnist data input in input layer

n_classes = 10 # all kindes of output in output layer

#tf Graph Input

x=tf.placeholder("float",[None,n_input]) #input is 28*28 image,

y=tf.placeholder("float",[None,n_classed]) #output is 0~9

#Create model

bias_layer_1 = tf.Variable(tf.random_normal([n_hidden_1]))

h=tf.Variable(tf.random_normal([n_input,n_hidden_1]))

layer_1=tf.nn.sigmoid(tf.add(tf.matmul(x,h),bias_layer_1)) #output of layer 1

bias_layer_2 = tf.Variable(tf.random_normal([n_hidden_2]))

w=tf.Variable(tf.random_normal([n_hidden_1,n_hidden_2]))

layer_2=tf.nn.sigmoid(tf.add(tf.matmul(layer_1,w),bias_layer_2))

bias_output = tf.Variable(tf.random_normal([n_classes]))

output=tf.Variable(tf.random_normal([n_hidden_2,n_classes]))

output_layer=tf.nn.sigmoid(tf.add(tf.matmul(layer_2,output),bias_output)) #这里调用了sigmoid函数

#Construct model

#Minimize error using cross entropy

cost=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(output_layer,y)) #这里还用了一次softmax函数然后再计算交叉熵。

optimizer=tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

#Plot settings

avg_set = []

epoch_set=[]

#initializing the variables

init=tf.global_variables_initializer()

#Launch the graph

with tf.Session() as sess:

sess.run(init)

#training cycle

for epoch in range(training_epochs):

avg_cost=0

total_batch=int(mnist.train.num_examples/batch_size)

#print "total_batch = %d" % total_batch

#loop overall batches

for i in range(total_batch):

batch_xs,batch_ys=mnist.train.next_batch(batch_size)

sess.run(optimizer,feed_dict={x:batch_xs,y:batch_ys})

avg_cost+= sess.run(cost,feed_dict={x:batch_xs,y:batch_ys})/total_batch

if epoch %display_step ==0:

print "Epoch:",'%04d'%(epoch+1),"cost=","{:.9f}".format(avg_cost)

avg_set.append(avg_cost)

epoch_set.append(epoch+1)

correct_prediction=tf.equal(tf.argmax(output_layer,1),tf.argmax(y,1))

accuracy=tf.reduce_mean(tf.cast(correct_prediction,"float"))

print "Model accuracy:",accuracy.eval({x:mnist.test.images,y:mnist.test.labels})

print "Training phase finished"

sigmoid函数(也叫逻辑斯谛函数):

引用wiki百科的定义:

  A logistic function or logistic curve is a common “S” shape (sigmoid curve).

  其实逻辑斯谛函数也就是经常说的sigmoid函数,它的几何形状也就是一条sigmoid曲线。

logistic曲线如下:

同样,我们贴一下wiki百科对softmax函数的定义:

softmax is a generalization of logistic function that “squashes”(maps) a K-dimensional vector z of arbitrary real values to a K-dimensional vector σ(z) of real values in the range (0, 1) that add up to 1.

这句话既表明了softmax函数与logistic函数的关系,也同时阐述了softmax函数的本质就是将一个K

维的任意实数向量压缩(映射)成另一个K维的实数向量,其中向量中的每个元素取值都介于(0,1)之间。

softmax函数形式如下:

总结:sigmoid将一个real value映射到(0,1)的区间(当然也可以是(-1,1)),这样可以用来做二分类。

而softmax把一个k维的real value向量(a1,a2,a3,a4….)映射成一个(b1,b2,b3,b4….)其中bi是一个0-1的常数,然后可以根据bi的大小来进行多分类的任务,如取权重最大的一维。

本例中sigmoid计算后的结果再进行一次softmax压缩,使得每种结果可以表示成一个概率。

【adam优化器的特点】

  • Adam梯度经过偏置校正后,每一次迭代学习率都有一个固定范围,使得参数比较平稳。

  • 结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点

  • 为不同的参数计算不同的自适应学习率

  • 也适用于大多非凸优化问题——适用于大数据集和高维空间。

由此相较于单层感知器,多层感知器在实现上有以下一个改进:

  • 构建模型时多加几条代码即可完成模型构建

  • sigmoid之后再调用softmax进行一次映射,使得每次运算结果都是一个概率分布。

  • 模型复杂度增加,原有的优化算法性能上存在问题,这里采用adam优化算法

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接