< 更新 更早 >

近来的技术兴趣(上)

在这世上,那些最为自己的事情,你只能自己动手。别人的推导和模拟无法替你建立到物理世界的桥梁,别人写的程序与你的需求总是有所偏差,别人设计的博客主题与你的审美总有些许不同,别人的文字无法表达你的真实感受。如果你可以,就不应该依赖别人从而差强人意地生活。

这就是我学习和倒腾许多东西的动力,一如我技术博客的签名:“对用语句构建世界的迷恋,以及对世界背后的话语的追索”。前半句的外延里,物理公式、程序代码、线条与色彩、文字乃至我所不掌握的音乐,都是构建世界的语句,是它们使我感觉到自己对这个世界的能动性。后半句是说,生活在一个自己可以设法理解的世界对于我而言是多么重要,虽然我或许没有能力为其它的人类贡献认知,但我如此享受以认真的态度消化和重新整合前人的认知的过程。

这是我在上篇博客《用Middleman搭建静态博客》里写的话。

庄子说:

吾生也有涯,而知也无涯。以有涯随无涯,殆己。

这基本上是对我这种强烈的认知和动手的愿望的一种反讽。我的生活、我的青春、我的时间、我的精力,仿佛就这样被我过于广泛的兴趣吞噬;而我这些广泛的兴趣却又仿佛被我的拖延症无限地稀释,时间里留下的尽是敝帚自珍的半成品碎片。

这篇博客是为了梳理我这段时间发散出来的技术兴趣点,做一个TODO List式的东西,避免这些曾经的兴趣和进展,变成许久以后翻找出来的一声叹息。

下面的每一项兴趣点,都包含初衷、进展(含技术选型)这几部分。

PDF文件重排

初衷

我有一个三星Galaxy S3的手机,它是我上下班时的伴侣。但它的屏幕没有iPad那么大,所以它没法舒适地阅读没为小屏幕移动设备重排过的PDF,尤其是不仅仅包含文字,还包含数学公式和图表,甚至是多栏的PDF。

所以我希望做一个能把PDF转成Responsive的Web页面的东西。

进展

语言:ruby, html5/css3/js

首先看一下有没有现成的产品或库。试用了JavaScript写的PDF.JS,它不能很好地进行屏幕适配,也不能很好地渲染数学公式。

那么就需要能够解析PDF文件格式的库。

发现了ruby的库pdf-reader。用它成功读取了PDF文件的文本内容和每个文本的位置,从而用position:absolute的CSS把PDF渲染成HTML。一开始是渲染单页,然后推广到多页的PDF。

纯粹的图片我还没有实验,但看起来并不困难。

库里自带一种根据位置相对关系把单个的字符合并成文本块的算法,十分有用,提升了渲染效果。可以根据这个思路,对数学公式进行合并,避免发生公式被重排拆散的问题。有了文本块,可以根据文本块的相对关系来计算文本块相互之间的优先级,也可以把单个的文本块进行换行等,从而实现重排。

遇到的问题有:

  1. 这个库大包大揽解决了PDF特有的编码问题,也导致它对中文PDF支持一塌糊涂;
  2. 这个库虽然支持读PDF内嵌的TTF字体,使得我可以用HTML5的WebFonts来解决字体渲染的问题,但不支持Adobe Type 1 Font Format(这是一种可以用PostScript的子集和一些预定义的PS子程序来描述字体glyph的字体格式,以下简称Type 1),见我提交的这个Issue,而很多含数学公式的PDF经常内嵌这种字体,用来绘制数学符号甚至图表,使得这种支持变得必须。

我按照Type 1的spec和别人写的一个指引,尝试自己解析这种字体,取得了一些进展,但在二层解密处以和spec完全一致的算法无法解出相应的ps语句。

然后我想起了FreeType,它可以支持Type 1的解析,我只需要用它的ruby-binding或者直接采用ffi的方式来读取Type 1的字体,把它转成TTF或者渲染成图片就可以解决这个问题。渲染成图片已经实现,但是转成其它字体格式却并不可行,因为FreeType的设计目标是渲染字体,并不是要做一个全能的字体操纵和转换的库,这方面需要另想办法。

最近看到了一个C++把含多栏和数学公式的PDF较好地转成HTML的项目pdf2htmlEX。缺点是这个项目并没有在html中保留可用来做重排的语义信息(如分栏、公式位置)。

最近从图书馆借了一本书《Visual C++数字图像模式识别典型案例详解》,这本书以很大的篇幅详尽介绍了如何把扫描版的含多栏和数学公式的PDF,利用数字图像模式识别技术,转成文字版的PDF,里面包括inline和非inline的数学公式的提取、单个数学符号的提取与识别,有很多很有启发的思想。

借助文件完成的Socket转发(aka file-to-datapipe)

