Neural Networks(神经网络)

原创 2017年10月20日 17:13:22

神经网络基本原理:

这里写图片描述

人类一向善于从大自然中寻找启发,并做出必要的改进来满足某种需要。而人类本身就有很多不可思议的事情,比如大脑。机器学习,学习学习,参考人类本身的学习就是对所见的事物一步一步的总结,一层一层的抽象,而大脑的神经-中枢-大脑的工作过程或许是一个不断迭代,不断抽象的过程,从原始的信号,做低级的抽象,逐渐向高级抽象迭代。

感知机中,它采用了多个输入单元来抽象,但是学习能力非常有限,无法解决非线性可分的问题,虽然SVM延伸了核技术解决了这一点,但是实际上利用多层的感知机(Multi-layer Perception)也能完成,不过虽然是多层,其实是只有一层隐层节点的浅层模型。比如很多的分类,回归的学习方法都是浅层的算法,在于有限的样本和计算单元情况下对复杂的函数的表达能力有限,泛化能力不佳,计算量大。所以简单的多层网络的学习规则肯定是不够的,类比大脑产生更强大的算法是必要的。

这里写图片描述

正如一个感知机一样,它有多个输入,不过这些输入可以取0~1的任何值而不是仅仅0,1。改进原先的激活函数为Sigmoid函数:

σ(z)=11+ez

这里写图片描述

为什么用Sigmoid?其实使用不同的激活函数最大的变化只是求偏导时某些值的改变,事实证明这样做能够简化计算。

这里写图片描述

模拟生物神经网络,当神经元“兴奋”时就会向其相连的神经元发送某些化学物质去改变相连神经元的电位,而且如果电位超过某个阈值(threshold),神经元将就会被激活。事实上,不考虑它是否真的模拟了生物神经网络,只需将一个神经网络视为包含了许多参数的数学模型,由若干个函数相互嵌套即可。采用Sigmoid做激活函数(activation function),可以构建一个多层感知机,由许多逻辑单元按照不同层级组织起来,每一层的输出变量都是下一层的输入变量:

这里写图片描述

其中x1,x2,x3是输入单元(input units),将原始数据输入给它们。a1,a2,a3是中间单元,负责处理数据,然后呈递到下一层,最后是输出单元,它负责计算h(x)。然后与感知机类似,可以算出

a(2)1=σ(w(1)11x1+w(1)12x2+w(1)13x3+b(1)1)

a(2)2=σ(w(1)21x1+w(1)22x2+w(1)23x3+b(1)2)

a(2)3=σ(w(1)31x1+w(1)32x2+w(1)33x3+b(1)3)

计算结果做下一次的输入,然后可得:
hW,b(x)=σ(w(2)11a(2)1+w(2)12a(2)2+w(2)13a(2)3+b(2)1)

机器学习老套路,此时需要一个损失函数来微调,常见的均方误差:
J(W,b,x,y)=12||hW,b(x)y||22

然后基于梯度下降策略,对参数们进行一层一层的误差逆传递(Error BackPropagation,BP)更新参数。
Wl=Wlαi=1mδi,l(ai,l1)T

bl=blαi=1mδi,l

这里写图片描述

简单来说就是参数的随机初始化,利用正向传播计算所有的h(x),计算代价函数j,利用反向传播计算所有的偏导,利用数值检验来检验偏导,最后使用优化算法(梯度下降等)来最小化代价函数。

