当前位置: 澳门新濠3559 > 编程 > 正文

代表三维点的 (x,根据输入的值得到一个输出

时间:2019-11-07 12:30来源:编程
本篇内容基于 Python3 TensorFlow 1.4 版本。 在上一章已经了解了tensorflow的工作原理,那么今天来学习一下神经网络。 本节内容 本节通过最简单的示例 —— 平面拟合来说明 TensorFlow 的基本

本篇内容基于 Python3 TensorFlow 1.4 版本。

在上一章已经了解了tensorflow的工作原理,那么今天来学习一下神经网络。

本节内容 本节通过最简单的示例 —— 平面拟合来说明 TensorFlow 的基本用法。

(一)首先看一下最简单的神经网络:

构造数据 TensorFlow 的引入方式是:

     和图中表示的一样,最左边是我们的数据集,然后中间使我们的神经网络,包括输入层、隐层、和输出层。

import tensorflow as tf

澳门新濠3559 1

接下来我们构造一些随机的三维数据,然后用 TensorFlow 找到平面去拟合它,首先我们用 Numpy 生成随机三维点,其中变量 x 代表三维点的 (x, y) 坐标,是一个 2×100 的矩阵,即 100 个 (x, y),然后变量 y 代表三位点的 z 坐标,我们用 Numpy 来生成这些随机的点:

     输入层是特征向量(这个特征向量需要我们一个特征提取的过程,书上说用于描述实体的数字的组合成为一个实体的特征向量,比如一个零件可用【0.5,1.6】来描述他0.5m长和1.6kg重的特征)。这个部分通过图中可以看到他可以简单的输入x1、x2两个数据,也可以输入他们的平方,相乘等多种输入形式。我认为神经网路就是把输入的数据进行一个函数拟合的过程,说白了就是建立一个函数,根据输入的值得到一个输出,这里的输入和输出都为一个多维数组,当然也可以是单一的一个数字。所以只要能包含输入特征的运算过程都可以作为输入,当然这只是我自己的理解。

import numpy as np
x_data = np.float32(np.random.rand(2, 100))
y_data = np.dot([0.300, 0.200], x_data) + 0.400

print(x_data)
print(y_data)

     接下来就是神经元了。神经元到底是什么!这个其实很重要,面试的时候有可能会问。神经元,说白了我认为就是一个函数!左面是输入、右边是输出。他的具体结构如下图:

这里利用 Numpy 的 random 模块的 rand() 方法生成了 2×100 的随机矩阵,这样就生成了 100 个 (x, y) 坐标,然后用了一个 dot() 方法算了矩阵乘法,用了一个长度为 2 的向量跟此矩阵相乘,得到一个长度为 100 的向量,然后再加上一个常量,得到 z 坐标,输出结果样例如下:

澳门新濠3559 2

[[ 0.97232962  0.08897641  0.54844421  0.5877986   0.5121088   0.64716059
   0.22353953  0.18406206  0.16782761  0.97569454  0.65686035  0.75569868
   0.35698661  0.43332314  0.41185728  0.24801297  0.50098598  0.12025958
   0.40650111  0.51486945  0.19292323  0.03679928  0.56501174  0.5321334
   0.71044683  0.00318134  0.76611853  0.42602748  0.33002195  0.04414672
   0.73208278  0.62182301  0.49471655  0.8116194   0.86148429  0.48835048
   0.69902027  0.14901569  0.18737803  0.66826463  0.43462989  0.35768151
   0.79315376  0.0400687   0.76952982  0.12236254  0.61519378  0.92795062
   0.84952474  0.16663995  0.13729768  0.50603199  0.38752931  0.39529857
   0.29228279  0.09773371  0.43220878  0.2603009   0.14576958  0.21881725
   0.64888018  0.41048348  0.27641159  0.61700606  0.49728736  0.75936913
  0.04028837  0.88986284  0.84112513  0.34227493  0.69162005  0.89058989
   0.39744586  0.85080278  0.37685293  0.80529863  0.31220895  0.50500977
   0.95800418  0.43696108  0.04143282  0.05169986  0.33503434  0.1671818
   0.10234453  0.31241918  0.23630807  0.37890589  0.63020509  0.78184551
   0.87924582  0.99288088  0.30762389  0.43499199  0.53140771  0.43461791
   0.23833922  0.08681628  0.74615192  0.25835371]
 [ 0.8174957   0.26717573  0.23811154  0.02851068  0.9627012   0.36802396
   0.50543582  0.29964805  0.44869211  0.23191817  0.77344608  0.36636299
   0.56170034  0.37465382  0.00471885  0.19509546  0.49715847  0.15201907
   0.5642485   0.70218688  0.6031307   0.4705168   0.98698962  0.865367
   0.36558965  0.72073907  0.83386165  0.29963031  0.72276717  0.98171854
   0.30932376  0.52615297  0.35522953  0.13186514  0.73437029  0.03887378
   0.1208882   0.67004597  0.83422536  0.17487818  0.71460873  0.51926661
   0.55297899  0.78169805  0.77547258  0.92139858  0.25020468  0.70916855
   0.68722379  0.75378138  0.30182058  0.91982585  0.93160367  0.81539184
   0.87977934  0.07394848  0.1004181   0.48765802  0.73601437  0.59894943
   0.34601998  0.69065076  0.6768015   0.98533565  0.83803362  0.47194552
   0.84103006  0.84892255  0.04474261  0.02038293  0.50802571  0.15178065
   0.86116213  0.51097614  0.44155359  0.67713588  0.66439205  0.67885226
   0.4243969   0.35731083  0.07878648  0.53950399  0.84162414  0.24412845
   0.61285144  0.00316137  0.67407191  0.83218956  0.94473189  0.09813353
   0.16728765  0.95433819  0.1416636   0.4220584   0.35413414  0.55999744
   0.94829601  0.62568033  0.89808714  0.07021013]]
[ 0.85519803  0.48012807  0.61215557  0.58204171  0.74617288  0.66775297
  0.56814902  0.51514823  0.5400867   0.739092    0.75174732  0.6999822
  0.61943605  0.60492771  0.52450095  0.51342299  0.64972749  0.46648169
  0.63480003  0.69489821  0.57850311  0.50514314  0.76690145  0.73271342
  0.68625198  0.54510222  0.79660789  0.58773431  0.64356002  0.60958773
  0.68148959  0.6917775   0.61946087  0.66985885  0.80531934  0.5542799
  0.63388372  0.5787139   0.62305848  0.63545502  0.67331071  0.61115777
  0.74854193  0.56836022  0.78595346  0.62098848  0.63459907  0.8202189
  0.79230218  0.60074826  0.50155342  0.73577477  0.70257953  0.68166794
  0.6636407   0.44410981  0.54974625  0.57562188  0.59093375  0.58543506
  0.66386805  0.6612752   0.61828378  0.78216895  0.71679293  0.72219985
  0.58029252  0.83674336  0.66128606  0.50675907  0.70909116  0.6975331
  0.69146618  0.75743606  0.6013666   0.77701676  0.6265411   0.68727338
  0.77228063  0.60255049  0.42818714  0.52341076  0.66883513  0.49898023
  0.55327365  0.49435803  0.6057068   0.68010968  0.77800791  0.65418036
  0.69723127  0.8887319   0.52061989  0.61490928  0.63024914  0.64238486
  0.66116097  0.55118095  0.80346301  0.49154814]

     OK~就是一堆输入的线性组合加上一个非线性的函数,某软面试官居然特么跟我说神经元里没有非线性函数,真是各位选好公司很重要!那么一个神经元的输出只能是一个值,但是可以输出到多个不同的神经元。也就是说,神经元的输出可以有多条线,但是每条线输出的值是一样的!

这样我们就得到了一些三维的点。

     经过了多层隐层以后便得到了输出层,这个输出层输出的不是上图中那个图,而就是简简单单的一个值。这个值如果大于0就是蓝色,小于0就是橘黄色,所以根据不同的输入值就将两种颜色的点点分离开来!真神奇。

构造模型 随后我们用 TensorFlow 来根据这些数据拟合一个平面,拟合的过程实际上就是寻找 (x, y) 和 z 的关系,即变量 x_data 和变量 y_data 的关系,而它们之间的关系刚才我们用了线性变换表示出来了,即 z = w * (x, y) + b,所以拟合的过程实际上就是找 w 和 b 的过程,所以这里我们就首先像设变量一样来设两个变量 w 和 b,代码如下:

(二)前向传播算法

x = tf.placeholder(tf.float32, [2, 100])
y_label = tf.placeholder(tf.float32, [100])
b = tf.Variable(tf.zeros([1]))
w = tf.Variable(tf.random_uniform([2], -1.0, 1.0))
y = tf.matmul(tf.reshape(w, [1, 2]), x) + b

     看完这部分我也是服了,这也叫算法呀---所谓前向传播,就是输入通过权重和神经元的函数后,计算得出结果的这一个过程。如下图所示:

在创建模型的时候,我们首先可以将现有的变量来表示出来,用 placeholder() 方法声明即可,一会我们在运行的时候传递给它真实的数据就好,第一个参数是数据类型,第二个参数是形状,因为 x_data 是 2×100 的矩阵,所以这里形状定义为 [2, 100],而 y_data 是长度为 100 的向量,所以这里形状定义为 [100],当然此处使用元组定义也可以,不过要写成 (100, )。

澳门新濠3559 3

随后我们用 Variable 初始化了 TensorFlow 中的变量,b 初始化为一个常量,w 是一个随机初始化的 1×2 的向量,范围在 -1 和 1 之间,然后 y 再用 w、x、b 表示出来,其中 matmul() 方法就是 TensorFlow 中提供的矩阵乘法,类似 Numpy 的 dot() 方法。不过不同的是 matmul() 不支持向量和矩阵相乘,即不能 BroadCast,所以在这里做乘法前需要先调用 reshape() 一下转成 1×2 的标准矩阵,最后将结果表示为 y。

     而由于在TensorFlow中矩阵的乘法是非常容易实现的,所以前向传播的过程常表示为矩阵乘法。这里主要是矩阵之间的乘法,行向量乘以列,然后再相加的这个过程。

这样我们就构造出来了一个线性模型。

澳门新濠3559 4

这里的 y 是我们模型中输出的值,而真实的数据却是我们输入的 y_data,即 y_label。

(三)神经网络参数与TensorFlow变量

损失函数 要拟合这个平面的话,我们需要减小 y_label 和 y 的差距就好了,这个差距越小越好。

     在TensorFlow中,tf.Variable的作用就是保存和更新神经网络的参数。    

所以接下来我们可以定义一个损失函数,来代表模型实际输出值和真实值之间的差距,我们的目的就是来减小这个损失,代码实现如下:

weight = tf.Variable(tf.random_normal([2,3],stddev=2))

loss = tf.reduce_mean(tf.square(y - y_label))

     上面一行代码就是参数初始化的过程,初始化一个2*3的参数矩阵,均值为0,标准差为2.当然,此外还有很多初始化变量的方法。    

这里调用了 square() 方法,传入 y_label 和 y 的差来求得平方和,然后使用 reduce_mean() 方法得到这个值的平均值,这就是现在模型的损失值,我们的目的就是减小这个损失值,所以接下来我们使用梯度下降的方法来减小这个损失值即可,定义如下代码:

澳门新濠3559 5

optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)

