2019年8月22日木曜日

Google ColabでJupyterを使ってみる

IT系のブログや記事を見ていると、開発や機械学習でGoogleのColaboratory (Google Colab)というサービスを利用することについて解説してあるのをよく見る。Colaboratoryは、個人が機械学習の教育や研究をするときに使える無償のツールで、Jupyterノートブックの環境として利用できる。googleのアカウントを持っている人だったら、そこから使うことができる。自分はsafariから使ってみたが、chrome, firefox、safariでは検証済みとのことだ。話題になっているのは、機械学習に必要なGPUなどのリソースを無償で使うことができるためのようだ(ただし、連続使用時間は12時間に制限されているらしい。暗号通貨採掘などに使われないようにするためのようだ)。Jupyterは自分で使う場合、pythonの他にRやBashなどのカーネルを利用するようにできるが、Colabではpython2と3のみ提供されている。将来的には他のカーネルを利用することができるようになるかもしれない。

自分のgoogleアカウントに行き、colabを立ち上げてみる。デザインは少し異なるが、Jupyterノートブックのファイルができるので、helloworldしてみる。




使い方はほとんどローカルのJupyterと同じだった。ファイルを保存するとgoogleドライブに.iynb形式でファイルが保存される。ファイルを利用するために、ドライブの設定で、Colabのところにチェックを入れた。


そうすると、利用するアプリとして、google colaboratoryが出てくるようになる。



 Markdownはテキストボックスという名前で利用できる。左側で入力すると、右側に成形された書式で出力される。


実行すると、以下のように出力される。


colabには、よく使われるライブラリがあらかじめ使えるようになっている。numpyをインポートして、行列の演算を行ってみた。


anacondaを導入しても、あらかじめ主要なライブラリを一緒にインストールすることができるが、colabは自分のパソコンで何もしなくてもだいたい必要なものが利用できるようになっているのは便利だと思った。さらに、機械学習などで利用されると思われるコードがあらかじめスニペットとして用意されているようだ。左側のメニューでコードスニペットを選んで、簡単にスニペットのセルをコピーすることができる。


実際に実行してみたところ。これは手間いらずだ。


googleドライブにアップロードしたファイルを参照するときは、ドライブをマウントする必要がある。やり方は簡単で、左側からドライブにマウントのボタンをクリックすると、必要なコードがコピーされ、それを実行すると以下のようになる。リンクをクリックして自分のドライブがあるアカウントにログインすると、キーが表示されるので、コピーして入力する。

以上の作業を行うと、/content/drive/My\ Drive/の下にgoogleドライブがマウントされる。一度colabのノートブックを閉じて再度開いたときもマウントされたので、一定期間はマウントされるのかもしれない。せっかくなので、ランダムドリフトの簡単なシミュレーションをして結果をプロットするスクリプトをアップロードして、colabで実行してみた。

見えているファイルplot.pyを実行する。pythonファイルを実行するときは、%run file.pyでいけるようだ。初期頻度や世代数、集団サイズ、試行回数を入力すると、以下のように結果がプロットされる。図では、初期頻度が0.5で、30世代100個体の集団を4回シミュレーションしている。


すごいサービスだと思った。何も設定しなくても、googleアカウントがあればすぐにJupyterノートブックを使うことができるし、機械学習などの勉強に必要なリソースが無償で利用できるのだから、使ってみる価値があると思った。大学の研究室でpythonを導入したり、学習したりする場合にも、環境の準備をほとんどすることなくいきなり始めることができるわけなので、導入の敷居はとても低くなる。とりあえず、研究室の研究なり学習でよく使うスクリプトなどをライブラリとしてアップロードした上で使えば、使用PCの条件なども問題にすることなく一斉に演習ができるというのは、かなり便利なのではないかと思う。




2019年8月18日日曜日

Dockerの導入

夏季休業の期間を利用して、以前から使いたかったDockerを導入してみた。Dockerは、Docker社が開発しているプラットフォームで、アプリケーションの単位の仮想環境を作成したり、それを配布したりすることができる(らしい)。技術的な詳細は自分には難しいのだが、いろいろな解説を見ると、普通の仮想化デスクトップが、ゲストのOSを丸ごとホストのOSの上で動かしているのに対し、コンテナ技術では、アプリケーションの単位で仮想環境が作られているらしい。説明の図には、ホストOSの上にDockerのエンジンが乗り、その上にOSではなくbinaries/librariesが乗っている図があり、(情報系の人のような正確な理解じゃないけれど)なんとなく直感的には理解できる。




