WEKA使用教程(经典教程转载) - Coding for Dreams - 博客频道 - CSDN.NET

mikel阅读(1572)

WEKA使用教程目录 1. 简介2. 数据格式3.数据准备4. 关联规则(购物篮分析)5. 分类与回归6. 聚类分析 1. 简介 WEKA的全名是怀卡托智能分析环境(Waikato Environment for Knowledge Analysis),它的源代码可通过http://www.cs.waikato.ac.nz/ml/weka得到。同时weka也

来源: WEKA使用教程(经典教程转载) – Coding for Dreams – 博客频道 – CSDN.NET

WEKA使用教程

目录
1. 简介
2. 数据格式
3.数据准备
4. 关联规则(购物篮分析)
5. 分类与回归
6. 聚类分析

1. 简介

WEKA的全名是怀卡托智能分析环境(Waikato Environment for Knowledge Analysis),它的源代码可通过http://www.cs.waikato.ac.nz/ml/weka得到。同时weka也是新西兰的一种鸟名,而WEKA的主要开发者来自新西兰。

WEKA作为一个公开的数据挖掘工作平台,集合了大量能承担数据挖掘任务的机器学习算法,包括对数据进行预处理,分类,回归、聚类、关联规则以及在新的交互式界面上的可视化。
如果想自己实现数据挖掘算法的话,可以看一看weka的接口文档。在weka中集成自己的算法甚至借鉴它的方法自己实现可视化工具并不是件很困难的事情。

2005年8月,在第11届ACM SIGKDD国际会议上,怀卡托大学的Weka小组荣获了数据挖掘和知识探索领域的最高服务奖,Weka系统得到了广泛的认可,被誉为数据挖掘和机器学习历史上的里程碑,是现今最完备的数据挖掘工具之一(已有11年的发展历史)。Weka的每月下载次数已超过万次。

–整理自http://www.china-pub.com/computers/common/info.asp?id=29304

2. 数据格式

巧妇难为无米之炊。首先我们来看看WEKA所用的数据应是什么样的格式。
跟很多电子表格或数据分析软件一样,WEKA所处理的数据集是图1那样的一个二维的表格。

图1 新窗口打开
这里我们要介绍一下WEKA中的术语。表格里的一个横行称作一个实例(Instance),相当于统计学中的一个样本,或者数据库中的一条记录。竖行称作一个属性(Attrbute),相当于统计学中的一个变量,或者数据库中的一个字段。这样一个表格,或者叫数据集,在WEKA看来,呈现了属性之间的一种关系(Relation)。图1中一共有14个实例,5个属性,关系名称为“weather”。

WEKA存储数据的格式是ARFF(Attribute-Relation File Format)文件,这是一种ASCII文本文件。图1所示的二维表格存储在如下的ARFF文件中。这也就是WEKA自带的“weather.arff”文件,在WEKA安装目录的“data”子目录下可以找到。


需要注意的是,在Windows记事本打开这个文件时,可能会因为回车符定义不一致而导致分行不正常。推荐使用UltraEdit这样的字符编辑软件察看ARFF文件的内容。

下面我们来对这个文件的内容进行说明。
识别ARFF文件的重要依据是分行,因此不能在这种文件里随意的断行。空行(或全是空格的行)将被忽略。
以“%”开始的行是注释,WEKA将忽略这些行。如果你看到的“weather.arff”文件多了或少了些“%”开始的行,是没有影响的。
除去注释后,整个ARFF文件可以分为两个部分。第一部分给出了头信息(Head information),包括了对关系的声明和对属性的声明。第二部分给出了数据信息(Data information),即数据集中给出的数据。从“@data”标记开始,后面的就是数据信息了。

关系声明
关系名称在ARFF文件的第一个有效行来定义,格式为
@relation <relation-name>
<relation-name>是一个字符串。如果这个字符串包含空格,它必须加上引号(指英文标点的单引号或双引号)。

属性声明
属性声明用一列以“@attribute”开头的语句表示。数据集中的每一个属性都有它对应的“@attribute”语句,来定义它的属性名称和数据类型。
这些声明语句的顺序很重要。首先它表明了该项属性在数据部分的位置。例如,“humidity”是第三个被声明的属性,这说明数据部分那些被逗号分开的列中,第三列数据 85 90 86 96 … 是相应的“humidity”值。其次,最后一个声明的属性被称作class属性,在分类或回归任务中,它是默认的目标变量。
属性声明的格式为
@attribute <attribute-name> <datatype>
其中<attribute-name>是必须以字母开头的字符串。和关系名称一样,如果这个字符串包含空格,它必须加上引号。
WEKA支持的<datatype>有四种,分别是
numeric————————-数值型
<nominal-specification>—–分类(nominal)型
string—————————-字符串型
date [<date-format>]——–日期和时间型
其中<nominal-specification> 和<date-format> 将在下面说明。还可以使用两个类型“integer”和“real”,但是WEKA把它们都当作“numeric”看待。注意“integer”,“real”,“numeric”,“date”,“string”这些关键字是区分大小写的,而“relation”“attribute ”和“date”则不区分。

数值属性
数值型属性可以是整数或者实数,但WEKA把它们都当作实数看待。

分类属性
分类属性由<nominal-specification>列出一系列可能的类别名称并放在花括号中:{<nominal-name1>, <nominal-name2>, <nominal-name3>, …} 。数据集中该属性的值只能是其中一种类别。
例如如下的属性声明说明“outlook”属性有三种类别:“sunny”,“ overcast”和“rainy”。而数据集中每个实例对应的“outlook”值必是这三者之一。
@attribute outlook {sunny, overcast, rainy}
如果类别名称带有空格,仍需要将之放入引号中。

字符串属性
字符串属性中可以包含任意的文本。这种类型的属性在文本挖掘中非常有用。
示例:
@ATTRIBUTE LCC string

日期和时间属性
日期和时间属性统一用“date”类型表示,它的格式是
@attribute <name> date [<date-format>]
其中<name>是这个属性的名称,<date-format>是一个字符串,来规定该怎样解析和显示日期或时间的格式,默认的字符串是ISO-8601所给的日期时间组合格式“yyyy-MM-ddTHH:mm:ss”。
数据信息部分表达日期的字符串必须符合声明中规定的格式要求(下文有例子)。

数据信息
数据信息中“@data”标记独占一行,剩下的是各个实例的数据。

每个实例占一行。实例的各属性值用逗号“,”隔开。如果某个属性的值是缺失值(missing value),用问号“?”表示,且这个问号不能省略。例如:
@data
sunny,85,85,FALSE,no
?,78,90,?,yes

字符串属性和分类属性的值是区分大小写的。若值中含有空格,必须被引号括起来。例如:
@relation LCCvsLCSH
@attribute LCC string
@attribute LCSH string
@data
AG5, ‘Encyclopedias and dictionaries.;Twentieth century.’
AS262, ‘Science — Soviet Union — History.’

日期属性的值必须与属性声明中给定的相一致。例如:
@RELATION Timestamps
@ATTRIBUTE timestamp DATE “yyyy-MM-dd HH:mm:ss”
@DATA
“2001-04-03 12:12:12”
“2001-05-03 12:59:55”

稀疏数据
有的时候数据集中含有大量的0值(比如购物篮分析),这个时候用稀疏格式的数据存贮更加省空间。
稀疏格式是针对数据信息中某个实例的表示而言,不需要修改ARFF文件的其它部分。看如下的数据:
@data
0, X, 0, Y, “class A”
0, 0, W, 0, “class B”
用稀疏格式表达的话就是
@data
{1 X, 3 Y, 4 “class A”}
{2 W, 4 “class B”}
每个实例用花括号括起来。实例中每一个非0的属性值用<index> <空格> <value>表示。<index>是属性的序号,从0开始计;<value>是属性值。属性值之间仍用逗号隔开。这里每个实例的数值必须按属性的顺序来写,如 {1 X, 3 Y, 4 “class A”},不能写成{3 Y, 1 X, 4 “class A”}。
注意在稀疏格式中没有注明的属性值不是缺失值,而是0值。若要表示缺失值必须显式的用问号表示出来。

Relational型属性
在WEKA 3.5版中增加了一种属性类型叫做Relational,有了这种类型我们可以像关系型数据库那样处理多个维度了。但是这种类型目前还不见广泛应用,暂不作介绍。

–整理自http://www.cs.waikato.ac.nz/~ml/weka/arff.htmlhttp://weka.sourceforge.net/wekadoc/index.php/en:ARFF_%283.5.3%29

3.数据准备

使用WEKA作数据挖掘,面临的第一个问题往往是我们的数据不是ARFF格式的。幸好,WEKA还提供了对CSV文件的支持,而这种格式是被很多其他软件所支持的。此外,WEKA还提供了通过JDBC访问数据库的功能。
在这一节里,我们先以Excel和Matlab为例,说明如何获得CSV文件。然后我们将知道CSV文件如何转化成ARFF文件,毕竟后者才是WEKA支持得最好的文件格式。面对一个ARFF文件,我们仍有一些预处理要做,才能进行挖掘任务。

.* -> .csv
我们给出一个CSV文件的例子(bank-data.csv)。用UltraEdit打开它可以看到,这种格式也是一种逗号分割数据的文本文件,储存了一个二维表格。

Excel的XLS文件可以让多个二维表格放到不同的工作表(Sheet)中,我们只能把每个工作表存成不同的CSV文件。打开一个XLS文件并切换到需要转换的工作表,另存为CSV类型,点“确定”、“是”忽略提示即可完成操作。

在Matlab中的二维表格是一个矩阵,我们通过这条命令把一个矩阵存成CSV格式。
csvwrite(‘filename’,matrixname)
需要注意的是,Matllab给出的CSV文件往往没有属性名(Excel给出的也有可能没有)。而WEKA必须从CSV文件的第一行读取属性名,否则就会把第一行的各属性值读成变量名。因此我们对于Matllab给出的CSV文件需要用UltraEdit打开,手工添加一行属性名。注意属性名的个数要跟数据属性的个数一致,仍用逗号隔开。

