循环神经网络 RNN (Recurrent Neural Network)

mikel阅读(1327)

循环神经网络 RNN (Recurrent Neural Network) 作者: Morvan 编辑: Morvan 学习资料: Tensorflow RNN 例子1 Tensorflow RNN 例子2 Tensorflow RNN 例子3 Keras 快速搭建 RNN 1 Keras 快速搭建 RNN 2 RNN 作曲 链接 今天我们会来聊聊在语言分析, 序列化数据中穿梭自如的循环神经网络 RNN. RNN 是用来干什么的 ? 它和普通的神经网络有什么不同 ? 我会将会一一探讨. 注: 本文不会涉及数学推导. 大家可以在很多其他地方找到优秀的数学推导文章. RNN 的用途 现在请你看着这个名字. 不出意外, 你应该可以脱口而出. 因为你很可能就用了他们家的一款产品 . 那么现在, 请抛开这个产品, 只想着斯蒂芬乔布斯这个名字 , 请你再把他逆序念出来. 斯布乔(*#&, 有点难吧. 这就说明, 对于预测, 顺序排列是多么重要. 我们可以预测下一个

来源: 莫烦 Python

循环神经网络 RNN (Recurrent Neural Network)

作者: Morvan    编辑: Morvan

今天我们会来聊聊在语言分析, 序列化数据中穿梭自如的循环神经网络 RNN. RNN 是用来干什么的 ? 它和普通的神经网络有什么不同 ? 我会将会一一探讨.

注: 本文不会涉及数学推导. 大家可以在很多其他地方找到优秀的数学推导文章.

RNN 的用途

现在请你看着这个名字. 不出意外, 你应该可以脱口而出. 因为你很可能就用了他们家的一款产品 . 那么现在, 请抛开这个产品, 只想着斯蒂芬乔布斯这个名字 , 请你再把他逆序念出来. 斯布乔(*#&, 有点难吧. 这就说明, 对于预测, 顺序排列是多么重要. 我们可以预测下一个按照一定顺序排列的字, 但是打乱顺序, 我们就没办法分析自己到底在说什么了.

序列数据

我们想象现在有一组序列数据 data 0,1,2,3. 在当预测 result0 的时候,我们基于的是 data0, 同样在预测其他数据的时候, 我们也都只单单基于单个的数据. 每次使用的神经网络都是同一个 NN. 不过这些数据是有关联 顺序的 , 就像在厨房做菜, 酱料 A要比酱料 B 早放, 不然就串味了. 所以普通的神经网络结构并不能让 NN 了解这些数据之间的关联.

处理序列数据的神经网络

那我们如何让数据间的关联也被 NN 加以分析呢? 想想我们人类是怎么分析各种事物的关联吧, 最基本的方式,就是记住之前发生的事情. 那我们让神经网络也具备这种记住之前发生的事的能力. 再分析 Data0 的时候, 我们把分析结果存入记忆. 然后当分析 data1的时候, NN会产生新的记忆, 但是新记忆和老记忆是没有联系的. 我们就简单的把老记忆调用过来, 一起分析. 如果继续分析更多的有序数据 , RNN就会把之前的记忆都累积起来, 一起分析.

我们再重复一遍刚才的流程, 不过这次是以加入一些数学方面的东西. 每次 RNN 运算完之后都会产生一个对于当前状态的描述 , state. 我们用简写 S( t) 代替, 然后这个 RNN开始分析 x(t+1) , 他会根据 x(t+1)产生s(t+1), 不过此时 y(t+1) 是由 s(t) 和 s(t+1) 共同创造的. 所以我们通常看到的 RNN 也可以表达成这种样子.

RNN 的运用

RNN 的形式不单单这有这样一种, 他的结构形式很自由. 如果用于分类问题, 比如说一个人说了一句话, 这句话带的感情色彩是积极的还是消极的. 那我们就可以用只有最后一个时间点输出判断结果的RNN.

又或者这是图片描述 RNN, 我们只需要一个 X 来代替输入的图片, 然后生成对图片描述的一段话.

或者是语言翻译的 RNN, 给出一段英文, 然后再翻译成中文.

有了这些不同形式的 RNN, RNN 就变得强大了. 有很多有趣的 RNN 应用. 比如之前提到的, 让 RNN 描述照片. 让 RNN 写学术论文, 让 RNN 写程序脚本, 让 RNN 作曲. 我们一般人甚至都不能分辨这到底是不是机器写出来的.

如果你觉得这篇文章或视频对你的学习很有帮助, 请你也分享它, 让它能再次帮助到更多的需要学习的人.

莫烦没有正式的经济来源, 如果你也想支持 莫烦Python 并看到更好的教学内容, 请拉倒屏幕最下方, 赞助他一点点, 作为鼓励他继续开源的动力.

卷积神经网络 CNN (Convolutional Neural Network)

mikel阅读(1207)

Morvan’s Python tutorials

来源: 莫烦 Python

卷积神经网络 CNN (Convolutional Neural Network)

作者: Morvan    编辑: Morvan

卷积神经网络是近些年逐步兴起的一种人工神经网络结构, 因为利用卷积神经网络在图像和语音识别方面能够给出更优预测结果, 这一种技术也被广泛的传播可应用. 卷积神经网络最常被应用的方面是计算机的图像识别, 不过因为不断地创新, 它也被应用在视频分析, 自然语言处理, 药物发现, 等等. 近期最火的 Alpha Go, 让计算机看懂围棋, 同样也是有运用到这门技术.

卷积 和 神经网络

我们来具体说说卷积神经网络是如何运作的吧, 举一个识别图片的例子, 我们知道神经网络是由一连串的神经层组成,每一层神经层里面有存在有很多的神经元. 这些神经元就是神经网络识别事物的关键. 每一种神经网络都会有输入输出值, 当输入值是图片的时候, 实际上输入神经网络的并不是那些色彩缤纷的图案,而是一堆堆的数字. 就比如说这个. 当神经网络需要处理这么多输入信息的时候, 也就是卷积神经网络就可以发挥它的优势的时候了. 那什么是卷积神经网络呢?

我们先把卷积神经网络这个词拆开来看. “卷积” 和 “神经网络”. 卷积也就是说神经网络不再是对每个像素的输入信息做处理了,而是图片上每一小块像素区域进行处理, 这种做法加强了图片信息的连续性. 使得神经网络能看到图形, 而非一个点. 这种做法同时也加深了神经网络对图片的理解. 具体来说, 卷积神经网络有一个批量过滤器, 持续不断的在图片上滚动收集图片里的信息,每一次收集的时候都只是收集一小块像素区域, 然后把收集来的信息进行整理, 这时候整理出来的信息有了一些实际上的呈现, 比如这时的神经网络能看到一些边缘的图片信息, 然后在以同样的步骤, 用类似的批量过滤器扫过产生的这些边缘信息, 神经网络从这些边缘信息里面总结出更高层的信息结构,比如说总结的边缘能够画出眼睛,鼻子等等. 再经过一次过滤, 脸部的信息也从这些眼睛鼻子的信息中被总结出来. 最后我们再把这些信息套入几层普通的全连接神经层进行分类, 这样就能得到输入的图片能被分为哪一类的结果了.

我们截取一段 google 介绍卷积神经网络的视频, 具体说说图片是如何被卷积的. 下面是一张猫的图片, 图片有长, 宽, 高 三个参数. 对! 图片是有高度的! 这里的高指的是计算机用于产生颜色使用的信息. 如果是黑白照片的话, 高的单位就只有1, 如果是彩色照片, 就可能有红绿蓝三种颜色的信息, 这时的高度为3. 我们以彩色照片为例子. 过滤器就是影像中不断移动的东西, 他不断在图片收集小批小批的像素块, 收集完所有信息后, 输出的值, 我们可以理解成是一个高度更高,长和宽更小的”图片”. 这个图片里就能包含一些边缘信息. 然后以同样的步骤再进行多次卷积, 将图片的长宽再压缩, 高度再增加, 就有了对输入图片更深的理解. 将压缩,增高的信息嵌套在普通的分类神经层上,我们就能对这种图片进行分类了.

池化(pooling)

研究发现, 在每一次卷积的时候, 神经层可能会无意地丢失一些信息. 这时, 池化 (pooling) 就可以很好地解决这一问题. 也就是说在卷集的时候, 我们不压缩长宽, 尽量地保留更多信息, 压缩的工作就交给池化了,这样的一项附加工作能够很有效的提高准确性. 有了这些技术,我们就可以搭建一个属于我们自己的卷积神经网络啦.

流行的 CNN 结构

比较流行的一种搭建结构是这样, 从下到上的顺序, 首先是输入的图片(image), 经过一层卷积层 (convolution), 然后在用池化(pooling)方式处理卷积的信息, 这里使用的是 max pooling 的方式. 然后在经过一次同样的处理, 把得到的第二次处理的信息传入两层全连接的神经层 (fully connected),这也是一般的两层神经网络层,最后在接上一个分类器(classifier)进行分类预测. 这仅仅是对卷积神经网络在图片处理上一次简单的介绍. 如果你想知道使用 python 搭建这样的卷积神经网络, 我会把教程的链接附在我的视频描述当中, 也欢迎订阅我的频道, 获得更多关于机器学习的知识~

如果你觉得这篇文章或视频对你的学习很有帮助, 请你也分享它, 让它能再次帮助到更多的需要学习的人.

莫烦没有正式的经济来源, 如果你也想支持 莫烦Python 并看到更好的教学内容, 请拉倒屏幕最下方, 赞助他一点点, 作为鼓励他继续开源的动力.

ARtoolkit学习一:Paddle交互代码理解和改写 - u011707827的专栏 - 博客频道 - CSDN.NET

mikel阅读(1414)

实习中项目要编写一个ARtoolkit实现交互的Demo给客户,在ARtoolkit中没有vuforia中集成的virtualbutton来直接实现,所以手动编写,查找ARtoolkit的原官方网站后,查到了一篇介绍交互的文章

来源: ARtoolkit学习一:Paddle交互代码理解和改写 – u011707827的专栏 – 博客频道 – CSDN.NET

实习中项目要编写一个ARtoolkit实现交互的Demo给客户,在ARtoolkit中没有vuforia中集成的virtualbutton来直接实现,所以手动编写,查找ARtoolkit的原官方网站后,查到了一篇介绍交互的文章

G. Gordan, M. Billinghurst, M. Bell, J. Woodfill, B. Kowalik, A. Erendi, J. Tilander. (2002)

The Use of Dense Stereo Range Data in Augmented Reality.
In Proceedings of the IEEE and ACM International Symposium on Mixed and Augmented Reality (ISMAR 2002) 30 Sept. – 1 Oct., 2002,

Darmstadt, Germany, IEEE Press, Los Alamitos, CA, pp. 14-23.

文章下载地址为:http://www.hitl.washington.edu/artoolkit/Papers/2002-ISMAR-DenseStereoData.pdf

具体可下载查看,其中交互的方法给出了两种,一种是基于paddle的,一种是基于freehand或pointer的。首先检测到交互实现的平面,跟基础的MarkerDetect一样,检测到Marker(标记物)来获得坐标系,在这里我们将这个平面叫做plane,并在这个plane上设置target的位置(实际就等于把一个button(按钮)位置定下来)。交互的工具paddle是另一个用一个Marker来表示,识别到这个Marker就找到了paddle,然后定位标记物的中心,并通过坐标转换投射到plane的坐标上,比较paddle的坐标和target的坐标,当距离非常近时,则触发交互的事件。

基于freehand或pointer的原理和前面的一样,只是检测pointer的方法改变了。由于手或者是笔这种物体不想Marker一样容易寻找,所以需要图像处理的内容,先将图像进行前景分割,然后找出手指或笔尖的位置,并通过坐标变换投射到plane上,后面的步骤后上述一样。单我对这个方法比较怀疑,因为每次都对整个帧图片进行分割等操作,开销一定不小。

文章读到这里后,去看ARtoolkit中有没有带这个接口,实际并没有写成接口,但是在ARToolKit-2.72.1版本中,examples中有paddleInteraction的一段样例代码,我上传到了这里,可以下载:http://download.csdn.NET/download/u011707827/9506183

在bin文件夹下,也有paddleInteractionTest.exe一段小程序,试着运行一下。这个程序中的定位plane的Marker是patterns中的pattMulti,打印出来后,将摄像头对准。屏幕显示出下图,可以看出根据Marker的位置定位出了plane平面。

然后做一个paddle,并检测出。

将这个paddle在平面上进行遮盖,触发了事件如下图,蓝色正方体变成了红色镂空正方体,不是很明显,但发生了改变。

可见这个代码的交互事件有点low,那就查看一下源码,并改写一下好了。开发环境VS2010+ARtoolkit2.72.1。代码中加载摄像机信息和一些基本变量设置不再赘述,一些用的到的会写出来。

直接看paddleInteraction.cpp中的主程序。

  1. int main(int argc, char **argv)
  2. {
  3.     //initialize applications
  4.     glutInit(&argc, argv); //glut初始化,不用管
  5.     init();<span style=“white-space:pre”>     </span>       //初始化
  6.     arVideoCapStart();
  7.     //start the main event loop
  8.     argMainLoop(NULL, keyEvent, mainLoop);//mainloop循环,是最重要的部分
  9.     return 0;
  10. }

从init()函数看起,打开定义。前面的一大坨都是初始化摄像机设置,直接用,也不用看,从paddle那行开始看。

  1. static void init(void)//初始化
  2. {
  3.     ARParam  wparam;
  4.     int i;
  5.     /* open the video path */
  6.     if (arVideoOpen(vconf) < 0) exit(0);
  7.     /* find the size of the window */
  8.     if (arVideoInqSize(&xsize, &ysize) < 0) exit(0);
  9.     printf(“Image size (x,y) = (%d,%d)\n”, xsize, ysize);
  10.     /* set the initial camera parameters */
  11.     if (arParamLoad(cparam_name, 1, &wparam) < 0) {
  12.         printf(“Camera parameter load error !!\n”);
  13.         exit(0);
  14.     }
  15.     arParamChangeSize(&wparam, xsize, ysize, &cparam);
  16.     arInitCparam(&cparam);
  17.     printf(“*** Camera Parameter ***\n”);
  18.     arParamDisp(&cparam);
  19.     /* load the paddle marker file */
  20.     //读取paddle的信息,并初始化paddle
  21.     if ((paddleInfo = paddleInit(paddle_name)) == NULL) {
  22.         printf(“paddleInit error!!\n”);
  23.         exit(0);
  24.     }
  25.     printf(“Loaded Paddle File\n”);
  26.     //读取MultiMarker的信息
  27.     if ((config = arMultiReadConfigFile(config_name)) == NULL) {
  28.         printf(“config data load error !!\n”);
  29.         exit(0);
  30.     }
  31.     printf(“Loaded Multi Marker File\n”);
  32.     /* initialize the targets */
  33.     //初始化target的位置
  34.     for (i = 0; i<TARGET_NUM; i++){
  35.         myTarget[i].pos[0] = 50.0*i;
  36.         myTarget[i].pos[1] = -50.0*i;
  37.         myTarget[i].pos[2] = 50.0*i;
  38.         myTarget[i].state = NOT_TOUCHED;
  39.     }

 

和加载marker信息一样,写了paddleInit()来读入,具体可以查看paddle.h和paddle.c中的代码,但实际上就是和普通marker的操作是一致的,而且我们重点是实现交互的时间,不是paddle检测本身,所以不做深究。config是个很重要的变量,查看定义 ARMultiMarkerInfoT  *config; 实际上config也是一种MarkerInfo的形式,其中最重要的成员是trans[3][4]这个数组,记录了从marker标定的plane坐标系到摄像头坐标系的转移矩阵,在后面会用到。

下面是一个循环体,发现是定义一个myTarget数组中的成员变量,myTarget是一个targetInfo数组。tragetInfo是一个struct体,代表了一个target的信息,target是我们交互中所定义的按键点,所以非常重要,查看targetInfo的定义部分。

  1. #define TOUCHED 1
  2. #define NOT_TOUCHED -1
  3. #define TARGET_NUM 5
  4. /* define a target struct for the objects that are to be touched */
  5. //定义出交互target信息
  6. typedef struct {
  7.     int id;                 //target的ID
  8.     int state;              //target的状态,TOUCHED或者UN_TOUCHED,TOUCHED时触发状态
  9.     float     pos[3];       //target的在plane坐标系中的三维信息
  10. } targetInfo;
  1. targetInfo myTarget[TARGET_NUM];  //定义一组target

所以init()中的循环部分定义myTarget的初始位置,注意,这个位置是基于Marker坐标系的,即plane平面而言。

所以init()函数中做了这些事:

初始化摄像机参数,载入paddle文件,载入multiMarker文件,定义了target在multiMarker坐标系的位置。

再看mainloop()函数。比较长,分段读。

  1. ARUint8         *dataPtr;       //每一帧的图像数据
  2.     ARMarkerInfo    *marker_info;  //marker的信息
  3.     int             marker_num;           //marker的数量
  4.     float curPaddlePos[3];              //paddle在plane坐标系中的三维坐标
  5.     int             i;
  6.     double          err;
  7.     /* 抓取一帧图像传入dataPtr中 */
  8.     if ((dataPtr = (ARUint8 *)arVideoGetImage()) == NULL) {
  9.         arUtilSleep(2);
  10.         return;
  11.     }
  12.     if (count == 0) arUtilTimerReset();
  13.     count++;
  14.     /* detect the markers in the video frame */
  15.     /* 检测图像中的Marker */
  16.     if (arDetectMarkerLite(dataPtr, thresh, &marker_info, &marker_num) < 0) {
  17.         cleanup();
  18.         exit(0);
  19.     }

curPaddlePos[3]是paddle的坐标,在后面要用到,其他的都是marker detect的功能,在最基础的simple程序中都有说明,不多说了。

下面一段程序跟显示有关,不需要理解。再往下看。是关于检测paddle和multiMarker分别得到paddle的转换矩阵以及multiMarker的转换矩阵。

  1. <span style=“white-space:pre”>    </span>for (i = 0; i < marker_num; i++) marker_flag[i] = 0;
  2.     /* 找到paddle坐标系和摄像机坐标系间转换矩阵 */
  3.     paddleGetTrans(paddleInfo, marker_info, marker_flag,
  4.         marker_num, &cparam);
  5.     /* draw the 3D models */
  6.     glClearDepth(1.0);
  7.     glClear(GL_DEPTH_BUFFER_BIT);
  8.     //如果检测到paddleInfo,绘制出paddle图形
  9.     if (paddleInfo->active){
  10.         draw_paddle(paddleInfo);//绘制函数
  11.     }
  12.     //有multimarker得到坐标系和转换矩阵
  13.     if ((err = arMultiGetTransMat(marker_info, marker_num, config)) < 0) {
  14.         argSwapBuffers();
  15.         return;
  16.     }

 

最后一部分。画出plane的平面,然后根据两个转换矩阵,换算出paddle在plane坐标系中的三维位置,然后通过checkCollision函数来检测是否Paddle的位置和target的位置有没碰撞,如果碰撞,则标记对应的myTarget的状态为TOUCHED,从而触发事件。这就是主程序代码的思路。

  1. <span style=“white-space:pre”>    </span>//绘制出plane平面
  2.     drawGroundGrid(config->trans, 20, 150.0f, 105.0f, 0.0f);
  3.     //检测出paddle在plane坐标系中的3D坐标
  4.     findPaddlePosition(curPaddlePos, paddleInfo->trans, config->trans);
  5.     //检测paddle和targets的位置有没有碰撞
  6.     for (i = 0; i<TARGET_NUM; i++){
  7.         myTarget[i].state = NOT_TOUCHED;
  8.         if (checkCollision(curPaddlePos, myTarget[i].pos, 20.0f))
  9.         {
  10.             myTarget[i].state = TOUCHED;
  11.             fprintf(stderr, “touched !!\n”);
  12.         }
  13.     }
  14.     /* draw the targets */
  15.     for (i = 0; i<TARGET_NUM; i++){
  16.         draw(myTarget[i], config->trans);
  17.     }
  18.     argSwapBuffers();

 

下篇将理解一些函数的代码,并改写它们实现另一些功能。

[转]如何用树莓派和TensorFlow来造一个能“看”东西的机器人

mikel阅读(2230)

编辑:Midkey        物体识别是现在机器学习领域的热点之一。相当长的…,本作文被阅读:100次。

来源: [转]如何用树莓派和TensorFlow来造一个能“看”东西的机器人

物体识别是现在机器学习领域的热点之一。相当长的时间里,计算机已经能相当可靠地识别人脸或者猫。但在更大的图片中去识别一个指定的物体还是人工智能领域的“圣杯”。人类的大脑能非常好地识别物体。我们可以毫无困难地把从物体上反射出来的具有不同频率的光子转化为关于我们周边世界的极度丰富的信息集。而机器学习还依然在为了完成这个简单的任务而奋斗。不过近几年,机器学习已经取得了相当不错的进步。

深度学习算法和一个超大的公共训练数据集(称为ImageNet)共同促成了物体识别领域的一系列令人映像深刻的进步。TensorFlow是一个广为人知的深度学习框架,它让在多种架构上实现深度学习算法变得很容易。TensorFlow善于利用GPU的运算能力,从而使得它非常适合运行深度学习的算法。

造我自己的机器人

我想造一个能自己识别物体的机器人。多年的开发程序和测试的经验已经把我塑造成了害怕和实际物体打交道。现实世界里,测试一个有缺陷的物理设备可能会把房子烧了,或是烧毁引擎,并让你等很多天才能拿到替换的零件。

图1 能识别物体的机器人的架构。

而新的第三代树莓派板是完成这个项目的最佳选择。在亚马孙上它仅售36美元,还带有无线功能、一个四核的CPU、1G的内存。加上一个报价6美元的迷你SD卡就可以载入一个基于DebianRaspberian操作系统。图1显示了所有这些部件是怎么组合在一起的。而图2则是这块板子的照片。

图2 运行在我车库里的树莓派板。

我很喜欢SainSmart制造的只用11美元的机器人底盘。这个底盘可以控制不同轮子采用不同的转速,运转的令人惊讶得好(见图3)。

图3 机器人底盘。

唯一让我在有更便宜的选择的时候还多花钱的东西就是这个Adafruit制造的电机扩展板(见图4)。这个直流电机的运行电压超过了树莓派板子可以提供的电压。所以单独的控制器就成为必须。而Adafruit电机扩展板极其方便好用。使用这个电机扩展板是会要做一点焊接,但这个设备是极度的容错。而且Adafruit还提供了一个很好的库和教程来让你通过i2C总线来控制电机。我一开始用的是一个便宜的电机控制器,但不小心把我的树莓派板给烧掉了,所以我决定买一个质量好一点的替代品。

图4 已经安装了摄像头和电机的树莓派板。

一个标价15美元的摄像头正好能装在树莓派板上,它能提供实时的视频来作为物体识别的输入。摄像头的选择就太多了。我选了一个带红外功能的摄像头,这样就可以让我的机器人有夜视功能了。

树莓派板需要大概2安培的电源,但3安培电流对于我要装的扬声器是一个更保险的选择。iPhone的充电宝是这一任务的理想选择。更低安培的充电宝一般不能产生足够的电流,从而会导致一些问题。不过这个Lumsing power bank的充电宝却很不错,而且只用18美元。

这几个HC-SR04型的声呐传感器可以让机器人免于撞车。11美元就能买到5个。

我还买了我能找到的最便宜的USB扬声器,然后用了一堆的胶带、热胶和泡沫板来把所有的东西粘到一起。作为废物利用,我还把一些电子设备的包装材料给剪了,并在上面画了一些东西来给这个机器人增加一点点人性。这里我要说的是,我实际上造了两个机器人(见图5),因为我实验了不同的底盘、摄像头、声呐、软件和其他的东西。结果加在一起发现足够造两个版本的机器人了。

图5 我的四驱动机器人(右边的)和他的两驱动机器人妹妹。

把机器人组装好了之后,就该让它变聪明了。网上有海量的教程教你如何使用树莓派。如果你曾用过Linux,树莓派的一切对你而言就都很熟悉了。

如果你想把摄像头的视频记录下来,RPi Cam Web接口能很好地胜任。它非常容易配置。默认是把来自摄像头的最新的画面存放在RAM磁盘的/dev/shm/mjpeg/cam.jpg里。

如果你想把摄像头的数据发布到网页里(这对调试是非常有帮助的),你可以用Nginx,一个极度快的开源网页服务器。我把Nginx配成对摄像头画面的网页请求直接指向上面文件的地址,而其他的请求都发送到网页服务器。

http {

server {

location / {

proxy_pass http://unix:/home/pi/drive.sock;

}

location /cam.jpg {

root /dev/shm/mjpeg;

}

}

}

我随后开发了一个简单的Python 网站服务器,可以接收键盘的指令来转动机器人的轮子。控制键盘本来是一个的遥控汽车的。

另外要说的是,利用声呐和驾驶系统来控制机器人的行驶路线从而让它能避开物体是一件非常有趣的事。

    给我的机器人开发程序

终于,是时候安装TensorFlow了。安装TensorFlow有很多种方法,但TensorFlow提供了makefile命令,从而能针对你特定的操作系统进行编译。这一步骤花费了我几个小时,并需要一些依赖包,但总体来说还算顺利。

TensorFlow自带了一个预建好的模型,叫inception。它可以完成物体识别。这是如何使用运行它的教程

对一张来自摄像头的画面运行tensorflow/contrib/pi_examples/label_image/gen/bin/label_image命令,TensorFlow会返回5个可能物体的猜测。这个模型对于相当多的东西的识别都非常好,但是它也很明显地缺少一个确定的“先验条件”,即它不知道将会看到的东西是什么。它的训练数据里也明显漏掉了不少物品。比如,它能很好的识别我的笔记本,即使是从很特殊的角度看。但当让它看我的装一堆电线的篮子的时候,它就一直认为这是个烤面包机。当摄像头被遮挡,拍到的图像为黑屏或是比较模糊的时候,它就会认为是在看一些线虫。很明显线虫是它的训练数据里的东西。

图6 接着键盘和显示器的机器人.

最后我采用Flite开源软件包来作为机器人的输出部分,把文字变成语音。这样机器人就可以说出它看到的物体了(见图6)。

        测试我的机器人

看,这里就是我自制的两个可以使用深度学习进行物体识别的机器人

Midkey说:对于性能再次提升而且价格不变的树莓派,不得不给个大写的服。用树莓派搭载上Tensorflow,再一次拉近了深度学习与我们之间的距离,变得触手可得。然而以上这个小项目,看似简单,还是涉及了许多各方面的问题。

  1. 需要学习树莓派的使用,在树莓派上搭建Linux系统,驱动树莓派的GPIO以及摄像头(树莓派拥有不少的库函数,实际使用起来并不太难,需要了解一些Linux的基本操作)
  2. 搭建服务器并不是必要,(如果喜欢,也可以自己搭着玩),可以直接通过一个蓝牙模块进行控制小车的移动(名曰:遥控小车So easy!)
  3. 语音合成方面,对于我们平时的小作品,大家可以尝试使用Ekho(余音)这款开源语音合成软件,能够说中文!只是合成声音较为无语而已。
  4. 关于电机驱动,我们可以直接使用较为常见的L298N电机驱动板。
  5. 最最关键的一点!!在树莓派上装TensorFlow,实为本项目最难,也是最重要的一环!而且在文章中也没有细说!至于怎么弄这个,可以跪见这个网址:https://github.com/samjabrahams/tensorflow-on-raspberry-pi

    因为树莓派本身的性能所致,可以预见的是,安装TensorFlow将会耗费大量时间,而且有可能出现各种问题,在此就先不细说了。(后续再作尝试)

  6. 建议有一定Linux操作基础的同学进行尝试。

【原创】C#玩高频数字彩快3的一点体会 - 数据之巅 - 博客园

mikel阅读(1479)

来源: 【原创】C#玩高频数字彩快3的一点体会 – 数据之巅 – 博客园

  购彩风险非常高,本人纯属很久以前对数字高频彩的一点研究。目前已经远离数字彩,重点研究足球篮球比赛资料库和赛果预测。

  这是一篇在草稿箱保存了1年多的文章,一直没发现,顺便修改修改分享给大家。以后会有更多关于足球和篮球体育彩票的玩法分析,希望大家关注。

本人不算专业程序员,但经常敲代码玩玩。上学时研究的是伪随机数这个东东,因此对彩票就情有独钟,从10年开始,就开始研究双色球,其中软件版本改了又改,但一直没有实际操作过,原因就是双色球的投注量太大。所以这1年多就没研究了。最近一次偶然的机会,发现了“高频彩-快3”,仔细研究了一番,发现这个比双色球有意思多了,1是每天82期,快,不用等开奖;2是号码总共就56注。想想应该比较容易。加上玩法多样,现在也比较收欢迎,所以从10月份开始,就开始重操旧业,用我对数字的理解以及会敲代码这个特长,结合起来,研究研究(很多老彩民,经验丰富,但不会写代码,不会搞Excel,所以后来被动)各位看官先莫乱说,且把文章看完,顺便我也写下对快3的理解。

彩票数据框架与分析预测总目录

【彩票】彩票预测算法(一):离散型马尔可夫链模型C#实现

【彩票】彩票预测算法(二):朴素贝叶斯分类器在足球胜平负预测中的应用及C#实现 

注意:我玩的是江苏快3,俗称老快3。顺便说一下快3的玩发:发一个链接吧,有兴趣去看。http://cp.360.cn/k3js/

先说一下,彩票的性质其实就是合法的赌博,虽然中国的彩票一直不透明,对快3来说,机器开奖,就更不用说了。

1.我认为快3人为操作的可能性很大,但不是每期都操作,操作的期数在少数;正因为如此,所以现在高频彩的私彩相当多,而且返奖率比官方高出一大坨。。

2.快3的返奖率不算高,但是快,所以刺激,同时也俗称吸金器,千万不要上瘾。

切记:玩彩风险非常大,一天输几万的很多,所以看过此文,请谨慎对待彩票。

1.建立基本框架

说平台太大了点,对我来说,其实就是一个分析软件。因为以前又开发双色球分析软件的经验,所以这次就省事了不少,特别是在数据库方面,很快就搞定了。先建立基本的数据库,快3的数据很简单,就是1个日期,期号,再就是号码。当然为了提高计算速度,避免每次重复的分析计算,我在数据库设计的时候,就把一些常规指标进行了统计,直接存到数据库,比如和值,跨度,奇数,偶数等等。

基本的思路就是:

1.实时采集数据。

2.先对基础数据进行统计,编写各种统计算法(其实都是很简单,就3个号码,怎么算,对程序员来说都不复杂,即使统计加加减减等)。

3.在初步统计的基础上,然后编写一些验证预测算法,测试准确性,如果可行,就做成界面(结果自己的不断努力和测试,现在已经取消验证环节了,直接把有价值的统计数据,放在表格中,人工观察,实时进行人为判断,如果机器能自动,那是不可能的,这样彩票中心可以下岗了)。

4.完善软件界面,不断根据自己的经验,增加统计数据。

2.数据库建立和数据采集

本人一直使用XCode组件来进行数据库的操作,具体组件使用,看我博客把。数据库的建立很简单,看代码中的实体模型好了。可能有些冗余,只是没时间完善而已。主要看看数据采集部分吧。我用的是HtmlAgilityPack组件,这个东西很多人都玩过,不详细解释了,HtmlAgilityPack+XPath,可以很轻松的解决固定页面的数据提取。直接上代码:

顺便提一下,考虑到网站的不稳定性,有时候会连不上,所以我每一种快3都有2种采集方案,就是有2个采集来源。 根据当前的数据库连接名称来采集。

复制代码
#region 抓取数据-52CP
private static void GetDataFormWeb_52CP(int perDay, Boolean isUpdateAll)
{
    string url;           
    if (perDay == 0) //今天
    {
        if (JS_K3_DayStatics.Meta.ConnName == "LotTickDayJL") url = @"http://www.52cp.cn/bull/index.php/Index/list_jlks";
        else url = @"http://www.52cp.cn/bull/index.php/Index/list_jsks";
    }
    else
    {
        if (JS_K3_DayStatics.Meta.ConnName == "LotTickDayJL")
        {
            url = @"http://www.52cp.cn/bull/index.php/Index/list_jlks/time/-" + perDay.ToString();
        }
        else
        {
            url = @"http://www.52cp.cn/bull/index.php/Index/list_jsks/time/-" + perDay.ToString();
        }
        //前几天        
    }
    HtmlWeb web = new HtmlWeb();
    HtmlDocument doc = web.Load(url);
    HtmlNodeCollection hc = doc.DocumentNode.SelectNodes(@"/html[1]/body[1]/div[3]/div[4]/div[4]/table[1]")[0].SelectNodes(@"tr");
    for (int j = hc.Count - 1; j > 0; j--)
    {
        HtmlNodeCollection hc1 = hc[j].SelectNodes(@"td");

        string noStr = hc1[0].InnerText.Trim();
        //如果此期号不存在,就加入
        int count = FindCount(_.No, noStr);
        if (count < 1 && Convert.ToInt32(noStr.Substring(0, 2)) > 11)//只采集12年1月1日之后的数据
        {
            string[] numbers = hc1[2].InnerText.Trim().Split(',');
            int a = Convert.ToInt32(numbers[0]);
            int b = Convert.ToInt32(numbers[1]);
            int c = Convert.ToInt32(numbers[2]);
            JS_K3Base model = new JS_K3Base(new int[] { a, b, c });
            model.No = noStr;
            model.Day = new DateTime(Convert.ToInt32("20" + model.No.Substring(0, 2)), Convert.ToInt32(model.No.Substring(2, 2)),
                Convert.ToInt32(model.No.Substring(4, 2)));
            model.Save();
            if (isUpdateAll)
            {
                //更新信息表 JS_K3
                if (JS_K3.Find(JS_K3._.No, model.No) == null) new JS_K3(model).Save();
            }
        }
        else
        {
            if (JS_K3.FindCount(_.No, noStr) < 1) new JS_K3(Find(_.No, noStr)).Save();
        }
    }
}
#endregion
复制代码

3.核心的统计扩展方法

因为计算就是对位置,频率这些东西进行计算,基本都很简单,所以都以扩展方法的形式存在。大家具体可以看代码。里面非常乱,没时间整理,举个例子吧:

复制代码
#region 邻号出现的情况
/// <summary>连续2期号码相同个数,剔除后 邻号出现个数
/// 返回数组第1个为 相同号码列表
/// 返回数组第2个为 邻号相同的列表
/// </summary>
public static int[][] K3_SameAndCloseCount(this JS_K3[] data)
{
    int[] SameCount = new int[data.Length - 1];
    int[] CloseCount = new int[data.Length - 1];

    for (int i = 0; i < data.Length -1; i++)
    {
        List<int> a1 = new List<int>() { data[i].Number_1, data[i].Number_2, data[i].Number_3 };
        List<int> a2 = new List<int>() { data[i + 1].Number_1, data[i + 1].Number_2, data[i + 1].Number_3 } ;
        //相同号码及移除
        List<int> a3 = new List<int>() { data[i + 1].Number_1, data[i + 1].Number_2, data[i + 1].Number_3 };
        foreach (var item in a3)
        {   //都包含才能移除
            if (a1.Contains<int>(item) && a2.Contains<int>(item))
            {
                a1.Remove(item);
                a2.Remove(item);
                SameCount[i] ++;
            }
        }
        //移除后号码的邻号统计,对于位置相减
        for (int j = 0; j < a1.Count ; j++)
        {
            int temp = Math.Abs(a1[j] - a2[j]);
            if (temp == 1) CloseCount[i] ++;
        }
    }
    return new int[][] { SameCount, CloseCount };
}
复制代码

同时对一些高频数据,重复数据的分析也很重要,下面是一些扩展方法:

复制代码
/// <summary>2不同重复出现的次数</summary>
public static int[] K3_Diff2_RepeatCount(this JS_K3[] data)
{
    Dictionary<string, int> result = new Dictionary<string, int>();
    int[] count = new int[2];
    foreach (var item in data)
    {
        if (item.IsDiff2)
        {
            if (result.ContainsKey(item.NoString))
            {
                result[item.NoString]++;
                count[0]++;
            }
            else result.Add(item.NoString, 1);
        }
    }
    foreach (var item in result) if (item.Value > 1) count[1]++;
    return count;
}

/// <summary>3同号重复的次数</summary>
public static int K3_Same3_RepeatCount(this JS_K3[] data)
{
    Dictionary<string, int> result = new Dictionary<string, int>();
    int count = 0;
    foreach (var item in data)
    {
        if (item.IsSame3)
        {
            if (result.ContainsKey(item.NoString)) count++;
            else result.Add(item.NoString, 1);
        }
    }
    return count;
}
复制代码

其实上面这些统计方法都比较简单,就是一些数据的统计。由于版本很老,当然还有很多其他的,由于经验不足,封装得不好,暂时就不全部发出来了。其他代码和文章还在计划中。至于统计和分析的界面,太久了,我也懒得去找程序。谢谢大家理解,一个小软件也是面面俱到,非常复杂的。

4.总结

本人2013年10月下旬开始玩江苏快3,因为自己会写程序,所有就做软件研究了下,当然经验不足,有时候运气比较好,也赢过。但每天的盘不一样,很容易就陷进去了。然后看了很多帖子,发现容易亏得很大,所以输了几百块,赶紧收手不玩了,这个心态一定要控制好。也看了很多论坛的帖子,发现很多人都很容易亏大,结合自己的经验,我发现的确是很容易掉进去,别说几万,如果没有策略,不加分析,几十万都很容易输掉。快3类型很多,说一点体会

1.江苏快3更刺激,总体平均还是不错,局部热号更明显;相反吉林快3的号更平稳和平均。
2.玩快3不能指望一夜暴富,如果收益能有10-20%,赶紧收手。不要手痒,我有好多次前面都有20-50%的盈利,但还不死心,结果很快就陷进去了。玩彩票心态很重要,一定要忍住,我也在控制自己的心态。
3.不要往死里追,除非你有大量的实际数据做论证,我会写软件,所以这方面经验比较多,当然软件分析也是多个角度,偶尔也会失误。因为一旦你陷进去,只需要5-10期,就可以让你彻底崩溃,快3的刺激就在于速度快,毕竟有56个号,你想在5-10期抓住,还是有难度的,但也有可能。我也有1-2期就追到号的情况。
4.快3一定要有玩法,如果你只是简单的看和值,追2同号,或者豹子,那么基本会输的很快,要有自己的策略和计划。

总的来说,高频彩返奖率50%,已经是世界最低了,真的没有玩的理由。从概率与回报率来说,闭着眼睛玩足球回报率也比这好(国彩足球返奖率高的时候有70-80%)。希望看到此文的人早点收手。另外群也不再公布了,有人说我拉人赌博,好好看文章把,本来是想给大家一个交流的机会的,我都用了这么大的粗体字,有些人跟疯狗一样,乱咬,真实没话说。


如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

.NET数据挖掘与机器学习,作者博客: http://www.cnblogs.com/asxinyu

E-mail:1287263703@qq.com

.NET平台机器学习资源汇总,有你想要的么? - 数据之巅 - 博客园

mikel阅读(1019)

来源: .NET平台机器学习资源汇总,有你想要的么? – 数据之巅 – 博客园

接触机器学习1年多了,由于只会用C#堆代码,所以只关注.NET平台的资源,一边积累,一边收集,一边学习,所以在本站第101篇博客到来之际,分享给大家。部分用过的 ,会有稍微详细点的说明,其他没用过的,也是我关注的,说不定以后会用上。机器学习并不等于大数据或者数据挖掘,还有有些区别,有些东西可以用来处理大数据的问题或者数据挖掘的问题,他们之间也是有部分想通的,所以这些组件不仅仅可以用于机器学习,也可以用于数据挖掘相关的。

按照功能把资源分为3个部分,开源综合与非综合类,以及其他网站博客等资料。都是能够在.NET平台使用的。谢谢大家支持,这些组件我日后肯定也会研究其使用,到时候有心得再分享上来。如果有兴趣,可以关注本博客。

本文原文地址:http://www.cnblogs.com/asxinyu/p/4422050.html

1.开源综合类

1.1 AForge.NET

  AForge.NET是一个专门为开发者和研究者基于C#框架设计的,他包括计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,模糊系统,机器人控制等领域。这个框架由一系列的类库组成。主要包括有:

AForge.Imaging —— 一些日常的图像处理和过滤器
AForge.Vision —— 计算机视觉应用类库
AForge.Neuro —— 神经网络计算库AForge.Genetic -进化算法编程库
AForge.MachineLearning —— 机器学习类库
AForge.Robotics —— 提供一些机器学习的工具类库
AForge.Video —— 一系列的视频处理类库
AForge.Fuzzy —— 模糊推理系统类库
AForge.Controls—— 图像,三维,图表显示控件

来自:http://baike.haosou.com/doc/1786119-1888850.html

官方网站http://www.aforgenet.com/

我个人认为这个是.NET平台机器学习和数据挖掘发展时间最长,最好,最全面的开源.NET组件之一。博客园有很多园友写过专门的使用文章。我本人也只是关注,还没有使用,因为方向和处理的问题不一样,暂时还没有实际应用。源代码,案例等都非常全面。

1.2 Accord.NET Framework

Accord.NET Framework是在AForge.NET基础上封装和进一步开发来的。功能也很强大,因为AForge.NET更注重与一些底层和广度,而Accord.NET Framework更注重与机器学习这个专业,在其基础上提供了更多统计分析和处理函数,包括图像处理和计算机视觉算法,所以侧重点不同,但都非常有用。

官方网站http://accord-framework.net/

1.3 Math.NET

不管是机器学习还是数据挖掘,都与数学离不开关系,既然是在.NET平台,那么这个组件以后你也许用得上。Math.NET是.NET平台下最全面的数学计算组件之一,基础功能非常完善。我的博客有对这个组件的详细研究:http://www.cnblogs.com/asxinyu/p/4329737.html 。当然更多的功能还得大家自己使用中发掘,毕竟提供了源代码。Math.NET初衷是开源建立一个稳定并持续维护的先进的基础数学工具箱,以满足.NET开发者的日常需求。目前该组件主要分为以下几个子项目,该组件同时也支持Mono,而且支持的平台也非常广泛。Math.NET Numerics是核心功能是数值计算。主要是提供日常科学工程计算相关的算法,包括一些特殊函数,线性代数,概率论,随机函数,微积分,插值,最优化等相关计算功能。详细的介绍和使用可以参考本站的菜单“Math.NET”,查看目录。

官方网站http://www.mathdotnet.com/

1.4 Infer.NET

好吧,上面说的那些很强大,强大一方面是说包括的面广,一方面是代码,注释,资源,案例也很完善。如果说上面那些是大炮,那么我认为这个Infer.NET就是战斗机,零零散散接触和研究,以及翻译它的文档代码已经有5个月了,时间越久,越感觉到它的火力之强大。我博客已经发表了2篇翻译的文档:http://www.cnblogs.com/asxinyu/p/4329742.html,请关注。

Infer.NET是微软剑桥研究院基于.NET平台开发的一款机器推理组件,该组件的采用的是Microsoft Research License Agreement 授权,Non-Commercial Use Only.Infer.NET是一个概率图模型中(graphical models)用于运行贝叶斯推理机(Bayesian inference)的框架。如果对概率图模型或者贝叶斯推理的意义不了解,你可以参考一下相关资源文件,在Resources and References page页面。Infer.NET为各种应用程序所需要推理提供了先进的消息传递算法和统计程序。Infer.NET更关注与概率图编程或者贝叶斯理论的相关应用。这个随机因素和不确定世界中的很多问题,都可以适用,所以他的强大一方面是专注,另一方面是提供的建模语言。与其他的组件不同,其他组件是算法级,而Infer.NET是建模级别,附带了各种通用和常见的推理算法。可以通过简单的代码来创建模型,按照微软的话说是MSL建模语言,这也是这个组件让我肃然起敬的地方,估计也只有微软的研究人员才会想到这么干一劳永逸的事情。

官方网站http://research.microsoft.com/en-us/um/cambridge/projects/infernet/default.aspx

1.5 numl

另外一个小巧的,包含比较多的机器学习算法类库,支持监督式和非监督式学习。支持很多常见的机器学习算法,文档资源还不错。包括Cluster,KMeans,PCA,DecisionTree,KNN,NaiveBayes,NeuralNetwork等学习算法,内容也非常丰富,功能强大,同时也包括一些数值计算的实现。这个组件个人认为没有以上的那么复杂,结构小巧合理,代码也很优雅。看看下面这段代码,很快就可以构建一个决策树学习器进行预测:

复制代码
 1 var generator = new DecisionTreeGenerator();
 2 generator.Descriptor = Descriptor.Create<Tennis>();
 3 generator.SetHint(false);
 4 
 5 Tennis[] tennis = TennisData.GetData();
 6 
 7 var learned = Learner.Learn(tennis, 0.80, 1000, generator);
 8 
 9 IModel model = learned.Model;
10 double accuracy = learned.Accuracy;
11 
12 Tennis t = new Tennis
13 {
14     Outlook = Outlook.Sunny,
15     Temperature = Temperature.High,
16     Windy = false
17 };
18 
19 Tennis predictedVal = model.Predict(t);
复制代码

  numl的入门案例和文档比较全面,如果本身对算法比较了解,熟悉C#,那入门应该不是问题。并且可以通过组件本身构建和解决更加复杂的问题。

官方网站http://numl.net/

1.6 Alglib

ALGLIB是一个跨平台的数值分析和数据处理函数库,该函数库包括开源版本和商业版本。它支持多种编程语言,如C++,C#,Pascal,VBA等,可以在多个操作系统平台上运行,如:Windows,Linux和Solaris。ALGLIB有以下特点:

(1)线性代数(包括矩阵分析);
(2)方程求解(线性和非线性);
(3)插值;
(4)最优化;
(5)快速傅里叶变换;
(6)数值积分;
(7)线性和非线性最小二乘拟合;
(8)常微分方程求解;
(9)特殊函数;
(10)统计(描述统计、假设检验);
(11)数据分析(分类、回归、神经网络);

官方网站http://www.alglib.net/

2.开源.NET平台非综合类

2.1 Adaboost算法

1.https://github.com/bgorven/Classifier

2.https://github.com/ElmerNing/Adaboost

2.2 Apriori算法

1.https://github.com/Omar-Salem/Apriori-Algorithm

2.https://github.com/simonesalvo/apriori

2.3 PageRank算法

https://github.com/archgold/pagerank

2.4 NativeBayes(朴素贝叶斯)算法

1.https://github.com/Rekin/Naive-Bayes-Classifier
2.https://github.com/ArdaXi/Bayes.NET
3.https://github.com/amrishdeep/Dragon
4.https://github.com/joelmartinez/nBayes

2.5 kmeans算法

http://visualstudiomagazine.com/articles/2013/12/01/k-means-data-clustering-using-c.aspx

3.其他资源与技术博客

【资源】108个大数据文档PDF开放下载-整理后打包下载,虽然是大数据的相关资料,主要是PPT等,但也有和机器学习有一点关系,需要的看看;

白话贝叶斯理论及在足球比赛结果预测中的应用和C#实现【附资料】 里面有贝叶斯相关的论文资料,文章本身对朴素贝叶斯的原理也介绍得非常清楚;

数据挖掘领域十大经典算法初探

机器学习10大经典算法

支持向量机通俗导论(理解SVM的三层境界)

从决策树学习谈到贝叶斯分类算法、EM、HMM

自然语言处理博客 ,包含的内容非常多,可能理论性有点强 http://www.52nlp.cn/

西北工业大学博导聂飞平博客:http://www.escience.cn/people/fpnie/index.html

一个机器学习数据挖掘的博客,有不少资源链接:http://www.zhizhihu.com/

http://mlg.eng.cam.ac.uk/mlss09/schedule.htm

一个机器学习资源集中平台  http://www.kernel-machines.org/software

算法杂货铺——分类算法之朴素贝叶斯分类(Naive Bayesian classification)

最大熵模型介绍

概率图模型

博客园Bobby0322的博客:http://www.cnblogs.com/Bobby0322/p/4052495.html 中的商务智能与数据挖掘应用系列文章:

  1. 《BI那点儿事》数据挖掘初探
  2. 《BI那点儿事》数据挖掘的主要方法
  3. 《BI那点儿事》浅析十三种常用的数据挖掘的技术
  4. 《BI那点儿事》数据挖掘与相关领域的关系
  5. 《BI那点儿事》Microsoft 关联算法
  6. 《BI那点儿事》Microsoft 聚类分析算法
  7. 《BI那点儿事》Microsoft 聚类分析算法——三国人物身份划分
  8. 《BI那点儿事》Microsoft 决策树算法
  9. 《BI那点儿事》Microsoft 决策树算法——找出三国武将特性分布,献给广大的三国爱好者们
  10. 《BI那点儿事》Microsoft 线性回归算法
  11. 《BI那点儿事》Microsoft 逻辑回归算法
  12. 《BI那点儿事》Microsoft 逻辑回归算法——预测股票的涨跌
  13. 《BI那点儿事》Microsoft Naive Bayes 算法
  14. 《BI那点儿事》Microsoft Naive Bayes 算法——三国人物身份划分
  15. 《BI那点儿事》Microsoft 神经网络算法
  16. 《BI那点儿事》Microsoft 顺序分析和聚类分析算法
  17. 《BI那点儿事》Microsoft 时序算法
  18. 《BI那点儿事》Microsoft 时序算法——验证神奇的斐波那契数列
  19. 《BI那点儿事》数据挖掘各类算法——准确性验证

4.我的100篇博客之路

从2009年8月1日注册博客园开始,已经有5年多的时间了。这是博客的第100篇正式随笔文章。在2015年元旦的时候,看着自己的博客很久没有更新,只有40多篇文章,然后列出了一个写作计划,初期是至少完成高质量的文章50篇左右。而到现在只有4个月,没想到我几乎完成了全年的目标。当然发表的50多篇文章中,我认为高质量和有意义的可能只有40篇,但丝毫没关系,至少还有很多时间。这些文章是对自己经历和知识的总结,也是一个提高。在这100篇博客里程碑到来的时候,我简单的回顾了一下这100篇文章。

第1篇首日浏览量到1000的文章:

XCode使用记录—使用XCode自动向数据库插入测试数据(2012-04-25 09:11)

第1篇首日浏览量到3000的文章:

拥有自己的代码生成器—Newlife.XCode模板编写教程 (2012-05-11 08:35)

第1篇 上博客园头条的文章:

挑战ORM性能——Newlife.XCode下500万sqlite数据库的分页(2012-08-22 12:22)

第1篇 推荐超过60的文章:

【原创】开源Word读写组件DocX介绍与入门 (2013-02-22 10:35)  24

第1篇 推荐超过80的文章:

【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】 (2014-04-29 08:02)

第1篇 总浏览量超1.6万的文章:

【吐槽】VS2012的安装项目只能用InstallShield Limited Edition (2013-09-07 11:20)

在所有的100篇随笔中,有13篇是目录和链接汇总,不能算是写的随笔,还有9篇文章是刚开始来博客园的时候,还在学习,技术含量不高。但我也没删除,毕竟是一段历史。加上有2篇关于比特币和源码的文章,准确的说不是我写的,大部分是@大石头的内容,还有2篇资源和百度吐槽是很随意临时写的,根本没打算发表在首页,只是做一个记录。所以实际比较有技术一点的文章或者心得数量是73篇。这73篇文章中:

在个人认为还不错的文章中有至少15 篇上了博客园头条(包括“最多推荐”和“最多评论”以及“编辑推荐”)

1.白话贝叶斯理论及在足球比赛结果预测中的应用和C#实现【附资料】

2.你用过这种奇葩的C#注释吗?如何看待 (2015-04-17 10:04)

3.【原创】C#玩高频数字彩快3的一点体会 (2015-04-11 09:03)

4.【踩坑经历】一次Asp.NET小网站部署踩坑和解决经历 (2015-04-01 06:10)

5.【分享】博客美化(4)为博客添加一个智能的文章推荐插件 (2015-03-24 07:55)

6.【原创】Newlife.XCode的常见功能使用(一)查询与数据初始化 (2015-01-26 08:52)

7.【原创】开源Math.NET基础数学类库使用(13)C#实现其他随机数生成器 (2015-03-18 08:32)

8.【反传销】传销故事总结—如何尽可能保护自身和家人安全 (2015-03-09 07:37)

9.【反传销】春节一个短暂误入传销和脱身的真实故事以及对技术的思考 (2015-03-03 06:10)

10.App乱世,3721离我们有多远 (2015-02-10 09:24)

11.【原创】开源Word读写组件DocX介绍与入门 (2013-02-22 10:35)

12.【原创】C#开源轻量级对象数据库NDatabase介绍 (2013-02-20 09:35)

13.【原创】.NET开源压缩组件介绍与入门 (2013-03-05 07:59)

14.【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】 (2014-04-29 08:02)

另外还有一篇文章被博客园作为编辑推荐文章:

15.【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数

总的来说,文章是非常高效和得到大家的认可的,虽然技术含量不是特别高级,但可能基础的技术更多的能引起共鸣吧。我想说的是,每一篇文章都是经过很用心的编辑和写出来的,结果也是非常理想的,得到了很多人的支持和理解,所以才有了如此高效的访问量和推荐以及评论。


如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

.NET数据挖掘与机器学习,作者博客: http://www.cnblogs.com/asxinyu

E-mail:1287263703@qq.com

【彩票】彩票预测算法(一):离散型马尔可夫链模型C#实现 - 数据之巅 - 博客园

mikel阅读(4728)

来源: 【彩票】彩票预测算法(一):离散型马尔可夫链模型C#实现 – 数据之巅 – 博客园

前言:彩票是一个坑,千万不要往里面跳。任何预测彩票的方法都不可能100%,都只能说比你盲目去买要多那么一些机会而已。

已经3个月没写博客了,因为业余时间一直在研究彩票,发现还是有很多乐趣,偶尔买买,娱乐一下。本文的目的是向大家分享一个经典的数学预测算法的思路以及代码。对于这个马尔可夫链模型,我本人以前也只是听说过,研究不深,如有错误,还请赐教,互相学习。

1.马尔可夫链预测模型介绍

马尔可夫链是一个能够用数学方法就能解释自然变化的一般规律模型,它是由著名的俄国数学家马尔科夫在1910年左右提出的。马尔科夫过程已经是现在概率论中随机过程理论的一个重要方面。经过了一百年左右的发展,马尔可夫过程已经渗透到各个领域并发挥了重要的作用,如在我们熟知的经济、通信领域,除此之外在地质灾害、医疗卫生事业、生物学等自然科学领域也发挥了非常重要的作用。

人们在对实际问题的研究中会发现随着时间的持续发展变化会产生很多现象。还有一些现象或过程可以表述如下:在“现在”是已知的情况下,这种变化过程的“未来”与“过去”是毫无联系的。也就是说这种过程的未来所出现的情况不依赖于过去的发展变化,我们就把具有上述性质的过程称之为马尔可夫过程。马尔可夫过程可以描述现实生活中的很多现象。例如,我们熟知的液体中的颗粒所做的布朗运动、在商业活动中所要研究的每天销售情况、在数字通信中的语音信号、视频信号等。马尔可夫链在其他领域的应用还有很多,如在银行的不良资产的管理、机车管理、企业管理、生态环境演变、城市用水量仿真、信息处理等科学研究和生产生活中都有广泛应用。

2.马尔可夫链的数学概念和性质

定义1:

定义2:

上面是2个最简单的马尔可夫链的数学定义,看不懂没关系,简单解释一下:

1.从状态k到k+1与时间k无关,也就是说这个随机过程与时间k无关,而从k到k+1状态,有一个转移概率,马尔可夫链的核心其实也就是这个转移概率;

2.根据马尔可夫链的思想,一步转移概率Pij很容易得到,但是预测的时候,往往要根据最近K期的数据来进行,所以要计算K步转移概率;

3.任意步的转移概率可以根据C-K方程来计算,CK方程是一种计算转移概率的基本方法,简单的算法就是:通过一步转移概率矩阵P独自相乘m次,就可以得到m步转移概率。

4.马尔可夫链的思想,就是根据历史的数据,统计得到转移概率,然后根据滞时权重对每个状态进行预测,概率最高的是最可能出现的。

5.对于离散型马尔可夫链序列变量,一般计算之前需要对变量进行“马氏性”检验,统计量就是卡方分布。

6.马尔可夫链的研究还有很多其他的方面,比如状态分类,极限概率,平稳分布等等,这些太高级,没时间去搞很懂,这些对预测过程的精度是有一定影响的。

3.离散型马尔可夫链变量预测步骤

3.1 状态分类

对于离散型变量来说,首先要把目标的数据进行归类,对模型来说,一般状态都是有限的,比如说双色球,可以把16个篮球号码分为8个状态,2个一组。当然一些经济和实际生活数据的状态分类,就要根据实际情况了。

3.2 计算转移概率矩阵

转移概率矩阵是可以根据历史数据的频率f(i,j)统计得到。f(i,j)是状态i到状态j转移的次数;然后概率转移矩阵

p(i,j) = f(i,j)/f(i.)  ;频数除以当前行的和值即为概率

3.3 “马氏性”检验

对于离散型的变量,需要利用历史数据进行“马氏性”检验。检验公式为:

然后根据显著性水平(程序中固定取0.05) ,查表求m自由度时的阀值,若 ,则满足 马氏性,可以进行下一步的预测,否则没有多大的意义。

3.4 计算自相关系数和各种步长的权重

若满足马氏性,就可以对下一个状态进行预测了,预测根据滞时k,有权重调整,权重W(k)是根据自相关系数R(k)计算得到的,公式如下:

k为滞时期,我程序测试里面选的5,L是总的历史数据次数,X是历史数据序列。

3.5 计算不同滞时期的转移概率矩阵

根据C-K方程提供的算法,计算k步的转移概率矩阵 Pi(k) ,又一次转移概率矩阵自乘 k次得到。

3.6 预测下一个状态

下一个状态的预测概率通过相同状态的各个预测概率加权和得到,计算用到公式:

最后一步的时候要注意,要根据最后k期的历史数据所在状态值和步长的权值相乘。滞时期为1的数据,是最后1期数据(最新的数据),这个循环的时候要注意,很容易掉进坑里。

4.离散型马尔可夫链模型代码

本文使用C#实现了简单的离散型马尔可夫链模型,在验证马氏性的时候,由于需要查表求值,所以暂时固定了自由度25,显著性水平0.05,模型核心代码:

 

复制代码
  1 /// <summary>离散型马尔可夫链预测模型</summary>
  2     public class DiscreteMarkov
  3     {
  4         #region 属性
  5         /// <summary>样本点状态时间序列,按照时间升序</summary>
  6         public List<int> StateList { get; set; }
  7         /// <summary>状态总数,对应模型的m</summary>
  8         public int Count { get; set; }
  9         /// <summary>概率转移矩阵Pij</summary>
 10         public List<DenseMatrix> ProbMatrix { get; set; }
 11         /// <summary>各阶的自相关系数</summary>
 12         public double[] Rk { get; set; }
 13         /// <summary>各阶的权重/summary>
 14         public double[] Wk { get; set; }
 15         /// <summary>频数矩阵/summary>
 16         public int[][] CountStatic { get; set; }
 17         /// <summary>目标序列是否满足"马氏性"/summary>
 18         public Boolean IsMarkov { get; set; }
 19         /// <summary>滞时期,K/summary>
 20         public int LagPeriod { get; set; }
 21 
 22         /// <summary>预测概率</summary>
 23         public double[] PredictValue { get; set; }
 24         #endregion
 25 
 26         #region 构造函数
 27         public DiscreteMarkov(List<int> data, int count,int K = 5)
 28         {
 29             this.StateList = data;
 30             this.LagPeriod = K;
 31             this.Count = count;
 32             this.CountStatic = StaticCount(data, count);
 33             this.ProbMatrix = new List<DenseMatrix>();
 34             var t0 = DenseMatrix.OfArray(StaticProbability(this.CountStatic).ConvertToArray<double>());
 35             ProbMatrix.Add(t0);
 36           
 37             for (int i = 1; i < K; i++) //根据CK方程,计算各步的状态转移矩阵
 38             {
 39                 var temp = ProbMatrix[i - 1] * t0;
 40                 ProbMatrix.Add(temp);
 41             }
 42             if (ValidateMarkov())
 43             {
 44                 CorrCoefficient();
 45                 TimeWeight();
 46                 PredictProb();
 47             }
 48             else
 49             {
 50                 Console.WriteLine("马氏性 检验失败,无法进行下一步预测");
 51             }
 52         }
 53         #endregion
 54 
 55         #region 验证
 56         /// <summary>验证是否满足马氏性,默认的显著性水平是0.05,自由度25</summary>
 57         /// <returns></returns>
 58         public Boolean ValidateMarkov()
 59         {
 60             //计算列和
 61             int[] cp1 = new int[Count];
 62             int allcount = CountStatic.Select(n => n.Sum()).Sum();//总数
 63 
 64             for (int i = 0; i < Count; i++)
 65             {
 66                 for (int j = 0; j < Count; j++) cp1[i] += CountStatic[j][i];
 67             }
 68             double[] cp = cp1.Select(n => (double)n / (double)allcount).ToArray();
 69 
 70             //计算伽马平方统计量
 71             double gm = 0;
 72             for (int i = 0; i < Count; i++)
 73             {
 74                 for (int j = 0; j < Count; j++)
 75                 {
 76                     if (CountStatic[i][j] != 0)
 77                         gm += 2 * CountStatic[i][j] * Math.Abs(Math.Log(ProbMatrix[0][i,j] / cp[j], Math.E));
 78                 }
 79             }
 80             //查表求a = 0.05时,伽马分布的临界值F(m-1)^2,如果实际的gm值大于差别求得的值,则满足
 81             //查表要自己做表,这里只演示0.05的情况  卡方分布            
 82             return gm >= 37.65;
 83         }
 84 
 85         /// <summary>计算相关系数</summary>
 86         public void CorrCoefficient()
 87         {
 88             double mean = (double)StateList.Sum() /(double) StateList.Count;//均值
 89 
 90             double p = StateList.Select(n => (n - mean)*(n-mean)).Sum();
 91 
 92             Rk = new double[LagPeriod];
 93 
 94             for (int i = 0; i < LagPeriod; i++)
 95             {
 96                 double s1 = 0;              
 97                 for (int L = 0; L < StateList.Count - LagPeriod ; L++)
 98                 {
 99                     s1 += (StateList[L] - mean) * (StateList[L + i] - mean);
100                 }
101                 Rk[i] = s1 / p;
102             }
103         }
104 
105         /// <summary>计算滞时的步长</summary>
106         public void TimeWeight()
107         {
108             double sum = Rk.Select(n=>Math.Abs(n)).Sum();
109             Wk = Rk.Select(n => Math.Abs(n) / sum).ToArray();
110         }
111 
112         /// <summary>预测状态概率</summary>
113         public void PredictProb()
114         {
115             PredictValue = new double[Count];
116             //这里很关键,权重和滞时的关系要颠倒,循环计算的时候要注意
117             //另外,要根据最近几期的出现数,确定概率的状态,必须取出最后几期的数据
118 
119             //1.先取最后K期数据
120             var last = StateList.GetRange(StateList.Count - LagPeriod, LagPeriod);
121             //2.注意last数据是升序,最后一位对于的滞时期 是k =1 
122             for (int i = 0; i < Count; i++)
123             {
124                 for (int j = 0; j < LagPeriod; j++)
125                 {
126                     //滞时期j的数据状态
127                     var state = last[last.Count - 1 - j] - 1;
128                     PredictValue[i] += Wk[j] * ProbMatrix[j][state ,i];
129                 }
130             }
131         }
132         #endregion
133 
134         #region 静态 辅助方法
135         /// <summary>统计频数矩阵</summary>
136         /// <param name="data">升序数据</param>
137         public static int[][] StaticCount(List<int> data, int statusCount)
138         {
139             int[][] res = new int[statusCount][];
140 
141             for (int i = 0; i < statusCount; i++) res[i] = new int[statusCount];
142 
143             for (int i = 0; i < data.Count - 1; i++) res[data[i]-1][data[i + 1]-1]++;
144 
145             return res;
146         }
147         /// <summary>根据频数,计算转移概率矩阵</summary>
148         /// <param name="data">频率矩阵</param>
149         public static double[][] StaticProbability(int[][] data)
150         {
151             double[][] res = new double[data.Length][];
152             for (int i = 0; i < data.Length; i++)
153             {
154                 int sum = data[i].Sum();
155                 res[i] = data[i].Select(n => (double)n / (double)sum).ToArray();
156             }
157             return res;
158         }
159         #endregion
160     }
复制代码

调用方法很简单,如下代码:这里使用的是论文文献中的数据,单个号码的随机概率为16.6%,程序预测的概率可以到25-30%的样子,应该还有调整的空间。

复制代码
1  //历史状态数据
2             List<int> data = new List<int>(){
3             6,4,4,5,2,4,6,1,2,6,  5,6,4,4,6 , 5,3,6,5,2 , 5,3,3,4,4,
4             4,1,1,1,1,3,5,6,5,5,  5,5,4,6,5 , 4,1,3,1,3 , 1,3,1,2,5,
5             2,2,5,5,1,4,4,2,6,1,  5,4,6,3,2,  2,6,4,4,4,  4,3,1,5,3,
6             1,2,6,5,3,6,3,6,4,6,  2,4,4,6,3,  3,6,2,6,1,  3,2,2,6,6,
7             4,4,3,1,4,1,2,6,4,4,  1,2};//,6,4,3,6,2,5,5,5
8 
9             var result = new DiscreteMarkov(data, 6,5);
复制代码

5.实际案例

哈哈,请关注博客,年后将根据此算法,对高频彩快3和11选5进行实证分析。因为这个过程有点复杂,不是一下子可以搞定的。

本文的相关文字资料,公式和数据来源根据这篇文献:“马尔可夫链预测模型及一些应用”,2012.3 温海彬

最后,彩票风险很大,购彩需谨慎。你的热情和推荐,是我的动力哦。

补充一下,其中有一个扩展方法,进行数组转换的,忘记贴上去了:

复制代码
1 public static T[,] ConvertToArray<T>(this T[][] data)
2         {
3             T[,] res = new T[data.Length, data[0].Length];
4             for (int i = 0; i < data.Length; i++)
5             {
6                 for (int j = 0; j < data[i].Length; j++) res[i, j] = data[i][j];
7             }
8             return res;
9         }
复制代码

 


如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

.NET数据挖掘与机器学习,作者博客: http://www.cnblogs.com/asxinyu

E-mail:1287263703@qq.com

Google机器学习笔记 4-5-6 分类器 - 梦里风林 - 博客园

mikel阅读(1165)

来源: Google机器学习笔记 4-5-6 分类器 – 梦里风林 – 博客园

转载请注明作者:梦里风林
Google Machine Learning Recipes 4
官方中文博客视频地址
Github工程地址 https://github.com/ahangchen/GoogleML
欢迎Star,也欢迎到Issue区讨论

Recipes 4 Let’s Write a Pipeline

复习与强化概念

  • 监督学习基础套路
  • 例子: 一个用于举报邮件的分类器

关键在于举报新的邮件

  • Train vs Test:隔离训练集,测试集以验证训练效果
  • f(x) = y

    feature: x, label: y, classifier其实就是一个feature到label的函数

  • 可以从sklearn中import各种分类器进行训练,各种分类器有类似的接口

这些不同分类器都可以解决类似的问题

  • 让算法从数据中学习到底是什么
  • 拒绝手工写分类规则代码
  • 本质上,是学习feature到label,从输入到输出的函数
  • 从一个模型开始,用规则来定义函数
  • 根据训练数据调整函数参数
  • 从我们发现规律的方法中,找到model
  • 比如一条划分两类点的线就是一个分类器的model,调整参数就能得到我们想要的分类器:

Example of Neural Network

Recipes 5 Writing Our First Classifier

  • 从底层实现一个分类器

目标

实现一个K近邻(k-Nearest Neighbour)问题

K Nearest Neighbour

  • 对于一个测试点,看它最近的邻居属于那个类别
  • 考虑最近邻居的时候,我们可以综合考虑与这个点距离最近的K个点,看它们中有多少输入类别A,多少属于类别B
  • 距离:两点间的直线距离(Euclidean Distance)

  • 即考虑各个feature之间差异的平方和

实现

  • 在Lesson4的基础上进行,我们在lesson4中使用了KNeighborsClassifier()作为分类器,现在我们要实现这个分类器
  • ScrappyKNN:最简单的一个K近邻分类器
  • 接口:
    • fit:用于训练,将训练集的feature和label作为输入
    • predict: prediction,将测试集的feature作为输入,输出预测的label
  • Random Classifier
    • 随机挑一个label作为预测输出,由于我们是在三种花的结果中随机挑取一种花作为结果,所以结果大概在33%
  • KNN:
  • 设置k=1,也就是我们只考虑最近的那个点属于那个类别
  • 用scipy.spatial.distance来计算距离
  • 返回测试点最近邻的label

结论

  • 准确率:90%以上(这里也可能看出feature选得好的重要性)
  • 优点:非常简单
  • 缺点:耗时;不能表示复杂的东西;

Recipes 6 Train an Image Classifier with TensorFlow for Poets

目标

区分图片之间的差异

工具

TensorFlow for Poets

  • 高度封装
  • 效果奇佳
  • 只需要目录中的图片和目录名字作为label,不需要预设feature

数据

分类器

  • TensorFlow
  • TensorFlow擅长于Deep learning
  • 由于提取特征很困难,因为世界上的变数太多了,所以深度学习自动提取特征的功能变得很重要
  • TFLearn:高阶的机器学习库
  • Image Classifier
  • 直接从像素级数据提取特征
  • 神经网络
  • 可以学习更复杂的函数

实现

后话

  • 图像识别关键在于:Diversity and quantity
  • Diversity:样本多样性越多,对新事物的预测能力越强
  • Quantity:样本数量越多,分类器越强大

西瓜书概念整理(chapter 1-2)熟悉机器学习术语 - 梦里风林 - 博客园

mikel阅读(1103)

来源: 西瓜书概念整理(chapter 1-2)熟悉机器学习术语 – 梦里风林 – 博客园

括号表示概念出现的其他页码, 如有兴趣协同整理,请到issue中认领章节

完整版见我的github:ahangchen

觉得还不错的话可以点个star ^_^

第一章 绪论

  • Page2: 标记(label)

    示例结果的信息,例如“好瓜”,称为标记

  • Page2: 假设(269)(hypothesis)

    学得模型对应了数据的某种潜在的规律,因此亦称假设

  • Page2: 示例(instance)

    数据集中的每条记录是关于某个事件或对象的描述,称为一个“示例”或“样本”

  • Page2: 属性(attribute)

    反映事务或对象在某方面的表现或性质的事项,如“色泽”,称为属性或特征

  • Page2: 属性空间(attribute space)

    属性长成的空间称为属性空间,样本空间,或输入空间

  • Page2: 数据集(data set)

    数据记录的集合称为一个数据集

  • Page2: 特征(247)(feature)

    同属性

  • Page2: 学习(learning)

    从数据中学得模型的过程称为学习或训练

  • Page2: 学习器(learner)

    学习过程就是为了找出或逼近真相,有时将模型称作学习器

  • Page2: 训练(training)

    同学习

  • Page2: 训练集(training data)

    训练过程中使用的数据称为“训练集”,其中每个样本称为一个“训练样本”,训练样本组成的集合称为训练集

  • Page2: 训练样本(training sample)

    见训练集

  • Page2: 样本(sample)

    同示例

  • Page2: 样本空间(sample space)

    同属性空间

  • Page2: 样例(sample)

    同示例(instance)

  • Page2: 真相(ground-truth)

    潜在规律本身称为真相或真实

  • Page3: 标记空间(label space)

    所有标记的集合称为标记空间或输出空间

  • Page3: 测试(testing)

    学得模型后,使用其进行预测的过程称为测试,被预测的样本称为测试样本

  • Page3: 测试样本(testing sample)

    见测试

  • Page3: 簇(197)(cluster)

    将训练集中的西瓜分成若干组,称为聚类,每个组称为一个簇

  • Page3: 独立同分布(267)(independent and identically distributed)

    我们获得的每个样本都是独立的从一个分布上采样获得的,即“独立同分布”

  • Page3: 多分类(multi-class classification)

    预测值涉及多个类别时,称为“多分类”

  • Page3: 二分类(binary classification)

    预测值设计两个分类的任务

  • Page3: 泛化(121,350)(generalization)

    学得模型适用于新样本的能力,称为“泛化”能力

  • Page3: 分类(classification)

    如果预测的是离散值,此类学习任务称为分类

  • Page3: 回归(regression)

    如果预测的值是连续值,此类学习任务称为回归

  • Page3: 监督学习(supervised learning)

    根据训练数据是否拥有标记信息,学习任务可以大致分为两大类:监督学习和无监督学习,分类和回归是前者的代表,聚类是后者的代表

  • Page3: 聚类(197)(clustering)

    见簇

  • Page3: 无导师学习

    同无监督学习

  • Page3: 无监督学习(197)(unsupervised learning)

    见有监督学习

  • Page3: 有导师学习

    同有监督学习

  • Page4: 概念学习(17)(concept learning)

    广义的归纳学习大体相当于从样例中学习,而狭义的归纳学习则要求从训练数据中学得概念,因此亦称为概念学习或概念形成

  • Page4: 归纳学习(11)(inductive learning)

    从样例中学习

  • Page5: 版本空间(version space)

    存在着一个与训练集一致的假设集合,称之为“版本空间”

  • Page6: 归纳偏好(inductive bias)

    机器学习算法在学习过程中对某种类型假设的偏好,称为归纳偏好

  • Page6: 偏好

    同归纳偏好

  • Page7: 奥卡姆剃刀(17)(Occam’s razor)

    若有多个假设与观察一致,则选最简单的那个

  • Page10: 符号主义(363)(symbolism)

    基于逻辑表示

  • Page10: 连接主义(connectionism)

    基于神经网络

  • Page10: 人工智能

    有很多种说法。。见仁见智

  • Page11: 机械学习

    信息存储与检索

  • Page11: 类比学习

    通过观察和发现学习

  • Page11: 示教学习

    从指令中学习

  • Page12: 统计学习(139)

    如SVM,核方法

  • Page14: 数据挖掘

    从海量数据中发掘知识

  • Page16: WEKA
  • Page17: 迁移学习

    类比学习升级版

第二章 模型评估与选择

  • Page23: 错误率(error rate)

    分类错误的样本数占样本总数的比例称为错误率,即如果在m个样本中有a个样本分类错误,则错误率E = a/m;相应的,1-a/m称为精度。

  • Page23: 泛化误差(generalization error)

    在新样本上的误差称为泛化误差

  • Page23: 过拟合(104,191,352)(overfitting)

    当学习器把训练样本学得太好了的时候,很可能已经把训练样本自身的一些特点当作了所有潜在样本都会具有的一般性质,这样就会导致泛化性能下降,这种现象称为过拟合

  • Page23: 过配

    同过拟合

  • Page23: 精度(29)(accuracy)

    精度=1-错误率

  • Page23: 经验误差(267)(empirical error)

    学习器在训练集上的误差称为“训练误差”

  • Page23: 欠配(underfitting)

    欠拟合,对训练样本的一般性质尚未学好

  • Page23: 误差(error)

    学习器的实际预测输出与样本的真实输出之间的差异称为误差

  • Page23: 训练误差(trainning error)

    同经验误差

  • Page24: 模型选择(model selection)

    选择学习算法与参数配置

  • Page25: 分层采样(stratified sampling)

    如果从采样的角度看待数据集的划分过程,则保留类别比例的采样方式通常称为“分层采样”

  • Page25: 留出法(hold-out)

    直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另一个作为测试集T,在S上训练出模型后,用T来评估其测试误差,作为对泛化误差的估计。

  • Page26: k折交叉验证(k-fold cross validation)

    交叉验证先将数据集D划分为k个大小相似的互斥子集,每个自己都尽可能保持数据分布的一致性,即从数据集中分层采样得到,然后,每次用k-1个子集的并集作为训练集,余下的那个子集作为测试集,这样就可以获得k组训练/测试集,最终返回k个测试结果的均值,交叉验证评估结果的稳定性和保真性很大程度上取决于k的取值,通常称之为k折交叉验证,最常用的k是10

  • Page26: 交叉验证法(cross validation)

    同k折交叉验证

  • Page27: 包外估计(179)(out of bag estimate)

    用于测试的样本没在训练集中出现,这样的测试结果称为包外估计

  • Page27: 自助法(bootstrapping)

    以自主采样法为基础,给定包含m个样本的数据集D,对它采样产生数据集D’:每次随机从D中挑选一个样本,将其考本放入D’, 然后再将该样本放回D中,下次可能再被采到,这个过程执行m次后,得到包含m个样本的数据集D’,m足够大时,有36.8%的样本不会被采到,于是可以用没采到的部分做测试集。

  • Page28: 参数调节(parameter tuning)

    大多数学习算法有些参数需要设定,参数配置不同,学得模型的性能往往有显著差别,因此,在进行模型评估与选择时,除了要对适用学习算法进行选择,还需要对算法参数进行设定,这就是参数调节或者调参。

  • Page28: 验证集(105)(validation set)

    通常把学得模型在实际使用中遇到的数据称为测试数据,为了加以区分,为了加以区分,模型评估与选择中用于评估测试的数据集常称为“验证集”。

  • Page29: 均方误差(54)(mean squared error)

    回归任务最常用的性能度量是均方误差(几何距离)

  • Page30: 查全率(recall)

    预测为真且正确的结果占所有预测正确的结果的比例。

  • Page30: 查准率(precision)

    预测为真且正确的结果占所有预测结果的比例。

  • Page30: 混淆矩阵(confusion matrix)
真实情况 预测为正例 预测为反例
正例 TP(真正例) FN(假反例)
反例 FP(假正例) TN(真反例)
  • Page30: 召回率

    同查全率

  • Page30: 准确率

    同查准率

  • Page31: P-R曲线

    查准率(纵轴)与查全率(横轴)的关系曲线

  • Page31: 平衡点(break-even point,bep)

    查准率=查全率时的取值。平衡点大的学习模型可以认为综合性能更好

  • Page32: F1

    查准率和查全率的调和平均,比算术平均(求和除以2)和几何平均(平方相乘开方)更重视较小值。

    1/F1 = 1/2 (1/P + 1/R)

    1/Fβ = 1/(1+β)(1/P + β²/R)

  • Page32: 宏F1(macro-F1)

    如果进行多次训练/测试,每次得到一个混淆矩阵,或是在多个数据集上进行训练/测试,可以在n个混淆矩阵上综合考察查准率和查全率

    macro-P = 1/n(∑Pi)

    macro-R = 1/n(∑Ri)

    1/macro-F1 = 1/2*(1/macro-P + 1/macro-R)

  • Page32: 宏查全率

    见宏F1之macro-R

  • Page32: 宏查准率

    见宏F1之macro-P

  • Page32: 微F1(micro-F1)

    将各混淆矩阵的对应元素进行平均,再去计算,可以得到micro-F1

  • Page32: 微查准率

    将各混淆矩阵的对应元素进行平均,再去计算

  • Page32: 微查全率

将各混淆矩阵的对应元素进行平均,再去计算

  • Page33: ROC曲线(46)

    真正例率(True Positive Rate,TPR)和假正例率(FPR)的关系曲线

    TPR = TP/(TP+FN)

    FPR = FP/(TN+FP)

  • Page35: 代价(47)(cost)

    为权衡不同类型错误所造成的不同损失,可为错误赋予“非均等代价”

  • Page35: 代价矩阵
真实情况 预测为0类 预测为1类
0类 0 cost01
1类 cost10 0
  • Page36: 代价敏感(67)(cost-sensitive)

    在损失函数中考虑了非均等代价

  • Page36: 代价曲线

    正例概率代价(横轴)和归一化代价(纵轴)的曲线

    正例概率代价: P(+)cost = p * cost01 /( p * cost01 + (1 – p) * cost10),p是样例为正例的概率

    归一化代价: cost_norm = (FNR * p * cost01 + FPR * (1-p) * cost10)/(p * cost01+ (1-p) * cost10)

  • Page36: 规范化(183)(normalization)

    将不同变化范围的值映射到相同的固定范围中,常见的是[0,1],此时亦称归一化

  • Page36: 归一化(regular)

    同规范化

  • Page36: 总体代价

    错误率是直接计算错误次数,并没有考虑不同错误会造成不同的后果,在非均等代价下,我们所希望的不再是简单的最小化错误次数,而是希望最小化总体代价

  • Page37: 假设检验(hypothesis test)

    假设是对学习器泛化错误率分布的某种判断或猜想,用测试错误率估计泛化错误率,以检查学习器性能。

  • Page38: 二项检验(binomial test)

    二项分布检验,根据收集到的样本数据,推断总体分布是否服从某个指定的二项分布。泛化错误率为e的学习器被测得测试错误率为e’的概率是服从二项分布的。

  • Page38: 置信度(confidence)

    估计总体参数落在某一区间时,可能不犯错误的概率,一般用符号1-α表示。

  • Page40: 交叉验证成对t校验(paired t-tests)

    对两个学习器A和B,使用k折交叉验证法分别得到k个测试错误率,如果两个学习器性能相同,则使用相同训练/测试集时测试错误率应该相同,求两个学习器的k个测试错误率的差,若abs(sqrt(k)*μ/σ)<临界值则认为两个学习器性能相同。

  • Page41: 5×2交叉验证

    由于交叉验证中,不同轮次的训练集之间有一定程度的重复,会过高估计假设成立的概率,因此做5次2折交叉验证,每次验证前将数据打乱,对5次2对2个学习器的测试错误率求差值,对所有差值求方差,对前两次差值求均值,再进行临界值判断。

  • Page41: McNemar检验

    两个学习器分类差别列联表

算法B\A 正确 错误
正确 e00 e01
错误 e10 e11

检验变量|e01-e10|是否服从正态分布,服从则认为两学习器性能相同等同于检查τx² = (|e01-e10|-1)²/(e01+e10) 是否服从自由度为1的卡方分布(标准正态分布变量的平方)

  • Page41: 列联表(187)

    见McNemar检验

  • Page42: Friedman检验

    有多个数据集多个学习器进行比较时使用,对各个算法在各个数据集上对测试性能排序,对平均序值计算τx²和τF,并进行临界值检验。

  • Page43: Nemenyi后续检验(Nemenyi post-hoc test)

    学习器性能性能显著不同时,进行后续检验来进一步区分各算法,临界值域:CD=qα* sqrt(k*(k+1)/6N)

  • Page44: 偏差-方差分解(177)

    对学习算法的期望泛化错误率进行拆解,学习算法在不同训练集上学得的结果很可能不同,真实输出与期望输出的差别称为偏差(bias),使用样本数相同的不同训练集产生的输出的方差为var(x),有:E(f;D) = bias²(x) + var(x) + ε²

Google机器学习笔记(七)TF.Learn 手写文字识别 - 梦里风林 - 博客园

mikel阅读(1349)

来源: Google机器学习笔记(七)TF.Learn 手写文字识别 – 梦里风林 – 博客园

转载请注明作者:梦里风林
Google Machine Learning Recipes 7
官方中文博客视频地址
Github工程地址 https://github.com/ahangchen/GoogleML
欢迎Star,也欢迎到Issue区讨论

mnist问题

  • 计算机视觉领域的Hello world
  • 给定55000个图片,处理成28*28的二维矩阵,矩阵中每个值表示一个像素点的灰度,作为feature
  • 给定每张图片对应的字符,作为label,总共有10个label,是一个多分类问题

TensorFlow

  • 可以按教程用Docker安装,也可以直接在Linux上安装
  • 你可能会担心,不用Docker的话怎么开那个notebook呢?其实notebook就在主讲人的Github页
  • 可以用这个Chrome插件:npviewer直接在浏览器中阅读ipynb格式的文件,而不用在本地启动iPython notebook
  • 我们的教程在这里:ep7.ipynb
  • 把代码从ipython notebook中整理出来:tflearn_mnist.py

代码分析

  • 下载数据集
mnist = learn.datasets.load_dataset('mnist')

恩,就是这么简单,一行代码下载解压mnist数据,每个img已经灰度化成长784的数组,每个label已经one-hot成长度10的数组

在我的深度学习笔记看One-hot是什么东西

  • numpy读取图像到内存,用于后续操作,包括训练集(只取前10000个)和验证集
data = mnist.train.images
labels = np.asarray(mnist.train.labels, dtype=np.int32)
test_data = mnist.test.images
test_labels = np.asarray(mnist.test.labels, dtype=np.int32)
max_examples = 10000
data = data[:max_examples]
labels = labels[:max_examples]
  • 可视化图像
def display(i):
    img = test_data[i]
    plt.title('Example %d. Label: %d' % (i, test_labels[i]))
    plt.imshow(img.reshape((28, 28)), cmap=plt.cm.gray_r)
    plt.show()

用matplotlib展示灰度图

  • 训练分类器
  • 提取特征(这里每个图的特征就是784个像素值)
feature_columns = learn.infer_real_valued_columns_from_input(data)
  • 创建线性分类器并训练
classifier = learn.LinearClassifier(feature_columns=feature_columns, n_classes=10)
classifier.fit(data, labels, batch_size=100, steps=1000)

注意要制定n_classes为labels的数量

  • 分类器实际上是在根据每个feature判断每个label的可能性,
  • 不同的feature有的重要,有的不重要,所以需要设置不同的权重
  • 一开始权重都是随机的,在fit的过程中,实际上就是在调整权重

  • 最后可能性最高的label就会作为预测输出
  • 传入测试集,预测,评估分类效果
result = classifier.evaluate(test_data, test_labels)
print result["accuracy"]

速度非常快,而且准确率达到91.4%

可以只预测某张图,并查看预测是否跟实际图形一致

# here's one it gets right
print ("Predicted %d, Label: %d" % (classifier.predict(test_data[0]), test_labels[0]))
display(0)
# and one it gets wrong
print ("Predicted %d, Label: %d" % (classifier.predict(test_data[8]), test_labels[8]))
display(8)
  • 可视化权重以了解分类器的工作原理
weights = classifier.weights_
a.imshow(weights.T[i].reshape(28, 28), cmap=plt.cm.seismic)

  • 这里展示了8个张图中,每个像素点(也就是feature)的weights,
  • 红色表示正的权重,蓝色表示负的权重
  • 作用越大的像素,它的颜色越深,也就是权重越大
  • 所以权重中红色部分几乎展示了正确的数字

Next steps