バイオインフォマティクスの分野でも、BioContainersで解析プログラムがインストールできるようになっており、以前から興味を持っていた。これができれば、十年前に依存環境の問題で何十時間も費やしていた(そして結果的にビルドに失敗した!)時のような地獄から解放されるかもしれない。また、今はそこまでではないが、将来的には論文の投稿時に、解析環境を丸ごと開示するのがデフォルトになるかもしれない。なったら、多分大変だろうが、生物系の研究の再現性を担保するためには、必要な道かもしれないと最近思う(でも、純粋なバイオインフォマティクス系でない研究室にとっては、やはり重荷になると思う、最初は)。

今回は、メインに使っているMacBook Proの環境(i7、16GbRAM)の環境にdocker desktopを導入した。


1TbのSSDを積んでいるが、色々とデータが増えてそこまで余裕はない。もしdockerでアプリケーションをたくさん導入するのであれば、解析の都度使うものをpullしたり、解析が終わったものを環境ごと保存しておくために大きなディスクを持っていた方がいいのかもしれない。この辺りの感覚は、これから使っていきながら掴んでいきたい。

dockerの概要は、webの解説に載っていた。

設定としては、最初なので勝手がわからないが、とりあえずCPUs4、メモリは8Gb、Swapは1Gbとした。負荷の大きい解析には、もう少しメモリ使用量をあげたほうがいいかもしれない(そもそも、linuxのサーバーマシンの方に導入してもっとリソースが割けるようにしたほうがいいだろう。今使っているものは、xeon、96GbRAM)。


手始めに、Parliament2というマッピングの結果からゲノムの構造変異を検出するためのコーラーを導入してみた。導入は非常に簡単で、コマンド一つ(docker pull dnanexus/parliament2 )でプルすることができる。parliament2の説明を見ると、幾つもの異なるコーラーを使い、その結果を統合してくれるようだ。多分、10年前の自分であれば、これらを個別に導入するという段階で、かなり腰が引けていたと思う(そして、相次ぐbuild失敗に際限なく時間が過ぎていき、結果が出ずに、というかそもそも解析が始められずに泣きそうになっていたんじゃないかと思う、技術の進歩すごい)。これから実際の解析に使っていきたい。

試しにいくつかのプログラムがbiocontainersで利用可能になっているか確かめてみた。メジャーなもので対応しているものも多いが、登録されていないものも見つかった。そもそも導入が簡単なものは、dockerを使わないほうが余計なリソースを割かずにすみ良いのだろう。この辺りの見極めをして、良い運用方法を決めていきたい。









2019年8月17日土曜日

numpyを使った行列の計算

最近線形代数を復習している。学生の時の講義で単位は取ったはずだが、もう様々なことがうろ覚えになってしまっている。とりあえず、先月にごく簡単な本を一冊読んだ。色々とうろ覚えだったことがはっきりしてきた。ただ単に復習をしているだけのはずだが、結構楽しい(むしろ、学生の時よりも楽しいのはなぜだろう?)。これなら、まだ時間も記憶力もあった(はずの)20代の頃にもっと勉強しておけばよかったと悔やむ気持ちだ。

大学の講義では、章末問題などを解きながら計算を覚えていくが、今回は少し違ったアプローチを取って、傍らでpythonによる計算をしながら行列演算の概念を押さえようと思っている。pythonで行列の演算をするには、いくつか方法があるようだ。ごく簡単に行列っぽい扱いをするには、普通にリストが要素となっているリストを作れば良い。
List1 = [[1,2,3],[4,5,6],[7,8,9]]
print(List1)
# [[1, 2, 3], [4, 5, 6]]
これは今までにも使ってきたやり方だが、行列の演算をするには不便だ。pythonの場合、numpyのarrayやmatrixがあり、これを使えば計算ができるようだ。どちらも基本的に同じことができるようだが、名前の通り、numpy.matrixの方が二次元の行列に特化したクラスのようだ。

まずはnumpyをインポートする。定石の方法に従ってnpとしてインポートする。行列を作るときは以下のようにする。
import numpy as np
ExArr1 = np.array([[1,2,3],[4,5,6]])
print(ExArr1)
# [[1 2 3]
#  [4 5 6]]

