2022年12月30日金曜日

backquote でIME OFF

MDなどでは、backquoteで等幅フォントを出すので、IMEが切れてくれるとありがたい、ということで設定。私はcmd-spaceでIMEのON/OFFをしているので、それを出している。デフォルトだとctl-spaceだとおもう。
  • .config/karabinar/assets/complex_modifications/xxxx.json に下記を登録
    {
      "title": "for vscode md",
      "rules": [
        {
          "description": "turn off IME with backslash",
          "manipulators": [
            {
              "type": "basic",
              "from": {
                "key_code": "grave_accent_and_tilde"
              },
              "to": [
                {
                  "key_code": "spacebar",
                  "modifiers": [
                    "command"
                  ]
                },
                {
                  "key_code": "grave_accent_and_tilde"
                }
              ],
              "conditions": [
                {
                  "type": "input_source_if",
                  "input_sources": [
                    {
                      "language": "ja"
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
    
  • karabinar-element のcomplex modificationで選択してインストール

2022年12月14日水曜日

vscode でawsome emacsを入れたら cmd-c でコピーできなくなる問題

なんか知らんが、title-case というキャピタライズするコマンドにマップされている。 コピーしようとすると微妙にキャピタライズされていてコンパイル通らなくなったりして 発狂しそうなので、対策 keyboard shortcut でMCX-Emacs: MCX-Emacs: Transform to title case の cmd-C の欄を削除すればいい。 自動的に上書きが消えるのか、デフォルトのコピー動作が復活するようだ。

2022年12月6日火曜日

matplotlibで適当なプロットを書く

  • tick_params で軸上の値を消す
  • PathPatch で線を引く
  • text で任意の場所に字を書く
    # モデルの複雑さと精度
    import matplotlib.pyplot as plt
    from matplotlib.path import Path
    import matplotlib.patches as patches
    
    plt.rcParams["font.family"] = "Hiragino Sans"
    plt.rcParams["font.size"] = 24
    
    train = [ (0., 0.),  (0.2, 1.),  (0.8, 1.0),  (1, 1.0),]
    test = [ (0., 0.),  (0.2, 0.95),  (0.8, 0.8),  (1, 0.5),]
    codes = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4, ]
    
    fig, ax = plt.subplots()
    fig.set_size_inches(12, 8, forward=True)
    
    ax.add_patch(patches.PathPatch(Path(train, codes), facecolor='none', lw=3, edgecolor="red"))
    ax.add_patch(patches.PathPatch(Path(test,  codes), facecolor='none', lw=3, edgecolor="blue", ls="--"))
    
    ax.set_ylabel("精度")
    ax.set_xlabel("小 <---- モデルの複雑度 ----> 大")
    ax.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False) 
    ax.tick_params(axis='y', which='both', left=False, right=False, labelleft=False) 
    ax.set_xlim(-0.05, 1.05)
    ax.set_ylim(-0.05, 1.05)
    ax.text(0.4, 0.9, '訓練')
    ax.text(0.7, 0.6, 'テスト')
    None
    
  • 2022年12月5日月曜日

    matplotlibで日本語フォント

    import matplotlib.pyplot as plt
    from matplotlib.font_manager import FontProperties
    fp = FontProperties(fname=r'/System/Library/Fonts/ヒラギノ丸ゴ ProN W4.ttc', size=16)
    
    plt.plot([1], [2], '^')
    plt.xlabel("test日本語", fontproperties=fp)
    
    とかやればいいようだ。 jupyter notebookでもいける。 フォントのパスを設定しなければならないのが面倒だが、
    from matplotlib.font_manager import findfont
    
    fp = FontProperties(fname=findfont('Osaka'), size=16)
    
    のようにすることもできるようだ。ただ、うまく見つけてくれない場合もあるようで、 よくわからない。Osakaは見つかるがヒラギノはこの方法だとうまく行かない。わからん。。
    fp = FontProperties(fname=findfont('Hiragino Sans'), size=16)
    
    でヒラギノ角ゴシックはいけるが、ヒラギノ丸ゴシックはうまく設定できなかった。なにがちがうのか。。

    逐一設定しなければならないのは面倒。 デフォルトのfontproperties を設定する方法はないのだろうか。 こちらによれば、下のようにすればいちいち設定しなくて済む。 しかし、ラベル以外に日本語フォントを使うのはあんまり良くないかもしれない。見栄えが悪い。

    plt.rcParams["font.family"] = "Hiragino Sans"
    plt.rcParams["font.size"] = 16
    
    plt.plot([1], [2], '^')
    plt.xlabel("test日本語")
    plt.ylabel("test日本語")  
    

    2022年9月2日金曜日

    M1 macbook Air でPytorch

    M1 chip内臓のGPUを使ってニューラルネットをアクセラレートするものが使えるようになったということで、 こちらの記事 のとおりに、インストールしてプログラムもダウンロードして実行。

    pyenv で普通に導入したpython 3.10だとlzmaが足りないということでエラーがでる。 ので、anacondaを導入してそちらを使ったらあっさり動いた。すばらしい。

    MPSを使うとこんなかんじ。

    Epoch 1 / 5: time = 95.05[s], loss = 170.33
    Epoch 2 / 5: time = 183.52[s], loss = 138.28
    Epoch 3 / 5: time = 270.67[s], loss = 124.85
    Epoch 4 / 5: time = 356.84[s], loss = 114.28
    Epoch 5 / 5: time = 458.32[s], loss = 106.25
    Train time on mps: 458.32[s] (Train loss = 106.25)
    
    Test time on mps: 52.92[s](Test loss = 21.62)
    
    CPUだとこんなかんじ。
    Epoch 1 / 5: time = 446.72[s], loss = 169.79
    Epoch 2 / 5: time = 899.81[s], loss = 136.01
    Epoch 3 / 5: time = 1379.53[s], loss = 122.38
    Epoch 4 / 5: time = 1818.74[s], loss = 112.07
    Epoch 5 / 5: time = 2305.36[s], loss = 105.47
    Train time on cpu: 2305.36[s] (Train loss = 105.47)
    
    Test time on cpu: 102.65[s](Test loss = 20.72)
    
    元記事とCPU性能は変わらないけどMPS性能は半分ぐらい、というかんじか。 元記事はMacbook ProでM1 MAX、こちらは Air なのでこんなものだろう。 CPUとMPSの差はざっくり5倍という程度。テストには使えそうなのでうれしい。

    しかし、負荷かけるとコア温度が76度ぐらいまでいくな。M1 Airではみたこともないような値。 ファンついてないんだけど大丈夫なんだろうか。

    2022年8月26日金曜日

    linux で sleep が失敗する

    同じラップトップでLinuxでも同じ症状だったので、こちらも対応。

    やはりsleep直後にwakeupしているようだ。 こことか こことか ここを 参考にいろいろ試してみた。

    > cat /sys/bus/usb/devices/*/power/wakeup
    
    とやったところ1−2がenableになっていることを発見。 これを強制的にdisableに書き換えたところ、安定してsleepするようになったようだ。 めでたい。

    ただ、電源ボタンがどうもIME ON/OFFに割り当てられているっぽいんだよな。そんなことできるの?

    windows でsleepが失敗する

     Windowsのノートでいつからかsleepがうまく行かなくなっていた。厳密にはsleepすると同時にsleepが解除されて起きてしまう、という症状。

    いろいろ調べてみた結果、どうもタッチパッドやキーボードからの入力を拾ってsleepが解除されていたようだ。デバイスマネージャのタッチパッドとキーボードのペインの「電源管理」タブで「このデバイスでスリープを解除する」を無効にしたら治ったようだ。

    2022年7月15日金曜日

    emacs mac gnupg

    macのemacsのepgでなぜかminibufferからのパスワード入力ができなくなった。 ~/.gnupg/gpg-agent.confに下記を追加したら別ウィンドウから入力できるようになった。 pinentry-macはbrewではいる。
    pinentry-program /opt/homebrew/bin/pinentry-mac
    

    2022年7月12日火曜日

    Google functions とdatastore

    App Engineからfunctionsに乗り換えるためにテスト。 調べてみるといろいろと新しいシステムデータベースはあるのだけど、 結局われわれの用途にはdatastoreが一番適しているという結論。つまらん。

    datastoreの認証がどうなっているのか心配だったのだが、GCPのプロジェクト内では 認証が不要っぽい感じ。逆にプロジェクト外部からは触れなさそう。 この辺、AWSのIAM Roleですべての認証を切り分けていくというのとは好対照だな。

    このブログを参考に試してみた。 データはdatastoreのWebサイトから直接データをいれていて、それをfunctionsから 取りに行く形。

    const functions = require('@google-cloud/functions-framework');
    const Datastore = require('@google-cloud/datastore');
    const datastore = Datastore();
    
    functions.http('helloHttp', (req, res) => {
       const key = datastore.key([req.body.kind, req.body.key]);
       console.log(req.body.kind, req.body.key);
       return datastore.get(key)
         .then(([entity]) => {
           res.status(200).send(entity);
         });
    });
    
    jsonをアップロードすると、自動的にパースしてくれるのね。便利。 package.jsonでdatastoreを参照する。最新版がいくつなのかわからないが、1.0.0だと 動かなかった。
    {
      "dependencies": {
        "@google-cloud/functions-framework": "^2.1.0",
        "@google-cloud/datastore": "1.4.1"
      }
    }
    
    アクセスはこんなかんじ。謎の文字列は、datastore上のentityのID。
    % curl -H "Content-type: application/json" -X POST -d '{"kind":"User", "key": 5634161670881280}' https://xxxx.xxxxx.x.run.app/
    
    {"name":"john"}
    
    返り値もjsonになってるけど、誰がやってくれてるんだろう。。不思議。

    2022年7月7日木曜日

    Julia のコードをssh越しにプッシュする

    Juliaには-eというオプションがあって、同じことができる。 方針は同じで、ダブルクォートをエスケープして、前後にダブルクォートをつける。 これは3行ぐらいのコードでしか試してないのでどのくらいいけるのかわからない。
    function read_and_process(filename) 
        open(filename, "r") do f
            l = join(readlines(f), "\n")
            "\"" * replace(l, "\"" => "\\\"") * "\""
        end
    end
    
    l = read_and_process("remote-test.jl")
    println(l)
    
    proc = My.open(`ssh localhost julia -e $l`, read=true)
    println(readlines(proc.out))
    

    python のコードをsshごしにプッシュする

    Python には-cというオプションがあり、これを使うとコードを引数として与える事ができる。例えば、test.py というファイルがあった場合、
    python -c "`cat test.py`"
    
    などとやれば、test.pyを実行できる。ではこれをSSH越しにできるかというとちょっと難しい。
    ssh REMOTE python -c "`cat.test.py`"
    
    とやれば良さそうなものだが、コード部分がリモートのシェルで一旦解釈されてしまうので、エスケープする必要がある。 色々試行錯誤してできたのがこんなコード。要するに、全体をダブルクォートで囲み、中のダブルクォートはバックスラッシュで エスケープする、というだけ。全体をシングルクォートで囲むと中のシングルクォートをエスケープする方法が無いので詰む。 要するにシェルから渡す引数にプログラムを全部乗っけるので、限界がありそうだが、 このページを参考に調べてみると、 ubuntu 22.04では2M、macosで1Mなので、そう簡単には破綻しなさそう。
    def load_and_preprocess(filename):
        with open(filename) as f:
            p = [l for l in f.readlines()]
            prog = "".join(p)
        prog = prog.replace('"', '\\"')
        prog = '"' + prog + '"'
        return prog
    
    
    proc = subprocess.Popen(
        ['ssh', 'localhost',
            'python',
        '-c',
            load_and_preprocess('src/rjupyter_server.py')
        ],
        stdout=subprocess.PIPE
    )
    

    2022年3月16日水曜日

    ABCIでjulia multi node

    ABCIではマルチノードを確保して、相互にsshできる。
    qrsh -g XXXX -I USE_SSH=1 -v SSH_PORT=2222 -l rt_F=2
    
    とかやる。すると環境変数SGE_JOB_HOSTLISTに書かれたファイルにホストのリストが 入るので、Juliaのジョブの中で下のような関数を実行してやれば、 workerを追加することができる。
    using Distributed
    
    function invoke_hosts(port)
        hosts = open(ENV["SGE_JOB_HOSTLIST"]) do f
            readlines(f)
        end
        pairs = map(hosts) do h
            "$h:$port"
        end
        addprocs(pairs; sshflags="-o StrictHostKeyChecking=no")
    end