anaconda

日経Linuxを立ち読みしてたら、Debian+PIXEL なんてのが年末に公開されたとかの記事が 出てた。オイラーもやってみたくなって、キーワードのPIXELを忘れないように、3度唱えて 書店を後にした。(書店のみなさん、スマソ。年始号は買ったから許してね)

早速ググル様に聞いてみたら、

MacやWindows PCで「Raspberry Pi」体験…「PIXEL」プロトタイプ公開 とか、 PIXEL for x86 (RaspberryPiのデスクトップ環境) を紹介されたよ。

ISOを落としてくるのに時間がかかるとか言ってたけど、ブームが終わったみたいで、1.3Gを 約30分で落とせた。

早速、VBOXで、64BitのDebianって指定して起動したら、ちゃんとDesktopが出てきた。 元のISOは32Bit用にも関わらず、そこの所は上手くやってくれるのね。

で、GUIで遊んでいると、証拠が残らないと思ったんで、CUIな端末からログイン出来るように ちゃちゃっとやってみた。下記セッションはちとうろ覚え。そうそう、キーボードが英式に なってたので、Preferencesから米式に変えたよ。配置がだいぶ違っていて焦ったぞ。

sudo apt update
sudo apt install ssh
vi /etc/ssh/sshd_config
 :
PasswordAuthentication yes
ChallengeResponseAuthentication yes
 :
/etc/init.d/ssh restart   ;; or below
sudo systemctl restart ssh; sudo systemctl enable ssh
useradd -m sakae
passwd sakae

sshのログインの所をさぼってしまったのは、お目こぼしを。

sakae@raspberrypi:~ $ uname -a
Linux raspberrypi 3.16.0-4-686-pae #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) i686 GNU/Linux

ちょいと昔のカーネルです。そして、調子に乗って色々なものを入れていったら、ぎりぎりな システムになってしまいましたよ。

sakae@raspberrypi:~ $ df
Filesystem     1K-blocks    Used Available Use% Mounted on
aufs              515912  493780     22132  96% /
tmpfs             206368    4560    201808   3% /run
/dev/sr0         1354560 1354560         0 100% /lib/live/mount/persistence/sr0
/dev/loop0       1267456 1267456         0 100% /lib/live/mount/rootfs/filesystem.squashfs
tmpfs             515912       0    515912   0% /lib/live/mount/overlay
devtmpfs           10240       0     10240   0% /dev
tmpfs             515912       0    515912   0% /dev/shm
tmpfs               5120       4      5116   1% /run/lock
tmpfs             515912       0    515912   0% /sys/fs/cgroup
tmpfs             515912      60    515852   1% /tmp
tmpfs             103184       4    103180   1% /run/user/1000
tmpfs             103184       0    103184   0% /run/user/1001

上記は、メインメモリーに1Gを割り当てた時のもの。どうもメモリーの半分がRAM-DISKと して使われてるように思える。検証の為、メモリーを3Gにしてみた。やっぱりね。

sakae@raspberrypi:~ $ df
Filesystem     1K-blocks    Used Available Use% Mounted on
aufs             1570472    9624   1560848   1% /
tmpfs             628192    8320    619872   2% /run
/dev/sr0         1354560 1354560         0 100% /lib/live/mount/persistence/sr0
/dev/loop0       1267456 1267456         0 100% /lib/live/mount/rootfs/filesystem.squashfs
tmpfs            1570472       0   1570472   0% /lib/live/mount/overlay
 :

home/piの下に、各種ゲームが収まっていて、ゲームするのと同時に考え方を学べて、 パイソンの勉強にはうってつけ。(すくなくとも、スクラッチよりは伸びしろが大きいと 思うぞ。)

