尝试克服一下小伙伴对神经网络的恐惧No.26

时间:2022-04-26
本文章向大家介绍尝试克服一下小伙伴对神经网络的恐惧No.26,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

我是小蕉。

研表究明,这的网官的demo,代码确实的是己打自的。

这两天仔细研究了一下神经网络,简单的结构其实没想象中那么恐怖,只是我们自己吓自己,今天希望能把理解到的东西分享给大家,克服一下大家的恐惧,我使用的框架是Tensorflow。

先提一个概念,placeholder占位符,这个东西是我们用来进行填坑的东西,也就是我们能在调用的使用传入的东西,其他的东西在网络编写完成之后,只能由程序进行变更,我们是不能人为干预的。

数据集是MNIST数据集,一堆的28 * 28像素的图片以及他们的标签值,测试集和训练集是分开的,不知道怎么下载的自己去官网看。我这里就直接引入了。

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

首先定义两个大坑。x就是我们的输入值,可以是测试数据,也可以是训练数据,也可以是实时的数据。tf.float32代表是,就是字面意义啦。[None,784]以及[None,10]的意思就是,第一个维度的None代表不限制输入的"行数",也就是不限制输入的数据集的大小,784代表是784输入值,10代表10个输出值。

    x   = tf.placeholder(tf.float32, [None , 784],name='input_x')
    y_ = tf.placeholder(tf.float32, [None, 10],name='input_y‘)

所以神经网络就是我们先定义好一个网络结构,其中有一个坑x是给我们的输入的,一个坑y_是给我们打好的标签。然后用训练集进行训练网络,测试集进行测试,如果效果还不错呢,我们就把这个训练完网络直接应用到实时预测当中去。再说一遍:训练完的网络可以直接应用到实时预测中。

那怎么去构建这个网络以及怎么训练呢?我们定义两个变量,w权重和b偏置值,这里定义为Variable,代表这两个变量的值是可以被程序变更的(不是认人为喔),没办法就是这么拖沓。tf.zeros意思是新建一个全0的矩阵。那这里为什么w是[784,10]的矩阵,而b是[10]的呢?这是因为我们输入的维度有784维,而输出是10维,所以我们的权重有784 * 10这么多,而输出值只有0-9,所以偏置项也只有10项。其实就是新建了784 * 10 个 y = wx + b这么一个线性模型,然后每个模型都能得给当前的y值打一个分数这样。

 w = tf.Variable(tf.zeros([784,10]))
 b = tf.Variable(tf.zeros([10]))
model = tf.matmul(x , w) + b

接下来重头戏来了,我们得到了10个类别各自的得分,咋办呢?

结果可能是 [0,0,0,0.5,0.2,0,0,0,0.1,0]这样。

那我们要选哪一个呢?我们一般来说就直接max选0.5这个啦,但是我们又不希望每次都只选0.5,那咋办?用softmax回归来做。

y = tf.nn.softmax(model)

softmax回归就是logistic回归在多项分布上的拓展,又加入了soft元素,来使得我们的结果更加具有泛化能力。(这个需要我说的留言,下次立马说,这里先不说)。

官网的图能直接说明他们的关系,这个网络够复杂了吧?

好啦,定义完网络该开始定义用于训练的隐藏层了。

一个叫损失函数的原名叫交叉熵小东西出现了,咱整个神经网络的目标,就是把这个值变小变小再变小,越小越好最好全局最小。

cross_entropy = - tf.reduce_sum( y_ * tf.log(y))

怎么把它变小呢?定义一个训练的步,专门用来训练的。有的算法能概率比较大达到全局最小,有的算法因为过拟合或者什么原因只能达到局部最小值。咱这里定义的就是一个使用以0.01学习率(步长)的梯度下降算法来最小化我们上面定义的损失函数。

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

华丽丽的分割线,好了到这里我们的网络就定义完了,上面的一切都只是定义,并没有跑起来。该给它投食了,该投多少食自己看着办,我这里投1000次,每次投100个数据。训练的过程就是每次拿一些数据,求损失函数最小值,然后把这个得到最小值的w和b,以加权的形式合并到原有的变量w和b上面去。

初始化一个会话,tensorflow一切一切的操作都只能在用会话来驱动。

sess = tf.Session()

初始化所有的变量,不跑这个,变量是不会自己初始化的喔。

sess.run(tf.initialize_all_variables())
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})

网络训练完了,该开始测试了吧?这里没啥好说的,有一个地方要特别说一下,tf.argmax(y,1)。这个地方就是说,y值可能是一个十维的向量,找到这个向量里面的最大值,并把它置为1。这样就可以对比由网络输出的y和我们已经打好的标签y_了。

 correct_prediction = tf.equal(tf.argmax(y,1) , tf.argmax(y_,1))
 accuray = tf.reduce_mean(tf.cast(correct_prediction,"float"))
 print sess.run(accuray , feed_dict={x:mnist.test.images , y_:mnist.test.labels})

至此,神经网络已经完成啦,接下来如果需要用于实时预测,那么直接就调用已经训练好的神经网络就行了。

result = sess.run(tf.argmax(y,1), feed_dict={x:SomeData})

持久化的话,tensorflow提供了saver这个小东西,我会慢慢说哒。

好啦,吾辈笨愚,小伙伴们对神经网络的恐惧有没有少一丢丢丢呢??