12 Aug 2017, 09:51

fast.aiの Cutting Edge Deep Learning For Coders, Part 2を受けた

fast.aiが提供する ディープラーニングのオンライン無料講座、Cutting Edge Deep Learning for Coders を受けたのだが、難しくて後半から挫折。。

とてもいい講座なので、布教のためにも講座の紹介と、各レクチャーの内容を書いておくことにする。

これは、fast.aiが提供するDeep Learning コースの Part2に当たる。Part1の感想は以下。

講座の紹介

紹介記事: Cutting Edge Deep Learning for Coders—Launching Deep Learning Part 2 · fast.ai

Cutting Edge(最先端)の意味〜論文を読め!

Part1のPracticalのテーマは、Kagglerになれ、ということだった。

Part2では、Cutting Edge = 最先端の手法が紹介される。Cutting Edgeとはなにか?それは、

論文を読め!! ということだ。

そのため、最先端を追いかけるために、arXivの論文を読むことが課題として課せられる。論文を読み、その内容を実装できるスキルをみにつけることが求められる。

論文というものに今まで触れたことがないので、かなりびっくりだ。

Kerasのバックエンドが theanoからTensorFlowに変更、PyTouchも使おう

Part1と同様に、Part2も丁寧に書かれたJupyter Notebookが提供されて、それにそってレクチャーが進む。

このJupyter Notebook, Keras と PyTouch の両方で実装されている。

なので、PyTouchを使いたいひとは、そっちを使うことができる。

Part1より難しい・・・

Part1には、充実したwikiがあったのだが、Part2にはWikiがない。

さらには、英語字幕もない。自分は、英語があまり聞き取れないので、Part1での勉強スタイルは、動画で雰囲気を掴んだあと、wikiを熟読してなんとか理解するものだった。今回、それができない。

また、内容的にも難しさが上がっている。Part1でやったことはすべてわかっている前提ではじまるので、Part1を飛ばしてPart2からやるのは厳しいと思う。

目安は100時間以上

正直、Lesson12くらいからよくわからなくなったのと、急いで終わらせる必要が出てきたので、、後半はあまり時間をかけなかった。

それでも、100時間はかかった。真面目にやったら150時間?はかかると思う。

ちなみに、Part1は真面目にやって100時間かかった。

レクチャーメモ

Lesson 8: Artistic Style

まずは、Part1でやったことの紹介と、これからやるPart2の紹介から始まる。

Part2では、最先端を追いかけるために論文を読め!と言われる。Mendeleyという論文管理ソフトが紹介される。

そしてStyle Transferの論文が紹介されてこれを理解するように、という課題が出される。

はじめから意味不明なコードとハイレベルな難易度で戸惑う。

やってけるかな??もうダメだ!と思ったら、丁寧な日本語解説記事を見つけて救われる\(^o^)/

これらも参考になる。

なんとか実装した。

Lesson9: GENERATIVE MODELS

Perceptual Losses for Real-Time Style Transferという論文の内容が説明される。この技術は、Super-Resolutionという画質を良くする技術と、Real-Time Style Transfer という Neural Style Transferを高速化した技術の、両方に応用できる。

講義では、Super-Resolutionが取り上げられる。課題は、論文を読んで理解し、Fast Style Transferを実装せよとのこと。またもやもうダメだと思ったら、解説記事を発見。

なんとか実装した。

ノートPCの webcamから動画を取り込んで、fast style transfer で変換して、再度出力するということをやったが、ノートPCの非力なCPUでは、リアルタイムでは行かなかった。

Lesson10: MULTI-MODAL & GANS

DeViSEという論文の紹介と実装。

画像から関連する単語を抽出する試み。ResNetとword2vecを組み合わせる。

あまり理解していない。

Pythonで大規模データ(996433個の画像!)を扱うTipsとかも紹介される。ImageNetの大量画像データをスレッドやbcolzを使ってリサイズしたりする。あまりやりたくなかったので、これはJupyter Notebookを読むだけにした。

後半は、GANの説明。オリジナルのGAN, DCGANが説明される。あまりよい結果が出ない。そこで、WGANが紹介される。WGANはPyTorchで実装も公開されているとのことで、ここでPyTorch登場。

課題は、与えられたPyTouchのWGANを修正して、改善を加えること。

PyTorchとWGANという大きな課題を前に、途方にくれる。