sakae@raspberrypi:/home $ ls pi/python_games/*.py
pi/python_games/blankpygame.py
pi/python_games/catanimation.py
pi/python_games/drawing.py
pi/python_games/flippy.py
pi/python_games/fourinarow.py
pi/python_games/gemgem.py
pi/python_games/inkspill.py
pi/python_games/memorypuzzle_obfuscated.py
pi/python_games/memorypuzzle.py
pi/python_games/pentomino.py
pi/python_games/simulate.py
pi/python_games/slidepuzzle.py
pi/python_games/squirrel.py
pi/python_games/starpusher.py
pi/python_games/tetrominoforidiots.py
pi/python_games/tetromino.py
pi/python_games/wormy.py

WebブラウザーとしてChromiumが入っていた。過去にChromiumで積み残してた事が有るな。 node.jsと組み合わせて、debugをChromiumの上からやろうって言う実験。あの時は、 Chromiumを入れるのに失敗してたんだ。

今回やってみた。ちゃんと動いた。バックトレースの階層が出て来るんだけど、それに 対応したソースがリアルタイムに表示されたぞ。さすがWebブラウザー、何かを表示する のは、得意中の得意です。nodeな人達っていいな。居ながらにして、ググル様の道具を 使えるのだから。

Windows7機にmaximaを入れてみた

Fedora24に入っていたmaximaではsbclが使われていた。OpenBSDのmaximaはeclを使ってた。 ならばDebianはどうか? gclが使われていた。やっぱりGNUと癒着してると系列なものを 使わざるを得ないのね。これぞ世のしがらみ。

じゃ、FreeBSDはどうよ? まだ入れてない。ってか、入れるまでもなくMakefileを覗けば 答えが書いてあるな。CLISP CMUCL GCL SBCL の中から選べます。デフォルトはSBCLですってさ。そんじゃ、

Windowsはどうよ? 入れてみた。こちらは、sbclとclispの2本だて。どちらか好きな 方を設定で切り替えて使えるようだ。

Cドライブ直下に入って、maximaの中のbinの下には、なんとtclとかgnuplotとかも 入っていて、maxima王国を作っていた。勿論wxmaximaが動いて、メニューも日本語で 表示してくれるんで、数学に疎い人(オイラーの事です)がちょっと使うにはうってつけ。

色々入って、500MのDISK容量を喰っていたよ。

Windows7機にoctaveも入れてみた

こちらもCドライブ直下に居座る傲慢さ。DISK容量は、1Gも喰ってた。なんでそんなに喰うか? gccとかの開発環境一式と、よく使うであろうunix流儀のコマンド類を引き連れて来たんだ。

調べると開発環境とかが新しい感じ。思わずPATHを通しちゃったぞ。

Windows7機にanacondaも入れてみた。

こちらは、入れる時、自分だけ使うって指定したら、自Homeの下に入った。1.6Gの豪華布陣で やってきた。遅くてかなわん。ちょっと使う気が起きないな。

それに、spyderって言う総合開発環境が動かんし。。。どうもpythonには良い印象が無い んだよなぁ。

OpenBSDにPython環境

機械学習の本は、オライリーから出てる ゼロから作るDeep Learning――Pythonで学ぶディープラーニングの理論と実装がお勧めらしい。

サンプルコードもgithubに上がっていて、その説明を見ると、Python 3.x, NumPy, Matplotlibだけが有れば良いらしい。そうか、それぐらいなら、何とかなるだろうってんで、OpenBSDの パッケージカタログを眺めてみた。

py3-matplotlibを入れたら、NumPyは一緒に付いてきた。ipythonが無かったのでpipから 入れよう。

py3-pip をいれたら、今後よく使うならpip3.4を別名でpipにしとくといいよと言われた。 仰せの通りにした後、root権限で、pip install ipython して、禁を破っておいた。

[ob: ch01]$ ipython
Python 3.4.5 (default, Jul 25 2016, 16:15:19)
Type "copyright", "credits" or "license" for more information.

IPython 5.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: run man.py
Initilized!
Hello David!
Good-bye David!

emacsから使う場合は、去年の5月末の記事を参照。それはいいんだけど、頂いてきた utf-8なファイルが文字化けする。調べてみたら、

(set-language-environment "Japanese")
(prefer-coding-system 'utf-8)

こんな設定をしとくと良いと言われたので、そうした。

octaveでは簡単にプロファイルを取れたけど、pythonではどうやればいいの? 調べてみたら、2.4. コードの最適化なんてのが引っかかってきた。

でも多分、こういう小手先の対処だけでは、機械学習に必要な快適さは確保出来ないはず。 だから、低火力ディープラーニングのための環境(自作ハード編) とか、 Distributed TensorFlowの話とかの 記事が書かれる訳です。

まあ、結論を言って しまえば、貧乏人は機械学習なんて手を出すんじゃねぇぞ、と言う身も蓋もない結論に なる訳ですな。

octaveで正規化

そこで、最後っ屁として前回やり残していた、任意データを0.0から1.0の間に入るように正規化するルーチンを 忘れないうちに書いておく。

a = csvread('current.csv');

function out = b10(in)
  out = zeros(size(in));
  tbl = [min(in); range(in)];
  for k = 1:size(in,2)
    out(:,k) = (in(:,k) - tbl(1,k)) / tbl(2,k);
  endfor
endfunction

b = b10(a(:,2:4));

ちょっと走らせて確認。

octave:2> whos
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  =====
        a        2012x4                      64384  double
        b        2012x3                      48288  double

Total is 14084 elements using 112672 bytes

octaveの基本関数として持っていてもよさそうだけどな。

正規化で検索していたら、 機械学習を1ヵ月で実践レベルにする #10 (正規化)なんて言うのにお目にかかった。オイラーの思っていた正規化とは 違うもっと高次なものだけど、全体が非常に良記事で得した気分。

octaveで信号解析

ちょっと目先を変えて、octaveで出来る他の事に注目してみます。

Octaveで周波数解析

Octaveで学習、通信システム

Octaveで遊ぶフーリエ変換入門

こういうのは、楽しいよね。元ハード屋さんとしては。何でも、音ファイルも一発で取り込める みたいだから、soxとかと組み合わせて色々やったら良いかな。

Anaconda3-4.2.0-Linux-x86.sh

ちょっとお遊びで、Debian+PIXELにanacondaを入れてみた。DISK容量を喰いそうだった ので、Vboxには、5Gのメモリーを与えた。

400M近いshellスクリプト(の後ろにデータが付いたもの)を落としたので、展開前は

pi@raspberrypi:~ $ df
Filesystem     1K-blocks    Used Available Use% Mounted on
aufs             2607780  440984   2166796  17% /

展開後は、こんな状態になった。このノーパソにはGPUは積まれていないけど、メモリーは まあ程よく載ってるので、これぐらいではびくともしない。

pi@raspberrypi:~ $ df
Filesystem     1K-blocks    Used Available Use% Mounted on
aufs             2607780 1884788    722992  73% /

bashから上記スクリプトを起動すると、ライセンスに同意させられて、インストール場所を 聞かれて、最後にPATHを通していいか聞かれるぐらいだから、何も考えんとRETを叩くだけ。

下記のように、ホームパイの下に、anaconda3ってdirが出来て、その中に全て収まる 仕組みになってた。これでDebian環境を汚さない、仮想環境が出来上がったのだ。

pi@raspberrypi:~ $ du -sh anaconda3/
1.4G    anaconda3/

どんな物が入ったかはipythonから多分調べられるだろうけど、オイラーはpythonのスキルが 決定的に足りないので、上記のshellスクリプトをひも解いてみる。

extract_dist python-3.5.2-0
extract_dist _license-1.1-py35_1
extract_dist _nb_ext_conf-0.3.0-py35_0
extract_dist alabaster-0.7.9-py35_0
extract_dist anaconda-clean-1.0.0-py35_0
extract_dist anaconda-client-1.5.1-py35_0
extract_dist anaconda-navigator-1.3.1-py35_0
  :
extract_dist anaconda-4.2.0-np111py35_0
extract_dist ruamel_yaml-0.11.14-py35_0
extract_dist conda-4.2.9-py35_0
extract_dist conda-build-2.0.2-py35_0

一体幾つ収納されてるんだろう? 数えてみるか。

pi@raspberrypi:~/Downloads $ grep extract_dist Anaconda3-4.2.0-Linux-x86.sh | wc
      1       4      49

幾らなんでも、一つって事はないでしょう。きっと、何かよからぬ事が怒ってるはず。

pi@raspberrypi:~/Downloads $ grep extract_dist Anaconda3-4.2.0-Linux-x86.sh
Binary file Anaconda3-4.2.0-Linux-x86.sh matches

ありゃ、やっぱりgrepが怒っているよ。えと、grepをてなづける方法を探しましょ。 manに聞いてみた。これでどうだ。

pi@raspberrypi:~/Downloads $ grep --binary-files=text extract_dist Anaconda3-4.2.0-Linux-x86.sh | wc
    192     383    6561

こんなにごちゃごちゃ(← 褒め言葉なんで、あしからず)、個人では用意出来ないよ。 楽しようと思ったら、これを使っておけと言うの頷けるな。

anaconda/bin の下を覗くと、腐る程色々なコマンドが用意されてる。anacondaなんてのが 用意されてたのでコマンドを叩いてみると、どうもクラウドで便利に使うものらしい。

condaなんてのもあった。マニュアル同梱で、-h とかするのが最近の流儀みたい。

pi@raspberrypi:~/anaconda3 $ conda list
# packages in environment at /home/pi/anaconda3:
#
_license                  1.1                      py35_1
_nb_ext_conf              0.3.0                    py35_0
alabaster                 0.7.9                    py35_0
anaconda                  4.2.0               np111py35_0
 :
xz                        5.2.2                         0
yaml                      0.1.6                         0
zeromq                    4.1.4                         0
zlib                      1.2.8                         3

他に使えそうなサブコマンドが無いか、探して実行したぞ。

pi@raspberrypi:~/anaconda3 $ conda update --prefix /home/pi/anaconda3 anaconda
Fetching package metadata .......
Solving package specifications: ..........

Package plan for installation in environment /home/pi/anaconda3:

The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    conda-env-2.6.0            |                0          502 B
    conda-4.2.13               |           py35_0         390 KB
    ------------------------------------------------------------
                                           Total:         391 KB

The following NEW packages will be INSTALLED:

    conda-env: 2.6.0-0

The following packages will be UPDATED:

    conda:     4.2.9-py35_0 --> 4.2.13-py35_0

Proceed ([y]/n)?

condaってパッケージマネージャの事なのね。

pi@raspberrypi:~/anaconda3 $ conda info
Current conda install:

               platform : linux-32
          conda version : 4.2.13
       conda is private : False
      conda-env version : 4.2.13
    conda-build version : 2.0.2
         python version : 3.5.2.final.0
       requests version : 2.11.1
       root environment : /home/pi/anaconda3  (writable)
    default environment : /home/pi/anaconda3
       envs directories : /home/pi/anaconda3/envs
          package cache : /home/pi/anaconda3/pkgs
           channel URLs : https://repo.continuum.io/pkgs/free/linux-32
                          https://repo.continuum.io/pkgs/free/noarch
                          https://repo.continuum.io/pkgs/pro/linux-32
                          https://repo.continuum.io/pkgs/pro/noarch
            config file : None
           offline mode : False

上記のURLへ行ってみると、Anaconda R なんてのも置いてあるな。R言語ったら、昔から 専用の集積地が有ったはずだけど、そこから厳選して再梱包してあるんだろうな。

うろうろしてたら、Miniconda installerなんてのも有ったぞ。こちらはパッケージが 同梱されていない最低限なやつだな。

cython

やや、Cythonなんてのもあるぞ。

pi@raspberrypi:~/python_games $ cython blankpygame.py
pi@raspberrypi:~/python_games $ cc blankpygame.c
blankpygame.c:4:20: fatal error: Python.h: No such file or directory
 #include "Python.h"
                    ^
compilation terminated.

気を取り直して

pi@raspberrypi:~/python_games $ cc -I /home/pi/anaconda3/include/python3.5m -L /home/pi/anaconda3/lib/python3.5m blankpygame.c
/usr/lib/gcc/i586-linux-gnu/4.9/../../../i386-linux-gnu/crt1.o: In function `_start':
/build/glibc-En_RtM/glibc-2.19/csu/../sysdeps/i386/start.S:111: undefined reference to `main'
/tmp/cc6fPax5.o: In function `__Pyx_PyObject_GetAttrStr':
blankpygame.c:(.text+0x41): undefined reference to `PyObject_GetAttr'
/tmp/cc6fPax5.o: In function `__pyx_import_star_set':
 :
blankpygame.c:(.text+0x3394): undefined reference to `PyObject_IsTrue'
collect2: error: ld returned 1 exit status

C語だとmainが必ず必要だけど、pyにそんなの有るわけは無い。根本的に使い方を間違えて いるな。チュートリアルを見れ。

下記、有名なfibをわざわざ再帰で書いて、負荷をかけるもの。サフィックスがpyxってなってて いかにも感がする。

pi@raspberrypi:/tmp/test $ cat fib.pyx

def fibR(n):
 if n==1 or n==2:
  return 1
 return fibR(n-1)+fibR(n-2)

print( fibR(40) )

これをコンパイルするためのドライバー相当になるのかな。

pi@raspberrypi:/tmp/test $ cat setup.py
from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules=cythonize("fib.pyx"),
)

コンパイルは、pythonから呼び出すのがcython風?

pi@raspberrypi:/tmp/test $ python setup.py build_ext --inplace
[1/1] Cythonizing fib.pyx
running build_ext
building 'fib' extension
creating build
creating build/temp.linux-i686-3.5
gcc -pthread -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -m32 -fPIC -I/home/pi/anaconda3/include/python3.5m -c fib.c -o build/temp.linux-i686-3.5/fib.o
gcc -pthread -shared -L/home/pi/anaconda3/lib -Wl,-rpath=/home/pi/anaconda3/lib,--no-as-needed build/temp.linux-i686-3.5/fib.o -L/home/pi/anaconda3/lib -lpython3.5m -o /tmp/test/fib.cpython-35m-i386-linux-gnu.so

上のパイソンコードには、printが含まれていて、それを含めてfibってライブラリィーに なってる。時間計測の為に、importするだけのコードを用意

pi@raspberrypi:/tmp/test $ cat test.py
import fib

そして、実行。

In [1]: run -t test.py
102334155

IPython CPU timings (estimated):
  User   :      14.66 s.
  System :       0.00 s.
Wall time:      14.65 s.

In [2]: run -t fib.py
102334155

IPython CPU timings (estimated):
  User   :      52.42 s.
  System :       0.00 s.
Wall time:      52.45 s.

素のコードでも測ってみた。

舞台裏。

pi@raspberrypi:/tmp/test $ ls
build  fib.cpython-35m-i386-linux-gnu.so  fib.pyx   test.py
fib.c  fib.py                             setup.py

fib.cの行数は2362行になってた。色々と環境を読み込んでいるんだなあ。

pi@raspberrypi:/tmp/test $ ldd fib.cpython-35m-i386-linux-gnu.so
        linux-gate.so.1 (0xb772e000)
        libpython3.5m.so.1.0 => /home/pi/anaconda3/lib/libpython3.5m.so.1.0 (0xb74c1000)
        libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb7494000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb731f000)
        libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb731a000)
        libutil.so.1 => /lib/i386-linux-gnu/libutil.so.1 (0xb7316000)
        librt.so.1 => /lib/i386-linux-gnu/librt.so.1 (0xb730d000)
        libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb72c8000)
        /lib/ld-linux.so.2 (0xb7731000)
pi@raspberrypi:/tmp/test $ ls -l fib.cpython-35m-i386-linux-gnu.so
-rwxr-xr-x 1 pi pi 65176 Jan 26 16:30 fib.cpython-35m-i386-linux-gnu.so

そして、出来上がったsoファイルもpythonの本体を含んでいるって事だな。

ああ、cython用に用意したpyxも普通のpythonで難なく実行出来たよ。逆にpyだけの ものでも、setup.pyにそれを指定すれば、ちゃんとコンパイルしてくれた。

まあ、後々の事を考えたら、これはcpythonでコンパイル出来るコードって、きっちり 見分けが付くようにしといた方が、混乱は無くなるな。