2018年2月8日 星期四

謹此感謝FakeApp對AI科技的付出

鬧上新聞的FakeApp被Reddit封鎖了。這感覺令人不悅。就像P2P事件一樣,一個好的工具因為影響了某些人的利益而被打壓。尊重彼此的利益是一種君子之爭。很顯然的,有一方人很不君子。

為了表達在下對FakeApp的支持。底下是我的使用手冊。軟體的部份因為主站被封鎖了。不過我相信一定會在哪裡重生。就請各位自己去找吧。


0. 準備程式
   下載FakeApp
   下載CUDA 8.0 (NVIDIA官網有),然後安裝。注意安裝後,其/bin要在%path%裡
   下載ffmpeg
1. 準備來源影片。在此稱...
   目標影片:
     - 人相會貼過來的影片
     - 感覺作者認為目標影片又分用來學習的和用來做成結果的
     - 我的實驗使用同一個
     - 作者稱Porn Video
   參考影片:
     - 人相的來源影片
     - 也可以是圖片
     - 目的是把這個畫面貼到目標影片去
     - 作者稱Celebrity Video
2. 將兩造影片切成數個frame(比如用ffmpeg),並做為不同的set
   指令:ffmpeg -i <.mp4> fps= ""
       - e.g. ffmpeg.exe -i y.mp4 -vf fps=23 "out%d.png"
   如果是參考圖檔,當然就不用切
   這兩種set作者稱Porn set與Celebrity set
     - 作者默認Porn set為A set;Celebrity set為B set
3. 將人相從frame取出(extract)
   執行FakeApp.bat以啟動GUI,到Extract頁,然後path指向各個set,然後按start
     - 兩個set都要做一次
   可以把沒有人相或人相不清楚的frame刪掉以節省時間。
     - 因為會刪掉部份的東西,最好把set再copy出來一份專門做Extract
   做完後會產生aligned目錄與alignments.json檔
4. 從兩個alignment中做學習(train),這個很花時間(hours, days...)
   執行FakeApp.bat以啟動GUI,到Train頁,然後指定目錄給算出來的模型(model)以及各個來源set的aligned,然後按start
   start後,FakeApp會開始學習。它會跳出一個Training Preview畫面顯示學習的結果
     - 當你覺得學得夠好了以後,於focus那個視窗時按下q離開
     - 你可以先離開以暫停,然後用同樣的設定再繼續算模型
   根據作者的說法,預設data A是參考影片的臉,data B是目標影片的臉,不過在大量學習後沒有差別
     - 不過記住在merge時,注意data A是參考影片,data B是目標影片 (AtoB)
   在model的路徑下會產生train好的檔案
   作者說,如果你的電腦慢的話,可以試著接上Google Cloud AI
5. 轉換目標影片
   將train好的檔案,如config.p、decoder...與encoder,copy到FakeApp/models的目錄下
   指定好model、目標影片frame的位置後按start
   完成後會放在merged目錄裡
6. 將merged目錄裡的frame結合成影片檔(比如用ffmpeg)
   指令:ffmpeg -r [INSERT FRAME RATE] -s [DIMENSIONS OF IMAGEs (i.e. 1280x720)] -pattern_type glob -i '*.png' -vcodec libx264 -crf 24 -pix_fmt yuv420p [OUTPUTFILENAME].mp4
     - 上面的指令無法在Windows執行,因為glob的檔案選擇法並不被Windows支援
     - 底下是一種Windows的解決方式
         1.將.png檔做成Windows支援的順序。在Windows,out120.png在out13.png之前。應將out13.png改為out013.png以修正順序。
           1.1.可以用dir > temp.txt的方式把檔案清單放到temp.txt,然後用類似Notepad++的編輯軟體做區塊的編輯,把所有要調整的檔案編輯成類似...
           1.2.ren
           1.3.然後把temp.txt改名為temp.bat,然後執行該.bat檔
         2.ffmpeg指令改用wildcard,如...
           ffmpeg -r [INSERT FRAME RATE] -s [DIMENSIONS OF IMAGEs (i.e. 1280x720)] -i out%04d.png -vcodec libx264 -crf 24 -pix_fmt yuv420p [OUTPUTFILENAME].mp4
           - e.g.ffmpeg.exe -r 30 -s 1920x1080 -start_number 1 -i out%04d.png -vcodec libx264 -crf 24 -pix_fmt yuv420p merged0126.mp4
           - 上面的e.g.有一個問題,就是,你的index不是1開始的話,或是中間有斷號,它就做不下去了...必須把index做好做滿
           - https://stackoverflow.com/questions/31201164/ffmpeg-error-pattern-type-glob-was-selected-but-globbing-is-not-support-ed-by