ここでは、最初の[1,2,3]が一行目、[4,5,6]が二行目となる。または、matrixを使い、
ExMat1 = np.matrix([[1,2,3],[4,5,6]])
print(ExMat1)
# [[1 2 3]
#  [4 5 6]]
となる。
行列の積を求めるときは、numpy.dot()、numpy.matmul()、または@が使える。
Arr1 = np.array([[1,2,3],[4,5,6],[7,8,9]])
Arr2 = np.array([[1,0,0],[0,1,0],[0,0,1]])
print(np.dot(Arr1, Arr2))
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]
print(np.matmul(Arr1, Arr2))
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]
print(Arr1 @ Arr2)
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]
np.matrixについては、*でも行列の積が計算できる。注意するべきは、numpy.ndarrayでは、*を使うと行列の要素ごとの積になることだ。
Mat1 = np.matrix([[1,2,3],[4,5,6],[7,8,9]])
Mat2 = np.matrix([[1,0,0],[0,1,0],[0,0,1]])
print(Mat1*Mat2)
# [[1 2 3]
#  [4 5 6]
#  [7 8 9]]
print(Arr1*Arr2)
# [[1 0 0]
#  [0 5 0]
#  [0 0 9]]
転置行列は.Tで計算できる。
print(Arr1.T)
# [[1 4 7]
#  [2 5 8]
#  [3 6 9]]
逆行列も簡単に計算できる。**-1と.Iが使えるのはnumpy.matrixの方だけで、numpy.ndarrayでは.linalg.invだけが使える。
mat1 = np.matrix([[2,3],[1,4]])
print(mat1)
# [[2 3]
#  [1 4]]
print(mat1.I)
# [[ 0.8 -0.6]
#  [-0.2  0.4]]
print(mat1**-1)
# [[ 0.8 -0.6]
#  [-0.2  0.4]]
print(np.linalg.inv(mat1))
# [[ 0.8 -0.6]
#  [-0.2  0.4]]
こういうところが、pythonを横で書きながら勉強していった方が捗るような気がする。例えば、逆行列をかけると単位行列になるのは簡単に確かめることができる。
print(mat1 * mat1.I)
# [[1. 0.]
#  [0. 1.]]
print(mat1.I * mat1)
# [[1. 0.]
#  [0. 1.]]
こういう細かい確かめをしながら進めていくのは結構有効なのでは、と思ったのだ。教科書の例題をスクリプトに書き起こしながら読んでいくとか。そういう方法での授業や講義はされているのだろうか?

固有値問題の場合は、numpy.linalg.eig()を使う。
mat1 = np.matrix([[1,2],[-1,4]])
w, v = np.linalg.eig(mat1)
print(w)
# [2. 3.]
print(v)
# [[-0.89442719 -0.70710678]
#  [-0.4472136  -0.70710678]]
固有値がw、それぞれの固有値に対応する固有ベクトルがvの列になっている。これを使い、
print(v**-1 * mat1 * v)
# [[2. 0.]
#  [0. 3.]]
が簡単に計算してみることができる。
pythonの計算の仕方についてはこの方法で教科書の例をそのままスクリプトに書きおこす方式で一通りやってみようと思う。スクリプトを書いて計算する分には、証明を斜め読みにしながら進んでいくことも可能だろう。学び方として褒められたものではないかもしれないが。

参考:
https://note.nkmk.me
nkmkさんのサイトが充実していて、いつも参考にさせていただいている。

2019年8月6日火曜日

Timeboxing

何かの記事で、プロジェクトマネジメントの手法として使われる時間管理術の一つである、timeboxingという考え方を知った。ある決まった時間を一つのタスク、活動に当てるやり方らしい。締め切りのなし崩し的な遅れや、それに伴う人的資源の逐次投入を防ぐ役割がある(みたい)。個人の時間管理術としても用いられていて、完璧主義的な傾向を抑え、時間内に物事を終わらせるプレッシャーをかけながら作業することが良い結果につながるようだ。

Lifehackerにはこの変種版的な、location boxing という考え方が紹介されていた。こちらは、作業によって場所(オフィス、喫茶店、作業場、など)ことで、集中力を増し作業効率を上げる効果があると紹介されている。

