モーグルとカバとパウダーの日記

モーグルやカバ(EXカービング)山スキー(BC)などがメインの日記でした。今は仕事のコンピュータ系のネタが主になっています。以前はスパム対策関連が多かったのですが最近はディープラーニング関連が多めです。

はてなブログへの移行

長らくはてなダイアリーで書いてきましたが、とうとうはてなブログへの移行を行いました。

移行者が多かったみたいでインポートができないという問題がありましたが、今日やったところ無事に移行できました。

最近書くものは、例えば手順書だったりプレゼン資料だったり、なるべくmarkdownで書くようにしていて、逆にmarkdownで欠けなかったはてなダイアリーの内容は後から手直ししていたため、そこは便利になる感じです。

長野ディープラーニング同好会 #6

ディープラーニング同好会6回め開催しました。

長野ディープラーニング同好会 #6 - connpass https://nseg.connpass.com/event/109608/


今回は初参加の方EijiUnoharaさんがいらしたのですが、ご自分でVGG使った転移学習で猫認識とかされてたりして、色々と参考になるお話を聞けたりしました。

あと、塩尻MLもくもく会(塩尻MLもくもく会 #12)主催されてるalaskaさんにも来ていただけました。
alaskaさんがどなたかわかってなかったのですが、お会いしてやっと顔とアカウントが合致したというか、あ、alaskaさんだったんだ、というのがわかりました。


ということで、当初第6回でやろうと思ってたことはやらず、ずっとディープラーニング系のよもやま話をして過ごしてしまいました。
が、僕的にはそういう話ができてとても楽しかったです。


塩尻MLもくもく会の進め方の話を聞いて、最初にこんなネタで今日は進めよう、というのだけやって終わりにみんなでちょこっと発表、みたいなのもいいかなと思いました。


まあこじんまりとやってるので、まあその時の感じで柔軟に進めるしかないかなと思いますが。

長野ディープラーニング同好会 #5

ディープラーニング同好会5回め開催しました。

長野ディープラーニング同好会 #5 - connpass


今回は、自分が告知するのがだいぶ遅かったため、人が集まらずに2人だけでやりました。


前回の続きで、CNNで大きく位置ずれやサイズの違いがあった場合にどうやれば認識率をあげられるかを試しました。


今回は、位置ずれやスケーリングした教師画像をプログラム的に作って大量に学習させる方法を試しました。

実は前回あまりうまく行かなかったため、絶対にこれでうまくいくだろう、と思っていた方法を試したのですが… 確かにだいぶ良くはなるのですが、MNISTのような簡単な問題で、ある程度の大きさのCNNで大量の自動生成データで試しているにもかかわらず、せいぜい90%程度となってしまいました。


だいぶ負けた気分です。

が、まあたぶんこの方法でちゃんと詰めていけば、99%とかまで持っていけそうな感じはしました。


ただ、それで詰めていってもあまりおもしろくはないと思うので、次回は方針を変えて、AEを作って、その中間層に次元削減されてできた出力を使って、そこから判定してみる、というのを試してみようと思います。

長野ディープラーニング同好会 #4

ディープラーニング同好会4回め開催しました。

長野ディープラーニング同好会 #4 - connpass


やっと色々試してみれる状況になったので、前に質問の出ていた、CNNで大きく位置ずれやサイズの違いがあった場合でも認識できるのか、認識できないならどうやればできるようになるのか、を試すことになりました。


自分は単純に、ネットワークを深くして最終のDense層を少なく、1層だけとかにして学習させれば、どこかのConvで文字が認識できるようになるんでは、とか思って試したのですが、確かに良くはなるものの、そこまで画期的によくはなりませんでした。


試すために、縮小や位置ズレを作るプログラムをその場で書いていたのですが、そこで時間使いすぎてしまったかと思います。
事前準備しといて、使える部品くらい提供しないと難しいなと思いました。

長野ディープラーニング同好会 #3

ディープラーニング同好会3回め開催しました。

長野ディープラーニング同好会 #3 - connpass


今回参加者が最終的に6名になったのですが、初参加の方が3人いらしたので、前回、前々回でやったGoogle Colab使うところからはじめて、ざっとパーセプトロンバックプロパゲーション、CNNの説明して、Kerasのコード動かしてみる、というところをおさらいしました。

んでTPU使った場合とGPU使った場合とでの速度比較もやってみました。
ただ、だいぶ時間なかったのでコード走らせて速度比較しただけで、どこ修正すればいいかとかまでは出来ずでしたが。

TPU使う場合の変更点としては下記エントリー参照ください。
Google ColabでKerasからTPUを使う方法とGPUとの速度差


これまでの3回、最初のブートストラップのところを何度もやることになってしまってますが、そんなに参加者も多くないので、今のところは、なるべく興味ある方全員を拾っていけたらな、と思います。


次回は、いろいろとデータセットやネットワークをいじって、いろいろと実験できたらいいなと思ってます。

Google ColabでKerasからTPUを使う方法とGPUとの速度差

必要なことまとめ

  • ランタイムで「TPU」を選択する
  • kerasではなくtensorflow.kerasを使う
  • modelをTPU用のモデルに変換する
  • TPUモデルではpredictができないので確認はCPUモデルに戻して行う


Google ColabでTPU使うのは、こちらの記事が詳しいです。自分もこちらを参考に試しました。
Google ColaboratoryのTPUを試してみる

またCholletさんが紹介されてた公式?のノートがあり、必要なコードがまとまってるのでおすすめです。
Keras Fashion MNIST and TPUs - Colaboratory

ランタイムで「TPU」を選択する

まず、仮想マシンのタイプを「TPU」が利用できるものに変更します。

ランタイム→ランタイムのタイプを変更→TPU

kerasではなくtensorflow.kerasを使う

下記のように「keras」からのものを使うとTPU未対応のためエラーが出て動きません。

from keras.models import Sequential
model = Sequential()

「keras」を「tensorflow.keras」にすべて置き換えてやる必要があります。

from tensorflow.keras.models import Sequential
model = Sequential()

modelをTPU用のモデルに変換する

modelは普通にそのまま作れますが、その作ったモデルをkeras_to_tpu_modelを使ってTPU用のモデルに変換して、compileやfitします。
また、model生成にはOSからTPU情報取得して渡す必要があります。

import tensorflow as tf
import os
tpu_model = tf.contrib.tpu.keras_to_tpu_model(
    model,
    strategy=tf.contrib.tpu.TPUDistributionStrategy(
        tf.contrib.cluster_resolver.TPUClusterResolver(tpu='grpc://' + os.environ['COLAB_TPU_ADDR'])
    )
)

tpu_model.compile(...)
tpu_model.fit(...)

ランタイムでGPU選択しただけでGPUが使えるため、ついTPUを選択しただけで早くなるのかと思ってしまいがちですが、変換しないとCPUのみになるのでめちゃ遅いので注意です。

TPUモデルではpredictができないので確認はCPUモデルに戻して行う

tpu_model.predict()がないため、学習後の重みを使って出力させることができません。
どうするのかな?と思ったら、CPUモデルに戻してやってそれでpredictする必要があるようです。

cpu_model = tpu_model.sync_to_cpu()
cpu_model.predict(...)

ColabのGPUとTPUランタイムでの速度差

Keras Fashion MNIST and TPUs - Colaboratory で使われている Conv2D x3 + Dense x2 のサンプルでは

GPU: 235秒
TPU: 89秒

となり、2.6倍程度の速度でした。

が、TPUはバッチサイズをもっと大きくすることができ、またネットワークサイズをGPUよりもだいぶ大きくして動かすことができます。
ネットワークサイズが大きくなるほど差が大きくなる感じです。

長野ディープラーニング同好会 #2

ディープラーニング同好会2回め開催しました。

長野ディープラーニング同好会 #2 - connpass


Google Colab使ってMNIST(数字認識)させるのの続きということで、前回はバックプロパゲーションを3層とか4層でやったのですが、今回はCNNで行いました。

以前やったディープラーニングハンズオンに参加されてない方もいたので、簡単に畳み込み層とプーリング層についての説明とかしたのですが、そこから話が深くなり、プーリングで位置ずれを吸収すると言ってもそんなに大きくは吸収できないのでは、というような質問が出ました。
例えば、画面いっぱいに「あ」と書いてあるので認識できるようになっても、画面1/4のサイズで端っこに「あ」があったら認識できないのでは、というものです。
CNNの下の方の層でもう「あ」が認識されてしまう状況ならたぶんどこにあっても認識されるはず(つまり「あ」という「部品」として認識可能になってる)だけど、層が浅くて最後のBPのフルコネクトでやっと認識できる状況だと、そういう状況になりそうと話しました。


この辺は次回でみんなで試せたらなと思います。

Google Colabで生成した動画をインライン表示する

つくりながら学ぶ!深層強化学習」という本の中で、CartPoleなどで動画を生成して表示しているものがあります。

Google Colab上で実行している場合、本の例ではそのまま動画で表示することができないのですが、Colab(Jupyter)のセル上で動画表示可能にすることができるようにしました。

といっても、こちらの「ChainerRL を Colaboratory で動かす - Qiita」を参考にさせていただいただけなのですが。


下記のように必要なツールやライブラリを入れて、HTMLへの出力(Javascriptでのアニメーション化)を利用します。

必要なツールやライブラリのインストール

!apt -qq install xvfb ffmpeg> /dev/null
!pip -q install gym
!pip -q install JSAnimation
!pip -q install pyglet==1.2.4
!pip -q install pyopengl
!pip -q install pyvirtualdisplay
!apt -qq install python-opengl

出力用の仮想ディスプレイを生成

from pyvirtualdisplay import Display
display = Display(visible=0, size=(1024, 768))
display.start()
import os
os.environ["DISPLAY"] = ":" + str(display.display) + "." + str(display.screen)

必要なPythonのライブラリをimport

import matplotlib
import gym
import JSAnimation
import pyglet
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

CartPoleの動きをランダムで行わせる

frames = []
env = gym.make('CartPole-v0')
observation = env.reset()

for step in range(0, 200):
  frames.append(env.render(mode='rgb_array'))
  action = np.random.choice(2)
  observation, reward, done, info = env.step(action)

動画をフレームごとに生成して表示

from JSAnimation.IPython_display import display_animation
from matplotlib import animation
from IPython.display import HTML

plt.figure(figsize=(frames[0].shape[1]/72.0, frames[0].shape[0]/72.0), dpi=72)
patch = plt.imshow(frames[0])
plt.axis('off')
  
def animate(i):
  patch.set_data(frames[i])
    
anim = matplotlib.animation.FuncAnimation(plt.gcf(), animate, frames=len(frames), interval=50)
HTML(anim.to_jshtml())

長野ディープラーニング同好会 #1

平日夜隔週でGEEKLAB長野さんとこで、ディープラーニングについての勉強会をやることになりました。
ただ、「勉強会」というよりもうちょっとゆるくしたかったので「同好会」としてみました。


長野ディープラーニング同好会 #1 - connpass


プレ回みたいなのを8月末にやったのですが、そこで話し合って、1回ごとや何回かで出来るような小さな課題を決めてみんなで試す、という方針でやってみることにしました。


初回は、ディープラーニングの「Hello World」ということで

  • Google Colab使ってMNIST(数字認識)させてみる

ということをやりました。


Colabを使うので環境構築とかは全くしなくて良いのではまらないだろう、と思っていたのですが、集まっためんつのうち3人がPCではなくタブレットで、Colabだからそれでも問題ないだろうと思ったのですけども、それだとGoogle DriveからColabの呼び出しがうまく行かず、それをどうしたらいいかでだいぶはまりました。

Google Driveをアプリではなく、Webページから入って使うとうまくいくのですが、そのためには一旦Google Driveのアプリをアンインストールしないといけないとか、謎な知見がたまりました。


その後あまり時間がなくなってしまったんで、簡単にバックプロパゲーションとKerasの説明おさらいをして、3層とか4層のバックプロパゲーションで認識ができるようになること、5層でもシグモイド関数だとぜんぜん性能でないことなんかを試しました。

Google ColabでPyTorchを使う

Google ColabはGoogleアカウントさえあれば即時TensorFlowの入ったJupyter環境が使えて、さらになんとめちゃ高いGPUまで使えちゃうという、まあいたれりつくせりで超おすすめです。
が、最近arXivとかで公開されてる論文のソースがPyTorchが使われてることも多く、PyTorchも使いたいなあと思うわけです。
でもGoogle Colab環境にPyTorchは入ってないんですよね。


(追記)
Colabの「コードスニペット」から「Install [pytorch](http://pytorch.org/)」を選択して実行すればできるようになっていました。
そちらをおすすめします。


で、Google ColabでPyTorch 0.4使うためにどうしたらいいかを調べたところ、下記内容でばっちり動かせるようになりました。

Pytorch 0.4.0 on Google colab - PyTorch Forums


下記コードをコードセルの最初に貼って実行すればOKです。
ランタイムGPU使うようにしてあれば、ちゃんとGPU使えるようになります。
pipでpytorchのインストールから行うことになりますが、そこまでは時間かかりません。

from os import path
from wheel.pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag
platform = '{}{}-{}'.format(get_abbr_impl(), get_impl_ver(), get_abi_tag())

accelerator = 'cu80' if path.exists('/opt/bin/nvidia-smi') else 'cpu'

!pip install -q http://download.pytorch.org/whl/{accelerator}/torch-0.4.0-{platform}-linux_x86_64.whl torchvision
import torch
print(torch.__version__)
print(torch.cuda.is_available())

出力セルにこんなふうに表示されたらOKです。
もし最後の行がFalseになってるときはGPU使えてない状態です。

tcmalloc: large alloc 1073750016 bytes == 0x5bd9a000 @  0x7fb18556f1c4 0x46d6a4 0x5fcbcc 0x4c494d 0x54f3c4 0x553aaf 0x54e4c8 0x54f4f6 0x553aaf 0x54efc1 0x54f24d 0x553aaf 0x54efc1 0x54f24d 0x553aaf 0x54efc1 0x54f24d 0x551ee0 0x54e4c8 0x54f4f6 0x553aaf 0x54efc1 0x54f24d 0x551ee0 0x54efc1 0x54f24d 0x551ee0 0x54e4c8 0x54f4f6 0x553aaf 0x54e4c8
0.4.0
True