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

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

長野ディープラーニング同好会 #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

NSEG勉強会#101

先月末6/30(土)に「メールとコミュニケーションツール」というお題でNSEG勉強会が開かれて参加してきました。

勉強会は参加エントリ書くまでが勉強会、と思ってるのにずっと放置してしまってました…


NSEG 勉強会 #101 / メールとコミュニケーションツール - connpass

NSEG 第101回勉強会 / メールとコミュニケーションツール #nseg - Togetter

NSEG 101 - YouTube


今回、bounceHammerやSisimaiという、エラーで返ってきたメール(バウンスメール)を解析するオープンソースのツールを開発されてる @azumakuniyuki さんと、DebianUbuntuのメンテナなど色々と活動されてる @henrich さんが遠方から来られたため、@suno88 さんとともに前日から歓迎の飲み会&次の日も午前中からお昼すぎまで観光やら温泉やら巡るなどして、大変楽しく交流することができました。


あずまさんの講演「Email is Slack」は、メールやバウンスメール解析ツールSisimaiの開発を実例としつつ、どんな開発コンセプトでサービスやツールを作るべきか、というお話でした。
「Email is Slack」のSlackは、チャットサービスのほうのSlackではなくて「活気がない」「ゆるい」という元の英語の意味の方の話です。
メール以外のSNSだとかのコミュニケーションツールは伸びてて、メールは伸びてはいないものの停滞しているということが資料から説明されました。
そして本業のエラーメールのバウンスメール解析の話につながり、バウンスメールの形式が雑でゆるいために、いろんなものがあるということでした。
そこから、現在のバウンスメール解析ライブラリであるSisimaiへの歩みがどんな感じだったかの話になりました。
そしてそこが本題で、最終的にはUNIX哲学にしたがって、小さく、堅く、一つのことだけを速くやる、というツールにしたほうが、結局使いやすい良いものになる、という話でした。
これが最初に紹介のあった本「UNIXという考え方」につながるわけですね。
あずまさんはLTもお話いただいて、実は長野すごい来てるんだってことがわかりました。


やまねさんのLT「Let's look into debootstrap」は、いかにしてdebootstrapのバグフィックス等改善していったか、という事例を話すことで、オープンソースへの取り組み、貢献をどうやって始めたり続けたりするのか、という話になっていたと思います。
僕はこの話を聞くまで、debootstrapのこと知らなかったのですが、すごい面白いツールで、特にdocker環境とかで有用だろうなと思いました。
で、動機だったdocker環境で動かしたい件についてどうなったのか、が最後のオチに出てきます。


とみたさんのLT「メールの文字化け」は、流石「文字化けソムリエ」だけある内容でした。
特にMIMEが絡んだエンコーディングのつらみがなんで起きるのか、RFC通りには実装されてないものデコードしないといけないこととか、メールならではの問題と絡んだ理由で説明され、とても楽しめました。
最初のタイトルへの持ってき方がずるいくらい面白い。


鍋太郎さんのLT「LINE の bot を作ってみた」は、LINEに通知を流せるbotを作るために、どんな(LINEに対しての)手続きやコードが必要かを実際の例から説明するものでした。
地区の連絡用に必要に迫られて、というのが良い感じです。
直接の実用性という意味では一番参考になると思いました。


自分は「スパム対策お焚き上げ」という題で、自分が以前考案して運用しているtaRgreyというスパムフィルタ手法と、そのログから最近のスパムがどのような状況となっているか、を説明する内容となっています。

スパム対策お焚き上げ

これ前半は、8年前にNSEG #10で話した下記内容を一部簡略化したものがベースとなっています。

taRgreyでコストを掛けずにスパム削減

僕にとっては実はちょっとせつない内容なんですが、そこそこウケてもらえたかな〜と思っています。
これは後でエントリー化したいと思っています。

PHP5.3からPHP7への移行で出たエラーと対応方法

最近は結構だいぶひまで、あまりネタがないので小ネタです。


新規サーバ移行に合わせPHP5.3からPHP7へ移行したいという話で、そのテストをしてたときにでたエラーとその対応についてまとめました。


まず、これはPHPの話じゃないんですが、Apacheのバージョンが新しくなったせいで、一部ページで文字化けが発生してたのの対策。
apacheのデフォルト文字コード指定がUTF-8になってると、S-JISとかEUCのページがあったときに化けるのでコメント化します。


Apache 文字化け対策 AddDefaultCharset – CentOSサーバ構築術 文具堂

/etc/httpd/conf/httpd.conf

#AddDefaultCharset UTF-8


「Parse error: syntax error, unexpected 'new' (T_NEW)」というエラーが出ていた件対策。
PHP7ではオブジェクトの参照渡し代入ができなくなっている(というか普通に代入すればよい)ため。


Parse error: syntax error, unexpected ‘new’ (T_NEW) in | ホームページ制作部ブログ | 中央区日本橋 しろくまシステムズ

PHP5

$my_query =& new WP_Query


PHP7

$my_query = new WP_Query


「Uncaught Error: Call to undefined function split()」というエラーが出ていた件対策。
splitが不用意に正規表現使われちゃうので関数名が変わった。正規表現の必要ないときはexplode使えと。


PHP5.6からPHP7.1にしたら出たエラー|Never catch a cold.

PHP5

split('/,/', $text)


PHP7

explode(',', $text)


「Fatal error: Call to undefined function mysql_connect()」というエラーが出ていた件対策。
mysql_*系はなくなりmysqli_*系になったので色々と置き換えが必要。


PHP7で、mysql_connect()が無いと怒られる件 (undefined function mysql_connect)

PHP5

mysql_connect(...)


PHP7

mysqli_connect(...)