読者です 読者をやめる 読者になる 読者になる

kaggleの練習コンペDogs vs. Catsに出場

machine learning kaggle

Kaggleで開催されていた練習用コンテスト Dogs vs. Cats Redux: Kernels Edition | Kaggle に参加しました。このコンテストでは、画像の中に犬または猫のどちらが映っているかを識別する識別器を学習し、その性能を競います。通常では犬か猫かの2値で答える問題設定が多いかと思いますが、このコンペでは犬か猫かの確率値を0.0から1.0の間の実数値で答えます。

結果は1314人中74位で、上位6%に入ったといえば聞こえはいいのですが、実態は手も足も出なかったという印象です。以下、簡単なメモです。

実装1: Chainer

まずはChainerを使ってDeepNetの自力実装を試みました。ディープラーニングの様々なモデルを使ってCIFAR-10画像データセットの分類を行う - Qiita のVGG likeなモデルを参考に、与えられた学習データのみを使ってスクラッチからのモデルの学習を試みました。

入力画像をGTX 1070のメモリが許す限り大きくしたり(144x144の画像からランダムな位置で128x128の画像を切り出し)、on-the-flyで画像に摂動を加えて水増ししたり、出力層をsigmoid cross entropyにして確率値を出せるようにしたりなど、思いつきそうな工夫をあれこれ入れました。しかしエラー値0.13(正解率にして95%程度、順位にして約50%のあたり)程度で足踏みしてしまいました。感覚的にはもう少しよい値が出そうだと感じましたが、これがネットワークの限界なのか、学習方法に何らかの不備があるのかは不明です。

実装2: Keras

Kaggleではコンペ中も掲示板形式で参加者同士の議論が公開されています。その中に、Kerasの70行ほどのコードでエラー値0.06を出すサンプルが掲載されていました(Dogs vs. Cats Redux: Kernels Edition | Kaggle)。このコードでは、あらかじめ学習済のネットワークを特徴量抽出器として流用し、犬猫判別の判別器部分のみを学習する、いわゆる転移学習が行われています。

このコードを使うと、あっさりとエラー値0.059が出ました。転移学習恐るべしです。さらに小手先の閾値調整(値の範囲をクリッピングして、誤分類時のペナルティを下げるなど)を実施して、エラー値が0.05164(正解率にして99%程度)まで下がりました。

感想

学習データが数万枚オーダーで存在したためスクラッチで学習してもそれなりの精度が出ることを期待しましたが、実際は転移学習によるサンプルコードの性能に遥か及びませんでした。

今回はほぼサンプルコードを動かしただけで終わってしまいましたが、次回は最低一つくらいは何らかの工夫を加えてサンプルコードよりよい成績を狙いたいと思います。また、Discussionをくまなくチェックし、素早く巨人の肩に乗る練習も行いたいと思います。

自作PCにUbuntu 16.10をインストール

linux

Core i7 7700 + GTX 1070 なPCを自作 - minus9d’s diary の続き。自作したPCにUbuntu 16.10をインストールしました。初物ハードウェアということでインストールがうまくいくか不安で、実際トラブルもありましたが、今のところ順調に動いています。

USBメディアの作成

今回はEtcher by resin.ioを使いました。

Ubuntu 16.10のインストールとトラブル

作成したUSBからブートしてUbuntu 16.10をSSDにインストールしました。インストール自体は問題なく終了しましたが、マウスポインタが画面の左上に固定されて動かないトラブルが発生しました。

GPUのドライバーを入れると直るという記事を読んだため、nVidiaの公式から最新のドライバー (現時点で NVIDIA-Linux-x86_64-375.26.run)を取得し、drivers - How to install NVIDIA.run? - Ask Ubuntu に従いドライバーのインストールを試みました。

しかし、途中で ERROR: The Nouveau kernel driver is currently in use by your system. This driver is incompatible with the NVIDIA driver, and must be disabled before proceeding. Please consult the NVIDIA driver README and your Linux distribution's documentation for details on how to correctly disable the Nouveau kernel driver. というエラーが出てインストールに失敗します。どうやらUbuntuにプリインストールされているNouveauというOSSのドライバーと競合しているようです。