まずは、GAN, DCGAN として、WGANというステップを踏んで学習することにした。

WGANに進んで論文読み始めたけど、この論文難しい。。数式とその証明が難しい。レクチャーでも、この論文は難しいと言っていた。先を急ぐので、WGANは後回しにすることにした。

Lecture11: MEMORY NETWORKS

前半は、最新の研究成果を追うためには論文を読むことを改めて強調される。そして、最近の研究成果を元にCNNを改良するためのたくさんのTipsとpaperが紹介される。

そのあと、k-means、Mean shiftというクラスタリング手法について説明がある。なんでここでクラスタリングなのかなと思ったら、PyTorchを使ってGPUの恩恵を受け、計算を高速化する方法が紹介される。

PyTorchはNumpyのようにデータを扱えるがブロードキャスト機能がないとのこと。そうなんだと思っていたら、v0.2.0で昨日追加された模様!link

最後に、Memory Network。これは、Facebook発のシンプルな自動応答のアルゴリズム。詳しい日本語の解説記事があった。

Lecture11から先は、明確なassignmentsがなくなり、課題としてなにをすればいいか悩む。正直、後半は完璧な理解は求めず、流しつつ進めた。とりあえず、与えられたJupyter Notebookと論文を読んで理解することにした。

Lecture12: ATTENTIONAL MODELS

k-meansの説明から始まる。Tensorflowでk-meansを実装する説明。k-meansについてよく理解していないので、ここの動画は飛ばしてしまった。(40分)

Attentional Modelsの説明とkeras実装が紹介される。はじめにencoder-decoderモデルを紹介して、これでは長文になるにつれて精度がでないねといって、Attentionモデルが出てくる。RNNや Embeddingsを忘れてしまったので、よくわからなかった。そういう人は、Lesson4,5,6を復習してねとのこと。まいったな。いよいよ 詳解 ディープラーニングを読んでみようかな。評判いいし。

(話は脇道にそれて、このDLコースのPart3はないよ、強化学習はやらない。代わりに、Part0を作って Practical machine learningをやるかも、とのこと。期待)

次は、いよいよCutting-Edgeな技術、ニューラル翻訳。予告編として、以下の論文が紹介される。

Lecture13: NEURAL TRANSLATION

ニューラル翻訳、英語からフランス語への翻訳、実はUdacityのDLNDで同じ課題をやったことがあるのだった。このときは、TensorFlowをつかった。TensorFlowは Seq2Seqのライブラリが充実していて、なんかよくわからないまま、講義のコピペで実装できてしまった。

fast.aiでは、KerasとPyTorch両方の実装が提供されている。よし学び直そうと思ったけど、やっぱり理解できなかったorz。とばし。

後半は、 Densenetの紹介。

Lecture14: TIME SERIES & SEGMENTATION

Final Lecture!

Kaggleのコンペを使って時系列データの扱いを学ぶ。Part1は主に画像データの扱いがメインだった。カグルマスターのKaggle攻略法講座が久しぶりに帰ってきた!!・・・が、真似できる気がしなかった。こうやって、カグルマスターは前処理をするのかと思った。

カテゴリカルデータをembeddingを使ってニューラルネットにぶち込む手法が参考になった。これを参考にして、自分は入門コンペのTitanicとか、House Prediction とかからはじめよう。Taxiコンペは Bengioさんが論文かいて手法を解説しているとか。

次に、segmentation(画像データをセグメントでわける処理)を学ぶ。これは、DenseNetを改良した、Transfer Learningに似たネットワークが使われる。

最後に、さらなる高みを目指して

  • コードを書こう!
  • Paperを読もう!
  • ブログを書こう!

と言われる。

ここまで、長い長い旅だった。英語力がもう少しあればと思うときが何度もあった。このPart2で得られた最も多きな、恩恵は、PyTorchと論文に触れたことだった。未消化な部分や飛ばした部分がPart2は多いので、復習しよう。

Part2で読んだPapers

論文はMendeleyで管理するのがすごく便利。

他にも、たくさん論文が紹介されたのだけれども、後半紹介された論文は、あまり読んでない。。。

18 May 2017, 23:06

ハイパーパラメータは可視化して決めよう!Keras で TensorBorad を使う

はじめに

とあるコンペに Keras で参加しているのだけれども、 ハイパーパラメータ、たとえば以下のようなパラメータ

  • 隠れ層のニューロンの数
  • ネットワークを何層にするか
  • 学習率