初衷

假设有两台PC,它们之间网络无法互通,但它们都能访问到某个文件服务器,而且可读可写,那么显然,它们之间可以交换数据。但是有很多场合是需要它们之间进行socket通讯的,比如远程桌面,再比如PC A能访问PC B不能访问的网络环境,需要代理或者转发。

进展

语言:ruby

socket相关操作采用EventMachine,文件变动侦听采用wdm,因为它在Windows下能利用ReadDirectoryChangesW这个支持侦听网络映射磁盘文件变动的API。

详细的方案已设计,但未开始编码。

RTX插件

初衷

在现实工作中需要批量导出RTX聊天记录,以供更高效地查找过往会话。

进展

语言:ruby, C++11

通过API Monitor追踪RTX对DLL的调用,研究出RTX读取本地聊天记录文件(加密的SQLite)的方式。已用ruby通过ffi调用同样的DLL,完成RTX聊天记录的批量导出,支持绘画中的文本、文本+图片、文本环绕图片、文件,支持伴随导出的html迁移图片,暂不支持迁移文件(但这个很容易添加)。

过程中发现VOLE - A Neat C++ COM/Automation Driver这个由我很推崇的《Extened STL》一书的作者写的调用COM的C++库,配合上也由他写的STLSoft - Robust, Lightweight, Cross-platform, Template Software中的dl_open,可以用C++高效简洁地完成同样的事情,而且可以方便地写RTX的插件。RTX的插件体系依赖VC6,VOLE对C++11不友好,这两个点虽然不造成实际编码的困难,但让对业务写的代码有审美洁癖的我很难受。

高性能异步业务逻辑服务

初衷

工作中存在这样的场景,实际运行中需要等待的IO(比如对外部系统的网络调用)很多,但同时业务逻辑又很重,比如需要多次调用外部系统,之间还有逻辑依赖。这种情况下如果需要承载大的业务量,不应每个请求都开一个线程在那里等IO,而应采用异步的思路,IO回来了,才占用线程。

但是异步的方式来写程序,思路是断开的。这个项目的目标正是希望能够以同步的方式写业务逻辑,但以异步方式执行。具体的实现思路可见asynchronous javascript,里面介绍了用deferred和promises进行异步编程的范式,这样可以做到代码写起来是同步的(思维顺着走,不用绕回调),跑起来是异步的(性能);而且某一步抛出异常,能够在最后统一处理。

进展

语言:Java, C++1

未开始编码,初步设想异步IO部分可采用Netty ,业务逻辑部分自然是新写。

基于NLP和MLN的AI对话系统

初衷

乔布斯去世前推出了Siri,但是Siri试用下来纯粹是模式匹配,毫无记忆和状态,而且过度依赖云端。以前也学过一些AI的我觉得时至今日,科技不应该只有这点实用水平。于是找了很多相关的资料来学习,然后发现这里面水很深,难怪实用性的APP仅采用了模式匹配的方式来做。但我始终觉得,具备一定对记忆和自学能力的AI对话系统是可行的,是一个可以追求、可以触达的目标。

这背后我有很多具体的想法,但在实现前先不再这里展开了。这里仅仅记下找到的一些开源库和资料。

语音识别方面

CMU Sphinx: Open Source Toolkit For Speech Recognition

Julius: Open-Source Large Vocabulary CSR Engine

SHoUT: Large vocabulary continuous speech recognition

VoxForge: Open-source acoustic models

LibriVox: Free audiobooks

Synthesis APIs In Windows Vista

自然语言处理方面

分词方面

分词库

全文搜索框架

词库

微博应用

算法

R语言、KNIME与宋词那些事

未整理的链接

机器学习算法方面

已有的算法有:

  1. Parallel Logistic Regression
  2. Bagging Logistic Regression
  3. Random Decision Tree/forest
  4. [Regular singular value decomposition]
    (http://en.wikipedia.org/wiki/Singular_value_decomposition)
  5. Gradient boosting decision tree

带概率的逻辑方面(主要是Markov Logic Network)

书籍

  • 《Clever Algorithms: Nature-Inspired Programming Recipes》
  • 《Information Theory, Inference and Learning Algorithms》
  • 《Machine Learning: A Probabilistic Perspective》
  • 《Speech and Language Processing: an Introducation to Natural Language Processing, Computational L inguistics, and Speech Recognition》
  • 《统计自然语言处理基础》
  • 《数据挖掘中的新方法:支持向量机》
  • 《集体智慧编程》与《智能Web算法》其一
  • 《人工智能:一种现代方法》
  • 《游戏开发中的人工智能》
  • 《小型智能机器人制作全攻略》

未完待续,继续写(下)

宋皿

Published under (CC) BY-NC-ND tagged with 自学记录