OK,接下来我们看一下如何用代码实现前向传播算法:

这里定义了 GradientDescentOptimizer 优化,即使用梯度下降的方法来减小这个损失值,我们训练模型就是来模拟这个过程。

import tensorflowas tf

运行模型 最后我们将模型运行起来即可,运行时必须声明一个 Session 对象,然后初始化所有的变量,然后执行一步步的训练即可,实现如下:

w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for step in range(201):
        sess.run(train, feed_dict={x: x_data, y: y_data})
        if step % 10 == 0:
            print(step, sess.run(w), sess.run(b))

w2 = tf.Variable(tf.random_normal([3,1],stddev=1,seed=2))

这里定义了 200 次循环,每一次循环都会执行一次梯度下降优化,每次循环都调用一次 run() 方法,传入的变量就是刚才定义个 train 对象,feed_dict 就把 placeholder 类型的变量赋值即可。随着训练的进行,损失会越来越小,w 和 b 也会被慢慢调整为拟合的值。

x = tf.constant([[0.7,0.9]])

澳门新濠3559,在这里每 10 次 循环我们都打印输出一下拟合的 w 和 b 的值,结果如下:

a = tf.matmul(x,w1)

0 [ 0.31494665  0.33602586] [ 0.84270978]
10 [ 0.19601417  0.17301694] [ 0.47917289]
20 [ 0.23550016  0.18053198] [ 0.44838765]
30 [ 0.26029009  0.18700737] [ 0.43032286]
40 [ 0.27547371  0.19152154] [ 0.41897511]
50 [ 0.28481475  0.19454622] [ 0.41185945]
60 [ 0.29058149  0.19652548] [ 0.40740564]
70 [ 0.2941508   0.19780098] [ 0.40462157]
80 [ 0.29636407  0.1986146 ] [ 0.40288284]
90 [ 0.29773837  0.19913   ] [ 0.40179768]
100 [ 0.29859257  0.19945487] [ 0.40112072]
110 [ 0.29912385  0.199659  ] [ 0.40069857]
120 [ 0.29945445  0.19978693] [ 0.40043539]
130 [ 0.29966027  0.19986697] [ 0.40027133]
140 [ 0.29978839  0.19991697] [ 0.40016907]
150 [ 0.29986817  0.19994824] [ 0.40010536]
160 [ 0.29991791  0.1999677 ] [ 0.40006563]
170 [ 0.29994887  0.19997987] [ 0.40004089]
180 [ 0.29996812  0.19998746] [ 0.40002549]
190 [ 0.29998016  0.19999218] [ 0.40001586]
200 [ 0.29998764  0.19999513] [ 0.40000987]

