美文网首页深度学习程序员人工智能
人工智能 - 多层感知机 MLP [3]

人工智能 - 多层感知机 MLP [3]

作者: SpikeKing | 来源:发表于2017-09-01 15:23 被阅读910次

    欢迎Follow我的GitHub,关注我的简书

    神经网络分为三层:输入层、隐含层、输出层。当引入非线性的隐含层后,理论上只要隐含的节点足够多,就可以拟合任意函数,同时,隐含层越多,越容易拟合更复杂的函数。隐含层的两个属性:每个隐含层的节点数、隐含层的层数。层数越多,每一层需要的节点数就会越少。

    本文源码的GitHub地址,位于multi_layer_perception文件夹。

    MLP

    神经网络问题

    神经网络的三大问题:过拟合、局部最优、梯度弥散。

    过拟合问题:模型拟合训练数据,泛化性较差,测试数据效果不好。解决方案:Dropout,在神经网络的层中,随机丢弃一些点,并且加强剩余的点,学习含有噪声的数据,增强模型的泛化性。

    import tensorflow as tf
    
    in_mat = [2., 3., 2., 1., 4., 2., 3.]
    keep_prop = 0.4
    print tf.Session().run(tf.nn.dropout(in_mat, keep_prop))
    """
    输出:[  5.    7.5   0.    2.5  10.    0.    7.5]
    keep_prop 随机保留40%的数据,并且将所有值增加2.5倍,2.5*0.4=1;
    如果keep_prop是0.5,则所有值增加2倍;
    """
    

    局部最优问题:神经网络不是一个凸优化问题,存在大量的局部最优点,然而,神经网络的局部最优正好可以达到比较好的效果,全局最优反而容易拟合。解决方案:使用自适应的Adagrad优化器代替SGD,减少计算参数的复杂度,学习速率先快后慢,恰好达到局部最优。

    梯度弥散问题:神经网络的的激活函数,将信息上一层传递至下一层的变换,使模型学习到更加高阶的特征。Sigmoid函数,在反向传播中,梯度会急剧减少;Softplus是单侧抑制,即负值转换为正值,但没有稀疏激活性,即没有0状态。真正的神经元具有稀疏性,根据输入信号,选择响应或是屏蔽。解决方案:ReLU,校正线性单元:Rectified Linear Unit,y=max(0,x),将负值抑制为0,即非激活状态,正值反馈。

    import tensorflow as tf
    
    in_mat = [2, 3, 0, -1, -2]
    relu = tf.nn.relu(in_mat)
    print tf.Session().run(relu)
    # 输出 [2 3 0 0 0]
    # 将全部负数都转换为0
    

    多层感知机

    多层感知机,Multi-Layer Perception,也称为多层神经网络(大于等于3层,即至少含有1层隐含层),也称为全连接神经网络(Fully Connected Network,FCN)。

    初始化数据源MNIST,手写数据源;创建可交互的Session,代码中可以直接使用张量的run()和eval()等函数;输入数据源的维数是784,28*28的手写灰度图片,隐含层的维度是300,即784(input) -> 300(hidden) -> 10(output)。

    mnist = input_data.read_data_sets("../MNIST_data/", one_hot=True)  # Data Set
    sess = tf.InteractiveSession()  # Session
    
    in_units = 784  # input neuron dimen
    h1_units = 300  # hide level neuron dimen
    

    初始化输入层的参数和隐含层的参数,W和b。激活函数是ReLU,需要给隐含层参数W1增加一些噪声,防止正态分布的完全对称,导致梯度为0;使用truncated_normal将大于2倍标准差的数据,全部重新输出,相当于增加噪声。输出层的参数,可以都设置为0。

    # hide level para
    # truncated_normal 重新选择超过两个标准差的值
    # 矩阵用大写字母,向量用小写字母
    W1 = tf.Variable(tf.truncated_normal([in_units, h1_units], stddev=0.1))
    b1 = tf.Variable(tf.zeros([h1_units]))
    
    # output para
    W2 = tf.Variable(tf.zeros([h1_units, 10]))
    b2 = tf.Variable(tf.zeros([10]))
    

    两个需要feed的数据,图片信息,dropout的保留率。保留率在训练中是小于1,随机舍弃;在测试中,是等于1,全保留。

    x = tf.placeholder(tf.float32, [None, in_units])  # 任意个in_units维的数
    keep_prob = tf.placeholder(tf.float32)  # dropout的保留比率
    

    创建多层感知机,使用线性回归y=wx+b。创建隐含层,激活函数是ReLU,并且在隐含层中使用Dropout()函数,将某些神经元设置为0(抑制)。输出层使用softmax()的激活函数。

    hidden1 = tf.nn.relu(tf.matmul(x, W1) + b1)  # 隐含层,校正线性单元:Rectified Linear Unit
    hidden1_drop = tf.nn.dropout(hidden1, keep_prob)  # 隐含层的dropout
    y = tf.nn.softmax(tf.matmul(hidden1, W2) + b2)  # 输出层
    

    需要feed的Ground Truth标签y_,真实数据使用下划线“_”标记,损失函数使用标准的交叉熵,优化器使用AdagradOptimizer,优化交叉熵函数cross_entropy。最后初始化,全局变量。

    y_ = tf.placeholder(tf.float32, [None, 10])  # ground truth
    cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
    train_step = tf.train.AdagradOptimizer(0.3).minimize(cross_entropy)
    
    tf.global_variables_initializer().run()  # 初始化全部变量
    

    训练模型,循环3000次,每次随机采样100个数据,feed三类数据:x数据,y_标签,keep_prob是dropout的保留率。

    for i in range(3000):
        batch_xs, batch_ys = mnist.train.next_batch(100)  # 随机采样
        train_step.run({x: batch_xs, y_: batch_ys, keep_prob: 0.75})  # Feed数据,并且训练
    

    使用测试集,验证模型效果,argmax选择最大数的索引,就是识别的数字,全部数据求平均。测试集的feed数据,同样的是数据与标准,注意keep_prob设置为1,不丢弃任何信息。

    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    
    print (accuracy.eval({x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))  # 评估数据
    """
    输出结果:0.9811
    """
    

    OK, that's all! Enjoy it!

    相关文章

      网友评论

        本文标题:人工智能 - 多层感知机 MLP [3]

        本文链接:https://www.haomeiwen.com/subject/gcckjxtx.html