TensorFlow101

即使你从来没有接触过TensorFlow,只要你写过哪怕几行的代码, 在阅读本文的10分钟之内,你也会弄明白TensorFlow 的基本语法是什么。

/pic/1_UCXfoUpB4zLPzkQU964qZJBx0MvC1Q.png

我们看上面的5行代码,和下面的图是对应的,我们可以把图中的每一个节点称作为tensor,而这些节点按照顺序连接起来,就是flow,这也是TensorFlow

名字的由来。那么问题是,上面的每一行代码左边对应的图中的那个节点,而右边的函数对应的哪一些线条了?

/pic/2_toiagR82tDSy18QKTArOicjO839GYg.png

有没有其他的方式来表示相同的运算了?答案是上图。从这里我们可以看出,Tensor 可以是一维,二维,多维的,也可以有不同的数据类型 整数(int),或者浮点数(float)。

/pic/3_RnJdlQPGibaPIt069iaYTrrMMPZTjA.png

构建好了图,tensorflow需要开启一个session来执行图上的运算。

/pic/4_lsJH30tpw0Zwax5ibnfws1mfgqfiaQ.png

下面我们根据一个例子来讲讲tensorflow的基本工作流。这里的问题是针对一组二维平面上的点,找出一个线性方程,来使这个方程能够最好的描述这些数据的趋势。

/pic/5_wjp3LeoyElr1ETvDyd97Ua3eiavtRA.png

首先是定义我们要学习的参数

W = tf.Variable(tf.zeros([2, 1]), name=“weights”)

b = tf.Variable(0., name=“bias”)

接下来告诉系统我们怎样计算从输入计算输出,即infernce 函数,由于我们是线性模型,那么我们的输入是x(输入),函数的输出值就是我们要拟合的变量

def inference(X):

return tf.matmul(X, W) + b

之后我们要定义怎么计算模型的误差,我们将每一个点预测出的值和真实值的欧式距离求平均值,这样一串复杂的运算,我们可以使用suqared_difference这一个函数来说明白,是不是很方便。

def loss(X, Y):

Y_predicted = inference(X)

return tf.reduce_sum(tf.squared_difference(Y, Y_predicted))

之后我们要定义tensorflow怎样去优化weight 和bias, 学习的步子不应该太大,优化参数的方法当然是经典的梯度下降。

def train(total_loss):

learning_rate = 0.0000001

return tf.train.GradientDescentOptimizer(learning_rate).minimize(total_loss)

最后我们可以去看看程序的效果

def evaluate(sess, X, Y):

print sess.run(inference([[80., 25.]])) # ~ 303

print sess.run(inference([[65., 25.]])) # ~ 256

好,下面是问题时间,这里的场景是预测年龄与体重和血糖的关系,有两个输入量,即年龄和体重,如果我们多了个输入变量,即BMI和性别,我们应该在那些地方修改我们的代码?

另一个问题是,我们上面比较模型预测值和真实值时用的是欧式距离,如果讲其换成是曼哈顿距离(具体公式搜索即可知道),我们应该在代码的那个部分中进行那些改变?

一个更难的问题是假设输入变量还是两个,即年龄和体重,但我们假设自己的模型不是线性的,而是包含平方项的非线性模型,即我们有两组 weight需要去学习,我们应该怎样去调整自己的代码?

下面我们给出用来训练的数据

def inputs():

weight_age = [[84, 46], [73, 20], [65, 52], [70, 30], [76, 57], [69, 25], [63, 28], [72, 36], [79, 57], [75, 44], [27, 24], [89, 31], [65, 52], [57, 23], [59, 60], [69, 48], [60, 34], [79, 51], [75, 50], [82, 34], [59, 46], [67, 23], [85, 37], [55, 40], [63, 30]]

blood_fat_content = [354, 190, 405, 263, 451, 302, 288, 385, 402, 365, 209, 290, 346, 254, 395, 434, 220, 374, 308, 220, 311, 181, 274, 303, 244]

return tf.to_float(weight_age), tf.to_float(blood_fat_content)

然后怎么讲程序串起来了,首先是将所有的变量初始化

tf.initialize_all_variables().run()

之后是定义该怎么去判断模型预测的差距

X, Y = inputs()

total_loss = loss(X, Y)

train_op = train(total_loss)

下面就是实际的模型训练了,我们将模型训练的过程分成一千步,每一步都站在之前的基础上,为了看到模型学习的进展,我们每10步打印一下当前模型预测的误差:

actual training loop

training_steps = 1000

for step in range(training_steps):

sess.run([train_op])

for debugging and learning purposes, see how the loss gets decremented thru training steps

if step % 10 == 0:

print “loss: “, sess.run([total_loss])

evaluate(sess, X, Y)

好了,装好了tensorflow的小伙伴可以试着让上面的代码跑起来了。这个代码主要是为了介绍tensorflow的基本工作流。基于这个代码,我们还有很多可以去做的,比如你可以试着做做下面的尝试:

假设我们想要回归的函数是 y =7x+3,我们先生成一组用于学习和一组用于验证的数据 ,两组数据各100个,按照y=7x+3+(一个平均为0的正态分布随机数)来生成,在生成了100个这样的随机数对之后,我们从训练数据中随机选择10,20,30…100 个数来作为训练集,看看不同情况下模型学习的效果(误差)分别是多少? 是否随着可用的数据量的增加而模型有了更好的效果?

在生成上述的随机数对时,我们使用的随机项方差没有规定,改变方差项的大小,记录在相同训练数据量时,方差(观测误差)对模型准确度的影响。

欢迎关注巡洋舰的深度学习实战课程, 手把手带你进行深度学习实战, 课程涵盖机器学习,深度学习, 深度视觉, 深度自然语言处理, 以及极具特色的深度强化学习,看你能不能学完在你的领域跨学科的应用深度学习惊艳你的小伙伴,成为身边人眼中的大牛, 感兴趣的小伙伴可以点击阅读原文。

阅读原文