suzuzusu日記

(´・ω・`)

Pykkaでping pong

Pythonでactor model使いたかったので忘備録として

Pykka

Pythonのactor model frameworkです.

インストール方法

pip install pykka

Actorの実装方法

標準のThreadによる実装やgeventなどがある. ドキュメントに gevent の方が一般的に Thread よりも早いことが記載されている.

gevent実装のActorを使用する場合,geventのインストール方法

pip install gevent

通信方法

ask は同期通信,tell は非同期通信となっている. ask の場合は返り値を受け取れるが,tell の場合は None が返り値となる.

ping pong

pingというメッセージに対してpongを返すサンプルを書いてみる.

以下は threading.Thread の実装

from pykka import ThreadingActor

class Actor(ThreadingActor):
    def __init__(self):
        super().__init__()

    def on_receive(self, message):
        print('recieve:', message)
        return 'pong'

actor = Actor.start()
r = actor.tell('ping') # None
print('tell:', r)
r = actor.ask('ping') # pong
print('ask:', r)
actor.stop()

'''
tell: None
recieve: ping
recieve: ping
ask: pong
'''

以下は gevent の実装

from pykka.gevent import GeventActor
class Gactor(GeventActor):
    def __init__(self):
        super().__init__()

    def on_receive(self, message):
        print('recieve:', message)
        return 'pong'

gactor = Gactor.start()
r = gactor.tell('ping')
print('tell:', r)
r = gactor.ask('ping')
print('ask:', r)
gactor.stop()

'''
tell: None
recieve: ping
recieve: ping
ask: pong
'''

参考

混合ガウス過程で多峰な関数を回帰する

忘備録として

混合ガウス過程と多峰な関数

以下のような多峰な関数を回帰する場合は,通常の単峰にフィッティングする回帰では困難なので混合ガウス過程を用いる.

f:id:suzuzusu:20190927182219p:plain
f1,f2関数

f:id:suzuzusu:20190927194603p:plain
多峰な関数

GPclust

GPclust という混合ガウス過程のライブラリが良さそうなので今回はこれを使用する.

以下コード

gist.github.com

結果

f:id:suzuzusu:20190927194641p:plain

結果の図から多峰な関数を回帰できていることが分かる.

参考

SSH in Elixir

ElixirでSSHをする方法を忘備録として書いておく.

iexして以下を実行する

iex(1)> ip = '1.2.3.4'
'1.2.3.4'
iex(2)> port = 22
22
iex(3)> ssh_config = [
...(3)>   user: 'user',
...(3)>   password: 'password1234',
...(3)>   silently_accept_hosts: true
...(3)> ]
[user: 'user', password: 'password1234', silently_accept_hosts: true]
iex(4)> :ssh.start
:ok
iex(5)> :ssh.shell(ip, port, ssh_config)
remote > # login

command実行の場合

iex(1)> ip = '1.2.3.4'
'1.2.3.4'
iex(2)> port = 22
22
iex(3)> ssh_config = [
...(3)>   user: 'user',
...(3)>   password: 'password1234',
...(3)>   silently_accept_hosts: true
...(3)> ]
[user: 'user', password: 'password1234', silently_accept_hosts: true]
iex(4)> :ssh.start
:ok
iex(5)> {:ok, con_ref} = :ssh.connect(ip, port, ssh_config)
{:ok, #PID<0.128.0>}
iex(6)> {ok, ch_id} =  :ssh_connection.session_channel(con_ref, :infinity)
{:ok, 0}
iex(7)> :ssh_connection.exec(con_ref, ch_id, "date", :infinity)
:success
iex(8)> flush
{:ssh_cm, #PID<0.128.0>,
 {:data, 0, 0, "2019年  9月  6日 金曜日 12:36:26 JST\n"}}
{:ssh_cm, #PID<0.128.0>, {:eof, 0}}
{:ssh_cm, #PID<0.128.0>, {:exit_status, 0, 0}}
{:ssh_cm, #PID<0.128.0>, {:closed, 0}}
:ok

参考

www1.erlang.org

Distributed Elixir

Elixirで分散ノードで処理をする方法を忘備録として書いておく.

環境

  • node01
    • 192.168.0.2
  • node02
    • 192.168.0.3

方法

node01で以下のプロセスを立ち上げる

iex --name node01@192.168.0.2 --cookie hoge

node02で以下のプロセスを立ち上げる

iex --name node02@192.168.0.3 --cookie hoge

node01のプロセスから以下を実行して接続する

iex(node02@192.168.0.2)1> Node.connect :"node02@192.168.0.3"
true
iex(node02@192.168.0.2)2> Node.list
[:"node02@192.168.0.3"]

別ノードで実行する方法

iex(node02@192.168.0.2)3> Node.spawn :"node02@192.168.0.3", fn -> IO.inspect Node.self end
:"node02@192.168.0.3"
#PID<11251.119.0>

参考

Windowsでmultiprocessingにおける「if __name__ == "__main__":」制限を回避してPandasで複数ファイルを並列で読み込む

忘備録として書く

題名長すぎる...

以下のようにWindowsの場合main guardを書かないとmultiprocessingが動かない stackoverflow.com

何とか回避してPandasを使って複数プロセスでファイルを読み込んでみる.具体的には以下のように別のpythonのプロセスを動かして,pickle経由でデータを受け取る

# -*- coding: utf-8 -*-
import pickle
import subprocess
import pandas as pd
from sklearn import datasets

mp = \
'''# -*- coding: utf-8 -*-
from multiprocessing import Pool
import pandas as pd
import sys
import pickle

def read_(f, header):
    return pd.read_csv(f, header=header)

def read(x):
    return read_(x[0], x[1])

def read_csv(fs):
    with Pool() as p:
        return p.map(read, fs)

if __name__ == "__main__":
    f = sys.argv[1]
    n1 = int(sys.argv[2])
    n2 = int(sys.argv[3])
    header = int(sys.argv[4])
    fs = []
    for i in range(n1, n2):
        fs.append((f.replace('{}', str(i)), header))
    dfs = read_csv(fs)
    binary = pickle.dumps(dfs)
    sys.stdout.buffer.write(binary)
'''

with open('mp.py', mode='w') as f:
    f.write(mp)

def read_csv(f_name, start=0, end=30, header=0):
    s_str = str(start)
    e_str = str(end)
    h_str = str(header)
    result = subprocess.run(['python', 'mp.py', f_name, s_str, e_str, h_str], stdout=subprocess.PIPE)
    return pickle.loads(result.stdout)


iris = datasets.load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
for i in range(30):
    df.to_csv('data'+str(i)+'.csv')

dfs = read_csv('data{}.csv', 0, 30)
print('len:', len(dfs))
print('===============================================')
print('head:')
print(dfs[0].head())
print('===============================================')
print('info:')
dfs[0].info()

出力

len: 30
===============================================
head:
   Unnamed: 0  sepal length (cm)  sepal width (cm)  petal length (cm)  \
0           0                5.1               3.5                1.4   
1           1                4.9               3.0                1.4   
2           2                4.7               3.2                1.3   
3           3                4.6               3.1                1.5   
4           4                5.0               3.6                1.4   

   petal width (cm)  
0               0.2  
1               0.2  
2               0.2  
3               0.2  
4               0.2  
===============================================
info:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 5 columns):
Unnamed: 0           150 non-null int64
sepal length (cm)    150 non-null float64
sepal width (cm)     150 non-null float64
petal length (cm)    150 non-null float64
petal width (cm)     150 non-null float64
dtypes: float64(4), int64(1)
memory usage: 5.9 KB

これをモジュール化してやれば良さそう

でもこんな事するくらいなら素直にmain guard書いた方がいい説...

ffmpeg filterの作り方

そろそろブログまとめようと思ったので移転記事です.

移転元 https://wiki.mma.club.uec.ac.jp/su_zu/ffmpeg%20filter%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9

MMA Advent Calendar 2016/12/21

これはMMA Advent Calendar 2016の21日目の記事です

ffmpeg filterとは

https://trac.ffmpeg.org/wiki/FancyFilteringExamples

標準でffmpegにはマンデルブロ集合とかライフゲームなどの面白いfilter機能がついています。今回はそのfilterの作り方を説明します。Libavfilterから直接作ることもできるのですが今回はFrei0rで作る方法を記述します。実際の動画編集はノンリニア編集するほうが便利ですが生配信などにはもしかして自作フィルターが使えるかもしれません(?)

Frei0r

Frei0rというのはクロスプラットフォームのvideo effect pluginです。最近の新しいffmpegはfrei0rに対応しています。ffmpeg -versionして--enable-frei0rと表示されていれば対応しています。

#include "frei0r.hpp"
#include "frei0r_math.h"
#include <stdlib.h>

// frei0r::filterを継承して作っていきます
class Mat33 : public frei0r::filter
{
public:
  Mat33(unsigned int width, unsigned int height)
  {
    // register_paramで引数を登録することができます
    register_param(m11, "m11", "matrix element m11");
    register_param(m12, "m12", "matrix element m12");
    register_param(m13, "m13", "matrix element m13");
    register_param(m21, "m21", "matrix element m21");
    register_param(m22, "m22", "matrix element m22");
    register_param(m23, "m23", "matrix element m23");
    register_param(m31, "m31", "matrix element m31");
    register_param(m32, "m32", "matrix element m32");
    register_param(m33, "m33", "matrix element m33");
  }

  // updateで一フレームごとの処理を書いていきます
  // inに編集前ピクセルデータがあり、outに編集後のピクセルデータを入れます
  virtual void update(double time,
                      uint32_t* out,
                      const uint32_t* in)
  {
    std::copy(in, in + width*height, out);
    for (unsigned int y=1; y<height-1; y++){
      for (unsigned int x=1; x<width-1; x++){
        unsigned char *p1 = (unsigned char *)&in[(y-1)*width+(x-1)];
        unsigned char *p2 = (unsigned char *)&in[(y-1)*width+x];
        unsigned char *p3 = (unsigned char *)&in[(y-1)*width+(x+1)];
        unsigned char *p4 = (unsigned char *)&in[y*width+(x-1)];
        unsigned char *p5 = (unsigned char *)&in[y*width+x];
        unsigned char *p6 = (unsigned char *)&in[y*width+(x+1)];
        unsigned char *p7 = (unsigned char *)&in[(y+1)*width+(x-1)];
        unsigned char *p8 = (unsigned char *)&in[(y+1)*width+x];
        unsigned char *p9 = (unsigned char *)&in[(y+1)*width+(x+1)];

        unsigned char *o = (unsigned char *)&out[y*width+x];
        for (int i=0; i<3; ++i){
          o[i] = CLAMP0255(abs(p1[i]*m11 + p2[i]*m12 + p3[i]*m13 + p4[i]*m21 + p5[i]*m22 + p6[i]*m23 + p7[i]*m31 + p8[i]*m32 + p9[i]*m33));
        }
        o[3] = ((unsigned char*)&in[y*width+x])[3];
      }
    }
  }
private:
  f0r_param_double m11;
  f0r_param_double m12;
  f0r_param_double m13;
  f0r_param_double m21;
  f0r_param_double m22;
  f0r_param_double m23;
  f0r_param_double m31;
  f0r_param_double m32;
  f0r_param_double m33;
};

// filterの登録処理です
frei0r::construct<Mat33> plugin("Mat33",
                                "3*3 Matrix filter",
                                "su_zu",
                                0,1,
                                F0R_COLOR_MODEL_RGBA8888);

上の例は3×3行列のフィルター処理を行えるフィルターを書いてみました。なんかフィルターフィルター言っててわかりづらい。。。

How to Use

# buildしたfilter DLLのmat33.dllをC:\Program Files (x86)\frei0r\lib\frei0r-1に置いたとしましょう

#FREI0R_PATH環境変数を設定
$ export FREI0R_PATH="C:\Program Files (x86)\frei0r\lib\frei0r-1"
$ ffmpeg -i INPUT.mp4 -vf "frei0r=hogefugafilter" OUTPUT.mp4

ちなみにdllは https://dl.dropbox.com/s/10izo6dycp8as7b/mat33.dll に置いておきました。信用できない人はソースはgithubに上げたので自分でビルドしてみてください。 https://github.com/suzusuzu/frei0r/blob/mat33/src/filter/mat33/mat33.cpp

sobel filter

sobel filterとは空間1次微分を計算してedgeを抽出するfilterです。

上から下へのsobel filter 上から下へのsobel filter

左から右へのsobel filter 左から右へのsobel filter

ちなみにfilterは","で処理を繋げることができる。今回はsobelフィルターをかけるまえにグレースケールを行う

元動画 http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi

$ ffmpeg -t 30 -i http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi -vf "format=gray,frei0r=mat33:1|2|1|0|0|0|-1|-2|-1" -pix_fmt yuv420p sobel.mp4

}}}

平滑化 filter

平均化 filterとも言います。

名前の通り平らに滑らかにするfilterです。

$ ffmpeg -t 30 -i http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi -vf "frei0r=mat33:0.111|0.111|0.111|0.111|0.111|0.111|0.111|0.111|0.111" -pix_fmt yuv420p ave.mp4

}}}