そこで、nvidia - How do I disable the “Nouveau Kernel Driver”? - Ask Ubuntu に従い、sudo update-initramfs -u を行ってからNVIDIA-Linux-x86_64-375.26.runを実行することで、ドライバーのインストールに成功しました。他の回答にある /etc/modprobe.d/nvidia-graphics-drivers.confファイルの手修正は、自分の場合は不要でした。

ドライバーを入れたあとは、マウスカーソルを自由に動かせるようになりました。LogicoolのマラソンマウスM705(Logicool独自のUnifyingを使用)も、ドングルを刺すだけで使えています。

nvidia cuda toolkitのインストール

cudaのインストールに関しては Install GPU TensorFlow From Sources w/ Ubuntu 16.04 and Cuda 8.0 – Justin’s Blog が参考になります。

CUDA 8.0 Downloads | NVIDIA Developer から、Ubuntu 16.04向けのrunファイルをダウンロードしました。単にsudo sh cuda_8.0.61_375.26_linux.runとするとError: unsupported compiler: 6.2.0. Use --override to override this check.というエラーが出てインストールに失敗したため、sudo sh cuda_8.0.61_375.26_linux.run --overrideとしてインストールしました。本当に問題がないかは不明です。

実際、pipでtensorflow-gpuとkerasを入れた後、keras/examples/mnist_cnn.pyを実行すると、3エポック目の途中のおそらくほぼ同じ場所でOSごと落ちるという現象を確認しています。これが原因かは不明です。

CapsをCtrlに変更

keyboard - How do I remap the Caps Lock and Ctrl keys? - Ask Ubuntu に従い、gnome-tweak-tool を使います。CapsとCtrlの入れ替えも試しましたが、terminalでCtrl + Shift + Tabによるタブ追加が効かなくなったので、Capsを潰してCtrlにしました。

Core i7 7700 + GTX 1070 なPCを自作

2010年に購入し、パーツを継ぎ足しつつ愛用していたDellXPS 8100。もはやベンチマークの比較対象にならなくなったCore i7の第一世代を積んだPCで、ちょっとした開発程度なら問題はないものの、本格的な開発をするには限界を感じ始めたため、一念発起してPCを新調することにしました。

BTOストアで購入した場合のシミュレーションをコスパ最強GTX1070搭載のおすすめゲーミングBTO PCを徹底比較! : 自作とゲームと趣味の日々を参考に行ったのですが、理想的な構成に変更すると思いの外高価になったため、初の自作を試みるに至りました。

パーツの選定

獲得したポイント分を差し引いて14万円強の出費でした。以下にその内訳を記します。購入金額はすべて税込です。

CPU: Intel Core i7 7700

オーバークロックありの7700kとなしの7700で迷いましたが、初の自作でオーバークロックはリスキーだと考え7700を選択しました。

マザーボード: ASUS STRIX H270F GAMING

自作だとASUSが定番だと聞いていたので、ASUSで決め打ちにして検討を開始しました。

まずチップセットの違いを【Kaby Lake】Z270, H270, B250チップセットの違いについてで学びました。Z270はH270やB250と異なりCPUのオーバークロックnVidiaGPUのSLIを可能にしますが、いずれも自分が行う可能性は低いため、H270のマザボから選ぶことにしました。

最初はPRIME H270-PROを買う予定だったのですが、途中でROG STRIX H270F GAMINGに変えました。"GAMING"と名のつくマザーボードは、GPUの刺し口である PCI Express 3.0 x16がSafeSlotと呼ばれる機構で補強されています。そのため、重量級のGPUを刺した時の耐久性が増しているようです。どこまで神経質になるべきかは分かりませんが。

メモリ: Crucial DDR4-2400

メモリはCrucialの8GB * 2です。

パソコン工房はCPU、マザーボードとメモリの3点セットを販売しています。パソコン工房 楽天市場店で購入(【楽天市場】[お買い得3点セット]Intel Core i7 7700+DDR4-2400 8GB×2枚+ASUS STRIX H270F GAMING 3点セット:パソコン工房 楽天市場店)し、67,020円 + ポイント6%でした。

GPU: ASUS ROG STRIX-GTX1070-8G-GAMING

TSUKUMOの店頭で5万円を切っていたので購入。48,078円でした。GTX1070-O8Gモデルよりも若干クロック数が劣ります。大きい分ファンが3個付いており静かです。