=============

ffmpeg在merge時遇到的問題,你也可以使用我寫的這個python來解決:

###########################################################
##
## This program uses to arrange file names
##
###########################################################

import sys

if len(sys.argv) !=3:
    print('wrong size of inputed arguments...; size: '+str(len(sys.argv)))
    print('usage: ')
    exit()

prefix = sys.argv[1]
subffix = sys.argv[2]

from pathlib import Path
path = Path('.');

print('looking for files in '+str(path.cwd())+' start with '+prefix+' and end with '+subffix)

listOfPath = list(path.glob(prefix+'*'+subffix))

print('number of found files with inputed condition: '+str(len(listOfPath)))

#########
# stage 1 take the same length of index number string
print('STAGE 1 MAKE THE SAME LENGTH OF INDEX NUMBER STRING')
# get max number for determine required zero
max = 0
for itemInPath in listOfPath:
    if itemInPath.is_file() == False:
        continue
       
    tmp = str(itemInPath)
    tmplen = len(tmp)
    tmp2 = tmp[len(prefix):(tmplen-len(subffix))]
    try:
        tmpnum = int(tmp2)
    except ValueError:
        print('invalid index number: '+tmp2)
        exit()
   
    if tmpnum > max:
        max = tmpnum
       
idxLen = len(str(max))
print('max number is '+str(max)+'; index string length is '+str(idxLen));

# check targets and determine destination file name
for itemInPath in listOfPath:
    if itemInPath.is_file() == False:
        continue
       
    tmp = str(itemInPath)
    tmplen = len(tmp)
    tmp2 = tmp[len(prefix):(tmplen-len(subffix))]
   
    needZero = idxLen - len(tmp2)
    if needZero <= 0:
        continue

    destName = tmp2 + subffix
    for i in range(needZero):
        destName = '0' + destName
    destName = prefix + destName
    print(tmp+' --> '+destName)
    #print(itemInPath)
    itemInPath.rename(destName)


#########
# stage 2 make index number string starts from 1
print('STAGE 2 MAKE INDEX NUMBER STRING STARTS FROM 1')
path = Path('.');

listOfPath = list(path.glob(prefix+'*'+subffix))

newIdx = 0
for itemInPath in listOfPath:
    if itemInPath.is_file() == False:
        continue
   
    newIdx+=1
   
    strIdx = str(newIdx)
    while len(strIdx)        strIdx = '0' + strIdx
   
    print(str(itemInPath)+' -> '+prefix+strIdx+subffix)
    itemInPath.rename(prefix+strIdx+subffix)

print("process done")

最後。謹此感謝FakeApp對AI科技的付出。
請不要不以為然,有時候,影響是來自意想不到的地方。

2018年1月24日 星期三

Do As Infinity - Hand in Hand

找不到中文歌詞。只好自己用Google翻譯和自己的一點點日語知識翻看看了...
歡迎各位朋友們補充。

-- Jackmis

=======================================

日文歌詞來源:MyMusic


思えば 道に迷い
途方に暮れてたあの頃
目の前の手のひら
握りしめていたんだ
いつしか出會いが出會いを呼び
戶惑いに搖り起こされて
不器用なぼくの
止まってた時計が動き出した
しあわせの鍵はいつも
この心に隱されてる
でも自分で見つけるのって
言うよりずっと難しくて
だからもうしばらく そばに…

たとえば 轉んだとき
ひざ小僧を擦りむいても
なんにも言わないで
待ち續けてくれた
手を貸すことはたやすいけれど
今のあなたには要らない
優しさは決して
ただ甘やかすことだけじゃないよ
しあわせになりたいなら
その脆さに負けないでと
聽こえるんだ 伝えてるんだ
くちびる嚙んで立ち上がれと
それに應えたくて ずっと…

