Tensorflow 1.11 + Cuda 10.0でDeep Learning

Ubuntu 18.04にTensorflow 1.11.0 とCuda 10.0をインストールしてKeras でDeep Learning

Nvidiaのcuda10.0がubuntu18.04に対応したので早速インストールして試してみた。

Tensorflow 1.11がリリースされたのでソースコードをダウンロードしてビルドした。

ビルド環境は:
Python3.6.5, Tensorflow 1.11 , Cuda 10.0, cudnn7.3, nccl2.3.4,  TensorRT-5.0, gcc7.3.0
でうまく行った。
実行時のKerasのバージョンは 2.2.2

ちなみにハード環境は:
CPU AMD Ryzen 5 1600, 16GBメモリ
GPU Nvidia GTX 1060 + GTX 1050 TI

インストール、ビルド方法はここのサイトを参考にした。各ソフトのバージョンを読み替えればうまくいくでしょう。

Keras解説本に記載されているサイトからダウンロードしたサンプルコードを実行したがうまく実行できたので、サンプルコードに日本語のコメントを追加して公開。
KerasはTensorflowのラッパーなので、比較的直感的なPythonコードでDeepなコードが書ける。

参考にした解説書は[DEEP LEARNING with Python]でKerasの開発者が著したものだ。
なかなかいい本だと思う。日本語版も出ている。
日本語のコメントには日本語版を参考にした。

Deep Learningによる文章生成という、興味深いトピックがあったのでこれを選んだ。
オリジナル版は哲学者ニーチェの英訳本を使っているが、ここでは日本の文豪、島崎藤村の「夜明け前」の青空文庫のテキスト版を使った。
テキストをすべてひらがなに変換して、サンプルプログラムで使えるようにしている。
ひらがな変換時の漢字まじり文の読み上げの拙さによる、不正確なひらがな文になっているところもある。
いずれにしてもDeep Learningの応用として興味深い分野だ。

サンプルコードのInの部分のPythonコードを逐次、順番に実行すれば動作するが、原本のJupyter notebook形式のファイルを近いうちにアップロードする予定です。

ランダムに抜き取ったサンプルの文章の一部から、Deep Learningで生成した文章の例を示します。