をどう決めていたかというと、直感である。

これでは、いけないなと最近気づく。もっと早く気付けよ。

モデルに最適なハイパーパラメータの決め方を調べてみた。

“ディープラーニング ハイパーパラメータ”を検索

みんな困っているようで、事例はすぐにみつかった。 たとえば、この記事なんて、まさに自分のこと!!

これはテストデータの精度に対して、試行錯誤を繰り返しながら決めていくしかありません。

StackOverFlow でも、

asically it is just trial and error. Those are called hyperparameters and should be tuned on a validation set (split from your original data into train/validation/test).

Tuning just means trying different combinations of parameters and keep the one with the lowest loss value or better accuracy on the validation set, depending on the problem.

ようは、総当たりしろ!!!ということか??

3 つの手法:

また、別のページでは、もっと効率のよい方法が紹介されている。大きく分けて、3 つあるようだ。

  • グリッドサーチ:

昔からある手法で、格子状の空間で最適なパラメータを探索する方法です。 格子の範囲を総当りするため、膨大な計算時間がかかるという課題があります。

  • ランダムサーチ :

無作為にパラメータを抽出して探索します。 グリッドサーチよりも計算時間が短くて済むというメリットがあります。

  • ベイズ最適化 (Bayesian Optimization) :

無作為にパラメータを抽出して探索します。 グリッドサーチよりも計算時間が短くて済むというメリットがあります。 ディープラーニングを含む機械学習の手法で、比較的良いハイパーパラメータを探索できることが知られています。

また、bengio 先生のおすすめレシピというのがある。

ハイパーパラメータはグリッドサーチするのではなく,ランダムサンプリングしたほうが性能が出る場合が多いよ

ベイズ最適化

ちょっとこのページは難しいが読み解くと、なにか得られそう。

ツール

scikit-learn には、GridSearchCV というものがあるらしい。いつか試そう。

hyperopt というツールもある。いつか試そう。

hyperopt の keras ラッパーもみつけた。いつか試そう。

調査結果

とりあえず、バカでも出来る全探索(グリッドサーチ)をする

目的

ここからが本題。

ニューラルネットワークのハイパーパラメータを調節したい。今回は簡単に以下の2つを調整。

  • 隠れ層の数
  • ニューロンの数

TensorBoard を Keras で使う

TensorBoard は、TensorFlow のログビューア。いい感じに可視化してくれる。

Keras で TensorBoard を使うには、Keras のコールバック機能を使う。 以下のように keras.collbacks.TensorBoard を利用する。

import keras
tbcb = keras.callbacks.TensorBoard(log_dir=log_filepath)

定義した変数を fit に渡す。

model.fit(trainX, trainY, epochs=30, batch_size=batch_size, validation_data=(validX, validY), callbacks=[tbcb])

これだけだ。簡単簡単。あとは log_filepath を指定して、tensorboard をコマンドラインから起動。port 6006 でアクセスできる。

$ tensorboard --logdir=[log_filepath]

参考: Keras から Tensorboard を使用する方法 - Qiita

複数のパラメータを追う

複数のパラメータをログするには、以下のように、log_dir に渡す文字列に変数を組み込む。

実例で示す。

import keras
from keras.models import Sequential
from keras.layers import Flatten, Dense, Dropout, BatchNormalization
from keras.optimizers import Nadam

batch_size=64

def get_model(num_layers, layer_size):
    model = Sequential()
    model.add(BatchNormalization(axis=1, input_shape=(256,3)))
    model.add(Flatten())
    for _ in range(num_layers):
        model.add(Dense(layer_size, activation='relu'))
        model.add(BatchNormalization(axis=1))
        model.add(Dropout(0.2))
    model.add(Dense(24, activation='softmax'))
    model.compile(Nadam(), loss='categorical_crossentropy', metrics=['accuracy'])
    return model

for num_layers in [2,3,4,5]:
    for layer_size in [64,128,265,512,1024]:
        log_string = 'logs/1/nl={},ls={}'.format(num_layers, layer_size)
        tbcb = keras.callbacks.TensorBoard(log_dir=log_string)
        model = get_model(num_layers, layer_size)
        model.fit(trainX, trainY, epochs=30, batch_size=batch_size, validation_data=(validX, validY), callbacks=[tbcb])

こうすると、logs/1/配下に nl=?,ls=? というディレクトリがそれぞれできて、そのなかにログがたまる。