.csv -> .arff
将CSV转换为ARFF最迅捷的办法是使用WEKA所带的命令行工具。
运行WEKA的主程序,出现GUI后可以点击下方按钮进入相应的模块。我们点击进入“Simple CLI”模块提供的命令行功能。在新窗口的最下方(上方是不能写字的)输入框写上
Java weka.core.converters.CSVLoader filename.csv > filename.arff
即可完成转换。
在WEKA 3.5中提供了一个“Arff Viewer”模块,我们可以用它打开一个CSV文件将进行浏览,然后另存为ARFF文件。
进入“Exploer”模块,从上方的按钮中打开CSV文件然后另存为ARFF文件亦可。

“Exploer”界面
我们应该注意到,“Exploer”还提供了很多功能,实际上可以说这是WEKA使用最多的模块。现在我们先来熟悉它的界面,然后利用它对数据进行预处理。

图2 新窗口打开
图2显示的是使用3.5版”Exploer”打开”bank-data.csv”的情况。我们根据不同的功能把这个界面分成8个区域。
区域1的几个选项卡是用来切换不同的挖掘任务面板。这一节用到的只有“Preprocess”,其他面板的功能将在以后介绍。
区域2是一些常用按钮。包括打开数据,保存及编辑功能。我们在这里把”bank-data.csv”另存为”bank-data.arff”。
在区域3中“Choose”某个“Filter”,可以实现筛选数据或者对数据进行某种变换。数据预处理主要就利用它来实现。
区域4展示了数据集的一些基本情况。
区域5中列出了数据集的所有属性。勾选一些属性并“Remove”就可以删除它们,删除后还可以利用区域2的“Undo”按钮找回。区域5上方的一排按钮是用来实现快速勾选的。
在区域5中选中某个属性,则区域6中有关于这个属性的摘要。注意对于数值属性和分类属性,摘要的方式是不一样的。图中显示的是对数值属性“income”的摘要。
区域7是区域5中选中属性的直方图。若数据集的最后一个属性(我们说过这是分类或回归任务的默认目标变量)是分类变量(这里的“pep”正好是),直方图中的每个长方形就会按照该变量的比例分成不同颜色的段。要想换个分段的依据,在区域7上方的下拉框中选个不同的分类属性就可以了。下拉框里选上“No Class”或者一个数值属性会变成黑白的直方图。
区域8是状态栏,可以查看Log以判断是否有错。右边的weka鸟在动的话说明WEKA正在执行挖掘任务。右键点击状态栏还可以执行Java内存的垃圾回收。

预处理
bank-data数据各属性的含义如下:
id a unique identification number
age age of customer in years (numeric)
sex MALE / FEMALE
region inner_city/rural/suburban/town
income income of customer (numeric)
married is the customer married (YES/NO)
children number of children (numeric)
car does the customer own a car (YES/NO)
save_acct does the customer have a saving account (YES/NO)
current_acct does the customer have a current account (YES/NO)
mortgage does the customer have a mortgage (YES/NO)
pep did the customer buy a PEP (Personal Equity Plan) after the last mailing (YES/NO)

通常对于数据挖掘任务来说,ID这样的信息是无用的,我们将之删除。在区域5勾选属性“id”,并点击“Remove”。将新的数据集保存一次,并用UltraEdit打开这个ARFF文件。我们发现,在属性声明部分,WEKA已经为每个属性选好了合适的类型。

我们知道,有些算法,只能处理所有的属性都是分类型的情况。这时候我们就需要对数值型的属性进行离散化。在这个数据集中有3个变量是数值型的,分别是“age”,“income”和“children”。
其中“children”只有4个取值:0,1,2,3。这时我们在UltraEdit中直接修改ARFF文件,把
@attribute children numeric
改为
@attribute children {0,1,2,3}
就可以了。
在“Explorer”中重新打开“bank-data.arff”,看看选中“children”属性后,区域6那里显示的“Type”是不是变成“Nominal”了?

“age”和“income”的离散化我们需要借助WEKA中名为“Discretize”的Filter来完成。在区域2中点“Choose”,出现一棵“Filter树”,逐级找到“weka.filters.unsupervised.attribute.Discretize”,点击。若无法关闭这个树,在树之外的地方点击“Explorer”面板即可。
现在“Choose”旁边的文本框应该显示“Discretize -B 10 -M -0.1 -R first-last”。 点击这个文本框会弹出新窗口以修改离散化的参数。
我们不打算对所有的属性离散化,只是针对对第1个和第4个属性(见区域5属性名左边的数字),故把attributeIndices右边改成“1,4”。计划把这两个属性都分成3段,于是把“bins”改成“3”。其它框里不用更改,关于它们的意思可以点“More”查看。点“OK”回到“Explorer”,可以看到“age”和“income”已经被离散化成分类型的属性。若想放弃离散化可以点区域2的“Undo”。
如果对“”(-inf-34.333333]””这样晦涩的标识不满,我们可以用UltraEdit打开保存后的ARFF文件,把所有的“’\'(-inf-34.333333]\””替换成“0_34”。其它标识做类似地手动替换。

经过上述操作得到的数据集我们保存为bank-data-final.arff

—-整理自http://maya.cs.depaul.edu/~classes/ect584/WEKA/preprocess.html

4. 关联规则(购物篮分析)
注意:目前,WEKA的关联规则分析功能仅能用来作示范,不适合用来挖掘大型数据集。

我们打算对前面的“bank-data”数据作关联规则的分析。用“Explorer”打开“bank-data-final.arff”后,切换到“Associate”选项卡。默认关联规则分析是用Apriori算法,我们就用这个算法,但是点“Choose”右边的文本框修改默认的参数,弹出的窗口中点“More”可以看到各参数的说明。

背景知识
首先我们来温习一下Apriori的有关知识。对于一条关联规则L->R,我们常用支持度(Support)和置信度(Confidence)来衡量它的重要性。规则的支持度是用来估计在一个购物篮中同时观察到L和R的概率P(L,R),而规则的置信度是估计购物栏中出现了L时也出会现R的条件概率P(R|L)。关联规则的目标一般是产生支持度和置信度都较高的规则。
有几个类似的度量代替置信度来衡量规则的关联程度,它们分别是
Lift(提升度?): P(L,R)/(P(L)P(R))
Lift=1时表示L和R独立。这个数越大,越表明L和R存在在一个购物篮中不是偶然现象。
Leverage(不知道怎么翻译):P(L,R)-P(L)P(R)
它和Lift的含义差不多。Leverage=0时L和R独立,Leverage越大L和R的关系越密切。
Conviction(更不知道译了):P(L)P(!R)/P(L,!R) (!R表示R没有发生)
Conviction也是用来衡量L和R的独立性。从它和lift的关系(对R取反,代入Lift公式后求倒数)可以看出,我们也希望这个值越大越好。
值得注意的是,用Lift和Leverage作标准时,L和R是对称的,Confidence和Conviction则不然。

参数设置
现在我们计划挖掘出支持度在10%到100%之间,并且lift值超过1.5且lift值排在前100位的那些关联规则。我们把“lowerBoundMinSupport”和“upperBoundMinSupport”分别设为0.1和1,“metricType”设为lift,“minMetric”设为1.5,“numRules”设为100。其他选项保持默认即可。“OK” 之后在“Explorer”中点击“Start”开始运行算法,在右边窗口显示数据集摘要和挖掘结果。