y = tf.matmul(a,w2)

可以看到,随着训练的进行,w 和 b 也慢慢接近真实的值,拟合越来越精确,接近正确的值。

sess = tf.Session()

 

init_op = tf.global_variables_initializer()

sess.run(init_op)

print(sess.run(y))

sess.close()

要写一段tf代码,我认为就是需要写出每个神经元和每条边。首先定义变量(Variable),也就是边(权重)。然后定义每次层的神经元,第一层为输入神经元,所以定义为常量输入,第二层和第三层分别进行了矩阵的乘法,也就是简单的线性组合。以上便定义好了张量,和计算图,然后我们定义会话,首先需要初始化所有的张量,而后如下这两句便完成了所有张量的初始化

init_op = tf.global_variables_initializer()

sess.run(init_op)

最后打印了y,然后关闭会话!

(四)训练网络模型

那么,在一个神经网络里我们有大量的输入(比如训练集),那么如果我们用之前定义constant的方式,那么需要定义大量的计算节点,这样是不可取的。那么tensor里定义了 一个placeholder,他作为一个计算节点,可以源源不断的帮我们传入输入值。

import tensorflowas tf

w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))

w2 = tf.Variable(tf.random_normal([3,1],stddev=1,seed=2))

#x = tf.constant([[0.7,0.9]])