$ tree 1
1
├── nl=2,ls=1024
│   └── events.out.tfevents.1495116649.letsnote-ubuntu
├── nl=2,ls=128
│   └── events.out.tfevents.1495115992.letsnote-ubuntu
├── nl=2,ls=256
│   └── events.out.tfevents.1495116161.letsnote-ubuntu
├── nl=2,ls=512
│   └── events.out.tfevents.1495116351.letsnote-ubuntu
├── nl=2,ls=64
│   └── events.out.tfevents.1495115856.letsnote-ubuntu
├── nl=3,ls=1024
│   └── events.out.tfevents.1495118093.letsnote-ubuntu
├── nl=3,ls=128
│   └── events.out.tfevents.1495117340.letsnote-ubuntu
├── nl=3,ls=256
│   └── events.out.tfevents.1495117513.letsnote-ubuntu
├── nl=3,ls=512
│   └── events.out.tfevents.1495117727.letsnote-ubuntu
├── nl=3,ls=64
│   └── events.out.tfevents.1495117193.letsnote-ubuntu
├── nl=4,ls=1024
│   └── events.out.tfevents.1495119950.letsnote-ubuntu
├── nl=4,ls=128
│   └── events.out.tfevents.1495119010.letsnote-ubuntu
├── nl=4,ls=256
│   └── events.out.tfevents.1495119233.letsnote-ubuntu
├── nl=4,ls=512
│   └── events.out.tfevents.1495119509.letsnote-ubuntu
├── nl=4,ls=64
│   └── events.out.tfevents.1495118840.letsnote-ubuntu
├── nl=5,ls=1024
│   └── events.out.tfevents.1495122077.letsnote-ubuntu
├── nl=5,ls=128
│   └── events.out.tfevents.1495121077.letsnote-ubuntu
├── nl=5,ls=256
│   └── events.out.tfevents.1495121291.letsnote-ubuntu
├── nl=5,ls=512
│   └── events.out.tfevents.1495121586.letsnote-ubuntu
└── nl=5,ls=64
    └── events.out.tfevents.1495120894.letsnote-ubuntu

これを tensorboard から見ると、accuracy, loss, valid loss, valid accuracy が見える。 以下の図は、valid accuracy.

闇雲にパラメータを調べるよりもよっぽど効率がよい。

05 May 2017, 10:00

LSTMで為替の予測をしてみた

RNN(LSTM)入門2日目。依然として、全然わかりません。

このあたりが自分のスキルの限界なのかもしれない。Udacity DLNDで株の値動きの予測をする動画が紹介された。

FXのシステムトレードを以前やっていたので、ディープラーニングで学んだことが生かせればいいなと思い、株を為替に置き換えて、LSTMで為替の値動きの予測をしてみた。

この記事は以下の記事をベースに書いている。

また、以下のkaggleコンペのkernelsも大いに参考にした。

準備

  <p>
    まずは、為替データを準備する。以下のサイトから、2017/4/24 の USD/JPY の 10分刻みのデータをダウンロードする。
  </p>

  <ul>
    <li>
      <a href="https://www.dukascopy.com/swiss/english/marketwatch/historical/">Historical Data Feed :: Dukascopy Bank SA | Swiss Forex Bank | ECN Broker | Managed accounts | Swiss FX trading platform</a>
    </li>
  </ul>

  <p>
    githubにも使用したデータをアップロードした。
  </p>

  <ul>
    <li>
      <a href="https://github.com/tsu-nera/futurismo/blob/main/blog/ipynb/USDJPY_Candlestick_10_m_BID_24.04.2017-25.04.2017.csv">futurismo/USDJPY_Candlestick_10_m_BID_24.04.2017-25.04.2017.csv</a>
    </li>
  </ul>

  <h3 id="環境">
    環境<a class="anchor-link" href="#環境">¶</a>
  </h3>

  <ul>
    <li>
      TensorFlow 1.1.0
    </li>
    <li>
      Keras 2.0.2
    </li>
  </ul>
</div>

LSTM Network for Regression

  <p>
    チュートリアルにしたがって順にコードを書いていく。
  </p>
</div>

In [1]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">print_function</span>

import numpy as np # linear algebra import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv) from keras.layers.core import Dense, Activation, Dropout from keras.layers.recurrent import LSTM from keras.models import Sequential from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error import matplotlib.pyplot as plt import math

    <div class="output_subarea output_stream output_stderr output_text">
      <pre>Using TensorFlow backend.