下面是挖掘出来的lift排前5的规则。
Best rules found:
1. age=52_max save_act=YES current_act=YES 113 ==> income=43759_max 61 conf:(0.54) < lift:(4.05)> lev:(0.0 [45] conv:(1.85)
2. income=43759_max 80 ==> age=52_max save_act=YES current_act=YES 61 conf:(0.76) < lift:(4.05)> lev:(0.0 [45] conv:(3.25)
3. income=43759_max current_act=YES 63 ==> age=52_max save_act=YES 61 conf:(0.97) < lift:(3.85)> lev:(0.0 [45] conv:(15.72)
4. age=52_max save_act=YES 151 ==> income=43759_max current_act=YES 61 conf:(0.4) < lift:(3.85)> lev:(0.0 [45] conv:(1.49)
5. age=52_max save_act=YES 151 ==> income=43759_max 76 conf:(0.5) < lift:(3.77)> lev:(0.09) [55] conv:(1.72)
对于挖掘出的每条规则,WEKA列出了它们关联程度的四项指标。

命令行方式
我们也可以利用命令行来完成挖掘任务,在“Simlpe CLI”模块中输入如下格式的命令:
java weka.associations.Apriori options -t directory-path\bank-data-final.arff
即可完成Apriori算法。注意,“-t”参数后的文件路径中不能含有空格。
在前面我们使用的option为
-N 100 -T 1 -C 1.5 -D 0.05 -U 1.0 -M 0.1 -S -1.0 命令行中使用这些参数得到的结果和前面利用GUI得到的一样。
我们还可以加上“- I”参数,得到不同项数的频繁项集。我用的命令如下:
java weka.associations.Apriori -N 100 -T 1 -C 1.5 -D 0.05 -U 1.0 -M 0.1 -S -1.0 -I -t d:\weka\bank-data-final.arff
挖掘结果在上方显示,应是这个文件的样子。

—-整理自http://maya.cs.depaul.edu/~classes/ect584/WEKA/associate.html

5. 分类与回归

背景知识
WEKA把分类(Classification)和回归(Regression)都放在“Classify”选项卡中,这是有原因的。
在这两个任务中,都有一个目标属性(输出变量)。我们希望根据一个样本(WEKA中称作实例)的一组特征(输入变量),对目标进行预测。为了实现这一目的,我们需要有一个训练数据集,这个数据集中每个实例的输入和输出都是已知的。观察训练集中的实例,可以建立起预测的模型。有了这个模型,我们就可以新的输出未知的实例进行预测了。衡量模型的好坏就在于预测的准确程度。
在WEKA中,待预测的目标(输出)被称作Class属性,这应该是来自分类任务的“类”。一般的,若Class属性是分类型时我们的任务才叫分类,Class属性是数值型时我们的任务叫回归。

选择算法
这一节中,我们使用C4.5决策树算法对bank-data建立起分类模型。
我们来看原来的“bank-data.csv”文件。“ID”属性肯定是不需要的。由于C4.5算法可以处理数值型的属性,我们不用像前面用关联规则那样把每个变量都离散化成分类型。尽管如此,我们还是把“Children”属性转换成分类型的两个值“YES”和“NO”。另外,我们的训练集仅取原来数据集实例的一半;而从另外一半中抽出若干条作为待预测的实例,它们的“pep”属性都设为缺失值。经过了这些处理的训练集数据在这里下载;待预测集数据在这里下载。

我们用“Explorer”打开训练集“bank.arff”,观察一下它是不是按照前面的要求处理好了。切换到“Classify”选项卡,点击“Choose”按钮后可以看到很多分类或者回归的算法分门别类的列在一个树型框里。3.5版的WEKA中,树型框下方有一个“Filter…”按钮,点击可以根据数据集的特性过滤掉不合适的算法。我们数据集的输入属性中有“Binary”型(即只有两个类的分类型)和数值型的属性,而Class变量是“Binary”的;于是我们勾选“Binary attributes”“Numeric attributes”和“Binary class”。点“OK”后回到树形图,可以发现一些算法名称变红了,说明它们不能用。选择“trees”下的“J48”,这就是我们需要的C4.5算法,还好它没有变红。
点击“Choose”右边的文本框,弹出新窗口为该算法设置各种参数。点“More”查看参数说明,点“Capabilities”是查看算法适用范围。这里我们把参数保持默认。
现在来看左中的“Test Option”。我们没有专门设置检验数据集,为了保证生成的模型的准确性而不至于出现过拟合(overfitting)的现象,我们有必要采用10折交叉验证(10-fold cross validation)来选择和评估模型。若不明白交叉验证的含义可以Google一下。

建模结果
OK,选上“Cross-validation”并在“Folds”框填上“10”。点“Start”按钮开始让算法生成决策树模型。很快,用文本表示的一棵决策树,以及对这个决策树的误差分析等等结果出现在右边的“Classifier output”中。同时左下的“Results list”出现了一个项目显示刚才的时间和算法名称。如果换一个模型或者换个参数,重新“Start”一次,则“Results list”又会多出一项。

我们看到“J48”算法交叉验证的结果之一为
Correctly Classified Instances 206 68.6667 %
也就是说这个模型的准确度只有69%左右。也许我们需要对原属性进行处理,或者修改算法的参数来提高准确度。但这里我们不管它,继续用这个模型。

右键点击“Results list”刚才出现的那一项,弹出菜单中选择“Visualize tree”,新窗口里可以看到图形模式的决策树。建议把这个新窗口最大化,然后点右键,选“Fit to screen”,可以把这个树看清楚些。看完后截图或者关掉

这里我们解释一下“Confusion Matrix”的含义。
=== Confusion Matrix ===
a b <– classified as
74 64 | a = YES
30 132 | b = NO
这个矩阵是说,原本“pep”是“YES”的实例,有74个被正确的预测为“YES”,有64个错误的预测成了“NO”;原本“pep”是“NO”的实例,有30个被错误的预测为“YES”,有132个正确的预测成了“NO”。74+64+30+132 = 300是实例总数,而(74+132)/300 = 0.68667正好是正确分类的实例所占比例。这个矩阵对角线上的数字越大,说明预测得越好。

模型应用
现在我们要用生成的模型对那些待预测的数据集进行预测了。注意待预测数据集和训练用数据集各个属性的设置必须是一致的。即使你没有待预测数据集的Class属性的值,你也要添加这个属性,可以将该属性在各实例上的值均设成缺失值。
在“Test Opion”中选择“Supplied test set”,并且“Set”成你要应用模型的数据集,这里是“bank-new.arff”文件。
现在,右键点击“Result list”中刚产生的那一项,选择“Re-evaluate model on current test set”。右边显示结果的区域中会增加一些内容,告诉你该模型应用在这个数据集上表现将如何。如果你的Class属性都是些缺失值,那这些内容是无意义的,我们关注的是模型在新数据集上的预测值。
现在点击右键菜单中的“Visualize classifier errors”,将弹出一个新窗口显示一些有关预测误差的散点图。点击这个新窗口中的“Save”按钮,保存一个Arff文件。打开这个文件可以看到在倒数第二个位置多了一个属性(predictedpep),这个属性上的值就是模型对每个实例的预测值。

使用命令行(推荐)
虽然使用图形界面查看结果和设置参数很方便,但是最直接最灵活的建模及应用的办法仍是使用命令行。
打开“Simple CLI”模块,像上面那样使用“J48”算法的命令格式为:
java weka.classifiers.trees.J48 -C 0.25 -M 2 -t directory-path\bank.arff -d directory-path \bank.model
其中参数“ -C 0.25”和“-M 2”是和图形界面中所设的一样的。“-t ”后面跟着的是训练数据集的完整路径(包括目录和文件名),“-d ”后面跟着的是保存模型的完整路径。注意!这里我们可以把模型保存下来。
输入上述命令后,所得到树模型和误差分析会在“Simple CLI”上方显示,可以复制下来保存在文本文件里。误差是把模型应用到训练集上给出的。
把这个模型应用到“bank-new.arff”所用命令的格式为:
java weka.classifiers.trees.J48 -p 9 -l directory-path\bank.model -T directory-path \bank-new.arff
其中“-p 9”说的是模型中的待预测属性的真实值存在第9个(也就是“pep”)属性中,这里它们全部未知因此全部用缺失值代替。“-l”后面是模型的完整路径。“-T”后面是待预测数据集的完整路径。
输入上述命令后,在“Simple CLI”上方会有这样一些结果:
0 YES 0.75 ?
1 NO 0.7272727272727273 ?
2 YES 0.95 ?
3 YES 0.8813559322033898 ?
4 NO 0.8421052631578947 ?

这里的第一列就是我们提到过的“Instance_number”,第二列就是刚才的“predictedpep”,第四列则是“bank-new.arff”中原来的“pep”值(这里都是“?”缺失值)。第三列对预测结果的置信度(confidence )。比如说对于实例0,我们有75%的把握说它的“pep”的值会是“YES”,对实例4我们有84.2%的把握说它的“pep”值会是“NO”。
我们看到,使用命令行至少有两个好处。一个是可以把模型保存下来,这样有新的待预测数据出现时,不用每次重新建模,直接应用保存好的模型即可。另一个是对预测结果给出了置信度,我们可以有选择的采纳预测结果,例如,只考虑那些置信度在85%以上的结果。

—-整理自http://maya.cs.depaul.edu/~classes/ect584/WEKA/classify.html

6. 聚类分析

原理与实现
聚类分析中的“类”(cluster)和前面分类的“类”(class)是不同的,对cluster更加准确的翻译应该是“簇”。聚类的任务是把所有的实例分配到若干的簇,使得同一个簇的实例聚集在一个簇中心的周围,它们之间距离的比较近;而不同簇实例之间的距离比较远。对于由数值型属性刻画的实例来说,这个距离通常指欧氏距离。
现在我们对前面的“bank data”作聚类分析,使用最常见的K均值(K-means)算法。下面我们简单描述一下K均值聚类的步骤。
K均值算法首先随机的指定K个簇中心。然后:1)将每个实例分配到距它最近的簇中心,得到K个簇;2)计分别计算各簇中所有实例的均值,把它们作为各簇新的簇中心。重复1)和2),直到K个簇中心的位置都固定,簇的分配也固定。

上述K均值算法只能处理数值型的属性,遇到分类型的属性时要把它变为若干个取值0和1的属性。WEKA将自动实施这个分类型到数值型的变换,而且WEKA会自动对数值型的数据作标准化。因此,对于原始数据“bank-data.csv”,我们所做的预处理只是删去属性“id”,保存为ARFF格式后,修改属性“children”为分类型。这样得到的数据文件为“bank.arff”,含600条实例。

用“Explorer”打开刚才得到的“bank.arff”,并切换到“Cluster”。点“Choose”按钮选择“SimpleKMeans”,这是WEKA中实现K均值的算法。点击旁边的文本框,修改“numClusters”为6,说明我们希望把这600条实例聚成6类,即K=6。下面的“seed”参数是要设置一个随机种子,依此产生一个随机数,用来得到K均值算法中第一次给出的K个簇中心的位置。我们不妨暂时让它就为10。
选中“Cluster Mode”的“Use training set”,点击“Start”按钮,观察右边“Clusterer output”给出的聚类结果。也可以在左下角“Result list”中这次产生的结果上点右键,“View in separate window”在新窗口中浏览结果。

结果解释
首先我们注意到结果中有这么一行:
Within cluster sum of squared errors: 1604.7416693522332
这是评价聚类好坏的标准,数值越小说明同一簇实例之间的距离越小。也许你得到的数值会不一样;实际上如果把“seed”参数改一下,得到的这个数值就可能会不一样。我们应该多尝试几个seed,并采纳这个数值最小的那个结果。例如我让“seed”取100,就得到
Within cluster sum of squared errors: 1555.6241507629218
我该取后面这个。当然再尝试几个seed,这个数值可能会更小。