-------------------------------------------------------------------------------------------
epoch 72
Epoch 1/1
85145/85145 [==============================] - 45s 523us/step - loss: 1.8636
--- Generating with seed: "のへんはがんせきのあいだで、ふきんにおおきないわがあったからで。
こどものじぶんのはんぞうをまえにすわらせておいて、きち"
------ temperature: 0.2
のへんはがんせきのあいだで、ふきんにおおきないわがあったからで。
こどものじぶんのはんぞうをまえにすわらせておいて、きちざえもんとかねへいとも、そのとき、きちざえもんとは、ひとつかいどうをつとめると、おれはそのときになってきた。
「おれも。そのじんのしょうじょうは、はんぞうはいえのものをながれて、かんさいはまだこのこくのところをしたちょうしたところにある。そういってくれると、しんたくになって、とうじのこくがくしゃのだいだんなことをしった。
「ことぶきひらじさん、きみはそれをおもいおしりすすすない。
「これは、おまえさまもおわいたちのあいだをさしだすか、うえにはよういしていた。そのとき、ひとつこくにきかなると、かれのひとつのにちにある。このうきのいってみをちかい、くろうけたこうように、かんさいがえどのほうへおもいがわたった。
「おれも。こしつ、これはおわりはんのるいかはなし、しかし、それからのとりかえってきている。そのとき、かねへいは、そのとき、ひとりのかたになった。
「ことぶきひらじさん、きみはわたしはなか
------ temperature: 0.5
のとりかえってきている。そのとき、かねへいは、そのとき、ひとりのかたになった。
「ことぶきひらじさん、きみはわたしはなかつがわのかいどうには、ふしみやのかんさいはだんたいがつをもつとめた。
「おたみ、おめいきのなかにもわれた。それにかえいだった。
なんてねんふたがつをつれてかえってみたが、こんどようとなりました。」
「ひとほんのしば、おやく、はんぞうはおたみをよんで、それをみかりさされた。そのとき、わたしはもうさまのようなきょうとにしんぱいをうらすうにした。
「さんじのうしのかみのだいみょうはおもいくれきあつりのあいだにもちであった。したしい。」
「さん、はんぞうはいえのものにちがすまにおりかぞくといって、かわのじょうしゅくのかいどうをかくものつとめいつあめにきかたるにも、やっきょうはおおやけぎのいえにひとばんさんがえどのほうへひき、おまんからはいらんないとして、はんぞうはおたみはあつまってみせて、しゅくのじょうにつうこうのほうへついた。おまえさまは、ついてはんぞうさまのいえのていいゃくのしょへいまもるとこ
------ temperature: 1.0
てみせて、しゅくのじょうにつうこうのほうへついた。おまえさまは、ついてはんぞうさまのいえのていいゃくのしょへいまもるところがかくけることでもはんぞうにちでにかぜのいっけんがじゅういたひじょうにわるためまでもたもっとがえた。
あしのなかのひそんをはうしおつよした。どれもみのできたということで、まごめのやすまかせいつだめまでもばくしてくる。みたままにねううさげにようとしていった。「おとうりょうで、、おたみにはこころふねんふのこれはやどをつけとちほそいをきかせる。はきがつは、はんぞうはいえのものにちからえんじょうしたはなしものをあった。
「そうおもやのかんさいはさべつののほうでおいかとがじきがあろかけたともとしそれのにちはかえってせあめににもつすほんのをざかのにわかせことのちょうしゅうをさわうしばわりですね。こんぶんはにしられるようなことのひかりる、ふたにちである。ちんきのじょうがひきかけているあめ、かまをみってとんのとむぽうとろうえをきく。あのかじゅうは、それをののうちにはなくかねこみされていた。かねへいはなか
------ temperature: 1.2
あめ、かまをみってとんのとむぽうとろうえをきく。あのかじゅうは、それをののうちにはなくかねこみされていた。かねへいはなかった。
きょうとがなんのじぶんをひきとにしてのぜんにらかくそこのいわりをえどれましれまかれたこともきいきゅうてきちがうよってきょうほんすのいじへはことむらできておるえていったいじゃでおきてきたいがくも、このしょきにほんじんにかれてきちざえもん、をぱつけれゅうようにしょうそうそうもそのちらいかりずをねんだ。とうじははいぞなのいえのものておりで、そのとにおもいらつやのちゃやであるまい。」
「そそさんはろはこちえのねんちゅうにあるろのしあげづかでありませんがなした。めれはいいひでのかんなじょんで、よこ、ごせんれいのわなかった。だいみょうにはなしをしておといろと、ありますよ。」
「さいだいそんのなかだでもわかるかさとのほうこうしもいなしておりぞうすにおうかきたいえがわらっている。あのいじかできいとちょうができてごさんかいがわる。みまもるにほんおくがだいたんろうとかれはかゆうへたよせいののぼりほうに
---------------------------------------------------------------------------------------------------

サンプルコードはこの下から始まる

In [1]:

import keras
keras.__version__
 
/home/goro/.pyenv/versions/anaconda3-5.2.0/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  from ._conv import register_converters as _register_converters
Using TensorFlow backend.
Out[1]:
'2.2.2'
 

LSTMによるテキスト生成

超短期記憶(LSTM)アルゴリズムによるRNN(リカレントニューラルネットワーク)を使ったシーケンスデータ(この場合は文章)の生成

 

文字データを準備する

ここでは青空文庫にある島崎藤村の長編小説「夜明け前」の前半の一部を使用する。 テキストデータは全部ひらがなに変換している。 ダウンロードしたファイルを解凍して、テキストデータへのPATHを指定する。

In [2]:
import keras
import numpy as np

#path = keras.utils.get_file(
#    'nietzsche.txt',
#    origin='https://s3.amazonaws.com/text-datasets/nietzsche.txt')
path = '/home/goro/Downloads/yoakemae_aozora.txt'
text = open(path).read().lower()
print('文書の長さ:', len(text))
 
文書の長さ: 255494
 

次に、 文字シーケンスのベクトル化 Pythonのプログラムを理解しやすいように、コメント付きのプログラムを追加している。 コメント#を外して実行するとプログラムの途中経過がわかる。