In [2]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># parameters to be set </span>

look_back = 1 epochs = 30 batch_size = 1

In [3]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># fix random seed for reproducibility</span>

np.random.seed(7)

PrePare Data

In [4]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># read all prices using panda</span>

dataframe = pd.read_csv(‘USDJPY_Candlestick_10_m_BID_24.04.2017-25.04.2017.csv’, header=) dataframe.head()

Out[4]:

    <div class="output_html rendered_html output_subarea output_execute_result">
      <div>
        <table class="dataframe" border="1">
          <tr style="text-align: right;">
            <th>
            </th>

            <th>
              Local time
            </th>

            <th>
              Open
            </th>

            <th>
              High
            </th>

            <th>
              Low
            </th>

            <th>
              Close
            </th>

            <th>
              Volume
            </th>
          </tr>

          <tr>
            <th>
            </th>

            <td>
              24.04.2017 00:00:00.000
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              0.0
            </td>
          </tr>

          <tr>
            <th>
              1
            </th>

            <td>
              24.04.2017 00:10:00.000
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              0.0
            </td>
          </tr>

          <tr>
            <th>
              2
            </th>

            <td>
              24.04.2017 00:20:00.000
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              0.0
            </td>
          </tr>

          <tr>
            <th>
              3
            </th>

            <td>
              24.04.2017 00:30:00.000
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              0.0
            </td>
          </tr>

          <tr>
            <th>
              4
            </th>

            <td>
              24.04.2017 00:40:00.000
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              109.072
            </td>

            <td>
              0.0
            </td>
          </tr>
        </table>
      </div>
    </div>
  </div>
</div>

In [5]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="n">dataset</span> <span class="o">=</span> <span class="n">dataframe</span><span class="p">[</span><span class="s1">'Close'</span><span class="p">]</span>

In [6]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># reshape to column vector</span>

#close_prices = close.values.reshape(len(close), 1) dataset = dataset.values dataset = dataset.astype(‘float32’) close_prices = dataset.reshape((-1,1))

ここで、データを0~1の間に正規化する。scikit-learnにMinMaxScalerという便利な関数があって、fit_transformとすると、正規化できる。戻すときは、inverse_transformをコールする。

In [7]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># normalize the dataset</span>

scaler = MinMaxScaler(feature_range=(, 1)) close_prices = scaler.fit_transform(close_prices)

訓練用データを 23, テスト用データを 1/3に分ける。

In [8]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># split data into training set and test set</span>

train_size = int(len(close_prices) * 0.67) test_size = len(close_prices) - train_size train, test = close_prices[:train_size,:], close_prices[train_size:len(close_prices),:]

print(‘Split data into training set and test set… Number of training samples/ test samples:’, len(train), len(test))

    <div class="output_subarea output_stream output_stdout output_text">
      <pre>Split data into training set and test set... Number of training samples/ test samples: 192 96

create_dataset()で訓練用のラベルを生成する。現在のデータから一つ先(look_back=1)のデータ、つまり10分後の値動きを予想する。

  <p>
    ちなみにこの関数は便利で、look_backを2にすると、2つ前のデータ、つまり現在と10分前のデータから10分後のデータを予測することができる。look_backパラメータを調整することで、過去のデータから10分後のデータを予測できる。これを元の記事では、Window Methodと書いてある。
  </p>
</div>

In [9]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># convert an array of values into a time series dataset </span>

# in form # X Y # t-look_back+1, t-look_back+2, …, t t+1

def create_dataset(dataset, look_back): dataX, dataY = [], [] for i in range(len(dataset)-look_back-1): a = dataset[i:(i+look_back), ] dataX.append(a) dataY.append(dataset[i + look_back, ]) return np.array(dataX), np.array(dataY)

# convert Apple’s stock price data into time series dataset trainX, trainY = create_dataset(train, look_back) testX, testY = create_dataset(test, look_back) (trainX.shape, trainY.shape, testX.shape, testY.shape)

Out[9]:

    <div class="output_text output_subarea output_execute_result">
      <pre>((190, 1), (190,), (94, 1), (94,))</pre>
    </div>
  </div>
</div>

In [10]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># reshape input of the LSTM to be format [samples, time steps, features]</span>