接下来“Cluster centroids:”之后列出了各个簇中心的位置。对于数值型的属性,簇中心就是它的均值(Mean);分类型的就是它的众数(Mode),也就是说这个属性上取值为众数值的实例最多。对于数值型的属性,还给出了它在各个簇里的标准差(Std Devs)。

最后的“Clustered Instances”是各个簇中实例的数目及百分比。

为了观察可视化的聚类结果,我们在左下方“Result list”列出的结果上右击,点“Visualize cluster assignments”。弹出的窗口给出了各实例的散点图。最上方的两个框是选择横坐标和纵坐标,第二行的“color”是散点图着色的依据,默认是根据不同的簇“Cluster”给实例标上不同的颜色。
可以在这里点“Save”把聚类结果保存成ARFF文件。在这个新的ARFF文件中,“instance_number”属性表示某实例的编号,“Cluster”属性表示聚类算法给出的该实例所在的簇。

—-整理自 http://maya.cs.depaul.edu/~classes/ect584/WEKA/k-means.html

 加快TensorFlow在树莓派上的执行速度——服务常驻内存 – 编码无悔 / Intent & Focused

mikel阅读(1975)

来源: [原创] 加快TensorFlow在树莓派上的执行速度——服务常驻内存 – 编码无悔 / Intent & Focused

转载请注明出处:http://www.codelast.com/

本文软硬件环境:
树莓派:3代 Model B V1.2,内存1GB
OS:Arch Linux ARM

上一篇文章中,我尝试了加快TensorFlow预测速度的一个方法——模型“预热”,实验证明它非常有效,但那仍然没有解决一个问题:每次运行程序,都要加载一次模型,然后预热N次,这个过程非常耗时,因此减少这部分时间也是非常关键的。把TensorFlow做成一个常驻内存的服务就可以解决这个问题。

『1』简单的思路
服务端,用Python实现一个web server,处理HTTP Get请求,通过解析URL中的参数(例如 http://127.0.0.1:8080/?image_path=/root/abc.jpg 中的 /root/abc.jpg),来获取待处理的图片的路径,处理完之后,把处理结果返回给客户端。
客户端,通过 curl 命令就可以调用服务了,例如:

curl http://127.0.0.1:8080/?image_path=/root/abc.jpg

这表示让服务端处理 /root/abc.jpg 这个文件。
当然,为了简单,这里的设定有一个局限:server和client都在同一个树莓派上,如果要跨机器,那么需要client把图片post到server端,server取出来之后再处理,但本文不涉及这种情况。
文章来源:http://www.codelast.com/
『2』简单Python web server的实现
不考虑什么并发,多线程之类的情况,我们可以用非常简单的一点代码就实现一个Python web server。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/python3.5                                                                                              
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import parse_qsl
class MyRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
# e.g. "/?image_path=/root/mobike.jpg"                                                                                                                  
path = self.path
# e.g. "/root/mobike.jpg"                                                                                                                               
image_path = parse_qsl(path[2:])[0][1] + '\n'
# send response status code                                                                                                                             
self.send_response(200)
# send headers                                                                                                                                          
self.send_header('Content-type','text/html')
self.end_headers()
# send message back to client, write content as utf-8 data                                                                                              
self.wfile.write(bytes(image_path, "utf8"))
return
def start_web_server():
print('Starting web server...')
server_address = ('127.0.0.1', 8080)
httpd = HTTPServer(server_address, MyRequestHandler)
httpd.serve_forever()
start_web_server()

其中,在 MyRequestHandler 这个类中,我们会处理每一个客户端的请求,这里只是把从URL中解析到的图片文件路径简单地发送回客户端。
此代码可在我的GitHub中下载。
文章来源:http://www.codelast.com/
『3』TensorFlow服务测试
按“模型加载1次,预热10次”的原则,再结合上面的简单web server代码,我们可以很容易地把TensorFlow做成服务。具体代码比较长,这里就不粘贴上来了,在我的GitHub可以下载到。

下面测试一下效果。
把service启动起来:

1
./run-tensorflow-service.sh

经历几十秒的漫长等待之后,模型加载&预热就完成了(命令行输出会有提示),此时,我们再在同一台树莓派上运行client,向server发送一个处理图片的请求:

1
./client.sh /root/raspberry-pi/ai/tensorflow-related/resource/test-images/mobike.jpg

大概4秒多之后,client端会打印出如下信息:

mountain bike, all-terrain bike, off-roader (score = 0.56671)
tricycle, trike, velocipede (score = 0.12035)
bicycle-built-for-two, tandem bicycle, tandem (score = 0.08768)
lawn mower, mower (score = 0.00651)
alp (score = 0.00387)
Prediction used time:4.171393394470215 Seconds
换一张大小相仿的图片来测试,消耗的时间也是差不多的,达到了我们预期的效果。至此,它距离“实用”又更近了一步。

[人工智能] 在树莓派上把文字转成语音(Text-To-Speech/TTS) – 编码无悔 / Intent & Focused

mikel阅读(3199)

来源: [原创] 在树莓派上把文字转成语音(Text-To-Speech/TTS) – 编码无悔 / Intent & Focused

转载请注明出处:http://www.codelast.com/

本文软硬件环境:
树莓派:3代 Model B V1.2,内存1GB
OS:Arch Linux ARM

有时候,我们需要在程序中添加文字转语音的功能,即通过某个程序或API,把输入的文字朗读出来,也就是通常所说的 text-to-speech(简写为TTS)。我尝试了一个简单的方案——使用Espeak来完成这个任务,在这里记录下来。

『1』TTS方案
我们可以使用本地的TTS软件,也可以使用云端的TTS服务来实现文字转语音。使用本地TTS软件的好处就是不需要联网,云端的TTS服务通常提供更好的语音转换效果,不过也通常麻烦得多得多——例如,需要写程序来发送数据、接收返回数据等。
本地的TTS软件非常多,例如Espeak,Festival等。
我试了一下Espeak:

Text to Speech engine for English, with support for other languages.

也就是说Espeak是一个英语的TTS引擎,但同时也支持其他语言。
文章来源:http://www.codelast.com/
『2』硬件连接
首先你要把可以播放声音的设备连接到树莓派上。使用有源音箱或者无源的耳机都可以。我使用的是耳塞,连接到树莓派的3.5mm音频输出接口上,如下图所示:
raspberry pi 3.5 mm audio interface
注意连接的瞬间可能会发出强电流声(爆音),最好不要戴在耳朵上。
文章来源:http://www.codelast.com/
『3』Espeak安装、系统配置及使用
安装非常简单:

1
pacman -S espeak alsa-utils

其中,alsa-utils 我记得是一个Espeak依赖的包,反正我装了。
然而这样安装好之后,你还是无法使用它的。不信可以直接试试:

1
espeak "hello"

这是让Espeak朗读“hello”。通常情况下会直接报错:

ALSA lib confmisc.c:767:(parse_card) cannot find card ‘0’
ALSA lib conf.c:4371:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4371:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name
ALSA lib conf.c:4371:(_snd_config_evaluate) function snd_func_refer returned error: No such file ordirectory
ALSA lib conf.c:4850:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM sysdefault
……
wave_open_sound > Pa_OpenStream : err=-9996 (Invalid device)

这是因为你需要让系统在启动的时候加载和音频相关的模块,修改 /boot/config.txt,在里面添加上一句:

dtparam=audio=on

然后重启系统即可。
文章来源:http://www.codelast.com/
重启之后,你再执行上面的Espeak命令,会发现仍然输出类似于下面的一堆错误信息:

ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.front
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround40
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround41
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround50
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround51
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround71
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2450:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
connect(2) call to /dev/shm/jack-0/default/jack_0 failed (err=No such file or directory)
attempt to connect to server failed

但这并不影响使用,此时已经可以正常发声了。
如果要让Espeak朗读中文,可以带参数这样执行:

1
espeak -vzh "编程"

文章来源:http://www.codelast.com/
『4』使用感受
最大的感觉就是朗读的语音“不自然”——完全是机器人在读的生硬感,而不是人类在读的顺畅感。并且,朗读的时候会带有比较明显的背景噪音。
此外还有一个致命的问题:如果我让它朗读一个非常长的句子(无论是英文还是中文),那么它读着读着就会越来越慢,并且产生越来越大的电流噪音,就好像一个人已经上气不接下气了。这个奇怪的现象我还不知道是为什么。总之,如果拿来读很短的句子或者单词,效果还是勉强能接受的。
如果要追求好的发声效果,还是要使用现在流行的一些云端服务,例如科大讯飞、百度的语音合成API等,它们不仅提供了良好的合成效果,并且还有很多可选的音色(男声,女声,成人声,小孩声,老人声,等等)。

[原创] 加快TensorFlow在树莓派上的执行速度——模型预热 – 编码无悔 / Intent & Focused

mikel阅读(2259)

来源: [原创] 加快TensorFlow在树莓派上的执行速度——模型预热 – 编码无悔 / Intent & Focused

转载请注明出处:http://www.codelast.com/

本文软硬件环境:
树莓派:3代 Model B V1.2,内存1GB
OS:Arch Linux ARM

上一篇文章中,我写了在树莓派上用TensorFlow做的一个深度学习(图像识别)实验,但正如文中所说,50秒执行一次预测的实用性为0。因此,有必要采取一些措施来加快TensorFlow的执行速度,其中一个可行的方法就是“预热”(warm-up),把TensorFlow移植到树莓派上的作者Sam Abrahams已经比较详细地在GitHub上列出了性能测试的结果。依照作者的描述,我也测试了一下,看看那悲催的50秒时间能减少到多少秒。

『1』什么是预热(warm-up)
首先,本文还是对TensorFlow的Python图像分类程序 classify_image.py 来描述的。
预热就是指在真正执行一次预测之前,先执行若干次 Session.run() 方法,从而达到加快一次预测的执行速度的目的。
文章来源:http://www.codelast.com/
『2』代码修改
代码改起来其实很简单。为了能衡量程序运行时间,需要使用Python的time模块,因此在一开始需要import:

1
import time

然后对 run_inference_on_image 方法做一些修改,如下:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def run_inference_on_image(image):
"""Runs inference on an image.
Args:
image: Image file name.
Returns:
Nothing
"""
if not tf.gfile.Exists(image):
tf.logging.fatal('File does not exist %s', image)
image_data = tf.gfile.FastGFile(image, 'rb').read()
# the image used to warm-up TensorFlow model
warm_up_image_data = tf.gfile.FastGFile('/root/tensorflow-related/test-images/ubike.jpg', 'rb').read()
# Creates graph from saved GraphDef.
create_graph()
with tf.Session() as sess:
# Some useful tensors:
# 'softmax:0': A tensor containing the normalized prediction across
#   1000 labels.
# 'pool_3:0': A tensor containing the next-to-last layer containing 2048
#   float description of the image.
# 'DecodeJpeg/contents:0': A tensor containing a string providing JPEG
#   encoding of the image.
# Runs the softmax tensor by feeding the image_data as input to the graph.
softmax_tensor = sess.graph.get_tensor_by_name('softmax:0')
print("Warm-up start")
for i in range(10):
print("Warm-up for time {}".format(i))
predictions = sess.run(softmax_tensor,
{'DecodeJpeg/contents:0': warm_up_image_data})
print("Warm-up finished")
# record the start time of the actual prediction
start_time = time.time()
predictions = sess.run(softmax_tensor,
{'DecodeJpeg/contents:0': image_data})
predictions = np.squeeze(predictions)
# Creates node ID --> English string lookup.
node_lookup = NodeLookup()
top_k = predictions.argsort()[-FLAGS.num_top_predictions:][::-1]
for node_id in top_k:
human_string = node_lookup.id_to_string(node_id)
score = predictions[node_id]
print('%s (score = %.5f)' % (human_string, score))
print("Prediction used time:{} S".format(time.time() - start_time))

其中,我们自己添加的代码有如下几部分:

1
2
# the image used to warm-up TensorFlow model
warm_up_image_data = tf.gfile.FastGFile('/root/tensorflow-related/test-images/ubike.jpg', 'rb').read()

这里使用了另外一张图片来预热模型(和真正预测时使用的不是同一张图片),为了简单写死了路径。
文章来源:http://www.codelast.com/

1
2
3
4
5
6
print("Warm-up start")
for i in range(10):
print("Warm-up for time {}".format(i))
predictions = sess.run(softmax_tensor,
{'DecodeJpeg/contents:0': warm_up_image_data})
print("Warm-up finished")

这里循环10次来预热模型。
文章来源:http://www.codelast.com/

1
2
3
4
# record the start time of the actual prediction
start_time = time.time()
# (中间省略)
print("Prediction used time:{} S".format(time.time() - start_time))

这里打印出了真正预测一张图片的执行时间(秒数),这个时间就是我们真正需要关心的,看它能减少到多少秒。
文章来源:http://www.codelast.com/
『3』测试结果
执行和上一篇文章一样的命令,输出如下:

/usr/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py:1750: VisibleDeprecationWarning: converting an array with ndim > 0 to an index will result in an error in the future
  result_shape.insert(dim, 1)
Warm-up start
Warm-up for time 0
W tensorflow/core/framework/op_def_util.cc:332] Op BatchNormWithGlobalNormalization is deprecated. It will cease to work in GraphDef version 9. Use tf.nn.batch_normalization().
Warm-up for time 1
Warm-up for time 2
Warm-up for time 3
Warm-up for time 4
Warm-up for time 5
Warm-up for time 6
Warm-up for time 7
Warm-up for time 8
Warm-up for time 9
Warm-up finished
mountain bike, all-terrain bike, off-roader (score = 0.56671)
tricycle, trike, velocipede (score = 0.12035)
bicycle-built-for-two, tandem bicycle, tandem (score = 0.08768)
lawn mower, mower (score = 0.00651)
alp (score = 0.00387)
Prediction used time:4.141446590423584 Seconds
文章来源:http://www.codelast.com/
可见:在10次预热之后,一次预测消耗的时间是 4.14 秒,虽然4秒多还是没有达到我们心目中的理想速度,但这已经比之前的50秒强太多了。
此外,从测试结果我们可以体会到的是:预热(Session.run())的头几次特别慢,后面就快起来了,所以,预热次数太少是不行的。