ストレージ: Crucial SSD MX300 525GB M.2 Type CT525MX300SSD4

最近のマザボにはM.2と呼ばれるスロットがあり、ここにSSDを装着できると聞き、付けてみることにしました。

Amazon.co.jpで16,696円でした。購入してから気付いたのですが、M.2スロットに挿して使うSSDには、SATAタイプとPCIeタイプの2種類があり、PCIeタイプのほうが高速だそうです (M.2 SSD は SATA? PCI Express? ソケットの種類)。私は値段だけ見て適当に買ってしまったので、SATAタイプのものを買ってしまいました。PCIeタイプのほうがSATAタイプのものよりかなり高額とはいえ、せっかくなのでPCIeタイプを買って最先端の速度を体験したかった気もします。しかし、PC内の配線が2本いらなくなるというメリットは享受できており、一定の効果は感じます。

ところで、私が購入したH270F GAMINGは2つのM.2スロットを備えますが、そのうち1つはSATAタイプとPCIeタイプの両方を受け付けるものの、もう1つはPCIeタイプのものしか受け付けません。購入の際には注意が必要です。

電源: Corsair CX650M 80PLUS BRONZE

価格.comの売れ筋ランキング1位のものを選びました。ヨドバシカメラで7,820円 + ポイント10%でした。

パソコンケース: SAMA 黒鉄

価格.comの売れ筋ランキング1位の価格.com - SAMA 黒透 JAX-02W 価格比較でいいかと思ったのですが、側面がアクリルで透けて見えるのは落ち着かなさそうだったので、サイドパネルが非アクリルである JAX-02 黒鉄 kurotetsu | パソコン工房【公式通販】 を購入しました。パソコン工房で3,980円でした。

無線LAN 子機: BUFFALO Air Station WLI-UC-G301N

LinuxのUSB無線LAN子機の対応状況 - Qiita で、Linuxでの動作実績を調べ、手軽な値段の本品を購入しました。実際、ドライバのインストールをすることなく、刺すだけで認識してくれました。Amazon.co.jpで1,267円でした。

OS: なし

自分を追い込むためOSは買いませんでした。そのうち日和ってWindowsを買うかもしれません。

組み立て

パソコンケースに説明書がなく組み立てに苦労しましたが、画像検索でこのケースを使っている人を見つけてなんとか組み立てできました。3時間くらいかかったと思います。

マザーボードの上部にある電源コネクタ(EATX12V)へ電源線が届かずどうしようかと思いましたが、電源から真上方向に線を這わせることで接続できました。光学ドライブも省略し、M.2 SSDを採用したため配線は必要最小限で、これならMicro-ATXを選択するのもありだったかなと思います。

M.2 SSDの装着時には、マザーボードに付属するスペーサーを使って底上げをする必要があります。最初このことをしらず、スペーサー無しで接続し、通電してしまっていました。

windows 10 + cuda + chainer で corecrt.h が見つからない問題

python Windows

Windowsに正式対応していないchainerをwindowsで動かす際のエラーについてメモします。

環境

現象

GPUを利用するchainerのコードを実行すると、以下のようにcuda絡みのエラーが出て実行に失敗しました。

  File "C:\Users\(ユーザ名)\Anaconda3\lib\site-packages\chainer\initializers\normal.py", line 31, in __call__
    loc=0.0, scale=self.scale, size=array.shape)
  File "cupy/core/core.pyx", line 1260, in cupy.core.core.ndarray.__setitem__ (cupy\core\core.cpp:24263)
  File "cupy/core/core.pyx", line 2336, in cupy.core.core._scatter_op (cupy\core\core.cpp:59948)
  File "cupy/core/core.pyx", line 1496, in cupy.core.core.elementwise_copy (cupy\core\core.cpp:51768)
  File "cupy/core/elementwise.pxi", line 774, in cupy.core.core.ufunc.__call__ (cupy\core\core.cpp:42682)
  File "cupy/util.pyx", line 37, in cupy.util.memoize.decorator.ret (cupy\util.cpp:1283)
  File "cupy/core/elementwise.pxi", line 582, in cupy.core.core._get_ufunc_kernel (cupy\core\core.cpp:39296)
  File "cupy/core/elementwise.pxi", line 32, in cupy.core.core._get_simple_elementwise_kernel (cupy\core\core.cpp:29818)
  File "cupy/core/carray.pxi", line 87, in cupy.core.core.compile_with_cache (cupy\core\core.cpp:29505)
  File "C:\Users\(ユーザ名)\Anaconda3\lib\site-packages\cupy\cuda\compiler.py", line 131, in compile_with_cache
    base = _empty_file_preprocess_cache[env] = preprocess('', options)
  File "C:\Users\(ユーザ名)\Anaconda3\lib\site-packages\cupy\cuda\compiler.py", line 94, in preprocess
    pp_src = _run_nvcc(cmd, root_dir)
  File "C:\Users\(ユーザ名)\Anaconda3\lib\site-packages\cupy\cuda\compiler.py", line 56, in _run_nvcc
    raise RuntimeError(msg)