trainX = np.reshape(trainX, (trainX.shape[], 1, trainX.shape[1])) testX = np.reshape(testX, (testX.shape[], 1, testX.shape[1])) (trainX.shape, testX.shape)

Out[10]:

    <div class="output_text output_subarea output_execute_result">
      <pre>((190, 1, 1), (94, 1, 1))</pre>
    </div>
  </div>
</div>

Build Model & Training

  <p>
    Kerasを利用してLSTMネットワークのモデルを作り、トレーニングを実施する。
  </p>
</div>

In [11]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># create and fit the LSTM network</span>

model = Sequential() model.add(LSTM(4, input_shape=(1, look_back))) model.add(Dense(1)) model.compile(loss=‘mean_squared_error’, optimizer=‘adam’) model.fit(trainX, trainY, epochs=epochs, batch_size=batch_size,verbose=2)

    <div class="output_subarea output_stream output_stdout output_text">
      <pre>Epoch 1/30

1s - loss: 0.1224 Epoch 230 0s - loss: 0.0332 Epoch 330 0s - loss: 0.0204 Epoch 430 0s - loss: 0.0160 Epoch 530 0s - loss: 0.0117 Epoch 630 0s - loss: 0.0082 Epoch 730 0s - loss: 0.0056 Epoch 830 0s - loss: 0.0041 Epoch 930 0s - loss: 0.0034 Epoch 1030 0s - loss: 0.0031 Epoch 1130 0s - loss: 0.0030 Epoch 1230 0s - loss: 0.0030 Epoch 1330 0s - loss: 0.0029 Epoch 1430 0s - loss: 0.0029 Epoch 1530 0s - loss: 0.0030 Epoch 1630 0s - loss: 0.0029 Epoch 1730 0s - loss: 0.0029 Epoch 1830 0s - loss: 0.0029 Epoch 1930 0s - loss: 0.0029 Epoch 2030 0s - loss: 0.0029 Epoch 2130 0s - loss: 0.0030 Epoch 2230 0s - loss: 0.0030 Epoch 2330 0s - loss: 0.0029 Epoch 2430 0s - loss: 0.0029 Epoch 2530 0s - loss: 0.0030 Epoch 2630 0s - loss: 0.0030 Epoch 2730 0s - loss: 0.0030 Epoch 2830 0s - loss: 0.0029 Epoch 2930 0s - loss: 0.0029 Epoch 3030 0s - loss: 0.0030

  <div class="output_area">
    <div class="prompt output_prompt">
      Out[11]:
    </div>

    <div class="output_text output_subarea output_execute_result">
      <pre>&lt;keras.callbacks.History at 0x7f29913c3b00&gt;</pre>
    </div>
  </div>
</div>

Predict

In [12]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># make predictions</span>

trainPredict = model.predict(trainX) testPredict = model.predict(testX)

In [13]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># invert predictions and targets to unscaled</span>

trainPredict = scaler.inverse_transform(trainPredict) trainY = scaler.inverse_transform([trainY]) testPredict = scaler.inverse_transform(testPredict) testY = scaler.inverse_transform([testY])

In [14]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># calculate root mean squared error</span>

trainScore = math.sqrt(mean_squared_error(trainY[], trainPredict[:,])) print(‘Train Score: %.5f RMSE’ % (trainScore)) testScore = math.sqrt(mean_squared_error(testY[], testPredict[:,])) print(‘Test Score: %.5f RMSE’ % (testScore))

    <div class="output_subarea output_stream output_stdout output_text">
      <pre>Train Score: 0.09638 RMSE

Test Score: 0.06509 RMSE

In [15]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># shift predictions of training data for plotting</span>

trainPredictPlot = np.empty_like(close_prices) trainPredictPlot[:, :] = np.nan trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict

# shift predictions of test data for plotting testPredictPlot = np.empty_like(close_prices) testPredictPlot[:, :] = np.nan testPredictPlot[len(trainPredict)+(look_back*2)+1:len(close_prices)-1, :] = testPredict

In [16]:
<div class="inner_cell">
  <div class="input_area">
    <div class=" highlight hl-ipython3">
      <pre><span class="c1"># plot baseline and predictions</span>

plt.plot(scaler.inverse_transform(close_prices)) plt.plot(trainPredictPlot) plt.plot(testPredictPlot) plt.show()

    <div class="output_png output_subarea ">
      <img src="http://futurismo.biz/wp-content/uploads/a3468b2a3ce342ea6e059347483820d6.png" />
    </div>
  </div>