[人工智能]在树莓派上用TensorFlow玩深度学习(Deep Learning) - 推酷

mikel阅读(2173)

在树莓派上用TensorFlow玩深度学习(Deep Learning)

来源: 在树莓派上用TensorFlow玩深度学习(Deep Learning) – 推酷

转载请注明出处:http://www.codelast.com/

本文软硬件环境:
树莓派:3代 Model B V1.2,内存1GB
OS:Arch Linux ARM

深度学习(Deep Learning)现在这么火,树莓派玩家们当然也不会放过,目前已经有很多树莓派项目都搭上了Deep Learning的车,纯粹出于“好玩”的目的,我在树莓派上也实验了一把,用TensorFlow来识别一张图片里的物体“是什么”。

『1』对深度学习(Deep Learning)的简单介绍
以下解释来自维基百科:

深度学习是机器学习拉出的分支,它试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

深度学习的用途实在太广泛,最为普通人所熟知的,就是以下和民生相关的应用:人脸识别,语音识别,图像搜索,在线翻译,等等。
目前流行的深度学习框架有TensorFlow(Google开源),MXNet(得到Amazon支持),Theano等,利用这些框架,我们只需要做比较少的工作,就能把深度学习能力带入我们自己的程序。
文章来源:http://www.codelast.com/
『3』树莓派上的深度学习
当前,主流的深度学习框架都不是主要为了移动平台/嵌入式平台而准备的——这是由于计算能力所限,在移动平台上运行local的深度学习程序,计算速度通常会非常慢。因此,移动平台上主要还是采用向云端提交计算请求、云端计算完成后返回结果的方式来处理数据。
作为一个“类嵌入式”平台,树莓派虽然是同类型里最受关注的产品,但我认为在深度学习的世界里,树莓派还没到像Android、iOS那种“开发一个App必须要支持”的程度。
因此,把任何一个主流的深度学习框架,在树莓派上跑起来都将是一个耗时耗力的工作。
好在TensorFlow是如此流行,并且IT界永远不缺牛人,已经有人把它成功地“移植”到了树莓派3代上(看这里),所以,在树莓派上用TensorFlow来实现深度学习应用是一个不错的选择。
文章来源:http://www.codelast.com/
『3』在树莓派上安装TensorFlow
按作者的文档,通过极其简单的几步操作,就可以在树莓派上把TensorFlow跑起来。如果你有兴趣,可以直接去看作者写的教程。
首先要声明的是:

  • 作者在树莓派上使用的最流行的Linux发行版Raspbian,而我使用的OS是Arch Linux ARM,不过这无所谓,经过我的测试,没有问题(至少我没遇到)
  • 由于在树莓派上开发其他程序的原因,我已经预先安装过了比较多的开发库/软件,类似于Protocol Buffers,NumPy,pip等,而这些软件有些可能会被TensorFlow依赖,所以,我就不需要像作者的文档里说的一样再去安装 pip,python-dev 之类的包了

文章来源:http://www.codelast.com/
然后剩下最关键的一步就是,从GitHub下载一个wheel文件并安装。
wheel是众多Python软件安装包格式中的一种,本质上是一个zip包格式,它使用.whl作为扩展名,用于安装Python模块。

如果你使用Python 2.7:

1
2
wget https://github.com/samjabrahams/tensorflow-on-raspberry-pi/releases/download/v0.11.0/tensorflow-0.11.0-cp27-none-linux_armv7l.whl
sudo pip install tensorflow-0.11.0-cp27-none-linux_armv7l.whl

如果你使用Python 3.3+:

1
2
wget https://github.com/samjabrahams/tensorflow-on-raspberry-pi/releases/download/v0.11.0/tensorflow-0.11.0-py3-none-any.whl
sudo pip3 install tensorflow-0.11.0-py3-none-any.whl

下载whl安装包的过程可能会比较漫长,我使用的是Python 3.5.2,下面是我的命令行输出内容:

Processing ./tensorflow-0.10.0-py3-none-any.whl
Collecting protobuf==3.0.0b2 (from tensorflow==0.10.0)
  Downloading protobuf-3.0.0b2-py2.py3-none-any.whl (326kB)
    100% |████████████████████████████████| 327kB 11kB/s
Collecting wheel>=0.26 (from tensorflow==0.10.0)
  Downloading wheel-0.29.0-py2.py3-none-any.whl (66kB)
    100% |████████████████████████████████| 71kB 18kB/s
Requirement already satisfied (use –upgrade to upgrade): numpy>=1.8.2 in /usr/lib/python3.5/site-packages (from tensorflow==0.10.0)
Requirement already satisfied (use –upgrade to upgrade): six>=1.10.0 in /usr/lib/python3.5/site-packages (from tensorflow==0.10.0)
Requirement already satisfied (use –upgrade to upgrade): setuptools in /usr/lib/python3.5/site-packages (from protobuf==3.0.0b2->tensorflow==0.10.0)
Installing collected packages: protobuf, wheel, tensorflow
Successfully installed protobuf-3.0.0b2 tensorflow-0.10.0 wheel-0.29.0
You are using pip version 8.1.2, however version 9.0.1 is available.
You should consider upgrading via the ‘pip install –upgrade pip’ command.

文章来源:http://www.codelast.com/
然后呢?然后就搞定了!就这么简单!

如果上面的步骤失败了,那么你就只能选择从源码来编译TensorFlow,这是一个相当麻烦的工作,只能祝你好运了,不过好消息就是,作者已经帮大家踩过很多坑了,教程在这里

