「オブジェクト指向と10年戦ってわかったこと」が素晴らしかった
これです。
自分はJava使い*1なのですが、オブジェクト指向の価値を全然活かせていないなぁと常々思っていました。
色々原因がありそうですが、この記事にあるようにしっかり考えてないからだ、ということがわかりました。
幾つか、自分に刺さったところを自分のために引用しておきます。
気になった人はリンク先の本文をぜひ読んでください。
クラスはとっかえひっかえするものをクラスにする
オブジェクト指向で書く理由、それは変更に対して柔軟に対応するためです。
(省略)
オブジェクト指向によるアプリケーション開発は、変更されない箇所を軸に、頻繁に変更される箇所をクラスに抽出するプログラミングスタイルです。
継承は様々な具体的なクラスを抽象化するためのボトムアッププロセスで、トップダウンにすべきではない
継承は機能を受け継ぐためのものではありません。継承の本質は、犬や猫を「動物」という抽象概念としてまとめ上げられるインターフェイスなのです。
その証拠として、別のクラスの機能を利用する方法にコンポジションがあります。コンポジションを使えば人間がパーツを組み合わせて「車」を作るような自然なオブジェクトの作り方ができるし、実は継承よりコンポジションの方がよく使います。
ポリモーフィズムは抽象のスーパークラスを扱う(ことによって見通しを良くする)
継承の本質はインターフェイスであると説明しましたが、ポリモーフィズムはそのインターフェイス(抽象)に対してプログラムするということです。
インスタンスをnewするのはメインクラス。メインクラスは素材を出して処理する調理場。
そのため、ファクトリを作るまでもないインスタンス生成はメインクラスで行うようにしましょう。メインクラスでnewしたインスタンスを他のクラスに渡すのです!
(省略)
メインクラスは調理場のような存在であり、メインクラスに疎結合性やモジュール性は必要ありません。そのため、メインクラスがnewの接着剤でベトベトに汚れてしまっても何も困ることはないのです。
カプセル化は難しい
しかし、小刻みにブレーキを踏まなければスリップし、小まめにギアチェンジする必要があり、カーブするときは倒れないように体重移動をしなければ倒れてしまう自動車があったら、僕はそれを運転できません。複雑だからです。だけど、ブレーキにはABSを搭載し、ギアはオートマチックで、カーブするときは倒れないよう重心が設計されていれば、あれこれ考えず運転できます。
つまりカプセル化とは複雑な部分を隠し、無駄な操作をしなくても良い状態にそのものを洗練させ、分かりやすい状態にするということです。
(省略)
実はこの「無駄を省き洗練させてわかりやすくする」というのはオブジェクト指向の原則というより、より抽象度の高い「デザイン」の原則なのです。
オブジェクト指向に不可欠なのはカプセル化ですから、つまり、オブジェクト指向でプログラミングする人にはデザインのセンスが必要になるということになります。
そんなもの、難しくて当然です!
カプセルにはただしい名前が必要
自動車には「自動車」という名前が、エレベーターには「エレベーター」という名前が付けられています。もしあなたが何かをカプセル化した場合、そのものにまだ名前が付いていない時は、それに正しい名前をつけるということが、カプセル化の最後の仕上げになります
Vagrantで仮想マシンぽこぽこ(Docker, Jenkinsへの道 on Windows(1))
ちょっとアレでアレなので、DockerとかJenkinsとかいう流行りものを触るだけでも触っておきたい*1という動機が出てきました。
で、いろいろ調べると、こういうものは仮想開発環境による開発/テスト/サービスデプロイ環境の環境同定・構築のために使うのが基本らしいということがおぼろげながらわかってきました。*2。
なのでもう1からやってみようということで、まずはVagrantによる仮想マシン環境のセットアップから。
参考にするのは
Vagrant始めました — | サイオスOSS | サイオステクノロジー
Windows上でVirtualBox+Vagrant+CentOSによる仮想環境構築 - Qiita
です。
Vagrantとは
仮想マシンソフトを簡単に使うためのフロントエンドとなるツール、らしい。
特に仮想環境をたくさん使ったりあるいは頻繁に変えるようなお仕事状況ではいちいちVMware/VirtualBoxでぽちぽちインストールとかしてらんないので、
仮想マシン+仮想OS環境の設定ファイルとイメージをコマンド一つで呼んで仮想環境を起動・破棄できるようにする
のがメインのご利益ぽい。
まずは仮想マシンソフトのインストール
ここではVagrantのデフォルトらしい、OracleのVirtualBox. VMwareだと面倒っぽいので。
ここからWindows 64bit用のインストーラをダウンロードしてインストールです。
何も考えることなくインストール完了。
Vagrantのインストール
Vagrantも公式HPからダウンロードしてインストールします。
今回はwindowsなのでインストーラ持ってきてインストール。
cmd.exeでvagrantのバージョンが出ればひとまず成功。
OSのイメージをゲット(Vagarnt box)
VagarantのOSその他設定ファイルイメージであるところの"box"をダウンロード。これを読み込んであげれば仮想環境(VirtualBox)上でLinuxが立ち上がるって寸法だな?
今回はCentOS6.5を選択。
cmd.exeでgithubからダウンロード。
$ vagrant box add centos65 https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box
よしよし。
$vagrant box list
centos65 (virtualbox, 0)
でcentos65ができていればOK.
いよいよ仮想OS起動!
まずは作業ディレクトリを作って初期化。
$ mkdir centos
$ cd centos
$ vagrat init centos65
Vagrantファイルができたので初期修正が必要だよ。GUIを入れましょう。
さあ、upすればCentOSが来るよ
$vagrant up
キターーーーー!
あとは好きなbox取ってくれば同じ要領でいくらでも仮想環境を作れますね!
最後に
vagrant、以下のプラグインは入れておいたほうがよさそうです
vagrant-winnfsd
vagrant-vbguest
vagrant-proxyconf
有益情報ですね(VMware + Ubuntu on Windowsとか)
埼玉大学の後藤先生(http://www.ke.ics.saitama-u.ac.jp/)が、ご自身の研究室HPで公開されている、「研究室メンバー向け」コンテンツが非常に良いです。
特に、「Ubuntuで作業環境を整えよう」(http://www.aise.ics.saitama-u.ac.jp/~gotoh/HowToUbuntu.html)はup-to-dateでメンテされているのでとても助かります。
ご自身の研究室運営のためのコンテンツなのだと思いますが、それをこうやって公開していただけると多くの社会人も助かります。
調べたら自分とあまり歳変わらないんですね・・・・やっぱり大学でポスト得る人たちはすごいです。
JUnitよちよち歩き on IntelliJ Idea
itelliJ idea上でJUnit4使ってテストコードを書くという練習。
基本的に"JUnit 実践入門"の第一章をreproduceするのが目的。
JUnitのjarをゲットする
なにはともあれ、JUnitのjarをゲットしましょう。
junit-4.12.jarとhamcrest-core-1.3.jarをゲットしておきます。
projectの準備
適当なところに新規プロジェクトを作成して、junit-tutorialという名前にします。
モジュール名もjunit-tutorialでいいや。
で、引き続きテストコード用のソースルートを作成します。
testというディレクトリをつくって、project structureとかでtestのディレクトリに設定。緑色になります。
あと、project structure -> modulesでjunitとhamcrestのjarを追加します。
するとこんな感じ。
テストにかけるクラスを書いてテストのひな形を生成
教科書にある通りCalculatorクラスを書きます。
エディター上でテストしたいクラス名(public Calculator)を右クリックしたらtestを生成するっぽいコマンドが出てくるのでテストのひな形を生成します。
(go to --> test --> create a new test. )
テストの設定はJunit4を選択。
適当にcode templateを整備しておくと、こんなのができるのであとは実装とテストですね。
この状態ではテストメソッドは何も実装していなくて、デフォルトでfailが出るようになっているので、runすると
無事に失敗します。
実装してテストする
ということで、multiplyとdivideのテストメソッドを作ってみる。
あと、Caculator.divideをfloat割り算するように修正。
めでたし!
例外処理のテスト
例外処理をテストするときには、@Testの後に出てきてほしい例外のクラス名を書いておくと、例外がでると成功、というテストになる。
例えば、除算のゼロ割でIllegalArgumentExceptionをthrowさせるように変更しておく。
これのテストの書き方と結果。
めでたしめでたし!これで1章を突破した。
moses on Cygwin/Windows
いまちょっと個人的にstatistical machine translationに興味があるので、とりあえずmosesをインストールして動かしてみよう!ってなった。
まずはありものの言語モデル等でmosesを動かすことが目標。
あと仕事じゃないので家のWIndows、すなわちCygwin環境での実行。
Cygwinインストール
まずは本家Cygwinからsetup.exeをダウンロードして使う。
cygwinのインストールは基本的にsetup.exe使うだけだけど、設定とかは
を参照しました。
lapack, boost, ssh emacs, zip, bzip, libtools, ncurses,wget,automake,zshなど思いつくものを全部入れる。
ターミナルから右クリックとかでメニューとか、Cygwinオワコンとかいう人もいるけど着実に便利になってるよね。
を実施します。
mosesと関連ライブラリ
mosesのインストールについては
が参考になりました。ただ、そのままでは通らないところもあったので
そこは試行錯誤。
まずはGIZA++はそのまま入りました。
SRILMはなぜかインストールがどうしても通らなかったので
IRSTLMだけインストールしています。
次のページ、boostはcygwinでパッケージされているのでパス。
mosesのインストールですが、
インストールコマンドは
./bjam -jX (XはCPU数)
だけでした。オプションつけると逆に動きません。
まずはテスト
この段階で欧米言語なら動くので、
にあるとおりにサンプルコードをダウンロードしてテスト。
Das ist eine klines haus. を翻訳する。
実行ディレクトリにnbest.txtというファイルができて、
おお、ちゃんと並んでいる!
日本語もやりたい
のでMecabを次はインストールしよう.
試行錯誤の挙句、
で配布してくれているパッチを当ててようやくmecabのインストールに成功。
Binary DNNs: articles(自分のメモもかねて)
岡野原さんのツイートで、binary netが話題になっていますね。重みも出力もすべて1 or -1に制限しても、性能が落ちずに計算が早くなると話題です。
この著者はNIPS2015でその前身の話を出しています。この時はアップデートする時だけバイナリにしているのでBinaryNetほど効率的ではないですし、なんとも歯切れの悪い内容になっていました。
あと、同じチームがICLR206にもsubmitしてますね。日付を見るとこれはbinarynetの前なので、結局binarynetが最新結果(一番大胆なことをしている)ことになります。
[1510.03009] Neural Networks with Few Multiplications
あと、最新のAAAIでも似たような話があります。ここではbackward方向だけ重みを変えていて、結局重みの符号だけが大事ということです。まだ会議の参加者限定でopenではないはずなのでリンクは張りませんが・・・
"How Important is Weight Symmetry in Backpropagation?", Liao, Leibo, and Poggio, in AAAI 2016.
以上眺めると、binary netにあるように全部バイナリでモデル化するのは問題がなさそうということですね。あとはこのためにgpu codeレベルで最適化されたコードが書けるかどうか、ということになりそうですね・・・
あ、そういえば岡谷先生の深層学習本@機械学習プロフェッショナルシリーズは通読しましたけど、素晴らしすぎる出来でしたのでオススメ