</div>

予測結果は上の図。あまりにフィットしすぎて、なんかウソっぽいけれども、一応これが結果。

  <p>
    ちなみに、元の記事だとこの先もあるが、stepや state, stacked LSTMs が読んでもよくわからなかった。もう少し時間が必要。
  </p>

  <ul>
    <li>
      How to create an LSTM for a regression and a window formulation of the time series problem.
    </li>
    <li>
      How to create an LSTM with a time step formulation of the time series problem.
    </li>
    <li>
      How to create an LSTM with state and stacked LSTMs with state to learn long sequences.
    </li>
  </ul>

  <p>
    元記事を元に試してみたけれども、修正を加えるたびに精度が悪くなっていくのだった。
  </p>
</div>

おわりに

  <p>
    LSTMを FXのストラテジに応用できるか考えてみたのだけれども、よいストラテジが思いつかない。
  </p>

  <p>
    単純に回帰ならば、LSTMを使わなくてももっと簡単な方法がある。
  </p>

  <p>
    トレーニングに時間がかかるので、リアルタイムに過去のデータを処理して未来の値を予測できるのか?
  </p>

  <p>
    とはいえ、面白い話題なので、もう少し調べてみる。
  </p>
</div>

01 May 2017, 06:36

Kaggle のタイタニック問題に Keras で挑戦した。前処理が課題だと分かった。

Kaggle のタイタニック問題に Keras で挑戦しました。

前置き

タイタニック問題は、Kaggle の看板コンペということで、いろんな人が挑戦している。

自分も早くデータサイエンティストになりたいので、登竜門であるコンペに挑戦してみた。

タイトルが、Titanic: Machine Learning from Disaster とある通り、機械学習を 使って問題を解くことが求められているのだけれども、自分の ToolBox には、 ニューラルネットワーク一本槍しかない。

他の手法も身につけたいのだけれども、他にも手を出すと知識が発散してしまうので、 今はニューラルネットワークひとつにかけている。

最近 Keras をいじりはじめたので、Keras でニューラルネットワークを組んで問題に挑戦してみた。

考察

モデルのチューニングが難しい。

以下のようなモデルを組んでみたのだけれども、精度が 75%。 これで上位 90% という惨憺たる結果。

# create model
model = Sequential()
model.add(Dense(64, input_shape=(8,)))

for i in range(0, 8):
    model.add(Dense(units=64))
    model.add(Activation('relu'))

model.add(Dense(units=1))
model.add(Activation('linear'))

model.compile(loss='mean_squared_error', optimizer='rmsprop')

9 層の Dense レイヤ(Relu 関数で activate) のあとに、1 ノードの出力層を設けた。 コスト関数は、最小二乗誤差、最適化手法は RMSProp.

Bach Norm や Dropout 層を入れることも検討したのだけれども、そうすると精度が下がる。 この設計以上にシンプルにしたり、複雑にしてみたりしたのだけれども、精度が下がる。

チューニング方法が試行錯誤なので、難しい。いい方法がないか、考察中。 チューニングにベストプラクティスはあるのだろうか?直感に頼るしかないのだろうか? 経験を積めば、知識が増えて、いい方法がすぐに思いついたりするのだろうか?

前処理はズルをしました

どういう特徴量を使うかは、以下の記事を参考(パクリ)にしました。

本当は、以下のようなデータ分析をしてデータの傾向を見る必要があるのだけれども、 そういうスキルが自分にはまだない。これから時間をかけて身につけていく。

おそらくだけれども、この前処理の段階を改善することで、精度がグンと上がるのだと思う。 Udemy に参考になりそうな講座がいくつかあるので、購入しようか検討中。(追記:セールだったので購入した。1200 円!)

そういう気づきを得られただけでも、今回参加した価値はあったと思う。 とにかく動くことで課題が明確になる。

コード

github に jupyter notebook をアップロードしました。

26 Apr 2017, 07:22

Vgg16 モデルを使って Kaggle の Dogs vs Cats をやってみた

fast.ai の Practical Deep Learning for Coders の week2 の課題で、 勉強の理解のために、スクラッチで教えた内容を自分で実装してみてねと書かれていたので、やってみた。

はじめに