『4』在树莓派上使用TensorFlow
要识别一张图片里的物体是什么,我们需要先训练一个图像分类模型,这个过程非常消耗计算资源,在树莓派上干这事是不明智的,我们可以直接使用Google已经训练好的Inception-v3模型

Inception-v3 is trained for the ImageNet Large Visual Recognition Challenge using the data from 2012. This is a standard task in computer vision, where models try to classify entire images into 1000 classes, like “Zebra”, “Dalmatian”, and “Dishwasher”.

先下载Inception-V3模型到任意目录中,并解压出来:

1
2
3
4
mkdir ~/tensorflow-related/model
cd ~/tensorflow-related/model
wget http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz
tar xf inception-2015-12-05.tgz

解压出来一堆文件:

classify_image_graph_def.pb
cropped_panda.jpg
imagenet_2012_challenge_label_map_proto.pbtxt
imagenet_synset_to_human_label_map.txt
LICENSE

然后就可以开始进行图像识别啦。在这里我从网上找了一张时下很流行的摩拜单车(MoBike)的图片:
mobike
文章来源:http://www.codelast.com/
用TensorFlow来识别它:

1
2
cd /usr/lib/python3.5/site-packages/tensorflow/models/image/imagenet
python3.5 classify_image.py --model_dir /root/tensorflow-related/model --image_file /root/tensorflow-related/test-images/mobike.jpg

其中,/usr/lib/python3.5/site-packages/tensorflow/models/image/imagenet 这个路径是TensorFlow的 Python图像分类程序 classify_image.py 所在的路径,不同的OS可能不一样。
–model_dir 参数传入的是我们前面解压出来的模型文件所在的路径,–image_file 是待识别的图片的路径。
输出如下:

/usr/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py:1750: VisibleDeprecationWarning: converting an array with ndim > 0 to an index will result in an error in the future
  result_shape.insert(dim, 1)
W tensorflow/core/framework/op_def_util.cc:332] Op BatchNormWithGlobalNormalization is deprecated. It will cease to work in GraphDef version 9. Use tf.nn.batch_normalization().
bicycle-built-for-two, tandem bicycle, tandem (score = 0.33731)
tricycle, trike, velocipede (score = 0.16082)
unicycle, monocycle (score = 0.12926)
mountain bike, all-terrain bike, off-roader (score = 0.10689)
parking meter (score = 0.01563)
[root@alarmpi imagenet]# python3.5 classify_image.py –model_dir /root/tensorflow-related/model –image_file /root/tensorflow-related/test-images/mobike.jpg
/usr/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py:1750: VisibleDeprecationWarning: converting an array with ndim > 0 to an index will result in an error in the future
  result_shape.insert(dim, 1)
W tensorflow/core/framework/op_def_util.cc:332] Op BatchNormWithGlobalNormalization is deprecated. It will cease to work in GraphDef version 9. Use tf.nn.batch_normalization().
mountain bike, all-terrain bike, off-roader (score = 0.56671)
tricycle, trike, velocipede (score = 0.12035)
bicycle-built-for-two, tandem bicycle, tandem (score = 0.08768)
lawn mower, mower (score = 0.00651)
alp (score = 0.00387)

可见,TensorFlow认为图片是山地自行车(mountain bike)/全地形自行车(all-terrain bike)/越野车(off-roader)的概率是0.56671,识别结果还算可以。
文章来源:http://www.codelast.com/
『5』计算速度问题
上面的一次图像识别试验,总共花了50多秒的时间!这么慢的速度在实际应用中基本没有实用价值。
但实际上,这个时间是可以大幅缩短的。

  • 为模型“预热”很有必要。根据作者等人的性能测试结果,在合理预热的情况下,计算时间会减少较多。我测试了一下,请看这篇文章。
  • 我们每运行一次程序,就重新加载一次模型,而模型文件又很大,这非常浪费时间,所以,应该把程序做成一个常驻内存的程序,只加载一次模型,每次识别一幅图像就能减少很多很多时间。我也实验了一下,请看这篇文章。
  • 使用TensorFlow的C++接口来实现程序应该比Python版速度快,可以尝试。
  • 暂时还不能让TensorFlow使用树莓派的GPU来计算(看这里),但大家期待未来有一天这个愿望会实现。

所以至少50多秒这种恐怖的数字是可以避免的。
文章来源:http://www.codelast.com/
『6』在树莓派上跑TensorFlow有什么用
我随意想到的一个可能比较有意义的应用就是:一个幼儿辅助学习系统。在树莓派上挂载一个摄像头,孩子在摄像头前拿着一样东西,摄像头抓拍一张图片,识别出里面的东西,朗读出概率最大的那个英文单词。
当然,这里面有非常多的工程上的问题需要解决。

我相信,随着树莓派下一代的计算能力继续增强,以及TensorFlow每一次发布,都让性能提高一些,在不久的将来,在树莓派上跑TensorFlow应用的实用性将会非常好。

使用forever运行nodejs应用 - tcrct - ITeye技术网站

mikel阅读(1045)

来源: 使用forever运行nodejs应用 – tcrct – ITeye技术网站

使用forever运行nodejs应用
何为forever

forever可以看做是一个nodejs的守护进程,能够启动,停止,重启我们的app应用。

官方的说明是说:

A simple CLI tool for ensuring that a given script runs continuously (i.e. forever).
// 一个用来持续(或者说永远)运行一个给定脚本的简单的命令行工具

Github地址:https://github.com/nodejitsu/forever
用途

forever的用途就是帮我们更好的管理我们node App服务,本质上就是在forever进程之下,创建一个node app的子进程。

比如,你有一个基于express的或者其他的一些个应用那么,它将会很方便你更新和操作你的服务,并且保证你服务能持续运行。

更好的一点就是每次更改文件,它都可以帮你自动重启服务而不需要手动重启。
安装forever

// 记得加-g,forever要求安装到全局环境下
sudo npm install forever -g

forever使用说明
启动相关

// 1. 简单的启动
forever start app.js

// 2. 指定forever信息输出文件,当然,默认它会放到~/.forever/forever.log
forever start -l forever.log app.js

// 3. 指定app.js中的日志信息和错误日志输出文件,
// -o 就是console.log输出的信息,-e 就是console.error输出的信息
forever start -o out.log -e err.log app.js

// 4. 追加日志,forever默认是不能覆盖上次的启动日志,
// 所以如果第二次启动不加-a,则会不让运行
forever start -l forever.log -a app.js

// 5. 监听当前文件夹下的所有文件改动
forever start -w app.js

文件改动监听并自动重启

// 1. 监听当前文件夹下的所有文件改动(不太建议这样)
forever start -w app.js

显示所有运行的服务

forever list

停止操作

// 1. 停止所有运行的node App
forever stopall

// 2. 停止其中一个node App
forever stop app.js
// 当然还可以这样
// forever list 找到对应的id,然后:
forever stop [id]

重启操作

重启操作跟停止操作保持一致。

// 1. 启动所有
forever restartall

更多一些

上面的一些解释足够平常使用,还有待之后继续补充。
开发和线上建议配置

// 开发环境下
NODE_ENV=development forever start -l forever.log -e err.log -a app.js
// 线上环境下
NODE_ENV=production forever start -l ~/.forever/forever.log -e ~/.forever/err.log -w -a app.js

上面加上NODE_ENV为了让app.js辨认当前是什么环境用的。不加它可能就不知道哦?
一些注意点

有可能你需要使用unix下的crontab(定时任务)

这个时候需要注意配置好环境变量。

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

后记

毋庸置疑,拥有了Github就拥有了世界。
参考

https://github.com/nodejitsu/forever
http://blog.nodejitsu.com/keep-a-nodejs-server-up-with-forever
https://github.com/nodejitsu/forever/issues/116

树莓派语音聊天机器人(基于讯飞语音和图灵机器人) - 河间老王的博客 - 博客频道 - CSDN.NET

mikel阅读(2309)

 

来源: 树莓派语音聊天机器人(基于讯飞语音和图灵机器人) – 河间老王的博客 – 博客频道 – CSDN.NET

使用方法:
终端进入/../../man_machine_interaction/bin/目录,运行source first.sh

实现过程:
通过语音识别技术将语音转换成文字,图灵机器人生成对话数据反馈回本地,语音合成技术将对话数据合成语音并播放,实现
实时人机语音交互

程序开发步骤(树梅派平台):
1:分别修改samples文件夹下三个文件夹中的32bit_make.sh文件,把x86换成RaspberryPi(如果使用first.sh文件此操作可省)
2:分别修改samples文件夹下三个文件夹中的Makefile文件,把x86和x64换成RaspberryPi
3:创建frist.sh
4:新建write_text.txt,read_text.txt,man.wav和tuling.wav四个文件,存储程序运行过程中产生的中间变量
5:新建sound_to_text.py,text_to_sound.py,turing.py和interface.py四个python文件,编写代码分别实现对应功能
6:修改tts_sample.c文件,修改生成音频名称,添加读取read_text.txt文件代码,,在c源程序139行添加自己的appid
7:修改iat_sample.c文件,添加写入write_text.txt代码,在c源程序238行添加自己的appid
8:创建iat.sh,tts.sh文件
9:编写python文件

文件功能说明:
first.sh              -> 编译samples文件夹下的源代码并生成可执行文件存放在bin文件夹下,用source执行
-> 执行完毕后在bin文件夹下会生成三个可执行文件
-> 代码内容和含义详见原文档
-> 运行python文件,启动程序
write_text.txt    -> 语音识别成文字后文本内容将储存在本文件中,本文件须在iat_sample.c文件中添加相应代码让反馈文
-> 本写入本txt文件,供turing读取
read_text.txt     -> 存储图灵反馈数据供语音合成程序读取,本文件由turing.py文件写入,存储图灵反馈文本内容,供

-> tts_sample.c读取

man.wav          -> 人说话的音频将存储在此文件中
turing.wav        -> 合成语音将存储在此文件中以供播放,本文件由tts_sample.c文件产生,修改此c文件可修改默认名称
sound_to_text.py  -> 提供声音转文字功能
text_to_sound.py  -> 提供文字转语音功能
turing.py                  -> 提供人机对话功能(图灵)
interface.py             -> 主程序及软件界面(不打算用tkiter编写界面了,有兴趣的可以自己写写)
tts.sh                       -> 用于在任何目录启动tts_sample
iat.sh                       -> 用于在任何目录启动iat_sample
again.wav              -> 我没有听清楚,有本事你在跟我说一遍  的音频
SDK文档说明        -> 讯飞SDK文件功能说明,修改c源程序可以依据此文档进行修改

注:
1:声卡在每次运行程序时会失灵,运行程序前重新拔插一下即可
2:语音识别和语音合成是科大迅飞的接口,对话部分是图灵机器人的接口

3:有什么不明白的可以QQ:1879369860联系我

4:readme.txt文件在bin目录下,先看一下

5:Linux平台SDK源代码(支持树莓派).zip为讯飞语音支持树莓派的源SDK文件,现在讯飞取消了对树莓派的支持,故必须用老版本

6:man_machine_interaction.zip为我自己编写的树莓派语音聊天机器人

7:下载地址http://download.csdn.NET/detail/lingdongtianxia/9745626

dede中的替换str_replace - IT技术宅 北方的刀郎专栏 - 博客频道 - CSDN.NET

mikel阅读(769)

 

来源: dede中的替换str_replace – IT技术宅 北方的刀郎专栏 – 博客频道 – CSDN.NET

在做英文站的时候 我们网站的当前位置 地方是主页字样 系统不能变为英文home
现在只需要在调用标签的时候修改一下仿站参数就可以了

PHP 代码复制内容到替换position
{dede:field name=’position‘ runphp=’yes’}
$b = array(“主页”);
$c = array(“home”);
@me=str_replace($b,$c,@me);
{/dede:field}

Nodejs服务器管理模块forever | 粉丝日志

mikel阅读(1161)

跨界的IT博客,核心IT技术包括:Hadoop, R, RHadoop, Nodejs, AngularJS, KVM, NoSQL, IT金融

来源: Nodejs服务器管理模块forever | 粉丝日志

Nodejs服务器管理模块forever

从零开始nodejs系列文章,将介绍如何利JavaScript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的JavaScript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/nodejs-server-forever/

nodejs-forever

目前

又说到服务器管理了,上次说的时候用的是Linux系统服务upstart, 今天准备尝试一下Nodejs自己模块化解决方案forever。

服务器管理是系统上线后,必须要面对的问题。最好有一个软件可以提供整套的服务器运行解决方案:要求运行稳定,支持高并发,启动/停止命令简单,支持热部署,宕机重启,监控界面和日志,集群环境。

接下来,就让我们看看forever能不能实现目标。

前言

  1. forever介绍
  2. forever安装
  3. forever命令行的中文解释
  4. forever服务器管理
  5. forever在Ubuntu进行服务器管理
  6. 模拟服务器宕机
  7. 开发环境和生产环境的启动配置

1. forever介绍

forever是一个简单的命令式nodejs的守护进程,能够启动,停止,重启App应用。forever完全基于命令行操作,在forever进程之下,创建node的子进程,通过monitor监控node子进程的运行情况,一旦文件更新,或者进程挂掉,forever会自动重启node服务器,确保应用正常运行。

2. forever安装

全局安装forever


~ D:\workspace\javascript>npm install -g forever
D:\toolkit\nodejs\forever -> D:\toolkit\nodejs\node_modules\forever\bin\forever
D:\toolkit\nodejs\foreverd -> D:\toolkit\nodejs\node_modules\forever\bin\foreverd

查看forever帮助


~ D:\workspace\javascript>forever -h
help: usage: forever [action] [options] SCRIPT [script-options]
help:
help: Monitors the script specified in the current process or as a daemon
help:
help: actions:
help: start Start SCRIPT as a daemon
help: stop Stop the daemon SCRIPT
help: stopall Stop all running forever scripts
help: restart Restart the daemon SCRIPT
help: restartall Restart all running forever scripts
help: list List all running forever scripts
help: config Lists all forever user configuration
help: set <key> <val> Sets the specified forever config <key>
help: clear <key> Clears the specified forever config <key>
help: logs Lists log files for all forever processes
help: logs <script|index> Tails the logs for <script|index>
help: columns add <col> Adds the specified column to the output in `forever list`
help: columns rm <col> Removed the specified column from the output in `forever list`
help: columns set <cols> Set all columns for the output in `forever list`
help: cleanlogs [CAREFUL] Deletes all historical forever log files
help:
help: options:
help: -m MAX Only run the specified script MAX times
help: -l LOGFILE Logs the forever output to LOGFILE
help: -o OUTFILE Logs stdout from child script to OUTFILE
help: -e ERRFILE Logs stderr from child script to ERRFILE
help: -p PATH Base path for all forever related files (pid files, etc.)
help: -c COMMAND COMMAND to execute (defaults to node)
help: -a, --append Append logs
help: -f, --fifo Stream logs to stdout
help: -n, --number Number of log lines to print
help: --pidFile The pid file
help: --sourceDir The source directory for which SCRIPT is relative to
help: --minUptime Minimum uptime (millis) for a script to not be considered "spinning"
help: --spinSleepTime Time to wait (millis) between launches of a spinning script.
help: --colors --no-colors will disable output coloring
help: --plain alias of --no-colors
help: -d, --debug Forces forever to log debug output
help: -v, --verbose Turns on the verbose messages from Forever
help: -s, --silent Run the child script silencing stdout and stderr
help: -w, --watch Watch for file changes
help: --watchDirectory Top-level directory to watch from
help: --watchIgnore To ignore pattern when watch is enabled (multiple option is allowed)
help: -h, --help You're staring at it
help:
help: [Long Running Process]
help: The forever process will continue to run outputting log messages to the console.
help: ex. forever -o out.log -e err.log my-script.js
help:
help: [Daemon]
help: The forever process will run as a daemon which will make the target process start
help: in the background. This is extremely useful for remote starting simple node.js scripts
help: without using nohup. It is recommended to run start with -o -l, & -e.
help: ex. forever start -l forever.log -o out.log -e err.log my-daemon.js
help: forever stop my-daemon.js
help:

通过“Commander写自己的Nodejs命令”一文的介绍,我们已经知道如何看懂,并实现自定义的命令行了。虽然,forever不是基于Commander的,而是基于另一个命令行开发包optimist,原理都是类似的。

所以,我们看到forever支持的命令和配置项确实不少,应该是偏命令行的管理工具。

3. forever命令行的中文解释

子命令actions:

  • start:启动守护进程
  • stop:停止守护进程
  • stopall:停止所有的forever进程
  • restart:重启守护进程
  • restartall:重启所有的foever进程
  • list:列表显示forever进程
  • config:列出所有的用户配置项
  • set <key> <val>: 设置用户配置项
  • clear <key>: 清楚用户配置项
  • logs: 列出所有forever进程的日志
  • logs <script|index>: 显示最新的日志
  • columns add <col>: 自定义指标到forever list
  • columns rm <col>: 删除forever list的指标
  • columns set<cols>: 设置所有的指标到forever list
  • cleanlogs: 删除所有的forever历史日志

配置参数options:

  • -m MAX: 运行指定脚本的次数
  • -l LOGFILE: 输出日志到LOGFILE
  • -o OUTFILE: 输出控制台信息到OUTFILE
  • -e ERRFILE: 输出控制台错误在ERRFILE
  • -p PATH: 根目录
  • -c COMMAND: 执行命令,默认是node
  • -a, –append: 合并日志
  • -f, –fifo: 流式日志输出
  • -n, –number: 日志打印行数
  • –pidFile: pid文件
  • –sourceDir: 源代码目录
  • –minUptime: 最小spinn更新时间(ms)
  • –spinSleepTime: 两次spin间隔时间
  • –colors: 控制台输出着色
  • –plain: –no-colors的别名,控制台输出无色
  • -d, –Debug: Debug模式
  • -v, –verbose: 打印详细输出
  • -s, –silent: 不打印日志和错误信息
  • -w, –watch: 监控文件改变
  • –watchDirectory: 监控顶级目录
  • –watchIgnore: 通过模式匹配忽略监控
  • -h, –help: 命令行帮助信息

4. forever服务器管理

创建一个web项目(express3+ejs),使用forever管理服务器。

安装express3


~ D:\workspace\javascript>express -e nodejs-forever
~ D:\workspace\javascript>cd nodejs-forever && npm install

通过forever启动应用


~ D:\workspace\javascript\nodejs-forever>forever start app.js
warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info:    Forever processing file: app.js

打开浏览器: http://localhost:3000,可以看到web界面

在win下面查看forever状态


~ D:\workspace\javascript\nodejs-forever>forever list
info:    No forever processes running

~ D:\workspace\javascript\nodejs-forever>forever stop app.js
error:   Forever cannot find process with index: app.js

我们发现forever的程序,工作不对了!!程序明明是运行状态,通过list确看不到。接下来,切换成Linux Ubuntu继续测试。

5. forever在Ubuntu进行服务器管理

Linux的系统环境

  • Linux: Ubuntu 12.04.2 64bit Server
  • Node: v0.11.2
  • Npm: 1.2.21

初始化项目:安装命令不解释了


~ cd /home/conan/nodejs
~ express -e nodejs-forever
~ cd nodejs-forever && npm install
~ sudo npm install forever -g

启动forever


~ forever start app.js
warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info:    Forever processing file: app.js

