これを用いて,ディープラーニングを行います。インストールする必要があります。ディープラーニングの手順まず,学習するテキストファイルを読み込み,辞書を作成します。次に,文字をベクトルに変換し,モデルの入力値と答えを作成します。学習に必要がデータが完成したら,モデルを構築し,学習を行います。最後に,学習済みのモデルを保存します。今回は,5つの単語をもとに,次の単語を予測するモデルを構築します。f.read().splitlines()テキストファイルarticles.txtを読み込みます。大きさは318KBです。'eos\n').splitlines()文末記号eosに改行文字を加え,.spilitlines()でリストtextsに行ごとのテキストを格納します。辞書の作成Tokenizerを用いると,テキストの前処理を簡単に行うことができます。TokenizerはKerasに含まれています。ディープラーニングでは,文字をそのままデータとして用いることはできません。扱うことができるのは数だけです。そこで,辞書を作成し,単語を数に置き換えます。Tokenizer()オブジェクトtokenizerを作成します。テキストを自動的に処理する機械が作られ,その名前がtokenizerである,とイメージするとよいでしょう。tokenizer.fit_on_texts(texts).fit_on_texts()はtokenizerにテキストを与えます。tokenizer.word_index.word_indexは辞書型リストを作成し,リストchar_indicesに格納します。6950}テキストで使われている単語に数が割り当てられました。リストは単語の出現頻度の順に並んでいます。単語の総数は6950語です。tokenizerは自動的に単語を小文字に変換し,ダブルクォーテーションやコロンなどの記号を取り除きます。char_indices.items()])逆引き辞書を作成し,indices_charに格納します。dict()は辞書型のリストを作成します。'editor'}予測の結果は単語を表す数で返されます。その後,逆引き辞書を用いて数を単語に戻し,結果を確認します。単語をベクトル化し,リストpre_vecに格納します。......]一つの単語は一つの数によって表されます。これは値が一次元ベクトルであることと同じです。通常はこれをベクトルとは言いません。実際には単語に複数の値を持たせることができます。ある単語を(13,87,25)として表すなら,これは三次元ベクトルになり,三階のテンソルとも言います。一次元ベクトルの値はほとんど意味を持ちません。私たちがその値から知ることができるのは,単語の出現頻度だけです。ベクトルの次数を増やすと,単語により多くの情報を与えることができ,より高度な学習を行うことができます。texts_vec.append(pre_vec[line])len(pre_vec)は文章の行数を表し,len(pre_vec[line])は行番号lineにおける単語数を表します。単語数が10以上の場合に,変換されたベクトルをリストtexts_vecに格納し,短い行をカットします。今回は5つの単語をもとに次の単語を予測するので,それぞれの行は少なくとも6つの単語を持つ必要があります。5今回は,5つの単語をもとに次の単語を予測します。これをseq_lengthで表します。入力値は(バッチサイズ,タイムステップ,入力次数)の形状をとります。5つの値の組がタイムステップです。タイムステップは単語を一つずつずらしながら作られ,その合計がバッチサイズになります。それぞれのタイムステップに続く1つの単語を答えとします。入力次数は単語ベクトルの次数のことです。今回は,次数は1となります。タイムステップを作成します。range(len(texts_vec[line])-5):lineは行番号を表し,iは行の中の単語の位置を表します。iはそれぞれの行の単語数より5つ少ない値まで変化します。y.append(texts_vec[line][i+5])xはモデルに与える入力値です。[i:i+5]はリストの範囲を表します。iの値が0なら,0から4までを意味します。0から5までではないことに注意してください。繰り返し処理はline=0,i=0から始まります。.append()を用いてtexts_vec[0][0]からtexts_vec[0][4]までの値をリストxに追加します。次にi=1となり,texts_vec[0][1]からtexts[0][5]までの値を追加します。して,一つずつ移動しながら5つの値の組を抽出していきます。......]yは答えです。line=0,i=0のとき,text_vec[0][5]が追加されます。......]yは予測されるべき値を意味します。モデルはxで与えられた入力値に対して,yと同じ値を出力するように訓練されます。学習が進んでいないモデルはランダムな値を返しますが,学習が進むと高い確率でyと同じ値を出力するようになります。np.reshape(x,(len(x),seq_length,1))np.reshape()はリストの形状を変更します。モデルに与える入力値は三次元のベクトルでなければなりません。......]この方法とは別に,初めに空の三次元のリストを用意し,値を一つずつ格納する方法もあります。np.reshape()の方が処理が高速です。one-hot形式では以下のように表されます。[0,0,0,0,1]今回,単語の総数は6950語ですが,モデルは出力値として単語それぞれについての確率を返します。......]]リストの中から最も確率の高いものを,予測値resultとします。このとき,モデルは答えyとresultを比較し,予測値が答えに近づくようにモデルを変更します。Sequential()オブジェクトmodelを構築します。modelは自然言語を学習する機械をイメージするとよいでしょう。modelに入力を与え,出力を受け取ります。Sequential()はモデルが鎖状に連結されたものであることを示しています。学習プロセスの概要です。それぞれの単語はベクトルに変換され,xに格納されます。5つの単語の組み(タイムステップ)を一つずつLSTMに与え,Denseレイヤーに集約します。Denseレイヤーは辞書にある単語それぞれの確率を出力し,確率の最も高いものを予測値として決定します。出力値とあらかじめ用意された答えyとのずれを計算し,ネットワークを遡ってずれが小さくなるように修正します。1)))モデルにLSTMレイヤーを加えます。LSTMは実際に学習を行うためのレイヤーです。ニューロンを128個設置します。1)はそれぞれのニューロンにおける入力値の形状を表します。seq_length=5なので,それぞれのニューロンに(5,1)の大きさのデータが与えられます。activation='softmax'))LSTMの出力をDenseレイヤーに集約します。Denseレイヤーはそれぞれの単語の確率を出力します。y.shape[1]は辞書に登録された単語の総数を表します。activation='softmax'は活性化関数としてsoftmax関数を用いることを表します。softmax関数はそれぞれの単語についての確率を求めます。Adam(lr=0.01)最適化関数としてAdamを指定します。最適化関数は出力値と答えとの誤差を修正するための関数です。lr=0.01は学習率です。学習率の値を大きくすると学習の速度が速くなる一方で,精度が向上しないという問題が起きます。反対に,学習率の値を小さくすると精度が向上する一方で,学習の速度が遅くなるという問題が起きます。metrics=['accuracy'])loss='categorical_crossentropy'は損失関数として交差エントロピー誤差を用いることを表します。損失関数は,結果と答えの誤差を表す尺度です。モデルは損失関数の値をもとに,その値が小さくなるようにネットワークを変更します。metrics=['accuracy']はモデルを評価するための方法として精度を用いることを表します。理解の難しい関数がいくつも登場しましたが,これらの関数の持つ役割は実際に学習を進めていきながら段階的に理解していきます。verbose=1)model.fit()でモデルに入力値xと答えyを与え,学習を行います。学習はepochという単位で行われます。epochを増やすと学習が段階的に進み,精度が向上します。epoch学習を行います。verboseは進行状況の表示方法を指定します。verbose=0とすると進行状況は表示されません。.fit()を実行すると以下のような出力が得られます。0.1814バッチサイズは37858で,これは5個の単語の組み(タイムステップ)が37858個あることを示しています。学習の結果,モデルは18.14パーセントの精度を得ました。これは十分な結果とは言えません。float(len(char_indices))結果を改善するために,入力値を正規化します。float()は整数を浮動小数点に変換します。入力値の最大は辞書の大きさに等しく,値を辞書の大きさで割るとxは0から1の間の小数になります。これを正規化と呼びます。モデルは,それぞれの単語についての確率を0から1の値で出力します。このとき,入力と出力の尺度を合わせると,学習効率が改善するのです。0.5174精度が51.74パーセントに改善しました。モデルの保存model.save('model_voa.h5')学習したモデルをファイルmodel_voa.h5に保存します。保存したモデルをあとから読み込んで,予測を行うことができます。y)辞書とデータセットをファイルに保存します。これらのファイルはあとで予測を行うときに必要になります。全体のコードを示します。modelmodel.save('model_voa.h5')結果を予測する構築したモデルが,実際に予測できるかどうかを確認します。allow_pickle=True)保存されたテキスト,辞書,データセットを読み込みます。load_model('model_voa.h5')保存されたモデルを読み込みます。range(5):繰り返し処理によって,予測を5回行います。chars.append(indices_char[x[pattern][i]]).append()はデータセットで作成した値をリストx_predに追加します。表示のために逆引き辞書を用いて値を単語に戻し,リストcharsに追加します。float(len(char_indices))学習のときと同様,入力値を(バッチサイズ,タイムステップ,入力次数)の形状に変更し,正規化します。verbose=0)model.predict()にx_predを与え,予測を行います。それぞれの単語の確率がリストpredictionに格納されます。np.argmax(prediction)np.argmax()はリストにある値から最大値を求めます。最大値をindexに格納します。indices_char[index]逆引き辞書を用いて値を単語に戻し,resultに格納します。'.join(chars)リストcharsを一つの文字列charに連結します。prediction:'+str(result))コードを実行し,結果を表示します。prediction:eos出力と答えが一致し,高い確率で正しく予測されていることが分かります。モデルは高い精度を持ちますが,これは学習用データをそのまま予測に用いているからです。本来,AIは未知のデータに対して妥当な結果を得ることが目標です。そのため,この結果はあくまで不十分なものに過ぎません。最後にコード全体を示します。