RuntimeError: `nvcc` command returns non-zero exit status.
command: ['nvcc', '--preprocess', '-Xcompiler', '/wd 4819', '-m64', 'C:\\Users\\(ユーザ名)\\AppData\\Local\\Temp\\tmp_c64g0d4\\kern.cu']
return-code: 2
stdout/stderr:
b'kern.cu\r\n#line 1

...(中略)...

#line 320 "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/../../VC/INCLUDE\\\\vcruntime.h"\r\n#line 10 "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/../../VC/INCLUDE\\\\crtdefs.h"\r\nC:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/../../VC/INCLUDE\\crtdefs.h(10): fatal error C1083: include (略) \'corecrt.h\':No such file or directory\r\nnvcc warning : The \'compute_20\', \'sm_20\', and \'sm_21\' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).\r\n'

試したこと1

corecrt.hが見つからないというエラー文をヒントに検索したところ、 Qtでcorecrt.hが見つからないと言われる問題 - あくまで個人的メモ用ブログ に「「ユニバーサルWindowsアプリ開発ツール」をインストールすることで直った」という報告が見つかりました。

しかし、残念ながら私の環境では直りませんでした。

試したこと2

「開発者コマンドプロンプト for VS2015」を起動し、このコマンドプロンプトを使ってpythonスクリプトを実行することで、上記エラーが出なくなることを確認しました。

「開発者コマンドプロンプト for VS2015」にてecho %INCLUDE%すると、corecrt.hを含むディレクトリであるC:\Program Files (x86)\Windows Kits\10\include\10.0.14393.0\ucrt;が登録されていることが分かります。このおかげのように思われますが、自信はありません。

pythonのsplit関数を使って空白文字で分割するときの注意点

python

pythonのsplit関数を使うと、文字列をある文字で分割することができます。

例えば、カンマで文字列を分割するには以下のようにします。

s = "a,b,c"
print(s.split(','))  # ['a', 'b', 'c']

s.split()s.split(' ')は同じ出力となると勘違いしていましたが、実際は以下のように挙動が異なるので注意が必要です。

s = "a b  c"
print(s.split())    # ['a', 'b', 'c']
print(s.split(' ')) # ['a', 'b', '', 'c']

s.split()では連続する空白をひとまとめに扱いますが、s.split(' ')は連続する空白をそれぞれ別々に分割していることが分かります。 python 2.7とpython 3.5で動作確認をしました。

multiset, multimapを使うにはset, mapをinclude

C++

しょうもないネタですが他にもハマる人がいるかもしれないので記事にします。C++11から導入されたstd::multiset, std::multimapを使おうと以下のコードを書きました。

#include <multiset>
#include <multimap>

しかしg++で以下のエラーが出ます。

致命的エラー: multimap: No such file or directory
 #include <multimap>

map, setをincludeするのが正しい方法です。これでstd::multiset, std::multimapが使えるようになります。

#include <set>
#include <map>

cygwinで日本語を含むutf-8ファイルをクリップボードにコピーする方法

cygwin

cygwinで日本語を含むutf-8ファイル(例えばaaa.txt)をクリップボードにコピーするには以下のコマンドを使います。

$ cat aaa.txt > /dev/clipboard

以下のコマンドだと文字化けしてしまうようです。

$ clip < aaa.txt