POSTD PRODUCED BY NIJIBOX

POSTD PRODUCED BY NIJIBOX

ニジボックスが運営する
エンジニアに向けた
キュレーションメディア

Benjamin Tran Dinh

本記事は、原著者の許諾のもとに翻訳・掲載しております。

Mapbox Drive

ここでは少しの間、自律走行車のことは忘れてください。物事は深刻になってきています。この記事では、独自のコードを書くマシンを作ることに的を絞って話を進めていきたいと思います。

GlaDoS Skynet Spynetを使用します。

具体的に言うと、Pythonのソースコードを入力することで、自分でコードを書くように、文字レベルでのLong Short Term Memoryニューラルネットワークを訓練していきます。この学習は、TheanoとLasagneを使って、EC2のGPUインスタンス上で起動させます。説明が曖昧かもしれませんが、分かりやすく説明できるように頑張ってみます。

この試みは、 こちらの素晴らしいブログ記事 に触発され行うに至りました。皆さんもぜひ読んでみてください。

私はディープラーニングのエキスパートではありませんし、TheanoやGPUコンピューティングを扱うのも初めてです。この記事を皆さんが読むことによって、いかにこの取り組みが簡単であるかを証明できたらと思います。

背景

ニューラルネットワークは機械学習アルゴリズムの一種で、インプットを人工的なニューロンのレイヤを通して処理し、アウトプットを生成します。期待されるアウトプットとネットワークの出力結果を比較し、ニューロン間での重みを変更することで結果ができるだけ近づくようにする、というやりかたで学習が行われます。計算には大量の行列の乗算が含まれるのですが、GPUはこれらを高速で処理する能力にたけています。そのため、近年のGPUコンピューティングの進歩によって、ディープラーニングは高い評価を受け、より効率的になってきています。

多くの研究では、学習が容易で、特定のタイプのタスクに効率的であるネットワークアーキテクチャを設計しています。例えば、畳み込みニューラルネットワークのようなフォードフォワードアーキテクチャは、画像認識処理を行うのに適しています。ここでは、シーケンスを処理するのに適している リカレントニューラルネットワーク(RNN) について話をしていきます。RNNの中でも高い評判を得ているアーキテクチャの1つが、 Long Short Term Memory (LSTM) です。<- LSTMで何ができるのか、そしてなぜこれが長いシーケンスを処理するのに適しているのか知りたい方は、この記事を読んでみてください。

ここでは、文字シーケンスでLSTMを使用していきます。何が起こるかというと、ネットワークに文字シーケンスを与えると、ネットワークが次にどの文字がくるかを推測するのです。例えば、インプットが”chocol”であれば、次にくる文字は”a”であると予測します。LSTMの素晴らしいところは、長期依存が学習できるところにあります。例えば、文字列”(“があった場合、LSTMは閉じ丸括弧が必要になるということを学習することができます。また、それよりも前に何千もの開き丸括弧があっても同様です。

前述した通り、GPUはこのようなニューラルネットワークを素早く学習させることができます。GPUコンピューティング向けで最も評判を得ているフレームワークは、Nvidiaが提供している CUDA です。ほとんどのディープラーニングのライブラリには、CUDAに対するいくつかのインターフェースが用意されており、GPUの計算を実行することが可能です。私がPythonでコードを書く際に選択するのは Theano です。テンソルの計算をする場合に、とても効率の良いライブラリです。Theanoに加えて利用するのが Lasagne です。ニューロンのレイヤを定義するのが容易で、LSTMネットワークを設定するためのシンプルなAPIを持つPythonのライブラリです。

ステップ1:GPUインスタンスを作動させる

コードを実行するために、g2.2xlargeインスタンスを開始し、必要なものを全てインストールします。インストラクションの大部分は こちら で見つけることができるので、書き換える必要はありません。また、Notebookを用いてコードを書くために、 LasagneIPythonJupyter をインストールしました。結果のAMI(残りのコードも含む)は、AWSのN.Californiaゾーンから ami-64f6b104 のIDを使って入手することができます。詳しいAWSアカウントの設定方法、AMIの開始方法は、Amazonの ドキュメントページ をご確認ください。

コードを書くのには、Jupyter Notebookを使います。ノートパソコンで起動させるために、Notebookのサーバの設定を許可するbashスクリプトを作成しました。直接ブラウザにコードを書くことができ、インスタンスでの起動が可能になります。 ここに記載されているインストラクション に従って作成しました。スクリプトの24行目を自分のパスワードに書き換えることを忘れないでください。

ステップ2:学習データを集める

Pythonコードを書くことをニューラルネットワークに学習させるために、まず、可能な限り入手可能なPythonコードを探します。幸いにも、Pythonのオープンソースプロジェクトが多く存在します。

以下に挙げるライブラリの、ファイル名に test が含まれない .py ファイルを連結させました。:Pandas、NumPy、SciPy、Django、scikit-learn、PyBrain、Lasagne、Rasterio。これにより、27MBの単一のファイルを得ました。これは、学習データとして程よい容量ではありますが、より大きい方が最適であることは確かです。

ステップ3:コードを書き、実行する :)

