美文网首页
Tensorflow初探(1)--实现一个神经网络

Tensorflow初探(1)--实现一个神经网络

作者: zhfish | 来源:发表于2018-06-02 21:06 被阅读0次

    今天我们来实现一个神经网络,其中部分内容参考
    https://www.jianshu.com/p/596a30d46f34
    如有冒犯请私信我或者留言,希望一些小小的工作能为大家的学习和工作带来便利。

    一、神经网络

    我在看Michael Nielsen 大神的 《Neural Networks and Deep Learning》这本书时第一次接触到神经网络这个概念。这本书由浅入深,讲述得细致而不失深度。有兴趣的朋友可以看看,下面是中文版链接。
    http://www.liuxiao.org/wp-content/uploads/2016/10/nndl-ebook.pdf
    那么什么是神经网络?神经网络又能干什么呢?我相信有不少同学听过这句话“神经网络可以计算任何函数”。神经网络拥有一种普遍性。这非常非常有吸引力。关于这点的证明(说是“解释”可能更好)可以参考Approximation by superpositions of a sigmoidal function这篇文章。现在我们更关心怎么实现一个神经网络。

    二、实现步骤

    先简单说明一下待拟合的函数。毕竟咱们得先找个目标嘛!先从拟合简单的函数来说明下大概流程,后面再逐步复杂起来。
    我们需要拟合的函数非常简单——y = x^2 - 0.5,对!就是我们之前演示过的函数。我们通过numpy来生产模拟数据。

    def createdata():
        x_data = np.linspace(-1,1,300)[:,np.newaxis]
        noise = np.random.normal(0,0.05,x_data.shape).astype(np.float32)
        y_data = np.square(x_data) - 0.5 + noise
        return x_data,y_data
    

    我们需要关注的就是返回值,这个函数返回x_data,y_data。x_data相当于原始inputs,y_data相当于我们需要拟合的对象targets。至此数据便有了。
    接下来我们需要做什么?是不是好多时候去实现一个东西的时候一脸懵逼?其实,觉得困惑是因为我们没有理清思路。我们得多问问自己一些问题。
    我们首先问问自己一个问题:

    我们知不知道,这是 一个什么样的函数,我们有没有先验的知识?

    我们为什么要关注函数形态?因为这关系到我们需要怎么设置参数。比如y=kx+b只需要设置两个函数拟合,而y=sin(kx)+b就需要三个。
    我们再问一个问题:

    我们怎么来拟合一个函数?或者说,函数怎么就三下两下就出结果了?

    其实我和大家一样,一开始也很困惑,读完梯度下降算法之后,稍微好了一些,但还是有些不太理解。
    关于第一个问题,我们其实可以先通过假设的方式来解决一下,后面我们可以通过更高级的方式来探索“这可能是一个什么函数?”
    第二个问题很关键:神经网络的普适性。
    Michael Nielsen的书中提到了这个问题,在第四章讲到了“神经网络可以计算任何函数的可视化证明”
    下面我们简单探讨一下这个问题。有两点需要注意:

    一、一个网络并不能准确地计算任何函数。而是说,我们可以获得尽可能好的一个近似。通过增加隐藏元的数量,可以提升近似的精度

    二、近似的函数类是连续函数,对于阶跃函数,我们使用连续函数进行模拟。

    大家都学过微积分吧!对于任意函数我们都可以用一个个小方块来拟合,对吧?那么在神经网络中我们的小方块又是什么呢?先看下图,这是一个特殊的sigmod函数,w=999 几乎就是个阶跃函数了。

    image.png
    现在我们有两个参数w,b实际上我们可以用s = −b/w简化我们描述隐藏神经元的方式,这就是阶跃位置。
    image.png
    越来越接近我们的目标了.
    下边的绘图是隐藏层的加权输出 w1a1 + w2a2 。这里 a1 和 a2 各自是顶部和底部神经元的输出。这些输出由a表示,是因为它们通常被称为神经元的 激活值(activations)。
    image.png
    我们再看一张图,我相信看完这张图,你就会发现"小方块"在哪里了。
    image.png
    详细内容可以参考上文提到的资料。这里不多说了,再说下去大家可能没兴致看了。
    我们回到正题。先用tensorflow构建一个简单的层,输入的参数是该层输入,输入数据的大小,输出数据的大小,以及使用的激活函数,激活函数在默认情况下是None,即不适用激活函数:
    def add_layer(inputs,in_size,out_size,activation_function=None):
        Weights = tf.Variable(tf.random_normal([in_size,out_size]))
        biases = tf.Variable(tf.zeros([1,out_size])+0.1)
        Wx_plus_b = tf.add(tf.matmul(inputs,Weights),biases)
        if activation_function is None:
            outputs = Wx_plus_b
        else:
            outputs = activation_function(Wx_plus_b)
        return outputs
    

    这里,我们定义输入层-隐藏层-输出层的三层神经网络结构,其中输入层和输出层仅有一个神经元,而隐藏层有10个神经元。同时,我们定义我们的损失是平方损失函数,通过梯度下降法来最小化我们的损失。

    def createnet():
        xs = tf.placeholder(tf.float32,[None,1])
        ys = tf.placeholder(tf.float32,[None,1])
    
        l1 = add_layer(xs,1,10,activation_function=tf.nn.relu)
        prediction = add_layer(l1,10,1,activation_function=None)
    
        loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction),
                                    reduction_indices = [1]))
        train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
    
        init = tf.global_variables_initializer()
    
        x_data,y_data = createdata()
        with tf.Session() as sess:
            sess.run(init)
            for i in range(1000):
                sess.run(train_step,feed_dict={xs:x_data,ys:y_data})
                if i % 50 == 0:
                    print(sess.run(loss,feed_dict={xs:x_data,ys:y_data}))
    

    非常简单的一个例子动手敲一下就会明白了,有些内容在之前的博客里做了记录,比如reduce_sum的用法等等。不多做赘述了。
    完整代码如下

    import tensorflow as tf 
    import numpy as np 
    
    def add_layer(inputs,in_size,out_size,activation_function=None):
        Weights = tf.Variable(tf.random_normal([in_size,out_size]))
        biases = tf.Variable(tf.zeros([1,out_size])+0.1)
        Wx_plus_b = tf.add(tf.matmul(inputs,Weights),biases)
        if activation_function is None:
            outputs = Wx_plus_b
        else:
            outputs = activation_function(Wx_plus_b)
        return outputs
    
    def createdata():
        x_data = np.linspace(-1,1,300)[:,np.newaxis]
        noise = np.random.normal(0,0.05,x_data.shape).astype(np.float32)
        y_data = np.square(x_data) - 0.5 + noise
        return x_data,y_data
    
    def createnet():
        xs = tf.placeholder(tf.float32,[None,1])
        ys = tf.placeholder(tf.float32,[None,1])
    
        l1 = add_layer(xs,1,10,activation_function=tf.nn.relu)
        prediction = add_layer(l1,10,1,activation_function=None)
    
        loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction),
                                    reduction_indices = [1]))
        train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
    
        init = tf.global_variables_initializer()
    
        x_data,y_data = createdata()
        with tf.Session() as sess:
            sess.run(init)
            for i in range(1000):
                sess.run(train_step,feed_dict={xs:x_data,ys:y_data})
                if i % 50 == 0:
                    print(sess.run(loss,feed_dict={xs:x_data,ys:y_data}))
    
    createnet()
    

    相关文章

      网友评论

          本文标题:Tensorflow初探(1)--实现一个神经网络

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