研究に関係する似たようなtipsとして、毎日一定時間論文を書く時間を作る、というのはよく聞く。論文を書くのは面倒だったり苦しかったりすることもあり自然と後回しにされがちだが、研究の仕事は論文が受理されて出版されない限り完結しない。執筆から逃げてしまわないために、毎日決まった時間帯に30分なり1時間なり時間を決めて論文を書くことに使う(なかなか進まなくてもとりあえずその時間にはファイルを開いて論文を書くことにする)というのは、良い方法だし効果があると思う。自分は、昨年に受理された3報の論文ではこのやり方を取り入れた(ただ、最終的に徹夜して一気に書いて完成させることが多かった)。今査読されている論文は、2週間のあいだ、午後の時間を使って書いていって原稿を準備した。

作家の村上春樹が昔からエッセイで、決まった時間にタイプライターの前に座って時間が来るまで仕事して、時間が来たら筆が乗ってるかどうかに関係なくその日の仕事をおしまいにする、といった趣旨のことを書いていたと思う。これもちょっと先述の論文の書き方に似ているなと思った。何にでも、リズムを作るのは大事なのかもしれないし、決まった時間に継続して作業することで、その時間に書く準備が自分の中に整ってくるのかもしれない。

ちょっと儀式めいた作業にする、というのも何かの意味があるのかもしれない。隙間の時間にその都度論文を書くことに集中できればいいのだろうが、なかなか難しいように感じる。その作業をするにはそれに適した作業の始め方やリズムみたいなものはあるんだろう。

学生の頃の記憶で思い出したのは、違う研究室の先生が、だいたい決まった時間に大きな辞書か辞典のようなものを持って図書館に通って、研究の何かの作業をされていたことだ。人づてに聞いたところによると、学生に邪魔されずに集中する時間を作るため、とのことだった。確かに集中しようとしている時に質問などで中断するのは効率がだいぶ落ちると思う。

ロケーションボクシングの例としては、他にも三島には論文の原稿を抱えた教授が何人か出没するファミレスがある、という話を聞いた。遺伝研の先生たちは、大学よりかは雑務が少ないし静かな研究環境だと思うけれど、集中して論文を推敲したいときは、どこかに場所を移して人に邪魔されずに作業するのだろう。

大学には、割とロケーションボクシングに適した場所がある。第一は図書館だ。大抵静かだし空いている。あと、あの物量として本がたくさんある中にいるのは、何かに集中するのには良い場所だと思う。あと、今風のキャンパスにはラーニングコモンズ的なスペースがあることも多い。ただ、何度か試してみたが自分には向いていなかった。

自分も少しタイムボクシング、ロケーションボクシング的なことを自然と取り入れている。帰る前に1時間程度図書館によることがある。ここでは、研究で進めていることの続きではなく、紙ベースで論文を読んだり、ノートに書きながらやる演習的なことをすることが多い。家では、メインではないプロジェクトの解析を自由研究的にやることが多い。これは、時間を区切ってプロジェクトに従事する例だと思う。


2019年8月2日金曜日

海外学生の短期訪問プログラム

学部が海外からの学生(学部~修士学生くらいか)を短期的に受け入れ、実験や解析などの実習を各研究室で行うプログラムを実施している。韓国、インドネシア、タイなどの国から二十人ほどの学生がやってきて、3~4人程度のグループに分かれて実習を行う。このプログラムで、今日三人の学生が研究室に来た。タイ、韓国、インドネシアからやってきたらしく、みんなgraduate studentsのようだった。

研究室での実習内容は昨年と同じく、rbcSの配列をデータベースから取得してアラインメントしたのちに、系統樹の推定をした。内容的にはあまり込み入っていないので、英語で説明するのもそんなに難しくはなかった。たまに記号などの英単語が出て来ずに言い淀む事はあった。

午前中2時間半程度の時間しかないので、あまり難しい事は出来ない。昨年、今年と手伝いに入って、もう少し大量データ解析によった内容の方が今日的かなと思うことがあるものの、1日くらいのスケジュールにする必要はあるだろう。

普段英語は書いて読むだけで、声に出してのコミュニケーションは機会がないので貴重だ。学生の時の方が、留学生もいて日常的に話していた気がする。話す力を維持向上させる機会は環境によってだいぶん違う。聞くだけなら、今はネット経由でMOOCsも含めてたくさんのコンテンツがあるから、逆に容易になった。CDからiPodにちまちまダウンロードして聞いていた時代すら懐かしく感じる。

実習は一応無事に終わった。少しでも学生の役に立っていればなあと思う。