x = tf.placeholder(tf.float32,shape=(3,2),name="input")

a = tf.matmul(x,w1)

y = tf.matmul(a,w2)

sess = tf.Session()

init_op = tf.global_variables_initializer()

sess.run(init_op)

print(sess.run(y,feed_dict={x:[[0.7,0.9],[0.1,0.4],[0.5,0.8]]}))

sess.close()

上图中我们定义了placeholder,然后再run里的feed_dict中输入我们的x。

那么接下来就是反向传播的调参过程。

 反向传播的整体思路是这样的:我们根据设置的参数得到的输出结果与真实结果的差,我们称之为损失函数(代表的就是我们的输出与真实的差距),反向传播的过程就是想办法使损失函数降低到一个最小值。

Loss = (w1*x1 + w2*x2 + b) - y 括号里的当然不只是线性的组合,还有各种非线性的组合。x1,x2等是我们的输入,y是标签的值,所以这些都是常数,所以Loss函数就是关于各种w和b的多元函数。

OK,那么现在这个调参的过程变成了一个多元函数的求最小值的问题。那么为了让这个损失函数变小的最快,这里使用了“梯度下降法”(又称最速下降法)。 我们知道多元函数关于在任何方向上都有变化,那么这个就叫做方向导数。然而这个函数的值变化最快的方向,就叫做梯度!!!!!(这个稍微有些难理解)那么这个梯度的求解方法就是各个方向的偏导数乘当前方向的单位向量再相加。

澳门新濠3559 6

所以就可以把所有的参数都从他们的偏导数方向上减少:

澳门新濠3559 7

其中n就是他们的学习率。而求偏导的过程就使用了链式规则:

澳门新濠3559 8

当然,这个过程在tf中不需要这么复杂,只需要使用封装好的代码就可以。具体的代码明天上。

编辑:编程 本文来源:代表三维点的 (x,根据输入的值得到一个输出

关键词: