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

mikel阅读(1995)

来源: [原创] 加快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阅读(3252)

来源: [原创] 在树莓派上把文字转成语音(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阅读(2301)

来源: [原创] 加快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阅读(2208)

在树莓派上用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阅读(1089)

来源: 使用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阅读(2370)

 

来源: 树莓派语音聊天机器人(基于讯飞语音和图灵机器人) – 河间老王的博客 – 博客频道 – 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阅读(777)

 

来源: 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阅读(1187)

跨界的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阅读(1265)

来源: 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/访问到正常的页面,代表成功了

pycharm 2016 注册码_360知识管理

mikel阅读(1078)

pycharm 2016 注册码

来源: pycharm 2016 注册码_360知识管理

pycharm 2016 注册码(2017.2.19更新)

BIG3CLIK6F-eyJsaWNlbnNlSWQiOiJCSUczQ0xJSzZGIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IkZvciBlZHVjYXRpb25hbCB1c2Ugb25seSIsImNoZWNrQ29uY3VycmVudFVzZSI6ZmFsc2UsInByb2R1Y3RzIjpbeyJjb2RlIjoiQUMiLCJwYWlkVXBUbyI6IjIwMTctMTEtMjMifSx7ImNvZGUiOiJETSIsInBhaWRVcFRvIjoiMjAxNy0xMS0yMyJ9LHsiY29kZSI6IklJIiwicGFpZFVwVG8iOiIyMDE3LTExLTIzIn0seyJjb2RlIjoiUlMwIiwicGFpZFVwVG8iOiIyMDE3LTExLTIzIn0seyJjb2RlIjoiV1MiLCJwYWlkVXBUbyI6IjIwMTctMTEtMjMifSx7ImNvZGUiOiJEUE4iLCJwYWlkVXBUbyI6IjIwMTctMTEtMjMifSx7ImNvZGUiOiJSQyIsInBhaWRVcFRvIjoiMjAxNy0xMS0yMyJ9LHsiY29kZSI6IlBTIiwicGFpZFVwVG8iOiIyMDE3LTExLTIzIn0seyJjb2RlIjoiREMiLCJwYWlkVXBUbyI6IjIwMTctMTEtMjMifSx7ImNvZGUiOiJEQiIsInBhaWRVcFRvIjoiMjAxNy0xMS0yMyJ9LHsiY29kZSI6IlJNIiwicGFpZFVwVG8iOiIyMDE3LTExLTIzIn0seyJjb2RlIjoiUEMiLCJwYWlkVXBUbyI6IjIwMTctMTEtMjMifSx7ImNvZGUiOiJDTCIsInBhaWRVcFRvIjoiMjAxNy0xMS0yMyJ9XSwiaGFzaCI6IjQ3NzU1MTcvMCIsImdyYWNlUGVyaW9kRGF5cyI6MCwiYXV0b1Byb2xvbmdhdGVkIjpmYWxzZSwiaXNBdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlfQ==-iygsIMXTVeSyYkUxAqpHmymrgwN5InkOfeRhhPIPa88FO9FRuZosIBTY18tflChACznk3qferT7iMGKm7pumDTR4FbVVlK/3n1ER0eMKu2NcaXb7m10xT6kLW1Xb3LtuZEnuis5pYuEwT1zR7GskeNWdYZ0dAJpNDLFrqPyAPo5s1KLDHKpw+VfVd4uf7RMjOIzuJhAAYAG+amyivQt61I9aYiwpHQvUphvTwi0X0qL/oDJHAQbIv4Qwscyo4aYZJBKutYioZH9rgOP6Yw/sCltpoPWlJtDOcw/iEWYiCVG1pH9AWjCYXZ9AbbEBOWV71IQr5VWrsqFZ7cg7hLEJ3A==-MIIEPjCCAiagAwIBAgIBBTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE1MTEwMjA4MjE0OFoXDTE4MTEwMTA4MjE0OFowETEPMA0GA1UEAwwGcHJvZDN5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQC9WZuYgQedSuOc5TOUSrRigMw4/+wuC5EtZBfvdl4HT/8vzMW/oUlIP4YCvA0XKyBaCJ2iX+ZCDKoPfiYXiaSiH+HxAPV6J79vvouxKrWg2XV6ShFtPLP+0gPdGq3x9R3+kJbmAm8w+FOdlWqAfJrLvpzMGNeDU14YGXiZ9bVzmIQbwrBA+c/F4tlK/DV07dsNExihqFoibnqDiVNTGombaU2dDup2gwKdL81ua8EIcGNExHe82kjF4zwfadHk3bQVvbfdAwxcDy4xBjs3L4raPLU3yenSzr/OEur1+jfOxnQSmEcMXKXgrAQ9U55gwjcOFKrgOxEdek/Sk1VfOjvS+nuM4eyEruFMfaZHzoQiuw4IqgGc45ohFH0UUyjYcuFxxDSU9lMCv8qdHKm+wnPRb0l9l5vXsCBDuhAGYD6ss+Ga+aDY6f/qXZuUCEUOH3QUNbbCUlviSz6+GiRnt1kA9N2Qachl+2yBfaqUqr8h7Z2gsx5LcIf5kYNsqJ0GavXTVyWh7PYiKX4bs354ZQLUwwa/cG++2+wNWP+HtBhVxMRNTdVhSm38AknZlD+PTAsWGu9GyLmhti2EnVwGybSD2Dxmhxk3IPCkhKAK+pl0eWYGZWG3tJ9mZ7SowcXLWDFAk0lRJnKGFMTggrWjV8GYpw5bq23VmIqqDLgkNzuoog==