Practical Deep Learning for Coders では、 Kaggle の Compatition Dogs vs. Cats Redux| Kaggle に参加することが課題に課せられるのだが、 week1 でいきなり、上位 50% に入ってねという課題が出される。

無理だよ!と思ったのだけれども、week2 で上位 50%に入るための種明かしをしてくれる。 それが、vgg16 モデルを使った fine-tuning による転移学習。これについては、以下の記事がとても参考になった。

課題をスクラッチではなく(できないので)、与えられたコードコピペしまくりでなんとか実装してみた。元ネタこれ。

今回の課題の jupyter notebook は github に あるので、ここではコードを抜粋して載せる。

実装の抜粋

Rearrange image files into their respective directories

まずは、kaggle からデータを持ってきて、以下のようなディレクトクリ構造をつくる。 分類クラスごとにサブディレクトリ(dogs, cats, unknown)を作ることによって、 Keras の ImageDataGenerator がうまいこと処理してくれる。

├── test
│   └── unknown
├── train
│   ├── cats
│   └── dogs
└── valid
    ├── cats
    └── dogs

Finetune and Train model

VGG モデルを作成する。

def ConvBlock(layers, model, filters):
    for i in range(layers):
        model.add(ZeroPadding2D((1,1)))
        model.add(Convolution2D(filters, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

def FCBlock(model):
    model.add(Dense(4096, activation='relu'))
    model.add(Dropout(0.5))
# Mean of each channel as provided by VGG researchers
vgg_mean = np.array([123.68, 116.779, 103.939]).reshape((3,1,1))

def vgg_preprocess(x):
    x = x - vgg_mean     # subtract mean
    return x[:, ::-1]    # reverse axis bgr->rgb

def VGG_16():
    model = Sequential()
    model.add(Lambda(vgg_preprocess, input_shape=(3,224,224)))
    ConvBlock(2, model, 64)
    ConvBlock(2, model, 128)
    ConvBlock(3, model, 256)
    ConvBlock(3, model, 512)
    ConvBlock(3, model, 512)
    model.add(Flatten())
    FCBlock(model)
    FCBlock(model)
    model.add(Dense(1000, activation='softmax'))
    return model


def finetune(model, num_classes):
    # remove last layer
    model.pop()
    # set all layers untrainable.
    for layer in model.layers: layer.trainable=False
    # add new layer
    model.add(Dense(num_classes, activation='softmax'))
    model.compile(optimizer=Adam(lr=0.001),
                loss='categorical_crossentropy', metrics=['accuracy'])
    return model

def get_batches(path, dirname, gen=image.ImageDataGenerator(), shuffle=True,
                batch_size=64, class_mode='categorical'):
    return gen.flow_from_directory(path+dirname, target_size=(224,224),
                class_mode=class_mode, shuffle=shuffle, batch_size=batch_size)

そして、学習済みの重みを fast.ai のサーバから手に入れる。

wget http://files.fast.ai/models/vgg16.h5

ここ からもダウンロードできる。

なお、keras1.2.0 では、ここによると、 VGG16 モデルが keras.applications.vgg16 モジュールに実装されているらしい。

つまり、自分のやり方は古いということだ!!

model = VGG_16()

# load pre-trained weights!!!
model.load_weights('vgg16.h5')

# remove last layer and add new layer
ftmodel = finetune(model, 2)

print ftmodel.summary() で 最後の層に出力が 2 のレイヤが追加されたことを確認する。

dense_4 (Dense)                  (None, 2)             8194        dropout_2[0][0]                  

追加した層を犬猫判定ように調整する。

batch_size=64
path = DATA_HOME_DIR

batches = get_batches(path,'train', batch_size=batch_size)
val_batches = get_batches(path,'valid', batch_size=batch_size)

# train finetuned model(only last layer)
no_of_epochs=1

for epoch in range(no_of_epochs):
    print "Running epoch: %d" % epoch
    ftmodel.fit_generator(batches, samples_per_epoch=batches.nb_sample, nb_epoch=1,
                validation_data=val_batches, nb_val_samples=val_batches.nb_sample)
    latest_weights_filename = 'ft%d.h5' % epoch
    ftmodel.save_weights(latest_weights_filename)

Generate predictions

test データから犬猫の確率を推測。preds には[猫,犬]とデータが入っている。

test_batches = get_batches(path, 'test', batch_size=2*batch_size, class_mode=None)
preds = ftmodel.predict_generator(test_batches, test_batches.nb_sample)