LSTMっていうオモチャを見付けました
はじめに
これはぼくのインターンメモです。
LSTM
標語的にはリカレントニューラルネットワーク(RNN)の一種でLong short-term memoryの略だとか言われてますね。
この手法の何が他と違うかというと、ある決められた(人の手で入れる)長さのデータを保持しつつ(たまに忘却しつつ)
学習していくというところみたいですね、すごそう。下のリンクの記事は読んだ事ないですが貼ります
何に強いかというと時系列データだとか、文章(前後の繋がりがあるため)でその辺メインで使われてるらしい。
画像認識もいけるみたいだけど、わざわざやる意味はいまいち分かりません。
動かしてみた
株価予想とか腐る程出てくるので他のでやりたい、文章どうこうはあんまり興味がない
んで、今回は
「素数予想」
やります。
CNNで素数判定!みたいな話は結構出てくるんですが、時系列データとして生成するってのはあんまり出てこなかったんで。
まぁ多分やった結果面白くなかったから誰も言ってないないとか、数学的に不可能と証明されているとかそんな感じでしょう。
とりあえず素数をDLしましょう
10000個のやつでやりました、計算重いからね。
毎回思うんですが、こういうcsvファイルってプログラムに読み込ませる以外の用途思いつかないのに、なんで余計なヘッダー付いてるんでしょう。
エクセルで編集はあまりいい思い出が無いので、エディタで消しましょう。
import numpy as np import matplotlib.pyplot as plt import pandas as pd import math from keras.models import Sequential from keras.models import load_model from keras.layers import Dense from keras.layers import LSTM from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error #データ読み込み dataframe = pd.read_table('primelist10000.txt') #変数の抽出ためのデータフレーム作成 df = pd.DataFrame() #目的変数 df['prime'] = dataframe['Number']#csvのカラム名をぼくが勝手に変えました max_prime = max(df.prime)#データ範囲での最大値を取得 df.prime = df.prime/max_prime#絶対値0~1でスケール、LSTMはこれが推奨されてるらしい #説明変数+上と同じ操作 df['index'] = dataframe.index max_index = max(df.index) df.index = df.index/max_index #ここでnumpy-arrayにする。型は適当に設定 df = df.values df = df.astype('float32') #データ分割 train_size = int(len(df) * 0.9)#データの9割で学習、1割でテスト train, test = df[0:train_size,:], df[train_size:len(df),:] #LSTMが受け取れる形にしましょう、[データ行数][変数の個数][ルックバックの個数]みたいな形でしか受け取れない def make_dataset(dataset, look_back=1): dataX, dataY = [], [] for i in range(len(dataset)-look_back-1): xset = [] for j in range(dataset.shape[1]): a = dataset[i:(i+look_back), j] xset.append(a) dataY.append(dataset[i + look_back, 0]) dataX.append(xset) return np.array(dataX), np.array(dataY) look_back = 10#上で出てきましたが、保持しておくデータ数で今回は適当に10とおいた trainX, trainY = make_dataset(train, look_back)#訓練データリシェープ testX, testY = make_dataset(test, look_back)#テストデータリシェープ Hidden_Layer = 300#隠れ層の数、多いほどコスト上がるけど多いほどいいとかなんとか Epochs = 1000#学習回数 Batch_Size = 10#バッチサイズ(まとまった単位で最適化する感じかな?よくわかってなさそう) #モデル作成 model = Sequential() model.add(LSTM(Hidden_Layer, input_shape=(testX.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)#学習開始 model.save("prime_LSTM2.h5")#学習したモデル保存 #model = load_model("prime_LSTM.h5")#読み込む時はこっち #予測値 trainPredict = model.predict(trainX) testPredict = model.predict(testX) #リスケール trainPredict = trainPredict * max_prime trainY = trainY * max_prime testPredict = testPredict * max_prime testY = testY * max_prime # 誤差率評価 err_rate_train = (abs(trainPredict-trainY)/trainY) err_rate_test = (abs(testPredict-testY)/testY) #以下予測と実際の素数のプロット test_len = len(testY) x_pl = np.arange(test_len) plt.scatter(x_pl,testY,label="actual") plt.scatter(x_pl,testPredict,label="predict",color="r") plt.legend() plt.xlim([0,50]) plt.savefig("ac_pre.png") #予測された数値を整数として吐き出し np.savetxt('pre_train.csv',trainPredict.astype("int"),delimiter=',') np.savetxt('pre_test.csv',(testPredict.astype("int")),delimiter=',') np.savetxt('test.csv',testY.astype("int"),delimiter=',')
結果
うーん、微妙そうだけど素数が書く軌跡?みたいなのは若干拾えてそう。わからん!
というか予測した値が実際素数かどうか判定しなきゃ意味がないですね!このプロットはなんなんだ!(一応平行移動して心眼で見る事は可能)
そのプログラムは面倒なのでまた今度回しておきます・・・。
まとめ
よくわからん。
というか、int型での推定(離散的な推定)ってそれ用に何かあるのかな
色々改善できそうだけどもうやらなさそうです。
おしまい