人工智能之旅IIs-拟合与优化-真枪实弹

人工智能之旅IIs-拟合与优化-真枪实弹

在这一讲中,王校长将会手把手地教大家使用Python编写线性的拟合程序。不了解Python语言的童鞋可以通过官方所给的文档 [1],学习一下基本语法。这一讲王校长将会带大家学习两个用来做机器学习的Python库,分别是Scikit-Learn [2]和TensorFlow [3]。教程中完整的代码都放在了王校长的GitHub目录:https://github.com/physicso/AICourse

这里特别强调,大家要使用Python 2.x版本,不是因为王校长2,是因为Python 3.x不好用,很多语法与2.x也不兼容!

使用Scikit-Learn写拟合的程序非常简单,几行代码就可以搞定。我们使用一个小栗子为大家进行一下示范。

在这个栗子中,我们将根据五道口附近已有的学区房价格(实际的售价可能比我们例子中给出的还要高 ~!~),来拟合出一个房屋大小与售价之间的关系曲线,进而预测一个更大房子的可能售价。我们手中的数据是介个样子的:

房屋尺寸(平方米)售价(万元)
30320
40360
60400
80455
100490
120546
140580

接下来咱们上点代码,首先引入两个函数,分别用来作图和做拟合:

import matplotlib.pyplot as plt

from sklearn.linear_model import LinearRegression

然后定义一个生成图像句柄(大家可以把“句柄”理解为一个空白的画布)的函数:

def runplt():

plt.figure()

plt.title(u'Apartment Price Curve')

plt.xlabel(u'Size')

plt.ylabel(u'Price')

plt.axis([0, 150, 0, 600])

plt.grid(True)

return plt

接下来我们就可以把数据画出来啦:

plt = runplt()

X = [[30],[40],[60],[80],[100],[120],[140]]

y = [[220],[260],[300],[355],[390],[446],[480]]

plt.plot(X, y, 'k.')

plt.show()

这段代码的运行结果是一个散点图:

从图中可以看到,房屋尺寸和售价近似呈现一个线性的关系,下面我们就把这条线找出来:

model = LinearRegression()

model.fit(X, y)

那么现在model里面存放的,就是Scikit-Learn为我们拟合出的线性模型。我们使用这个模型来预测一下,如果土豪想买一个160平方米的房子,大概会花多少钱:

print 'The Price of Size 160m^2 Apartment: %.2fW' % model.predict([[160]])[0]

结果是:

The Price of Size 160m^2 Apartment: 633.52W

好贵~

我们画出这条线:

y_pred = model.predict(X)

plt.plot(X, y, 'k.')

plt.plot(X, y_pred, 'g-')

plt.show()

这个栗子就此熟了!

接下来我们介绍点高深的东东,这个神秘的主角叫TF,当然它不是TF Boys,因为TF Boys不是东东……它是TensorFlow。TF最近火爆了各个领域,大家肯定也在新闻中听到过它的飒爽英姿。今天,王校长将教给你如何驯服这个装*神器。

王校长就不跟大家介绍如何安装TF啦,大家可以查看TF的官方文档,不过要注意的是,要运行TF,必须是在Mac或者Linux环境下。大批使用Windows的可怜孩子可以用虚拟机来玩它。与Scikit-Learn不同的是,TF能够充分利用机器中的CPU和GPU进行运算,并且支持集群化计算。所以如果大家只是建立一些简单的模型,Scikit-Learn就已经足够。如果数据量足够大,建议大家还是采用TF。需要补充的是,使用TF还可以进行任意形式函数的拟合 :)

由于Scikit-Learn把内部的所有事情都帮我们做好了,虽然看着灰常Easy,但是我们并不能领悟到这个过程的细节。因此,在下面的TF代码中,我们将会完整地实现拟合和优化的细节。Ready? Let's Go!

既然称为Flow,那么我们就要把要做的事情写成一个图的形式,比如:

我们的线性模型输入是一个向量X,经过模型计算,输出是一个标量y_pred,通过与真实的值y_real比较,我们可以得到成本函数,通过成本函数,可以对线性模型进行优化。

首先,我们需要引入一些必须的库,包括TF和numpy。为啥需要numpy呢?是因为numpy可以大大加速矩阵的处理过程,因此TF的输入均为numpy的array。

import tensorflow as tf

import numpy

随后我们可以定义模型的参数,包括输入X、输出y、权重W,以及偏移b。

X = tf.placeholder("float")

y = tf.placeholder("float")

W = tf.Variable(numpy.random.randn(), name="weight")

b = tf.Variable(numpy.random.randn(), name="bias")

那么我们的预测值就是:

y_pred = tf.add(tf.mul(X, W), b)

可以看到,这里我们使用了线性的模型。通过修改这段代码,我们可以方便地使用任意的拟合函数,包括各种非线性的拟合。

成本函数为:

cost = tf.reduce_sum(tf.pow(y_pred- y,2))/(2 * n_samples)

其中n_samples是我们的样本数目。我们使用梯度下降的方法来对模型进行优化:

learning_rate = 0.01

optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

第二讲中所提到的各种优化方法,TF都为大家提供了,只需要修改GradientDescentOptimizer便可以使用。这里的学习速率我们定义成了0.01,优化的目标是最小化成本函数。

程序进行到这里时,只是建立了这么一张图,并没有做实质性的变量初始化。给定我们的训练数据:

train_X = numpy.asarray([30.0, 40.0, 60.0, 80.0, 100.0, 120.0, 140.0])

train_Y = numpy.asarray([320.0, 360.0, 400.0, 455.0, 490.0, 546.0, 580])

需要注意的是,输入的数据类型一定与图中给出placeholder的数据类型一致。下面这个命令告诉TF,一切就绪,干!

training_epochs = 1000

display_step = 50

with tf.Session() as sess:

sess.run(tf..initialize_all_variables())

for epoch in range(training_epochs):

for (x_train, y_train) in zip(train_X, train_Y):

sess.run(optimizer, feed_dict={X: x_train, y: y_train})

if epoch % display_step ==0:

print "Epoch:" + '%04d'% (epoch+1) + "cost=" + "{:.9f}".format(sess.run(cost, feed_dict={X: train_X, y: train_Y})) +"W=" + sess.run(W),"b=", sess.run(b)

print "Optimization Finished!"

training_cost = sess.run(cost, feed_dict={X: train_X, y: train_Y})

print "Training cost = " + training_cost + "W = " + sess.run(W) + "b=" + sess.run(b) + '\n'

这里我想跟大家复习一下上一节中的内容,即每一轮迭代应该使用多少样本对模型进行优化。

人工智能之旅IIs-拟合与优化-真枪实弹

容易看到,上面的代码中使用的是Full-Batch方法,因此一次的Iteration就是一个Epoch。程序中,我们定义了最大的Iteration次数为1000,也就是过1000遍全量的数据,每50次输出一次中间结果。程序的最后,输出一次成本函数的值和最后得到的模型参数。

熟悉第一讲的童鞋肯定会说,王校长,你忽略了一个重要的步骤!对,这个程序中,我们没有把训练数据分成三个集合:训练集、验证集、测试集,这是因为我们的数据实在是太少了。聪明的各位应该知道如何修改上面的代码把这个环节加进去吧!

[1] https://docs.python.org/2/tutorial/index.html

[2] http://scikit-learn.org/

[3] https://www.tensorflow.org/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值