In [3]:
# 抽出する文字シーケンスの最大長
maxlen = 60

# ステップ文字おきに新しいシーケンスをサンプリング、この場合は3文字おき
step = 3

# 抽出したシーケンスの保持
sentences = []

# 次にくる文字の保持
next_chars = []

for i in range(0, len(text) - maxlen, step):
    sentences.append(text[i: i + maxlen])
#    print(sentences)
    next_chars.append(text[i + maxlen])
#    print(next_chars)
#    input("Press Enter to continue...")
print('シーケンス数:', len(sentences))

# 文書の中のユニークな文字のリスト
chars = sorted(list(set(text)))
print('Unique characters:', len(chars))
# これらのユニークな文字をインデックスにマッピングする辞書
char_indices = dict((char, chars.index(char)) for char in chars)

# 次に、one-hot エンコーデイングで文字をバイナリ配列に入れる
print('Vectorization...')
x = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)
y = np.zeros((len(sentences), len(chars)), dtype=np.bool)
for i, sentence in enumerate(sentences):
    for t, char in enumerate(sentence):
        x[i, t, char_indices[char]] = 1
    y[i, char_indices[next_chars[i]]] = 1
 
シーケンス数: 85145
Unique characters: 81
Vectorization...
 

ネットワークの構築

ネットワークは一つの LSTM 層、次に続く Dense 分類器、そしてすべての文字候補に対応するsoftmax 関数で構成される。

In [4]:
from keras import layers

model = keras.models.Sequential()
model.add(layers.LSTM(128, input_shape=(maxlen, len(chars))))
model.add(layers.Dense(len(chars), activation='softmax'))
 

モデルを訓練するための損失関数として categorical_crossentropy を使用:

In [5]:
optimizer = keras.optimizers.RMSprop(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)
 

言語モデルの訓練とサンプリング

訓練された学習済みモデルとサンプリングされた文章片から、新しい文字を繰り返し生成する: 文字を決める条件に、候補文字の確率分布の加重平均を使用するパラメータを「温度」として追加する。 温度が高いと天才肌の不規則な文章になり、低いと堅実派の作家の文章になると思えばいい。

モデルの予測に基づいて、「温度」パラメータを指定して次の文字を予測する関数:

In [6]:
def sample(preds, temperature=1.0):
    preds = np.asarray(preds).astype('float64')
    preds = np.log(preds) / temperature
    exp_preds = np.exp(preds)
    preds = exp_preds / np.sum(exp_preds)
    probas = np.random.multinomial(1, preds, 1)
    return np.argmax(probas)
 

最後に、訓練と文字生成を繰り返す。 訓練の経過と「温度」によりどんな変化があるか楽しみにしよう。

In [8]:
import random
import sys

for epoch in range(1, 60):
    print('epoch', epoch)
    # Fit the model for 1 epoch on the available training data
    model.fit(x, y,
              batch_size=128,
              epochs=1)

    # Select a text seed at random
    start_index = random.randint(0, len(text) - maxlen - 1)
    generated_text = text[start_index: start_index + maxlen]
    print('ランダムに選択したサンプルの文章片から文章を自動生成中: "' + generated_text + '"')

    for temperature in [0.2, 0.5, 1.0, 1.2]:
        print('------ 温度:', temperature)
        sys.stdout.write(generated_text)

        # We generate 400 characters
        for i in range(400):
            sampled = np.zeros((1, maxlen, len(chars)))
            for t, char in enumerate(generated_text):
                sampled[0, t, char_indices[char]] = 1.

            preds = model.predict(sampled, verbose=0)[0]
            next_index = sample(preds, temperature)
            next_char = chars[next_index]

            generated_text += next_char
            generated_text = generated_text[1:]

            sys.stdout.write(next_char)
            sys.stdout.flush()
        print()
最終修正日2018/10/01(月) 15:10
(0 件の投票)
読む 103 回読まれました

関連アイテム

このカテゴリをもっと見る

KerasでTensorBoard »

コメントする

(*)で示された必須情報を入力したか確認して下さい。HTMLコードは許可されません。