查看node服务器状态


~ forever list
info:    Forever processes running
data:        uid  command             script forever pid   logfile                       uptime
data:    [0] L2tY /usr/local/bin/node app.js 18276   18279 /home/conan/.forever/L2tY.log 0:0:0:37.792

# 系统进程
~ ps -aux|grep node
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
conan    18296  0.5  1.1 597696 23776 ?        Ssl  15:48   0:00 /usr/local/bin/node /usr/local/lib/node_modules/forever/bin/monitor app.js
conan    18299  0.4  0.8 630340 18392 ?        Sl   15:48   0:00 /usr/local/bin/node /home/conan/nodejs/nodejs-forever/app.js

# 端口占用
~ netstat -nltp|grep node
tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN      18299/node

停止服务器


~ forever stop app.js
info:    Forever stopped process:
data:        uid  command             script forever pid   logfile                       uptime
[0] L2tY /usr/local/bin/node app.js 18276   18279 /home/conan/.forever/L2tY.log 0:0:0:45.621

我们看到在Linux Ubuntu环境中是正常的。

6. 模拟服务器宕机

两种测试方案:

  • 1. 用Linux命令,直接杀死node进程
  • 2. 在应用中,模拟异常退出

1). 用Linux命令,直接杀死node进程


# 查看node进程,PID=18299  
~ ps -aux|grep node

conan    18296  0.0  1.1 597696 23776 ?        Ssl  15:48   0:00 /usr/local/bin/node /usr/local/lib/node_modules/forever/bin/monitor app.js
conan    18299  0.0  0.8 630340 18392 ?        Sl   15:48   0:00 /usr/local/bin/node /home/conan/nodejs/nodejs-forever/app.js
conan    18315  0.0  0.0  13584   956 pts/5    R+   15:52   0:00 grep --color=auto node

# 杀死PID=19299
~ kill -9 18299

# 再看node进程,node自动重启,新的PID=18324  
~ ps -aux|grep node

conan    18296  0.0  1.1 597696 23916 ?        Ssl  15:48   0:00 /usr/local/bin/node /usr/local/lib/node_modules/forever/bin/monitor app.js
conan    18316  2.6  0.8 630340 18412 ?        Sl   15:52   0:00 /usr/local/bin/node /home/conan/nodejs/nodejs-forever/app.js
conan    18324  0.0  0.0  13584   956 pts/5    R+   15:52   0:00 grep --color=auto node

我们看到看杀死node进程,forever会帮助我们,重启node。

杀死forever的monitor


~ kill -9  18296
~ ps -aux|grep node

conan    18316  0.0  0.9 630340 18644 ?        Sl   15:52   0:00 /usr/local/bin/node /home/conan/nodejs/nodejs-forever/app.js
conan    18333  0.0  0.0  13584   952 pts/5    S+   15:57   0:00 grep --color=auto node

# 再杀死node进程
~ kill -9 18316
~ ps -aux|grep node

conan    18336  0.0  0.0  13584   956 pts/5    S+   15:58   0:00 grep --color=auto node

我们尝试杀死了forever的monitor,monitor程序没有自动重启,然后再杀死node进程后,node也不会自动重启了。

2). 在应用中,模拟异常退出
修改文件:app.js


~ vi app.js

//..
http.createServer(app).listen(app.get('port'), function(){
  console.log(new Date());
  console.log('Express server listening on port ' + app.get('port'));
});

setTimeout(function(){
  console.log(new Date());
  throw new Error('App is error from inner!');
},10*1000);

通过node命令启动


~ node app.js
Thu Sep 26 2013 16:08:44 GMT+0800 (CST)
Express server listening on port 3000
Thu Sep 26 2013 16:08:54 GMT+0800 (CST)

/home/conan/nodejs/nodejs-forever/app.js:41
  throw new Error('App is error from inner!');
        ^
Error: App is error from inner!
    at null._onTimeout (/home/conan/nodejs/nodejs-forever/app.js:41:9)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

10秒后,由于内部错误, node进程挂掉了。

通过forever命令启动


~ mkdir logs
~ chmod 777 -R logs
~ forever -p . -l ./logs/access.log -e ./logs/error.log start app.js

# 检查错误日志
~ cat logs/access.log ls
Thu Sep 26 2013 16:15:02 GMT+0800 (CST)
Express server listening on port 3000
Thu Sep 26 2013 16:15:12 GMT+0800 (CST)

/home/conan/nodejs/nodejs-forever/app.js:41
  throw new Error('App is error from inner!');
        ^
Error: App is error from inner!
    at null._onTimeout (/home/conan/nodejs/nodejs-forever/app.js:41:9)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
error: Forever detected script exited with code: 8
error: Forever restarting script for 1 time
Thu Sep 26 2013 16:15:13 GMT+0800 (CST)
Express server listening on port 3000
Thu Sep 26 2013 16:15:23 GMT+0800 (CST)

/home/conan/nodejs/nodejs-forever/app.js:41
  throw new Error('App is error from inner!');
        ^
Error: App is error from inner!
    at null._onTimeout (/home/conan/nodejs/nodejs-forever/app.js:41:9)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
error: Forever detected script exited with code: 8
error: Forever restarting script for 2 time
Thu Sep 26 2013 16:15:23 GMT+0800 (CST)
Express server listening on port 3000
Thu Sep 26 2013 16:15:33 GMT+0800 (CST)

/home/conan/nodejs/nodejs-forever/app.js:41
  throw new Error('App is error from inner!');
        ^
Error: App is error from inner!
    at null._onTimeout (/home/conan/nodejs/nodejs-forever/app.js:41:9)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
error: Forever detected script exited with code: 8
error: Forever restarting script for 3 time
Thu Sep 26 2013 16:15:33 GMT+0800 (CST)
Express server listening on port 3000
Thu Sep 26 2013 16:15:43 GMT+0800 (CST)

/home/conan/nodejs/nodejs-forever/app.js:41
  throw new Error('App is error from inner!');
        ^
Error: App is error from inner!
    at null._onTimeout (/home/conan/nodejs/nodejs-forever/app.js:41:9)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
error: Forever detected script exited with code: 8
error: Forever restarting script for 4 time

我们发现每10秒种,node内部挂掉,然后再被forever重启!!

通过list我们手动刷新几次也可以看到pid是变的。


~ forever list
info:    Forever processes running
data:        uid  command             script forever pid   logfile         uptime
data:    [0] SmtT /usr/local/bin/node app.js 18444   18579 logs/access.log 0:0:0:7.211

~ forever list
info:    Forever processes running
data:        uid  command             script forever pid   logfile         uptime
data:    [0] SmtT /usr/local/bin/node app.js 18444   18579 logs/access.log 0:0:0:8.921

~ forever list
info:    Forever processes running
data:        uid  command             script forever pid   logfile         uptime
data:    [0] SmtT /usr/local/bin/node app.js 18444   18604 logs/access.log 0:0:0:0.177

~ forever list
info:    Forever processes running
data:        uid  command             script forever pid   logfile         uptime
data:    [0] SmtT /usr/local/bin/node app.js 18444   18604 logs/access.log 0:0:0:2.206

这样forever就帮助我们完成了,几项比较重要服务器管理功能:“启动/停止命令简单”,“支持热部署”,“宕机重启”,“监控界面和日志”。

比起upstart管理,省略了配置脚本的步骤(/etc/init/nodejs-xx.conf)。其他的功能,还要更近一步的使用才知道。

7. 开发环境和生产环境的启动配置

开发环境


~ cd /home/conan/nodejs/nodejs-forever/
~ forever -p . -l ./logs/access.log -e ./logs/error.log -a -w start app.js

生产环境


~ export LOG=/var/log/nodejs/project
~ export PID=/var/log/nodejs/project/forever.pid
~ export APP_PATH=/home/conan/nodejs/nodejs-forever
~ export APP=$APP_PATH/app.js

~ forever -p $APP_PATH -l $LOG/access.log -e $LOG/error.log -o $LOG/out.log -a --pidFile $PID start $APP

转载请注明出处:
http://blog.fens.me/nodejs-server-forever/

Meteor在Windows下开发环境配置 - mergerly的专栏 - 博客频道 - CSDN.NET

mikel阅读(1247)

来源: Meteor在Windows下开发环境配置 – mergerly的专栏 – 博客频道 – CSDN.NET

Meteor 1.1 版本是支持 Windows 操作系统的版本,同时还支持 MongoDB 3.0 版本。提供一个原生安装器,包括所有 Meteor SDK 关键部分,还有 Windows 特定的 Node.js 二进制和 MongoDB 数据库引擎。
此版本还集成了 Visual Studio (当前添加了更好的 JavaScript 支持),Azure 和其他 Microsoft 生态系统。
获取 Meteor:https://www.meteor.com/install。

1、通过下面的安装包下载
https://install.meteor.com/windows
然后运行即可,安装需要联网,等待一段时间后,安装完成会弹出界面要求注册。
注册完成后就自动关闭。
默认安装在C:\Users\administrator\AppData\Local\.meteor

2、在环境变量设置中,在PATH环境变量里添加Meteor的路径。
C:\Users\administrator\AppData\Local\.meteor

3、打开cmd,进入工程目录,开始测试meteor。
1)创建工程

D:\Develop\node\meteor>meteor create demo
Created a new Meteor app in ‘demo’.To run your new app:
cd demo
meteor

If you are new to Meteor, try some of the learning resources here:
https://www.meteor.com/learn

2)执行工程

D:\Develop\node\meteor\demo>meteor
[[[[[ ~\D\Develop\node\meteor\demo ]]]]]=> Started proxy.
=> Started MongoDB.
=> Started your app.

=> App running at: http://localhost:3000/
Type Control-C twice to stop.

打开 http://localhost:3000/访问到正常的页面,代表成功了