未來の地圖を持って
最短距離を目指せ
きっとゆける
誰が邪魔をしようと
壁に阻まれようと
今 進むんだ

しあわせをつかみ取るんだ
なによりそれが ありがとう
しあわせを探す手には
いつもそこに絆がある
たとえ目に見えなくたって
心の手が放さないよ
獨り立ちしたって
たとえ離れたって ずっと…

 =============================

還記得嗎   迷路的時候
不知所措的時候
有張手掌伸到了我的眼前
我緊緊的握住了它
一直在尋找的人突然出現
感到混亂不安
笨拙的我
像原本時間靜止的手錶  動了起來
原來幸福的鑰匙一直都
藏在那顆心裡
但是要自己去找到它
有說不出的困難
只好先盤旋在你身旁

假如  轉過彎時
和你撞在了一起
請什麼都不要說
就這樣持續下去
雖然你可以很輕易的伸手幫我
但我現在不想要幫忙
溫柔不可以
僅僅只是呵護喔
想要幸福的話
不能輕易的認輸
聽到了嗎  傳達到了嗎
從唇齒之間發送出去
一直都想要這麼做

拿著未來的地圖
瞄準最短的距離
一定會去的
誰也別想妨礙我
曾經阻擋了我的那道牆
現在  我要越過去

把握幸福
無論如何  謝謝你
尋找幸福的手
總是有一種連繫
即使無法看見
心中的那雙手也不會放開
就算獨自站在那裡
就算遠離了,也一直感受的到

2017年12月29日 星期五

【劇透注意】Mark Palansky - 記憶重現(Rememory)

今年就用記憶重現收尾吧。

收看《記憶重現》,老實說是衝著『小惡魔』的人氣的關係。小惡魔是冰與火之歌裡面的一個角色,是一個領主的次子。他雖然身患侏儒症,但是比起其他健康俊美的角色們,更為睿智、有勇而且敢愛敢恨。演出者是彼德.汀克萊傑。他與劇中人同樣身患侏儒症。而在他傑出的演義下把小惡魔完美詮釋,甚至是超出這個角色給人們帶來的印象。(雖然最新這一季的小惡魔表現的有點阿呆)

曾經看到一篇訪問他的記錄裡,看到訪問者問他會不會在意別人討論他的缺陷 ?汀克萊傑只是簡單的回應自己已經過了那個會記較這件事的年齡。我們這些健康的人,有時會因為一些小事爭吵不休。是不是也該更豁達一點呢?

《記》的故事裡,主角為了翻回自己的記憶而找上了一個研究記憶的專家。這個專家發明了一種機器,可以把人的記憶從內心深出翻找回來。然而,在主要開口要求幫忙前,這位專家竟然遭到殺害了。

主角用了計,盜走機器。想用機器找回記憶,卻又不得其道。他試著藉由找到兇手,訪問專家的實驗對象。一來是進行探案,以回報這位已故的專家。另一方面則是為了尋找機器的使用方式。

隨著受試者一一出現。主角也愈來愈接近真相。故事試著探討記憶的真諦。為什麼人們會記得?會遺忘?想要從中找回什麼?還是想忘掉什麼?

記得之前在看《人工智慧的未來》一書時,該書作者提到,人類的大腦有很多重覆的結構。所以要在數十年內完全解析大腦的組成並非天方夜譚。然而,人並非只是這些結構所組成,而是這些結構中堆疊的東西,比如知識、記憶。人是這些東西組合起來的。就算是相同的結構,裡面的內容不同,就不會是同一個人。沒辦法透過了解大腦的結構來判斷、預測人的行為。要從這個人的知識與記憶去分析。

在《記》裡面也是一樣的。

劇透注意!!

劇透注意!!

劇透注意!!

很重要,所以說三次。

故事的最後,原來專家的死是因為他企圖刪除自己的記憶。這太合理了。沒有了記憶的人就像沒有內容的大腦。失去記憶延續性的大腦崩塌了當然就不會是一個完整的人,必然會死去。

本作裡,小惡魔演出的是一位雖然個性陰鬱,卻能為了真相、為了找回自己的記憶而不斷前進的角色。他是一個非常吸引人的人物。不得不說汀克萊傑選的劇本不錯。

網路上對這部作品的評價也很正面。

在此推薦給喜歡懸疑作品的各位。