机器学习是时下非常流行的话题,而Tensorflow是机器学习中最有名的工具包。TensorflowSharp是Tensorflow的C#语言表述。本文会对TensorflowSharp的使用进行一个简单的介绍。
本文会先介绍Tensorflow的一些基本概念,然后实现一些基本操作例如数字相加等运算。然后,实现求两个点(x1,y1)和(x2,y2)的距离。最后,通过这些前置基础和一些C#代码,实现使用KNN方法识别MNIST手写数字集合(前半部分)。阅读本文绝对不需要任何机器学习基础,因为我现在也才刚刚入门,行文不准确之处难免,敬请见谅。
本文的后半部分还在整理之中。
1. 什么是机器学习
用最最简单的话来说,机器学习就是不断改进一个模型的过程,使之可以更好的描述一组数据的内在规律。假设,我们拿到若干人的年龄(a1,a2,a3…)和他们的工资(b1,b2,b3…),此时,我们就可以将这些点画在一个二维直角坐标系中,包括(a1,b1),(a2,b2)等等。这些就称为输入或训练数据。
我们可以用数学的最小二乘法拟合一条直线,这样就可以得到最好的可以描述这些数据的规律y=ax+b了。当然,因为我们有很多个点,所以它们可能不在一条直线上,因此任何的直线都不会过它们所有的点,即一定会有误差。
但对于电脑来说,它可以使用一种截然不同的方式来得到y=ax+b中a,b的值。首先,它从一个随便指定的a和b出发(例如a=100,b=1),然后它算出y=100(a1)+1的值和b1的区别,y=100(a2)+1和b2的区别,等等。它发现误差非常大,此时,它就会调整a和b的值(通过某种算法),使得下一次的误差会变小。如果下次的误差反而变得更大了,那就说明,要么是初始值a,b给的不好,要么是y=ax+b可能不是一个好的模型,可能一个二次方程y=a^2+bx+c更好,等等。
经过N轮调整(这称为模型的训练),误差的总和可能已经到了一个稳定的,较小的值。误差小时,a和b的调整相对当然也会较小。此时的a和b就会十分接近我们使用最小二乘法做出来的值,这时,就可以认为模型训练完成了。
当然,这只是机器学习最简单的一个例子,使用的模型也只是线性的直线方程。如果使用更加复杂的模型,机器学习可以做出十分强大的事情。
2. 环境初始化
我使用VS2017创建一个新的控制台应用,然后,使用下面的命令安装TensorflowSharp:
nuget install TensorFlowSharp
TensorflowSharp的源码地址:https://github.com/migueldeicaza/TensorFlowSharp
如果在运行时发现问题“找不到libtensorflow.dll”,则需要访问
http://ci.tensorflow.org/view/Nightly/job/nightly-libtensorflow-windows/lastSuccessfulBuild/artifact/lib_package/libtensorflow-cpu-windows-x86_64.zip
下载这个压缩包。然后,在下载的压缩包中的\lib中找到tensorflow.dll,将它改名为libtensorflow.dll,并在你的工程中引用它。
这样一来,环境初始化就完成了。
3. TensorflowSharp中的概念
TensorflowSharp / Tensorflow中最重要的几个概念:
图(Graph):它包含了一个计算任务中的所有变量和计算方式。可以将它和C#中的表达式树进行类比。例如,一个1+2可以被看作为两个常量表达式,以一个二元运算表达式连接起来。在Tensorflow的世界中,则可以看成是两个tensor和一个op(operation的缩写,即操作)。简单来说,做一个机器学习的任务就是计算一张图。
在计算图之前,当然要把图建立好。例如,计算(1+2)*3再开根号,是一个包括了3个tensor和3个Op的图。
不过,Tensorflow的图和常规的表达式还有所不同,Tensorflow中的节点变量是可以被递归的更新的。我们所说的“训练”,也就是不停的计算一个图,