在電腦科學中,graphical model 是一個用來定義機率模型的好工具
而馬可夫鍊模型是graphical mode中常見的一個機率模型
最近看了 Mark Schmidt 所寫的 Matlab 函式庫和教學文件
覺得作者的講解很清楚
只要有基本的機率知識就能夠了解
有興趣的人可以看一看
首先推薦其中一篇說明 Markov chain model 教學文件
以 computer science 學生畢業後的出路為範例
每個人在他畢業後的60年內
每一年都會處於七種狀態之一
[業界, 唸博士, 玩電玩, 業界(有博士學位), 學界(有博士學位), 玩電玩(有博士學位), 離開電腦科學]
請問一個人在畢業後的第n年處於某一個狀態的機率是多少?
以下是我個人的心得
Markov chain 模型中所要描述的為一組隨機變數的機率
令這些隨機變數為 `X=X_1,X_2,...,X_N`
這些隨機變數的 joint probability 可以用一個機率函數 表示
`p(x)=p(x_1)p(x_2|x_1)p(x_3|x_2)...p(x_N|x_{N-1})`
而這個函式可以用更一般化的形式來表示
`p(x)=\frac{1}{Z}f_1(x_1,x_2)f_2(x_2,x_3)...f_{N-1}(x_{N-1},x_N)` (1)
由於加上了常數 Z , 此處的 f 不再限定是機率函數
以上的形式表現出Markov chain的性質:
由於每個隨機變數只和他相鄰的隨機變數相關
所以機率函式可以被分解為多個函數相乘
對於 `p(x)` 我們通常會感興趣的是某一個隨機變數處於某個狀態的機率
比如說 `x_2`=業界 (狀態為1)
以機率的術語來說就是 marginal probability
由於我們只考慮 `x_2` 的狀態
因此要把其他的變數的所有可能性都加總起來
`p(x_2=1)=\sum_{x_1,x_3,x_4,...)\frac{1}{Z}f_1(x_1,x_2)f_2(x_2,x_3)...f_{N-1}(x_{N-1},x_N)`
乍看之下其餘 N-1 個變數有 `2^{N-1}` 種可能
所以要計算這個總和需要非常大量的計算
但實際上卻是很容易計算的
關鍵就在於
分配律
先看一個簡單的例子
`a_1b_1+a_1b_2+a_2b_1+a_2b_2=(a_1+a_2)(b_1+b_2)`
左邊:先乘後加 -- 需要四個乘法和三個加法
右邊:先加後乘 -- 需要一個乘法和兩個加法
可以看出先加後乘在計算上比較有效率
是當變數增加的時候更為明顯
再回頭看(1)
可以發現是很相似的情況
先做 N-2 個乘法再加起來
除了一點不同:函數 f_i 牽涉到兩個變數
並無法把 `\sum_{x_1,\cdots \x_N}` 拆開
不過 當任何一個變數的值被限定時
就可以拆解開來
以上面的例子來說
令 `x2=1`
則我們可以把乘積分成兩段
`p(x_2=1)=\frac{1}{Z} [\sum_{x_1}f_1(x_1,x_2=1)][\sum_{x_3,...x_N}f_2(x_2=1,x_3)...f_{N-1}(x_{N-1},x_N)]`
到此已經解開最困難的關鍵
我們只需要分別計算以下兩個數字即可
`\sum_{x_1}f_1(x_1,x_2=1)` (3)
`\sum_{x_3,...x_N}f_2(x_2=1,x_3)...f_{N-1}(x_{N-1},x_N)` (4)
其中用來計算(3)的方法便稱之為 forward algorithm 為一種動態規劃的技巧 (dynamic programming)
forward algorithm
現在來計算 (3)
令 `Z_{i,j}` 為 `\sum_{x_1,...\x_{i-1}}f_1(x_1,x_2)f_2(x_2,x_3)...f_{i-1}(x_{i-1},x_i=j)` (3)
如此可以利用遞回的定義來計算
`Z_{i,j}=\sum_k Z_{i-1,k}f_i(k,j)`
`Z_{0,j}` 為常數 需要先定義好
有了`Z_{i,j}`之後
要計算 `p(x_i)` 便很容易
`p(x_i=j) = \frac{Z_{i,j}}{\sum_k Z_{i,k}}`
實務技巧
`Z_{i,j}`的值可能會非常大或非常小 此時難以用一般的變數來表示
比如說浮點述的精確度可能會不足
解決的方法在於加上兩個輔助的變數 `\kappa_i`, `a_{i,j}`
令 `Z_{i,j} = a_{i,j}\prod_{k=1}^i \kappa_k`
`\kappa_i` 的設定方式為使得 `\sum_k a_{i,k}=1`
如此一來 `a_{i,j}` 的範圍必定在 1 以內
此外計算 `p(x_i)` 時 `\kappa_i` 的值可以省去:
`p(x_i=j) = \frac{Z_{i,j}}{\sum_k Z_{i,k}}`
`p(x_i=j) = \frac{a_{i,j}\prod_{k=1}^i \kappa_k}{\sum_k a_{i,k}\prod_{k=1}^i \kappa_k}`
`p(x_i=j) = \frac{a_{i,j}}{\sum_k a_{i,k}}`
backward algorithm
和 forward algorithm 相似 差別只在於是從右邊算過來
在此就不贅述
經過以上的說明 有興趣的人可以看 Mark Schmidt 所寫的 Matlab 函式庫和教學文件
有完整的程式 可以實際動手玩玩看
Showing posts with label 程式設計. Show all posts
Showing posts with label 程式設計. Show all posts
Friday, May 7, 2010
Thursday, December 24, 2009
找出文章中的所有引用
最近在用 Word 寫計畫報告,我在引用參考資料時,是使用 [xx] 這種格式。[xx] 是個交互參照,用來連到文章的引用列表。到目前為止一切順利,不過後來發現引用列表中有不少項目是沒有被引用到的,為了節省空間要,要找出沒有被引用的的項目把他們刪除。
但是自己用眼睛看過30頁的文章實在太累,所以寫了一個 Python script 來幫我找出有用到的參考並加以排序。程式如下:
但是自己用眼睛看過30頁的文章實在太累,所以寫了一個 Python script 來幫我找出有用到的參考並加以排序。程式如下:
import re
refdict = {}
fin = open('doc.txt')
for line in fin:
refs = re.findall('\[\d+\]', line)
for ref in refs:
num = int(ref[1:-1])
refdict[num] = 1
used_ref = refdict.keys()
used_ref.sort()
print used_ref
Python 下用來處理 bibtex 的函式庫 -- pybtex
最近在寫報告的時候,需要和同事整合各自的參考 bibliography),我本身是採用 JabRef 來做書目管理, JabRef 使用的格式為 bibtex。為了檢查大家的參考書目書目有沒有重複,尋找了一下python 的函式庫,找到以下兩套:
1. python-bibtex
2. pybtex
python-bibtex 是書目管理工具,類似 JabRef,不過需要在 Linux 環境才能運作,所以就放棄了。
pybtex 是用來取代 latex 中的 bibtex 軟體,基本上功能和 bibtex 相同。好消息是 pybtex 有提供方便的函式可以直接剖析 bib 檔,用法大致如下:
1. python-bibtex
2. pybtex
python-bibtex 是書目管理工具,類似 JabRef,不過需要在 Linux 環境才能運作,所以就放棄了。
pybtex 是用來取代 latex 中的 bibtex 軟體,基本上功能和 bibtex 相同。好消息是 pybtex 有提供方便的函式可以直接剖析 bib 檔,用法大致如下:
from pybtex.database.input import bibtex有了 bibtex 這個工具之後,剩下來就只是比較 title 等簡單的工作了。
parser = bibtex.Parser(encoding="UTF-8")
bib_data = parser.parse_file('foo.bib')
print bib_data.entries.keys()
for k in bib_data.entries.keys():
print bib_data.entries[k].fields['title']
Saturday, December 12, 2009
語音合成 (一)
上個月的時候,朋友E先生發想做中文的語音合成。
經過搜尋,我們發現目前以工研院的引擎的效果最好 (這邊有線上demo)
不過還是感覺不夠完美,同時也沒有可以調整的參數,
我們的理想是能做出語調和感情的調整。
動手之前我們先做了一番研究,一份較易懂的參考資料如[1]
語音合成牽涉的範圍很廣,大致可以分成兩個部分:
1. 自然語言處理 (Natural Language Processing): 讀取文字,分析出每個字的唸法
2. 數位訊號處理 (Digital Signal Processing): 把獨立的字的發音組合成一個句子
我們決定從第二部分下手,
因為第一部分可以先由人來給訂,而且也無關乎發音是否悅耳
而數位訊號處理技術很多,大致上可以分為兩派
第一派被稱之為 synthesis-by-rule,主要由語音學家發展出來。
第二派被稱之為 synthesis-by-concatenation,和前者的差異為,只採用少量的語言學知識,將語音視為聲音的片段,利用技巧來把片段整合起來。
由於不是語音學的專家,我們決定從第二種方法開始。
首先要有語音資料,目前找到能使用的是 gcin 的語音檔 (ogg格式)
http://ftp.twaren.net/local-distfiles/gcin/ogg.tgz
這個檔案包含約一千個字的發音,對應到國語的所有單字 (包含五種聲調)
原本每一個發音檔是放在各自的目錄下,同時目錄的名稱是中文,所以並不好處理,我先用Python script把檔案轉換成漢語拼音,放在同一個目錄下面。
接著為了由於ogg格式比較少有函式庫可以處理,為了方便起見,我先用 Wav2Mp3 這個軟體把 ogg 轉成 wav 格式。
[1] Thierry DUTOIT, "High-quality text-to-speech synthesis: an overview"
(未完待續)
經過搜尋,我們發現目前以工研院的引擎的效果最好 (這邊有線上demo)
不過還是感覺不夠完美,同時也沒有可以調整的參數,
我們的理想是能做出語調和感情的調整。
動手之前我們先做了一番研究,一份較易懂的參考資料如[1]
語音合成牽涉的範圍很廣,大致可以分成兩個部分:
1. 自然語言處理 (Natural Language Processing): 讀取文字,分析出每個字的唸法
2. 數位訊號處理 (Digital Signal Processing): 把獨立的字的發音組合成一個句子
我們決定從第二部分下手,
因為第一部分可以先由人來給訂,而且也無關乎發音是否悅耳
而數位訊號處理技術很多,大致上可以分為兩派
第一派被稱之為 synthesis-by-rule,主要由語音學家發展出來。
第二派被稱之為 synthesis-by-concatenation,和前者的差異為,只採用少量的語言學知識,將語音視為聲音的片段,利用技巧來把片段整合起來。
由於不是語音學的專家,我們決定從第二種方法開始。
首先要有語音資料,目前找到能使用的是 gcin 的語音檔 (ogg格式)
http://ftp.twaren.net/local-distfiles/gcin/ogg.tgz
這個檔案包含約一千個字的發音,對應到國語的所有單字 (包含五種聲調)
原本每一個發音檔是放在各自的目錄下,同時目錄的名稱是中文,所以並不好處理,我先用Python script把檔案轉換成漢語拼音,放在同一個目錄下面。
接著為了由於ogg格式比較少有函式庫可以處理,為了方便起見,我先用 Wav2Mp3 這個軟體把 ogg 轉成 wav 格式。
[1] Thierry DUTOIT, "High-quality text-to-speech synthesis: an overview"
(未完待續)
Friday, November 20, 2009
Blocks -- 電腦視覺研究上的MATLAB framework
前陣子在讀ICCV的paper時,有兩位作者引起我很大的興趣,原因不在於論文的好壞,而是他們把自己做實驗時的研究方法公開在網頁上。
為什麼說這是一件重要的事情呢? 這要先岔題一下:
在電腦視覺的領域,一篇好的研究,除了理論完整、實驗漂亮之外,能否讓其他人重複得到該作者的實驗結果也是非常重要的。
目前在這個領域,已經有公用的測試資料庫供大家使用。想像一下,說假設我提出一套方法,可以找出照片中的行人,要評估我的方法好壞,可以用一組前人已經做過實驗的照片,用他們的結果來比較。而這樣的比較結果,自然是放在我的論文之中。不過問題來了,當有人質疑我的實驗結果時,他們必須用想辦法重現我的實驗結果,不過這是一件很困難的事情。
困難的理由在於,首先你要把我的方法寫成程式,這是一件很花功夫的事,然而當你寫好程式之後還有一個難關,在電腦視覺這個領域中 (電腦科學的很多領域也是),
一個演算法之中會有很多參數,而參數的設定不同就會造成實驗結果的差異
類比一下,好比說我給你一份食譜,裡面說要加牛肉幾兩、油、鹽、糖幾匙等等
如果我今天漏掉了其中一樣東西的分量,那你就只能自己嘗試,找出最好的分量,
不然味道就會差一點
令人驚訝的是,論文中就是會把很多參數給漏掉
這其實也不能責怪作者,當你的系統大到一個程度時,你自然不可能巨細靡遺的把每個參數寫在論文上面,尤其是當這些參數是跟你的演算法無關的部分。
面對這種情況,
許多論文作者並不會主動提供這些資訊,比如說放在個人網頁上面等等
有時候當你寫信去問時,得到的回覆可能是"抱歉,我的程式不知道放在哪個硬碟了"
這通常不是作者敷衍你,而是一個常見的情形,因為研究題目可能兩三年就會有變動,之前寫的程式往往不能再用(啊哈!你想到軟體的重複利用,但是研究人員不一定具有好的軟體工程能力)
比較好心的作者會把他的程式碼公開,讓其他的研究者可以輕鬆的重複實驗,
這樣子通常可以獲得回報:會提高其他研究者引用他的論文的意願,
而論文的被引用次數,是一個研究者最直接也是最重要的指標(甚至比發表的論文數目還重要)
回到一開始,Brian Fulkerson 和 Andrea Vedaldi 這兩位研究員,他們不只公開程式碼,同時也整理了整個實驗的架構,告訴你可以修改那些地方,讓你能在他們的基礎上來改進這個系統。這才真正的站在巨人的肩膀上! (當然這是指在學術界啦,在業界的話這可是公司賴以生存的寶物,怎能輕易公開!)
(未完待續)
為什麼說這是一件重要的事情呢? 這要先岔題一下:
在電腦視覺的領域,一篇好的研究,除了理論完整、實驗漂亮之外,能否讓其他人重複得到該作者的實驗結果也是非常重要的。
目前在這個領域,已經有公用的測試資料庫供大家使用。想像一下,說假設我提出一套方法,可以找出照片中的行人,要評估我的方法好壞,可以用一組前人已經做過實驗的照片,用他們的結果來比較。而這樣的比較結果,自然是放在我的論文之中。不過問題來了,當有人質疑我的實驗結果時,他們必須用想辦法重現我的實驗結果,不過這是一件很困難的事情。
困難的理由在於,首先你要把我的方法寫成程式,這是一件很花功夫的事,然而當你寫好程式之後還有一個難關,在電腦視覺這個領域中 (電腦科學的很多領域也是),
一個演算法之中會有很多參數,而參數的設定不同就會造成實驗結果的差異
類比一下,好比說我給你一份食譜,裡面說要加牛肉幾兩、油、鹽、糖幾匙等等
如果我今天漏掉了其中一樣東西的分量,那你就只能自己嘗試,找出最好的分量,
不然味道就會差一點
令人驚訝的是,論文中就是會把很多參數給漏掉
這其實也不能責怪作者,當你的系統大到一個程度時,你自然不可能巨細靡遺的把每個參數寫在論文上面,尤其是當這些參數是跟你的演算法無關的部分。
面對這種情況,
許多論文作者並不會主動提供這些資訊,比如說放在個人網頁上面等等
有時候當你寫信去問時,得到的回覆可能是"抱歉,我的程式不知道放在哪個硬碟了"
這通常不是作者敷衍你,而是一個常見的情形,因為研究題目可能兩三年就會有變動,之前寫的程式往往不能再用(啊哈!你想到軟體的重複利用,但是研究人員不一定具有好的軟體工程能力)
比較好心的作者會把他的程式碼公開,讓其他的研究者可以輕鬆的重複實驗,
這樣子通常可以獲得回報:會提高其他研究者引用他的論文的意願,
而論文的被引用次數,是一個研究者最直接也是最重要的指標(甚至比發表的論文數目還重要)
回到一開始,Brian Fulkerson 和 Andrea Vedaldi 這兩位研究員,他們不只公開程式碼,同時也整理了整個實驗的架構,告訴你可以修改那些地方,讓你能在他們的基礎上來改進這個系統。這才真正的站在巨人的肩膀上! (當然這是指在學術界啦,在業界的話這可是公司賴以生存的寶物,怎能輕易公開!)
(未完待續)
Subscribe to:
Posts (Atom)