import random
import numpy as np
class Network(object):

    def __init__(self, sizes):#sizes包含各层神经元的数量
        self.num_layers = len(sizes)
        self.sizes = sizes
        self.biases = [np.random.randn(y, 1) for y in sizes[1:]]#随机初始化
        self.weights = [np.random.randn(y, x)
                        for x, y in zip(sizes[:-1], sizes[1:])]

    def feedforward(self, a):
        for b, w in zip(self.biases, self.weights):
            a = sigmoid(np.dot(w, a)+b)
        return a

    def SGD(self, training_data, epochs, mini_batch_size, eta,
            test_data=None):#梯度下降
        if test_data: n_test = len(test_data)
        n = len(training_data)
        for j in xrange(epochs):
            random.shuffle(training_data)
            mini_batches = [
                training_data[k:k+mini_batch_size]
                for k in xrange(0, n, mini_batch_size)]
            for mini_batch in mini_batches:
                self.update_mini_batch(mini_batch, eta)#更新
            if test_data:
                print "Epoch {0}: {1} / {2}".format(
                    j, self.evaluate(test_data), n_test)
            else:
                print "Epoch {0} complete".format(j)

    def update_mini_batch(self, mini_batch, eta):
        nabla_b = [np.zeros(b.shape) for b in self.biases]
        nabla_w = [np.zeros(w.shape) for w in self.weights]
        for x, y in mini_batch:
            delta_nabla_b, delta_nabla_w = self.backprop(x, y)#调用backprop
            nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
            nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
        self.weights = [w-(eta/len(mini_batch))*nw
                        for w, nw in zip(self.weights, nabla_w)]
        self.biases = [b-(eta/len(mini_batch))*nb
                       for b, nb in zip(self.biases, nabla_b)]

    def backprop(self, x, y):
        nabla_b = [np.zeros(b.shape) for b in self.biases]
        nabla_w = [np.zeros(w.shape) for w in self.weights]
        # feedforward
        activation = x
        activations = [x]
        zs = [] 
        for b, w in zip(self.biases, self.weights):
            z = np.dot(w, activation)+b
            zs.append(z)
            activation = sigmoid(z)
            activations.append(activation)
        # backward pass
        delta = self.cost_derivative(activations[-1], y) * \
            sigmoid_prime(zs[-1])
        nabla_b[-1] = delta
        nabla_w[-1] = np.dot(delta, activations[-2].transpose())

        for l in xrange(2, self.num_layers):
            z = zs[-l]
            sp = sigmoid_prime(z)
            delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
            nabla_b[-l] = delta
            nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
        return (nabla_b, nabla_w)

    def evaluate(self, test_data):#判别正确的数量
        test_results = [(np.argmax(self.feedforward(x)), y)
                        for (x, y) in test_data]
        return sum(int(x == y) for (x, y) in test_results)

    def cost_derivative(self, output_activations, y):
        return (output_activations-y)

def sigmoid(z):
    """The sigmoid function."""
    return 1.0/(1.0+np.exp(-z))

def sigmoid_prime(z):#导数
    """Derivative of the sigmoid function."""
    return sigmoid(z)*(1-sigmoid(z))

收敛速度太慢?损失函数改进
采用交叉熵

J(W,b,a,y)=ylna(1y)ln(1a)

第一,它非负;第二结果越接近,交叉熵接近0。这两点将使收敛速度变快。

分类问题如何解决?
Softmax激活函数:

aLi=ezLij=1nLezLj

softmax函数能将输入值映射到(0,1),且所有输出值的累和为1,所以可以直接把它当概率,选取概率最大作最终结果。

这里写图片描述

继续加深神经网络效果怎么样?梯度问题
在BP算法中,使用了链式法则来求梯度,这样将会导致梯度问题。如果是一堆小于1的数字连乘,那么网络越深,连乘越多,慢慢的导致梯度消失,反过来如果是大于1的数据,将导致梯度爆炸。
修正线性单元(Rectified Linear Unit,ReLU)激活函数:

这里写图片描述

它在一定程度上能解决梯度消失,原因在于函数的右端的不会趋近于饱和,求导数时,导数不为零,从而梯度不消失,不过对于小于0的左边依然存在问题。

正则化问题
除了用L1,L2这种正则化外,神经网络可以通过dropout 来正则化,即在训练时随机去掉部分隐藏层的神经元。

这里写图片描述

随机dropout相当于训练了多个不同的神经网络,这样做能减轻过拟合,提升其泛化能力

如何选择超参数?
比如梯度下降的步率,批量数据的规模,周期和正则化的系数等等。
解决方案:可视化,不断尝试与调整以得到最好的结果。