ここでようやくPythonコードを用いてLSTMネットワークを学習させるコードを書くことができます。 Lasagne receipe にコードが掲載されていますが、学習データは別として、ほんの少し変更する点があります。

ネットワークは学習するのに数時間かかります。cPickleを使ってネットワークの重みを保存します。

その後、我々の小さなSpynetの出力する数行のコードを楽しむことができるのです。

Spynetはすでに疲れ切っているようですね。

assert os = self.retire()

__init__ 関数を定義し、コメントを追加しています。

def __init__(self, other):
    # Compute the minimum the solve to the matrix explicite dimensions should be a copy of the functions in self.shape[0] != None
    if isspmatrix(other):
        return result

NumPyを使うことを、 -ほぼ- 学びました。

if not system is None:
    if res == 1:
        return filter(a, axis, - 1, z) / (w[0])
    if a = np.asarray(num + 1) * t)
    # Conditions and the filter objects for more initial for all of the filter to be in the output.

…そして、ほぼ正しい配列(小さな構文エラーが1つありますが)を定義することも学びました。複数行にわたるコードについて、正しいインデントがされていることに注目してみてください。

array([[0, 1, 2, 2],
       [70, 0, 2, 3, 4], [0], [3, 3],
       [10, 32, 35, 24, 32, 40, 19],
       [002, 10, 13, 12, 1],
       [0, 1, 1],
       [25, 12, 51, 42, 15, 22, 55, 59, 37, 20, 44, 24, 52, 34, 26, 25, 17, 32, 13, 43, 22, 44, 43, 34, 82, 06],
       [0.42,  3.61.,  7.78, 0.957,  1.649,  2.672,  6.00126248,  1.079333574],  0.2016347110,  0.13763432],
       [0, 4, 9],
       [13, 12, 32, 42, 42, 20, 34, 20, 12, 24, 30, 20, 10, 32, 45],
       [0, 0, 0],
       [20, 42, 75, 35]])

独自にコードを書くコンピュータとはかけ離れているかもしれませんが、読み込んでいるコードの例から全てを学習しなければならないネットワークとして、そう悪くありません。文字から次に何の文字がくるかを推測するということだけを考えた場合は、特にです。インデントはほぼ正しく、丸括弧と角括弧を閉じることを忘れませんでした。

しかしながら、docstringテキストとコードが混在しており、アウトプットには実際にコンパイルできるであろう関数を見つけることができませんでした。 この 記事に掲載されているネットワークのように大きなネットワークを学習させることで、これは改善されるでしょう。加えて、学習を止めても損失は依然として悪化していきました。ですから、もう少し待っていれば、アウトプットが改善する余地はまだありました。

学習に使用した完全なスクリプトは こちら で確認することができます。AMIを自由に使って、改善を試みてください!