简单的NN应用:

import tensorflow as tf

#导入input_data用于自动下载和安装MNIST数据集
from tensorflow.examples.tutorials.mnist import input_data

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

x = tf.placeholder("float", [None, 784])

#权重值W和偏置值b
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

#使用softmax
y = tf.nn.softmax(tf.matmul(x, W) + b)

y_ = tf.placeholder("float", [None,10])

#计算交叉墒
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))

#梯度下降最小化交叉墒
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)


for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

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

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

print (sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

主要参考:
Michael Nielsen 《Neural Networks and Deep Learning》

版权声明:本文为博主自我学习整合内容,欢迎转载,转载请注明出处。 https://blog.csdn.net/qq_39388410/article/details/78297546

python 实现识别手写 MNIST数字集的程序

python 实现识别手写 MNIST 数字集的程序 我们需要做的第⼀件事情是获取 MNIST 数据。如果你是⼀个 git ⽤⼾,那么你能够 通过克隆这本书的代码仓库获得数据,  实现我们的⽹络来分类...
  • chen_shiqiang
  • chen_shiqiang
  • 2016-07-14 21:53:04
  • 14796

神经网络 - 入门

在机器学习和认知科学领域,人工神经网络(artificial neural network,缩写ANN),简称神经网络(neural network,缩写NN)或类神经网络,是一种模仿生物神经网络(动...
  • nicky918
  • nicky918
  • 2017-08-18 14:34:21
  • 205

《neural network and deep learning》题解——ch03 再看手写识别问题题解与源码分析

http://blog.csdn.net/u011239443/article/details/77649026完整代码:https://github.com/xiaoyesoso/neural-ne...
  • u011239443
  • u011239443
  • 2017-08-28 15:12:07
  • 995

Neural Networks and Deep Learning 神经网络和深度学习

在http://neuralnetworksanddeeplearning.com/看到这篇文章。写的简单易懂。适合初学者学习,不过是英文的。 自己尝试着一边翻译一边学习。 第一章 使用神经网络...
  • thirtyfive16
  • thirtyfive16
  • 2016-09-14 15:37:26
  • 1023

【论文笔记】二值化神经网络(Binarized Neural Network)

文章链接:Binarized Neural Networks: Training Deep Neural Networks with Weights and Activations Constrain...
  • elaine_bao
  • elaine_bao
  • 2016-03-22 09:45:35
  • 6644

机器学习深度学习基础笔记(2)——梯度下降之手写数字识别算法实现

该系列是笔者在机器学习深度学习系列课程学习过程中记录的笔记,简单粗暴,仅供参考。 下面的算法代码来自https://github.com/mnielsen/neural-networks-and-de...
  • qq_17105473
  • qq_17105473
  • 2017-05-17 17:17:48
  • 450

《Neural Networks and Deep Learning》读书笔记:最简单的识别MNIST的神经网络程序(2)

转载请注明出处:https://www.codelast.com/ 本文是上一篇文章的续文。 《Neural Networks and Deep Learning》一书的中文译名是《神经网...
  • my__darling
  • my__darling
  • 2017-12-21 10:55:30
  • 127

Neural Networks and Deep Learning-神经网络与深度学习

  • 2016年10月11日 19:49
  • 13.4MB
  • 下载

Neural Networks and Deep Learning-神经网络与深度学习 v0.5最新版

  • 2017年08月22日 00:19
  • 3.64MB
  • 下载

进神经网络的学习方式(译文)----中

过匹配和规范化 诺贝尔奖得主美籍意大利裔物理学家恩里科·费米曾被问到他对一个同僚提出的尝试解决一个重要的未解决物理难题的数学模型。模型和实验非常匹配,但是费米却对其产生了怀疑。他问模型中需要设置...
  • langb2014
  • langb2014
  • 2016-01-09 17:24:39
  • 2139
收藏助手
不良信息举报
您举报文章:Neural Networks(神经网络)
举报原因:
原因补充:

(最多只允许输入30个字)