■
今日もパイトーチについての学習。
今日は図形(matplotlib)によって、
視覚的に学習出力前と出力後の差についてわかりやすくしたコードを書いた。
まずは全コードから。
#全コード import torch from torch.autograd import Variable import torch.nn as nn import torch.nn.functional as F import torch.optim as optim import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline #日本語表記が入っているから #平均気温データのみカット data = pd.read_csv("weather/data.csv" , encoding = "shift-jis" , skiprows=[0,1,2,4]) temp_data = data["平均気温(℃)"] #データセット #2000/1/1 - 2014/12/31 train_x = np.array(temp_data[0:5479]) #2015/1/1 - 2018/12/31 test_x = np.array(temp_data[5479 : ]) mini_size = 180 tmp = [] # i -> 0 - 5299までの数字 for i in range(0 , len(train_x) - mini_size): #1回目 0 : 0 + 180 #2回目 1 : 1 + 181 ... #横180行×縦5299列 tmp.append(train_x[i : i + mini_size]) #トレーニング用 データ x_train = np.array(tmp) #モデル定義 class Net(nn.Module): #モデルレイヤー定義 def __init__(self): super(Net , self).__init__() #torch版の全結合 #エンコード -次元削除 self.fc1 = nn.Linear(180 , 128) self.fc2 = nn.Linear(128 , 64) self.fc3 = nn.Linear(64 , 64) self.fc4 = nn.Linear(64 , 32) #でコード - 次元復元 self.fc5 = nn.Linear(32 , 64) self.fc6 = nn.Linear(64 , 128) self.fc7 = nn.Linear(128 , 180) #活性化関数の定義 def forward(self , x): x = F.relu(self.fc1(x)) x = self.fc2(x) x = F.relu(self.fc3(x)) x = self.fc4(x) x = F.relu(self.fc5(x)) x = self.fc6(x) x = self.fc7(x) return x model = Net() #差分の計算 -> 差分の2乗して、へいきんを算出する criterion = nn.MSELoss() #最適化 optimizer = optim.Adam(model.parameters() , lr = 0.00015) #1000回学習させる for epoch in range(10000): total_loss = 0 #入力データ : ランダムに発生させた3か月のデータを100回分 input_x = [] for i in range(100): index = np.random.randint(0 ,5299) input_x.append(x_train[index]) #array & 浮動小数点数に変換 input_x = np.array(input_x , dtype="float32") #Tensor形式に変換 input_x = Variable(torch.from_numpy(input_x)) #最適化の初期 optimizer.zero_grad() output = model(input_x) loss = criterion(output , input_x) loss.backward() optimizer.step() total_loss += loss.item() if (epoch+1) % 1000 == 0: print(epoch + 1 , total_loss) #グラフ化############################################################### plt.plot(input_x.data[0].numpy() , label= "input") plt.plot(output.data[0].numpy() , label = "output") plt.legend() ######################################################################## #既にあるモデルで学習させる input_x = [] x_test = [] #test_X -> 1行×1461列 input_x.append(test_x[180:360]) input_x.append(test_x[360:540]) #input_x -> 180行×2列 input_x = np.array(input_x , "float32") #tensor形式に変換 input_test = Variable(torch.from_numpy(input_x)) output = model(input_test) #グラフ化############################################################### plt.plot(input_test.flatten()) plt.plot(output.data.numpy().flatten()) ########################################################################
今回、作ったものは下のネットワークの構造になる(後々見たら、隠れ層、ちょっと増えてますがイメージはこんな感じですw)
今回はエンコード、デコードでネットワークを構成。
エンコード…圧縮とかよく言われるけど、今回は、次元(ノード)の削減ってとってもらってOK
デコード…復元。エンコードとは反対に、次元を復元(元の次元数に戻す)
今回も、おなじみのライブラリです。
(Jupyter Notebook使ってるので、matplotlibは目をつぶってください)
import torch from torch.autograd import Variable import torch.nn as nn import torch.nn.functional as F import torch.optim as optim import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline
もうここまでは説明不要。
次に、今回は故郷の大阪の2000年~2018年の平均気温のデータを持ってくる(気象庁のHPからDL)
data = pd.read_csv("weather/data.csv" , encoding = "shift-jis" , skiprows=[0,1,2,4]) temp_data = data["平均気温(℃)"] #データセット #2000/1/1 - 2014/12/31 train_x = np.array(temp_data[0:5479]) #2015/1/1 - 2018/12/31 test_x = np.array(temp_data[5479 : ]) mini_size = 180 tmp = [] # i -> 0 - 5299までの数字 for i in range(0 , len(train_x) - mini_size): #1回目 0 : 0 + 180 #2回目 1 : 1 + 181 ... #横180行×縦5299列 tmp.append(train_x[i : i + mini_size]) #トレーニング用 データ x_train = np.array(tmp)
CSVデータをpandasで取得し、いらん情報をカット。
トレーニングとテストで分割。
mini_size で膨大なデータを180行で小さくまとめる(半年分)
それから、いつも通り、array形式でデータ保持
#モデル定義 class Net(nn.Module): #モデルレイヤー定義 def __init__(self): super(Net , self).__init__() #torch版の全結合 #エンコード -次元削除 self.fc1 = nn.Linear(180 , 128) self.fc2 = nn.Linear(128 , 64) self.fc3 = nn.Linear(64 , 64) self.fc4 = nn.Linear(64 , 32) #でコード - 次元復元 self.fc5 = nn.Linear(32 , 64) self.fc6 = nn.Linear(64 , 128) self.fc7 = nn.Linear(128 , 180) #活性化関数の定義 def forward(self , x): x = F.relu(self.fc1(x)) x = self.fc2(x) x = F.relu(self.fc3(x)) x = self.fc4(x) x = F.relu(self.fc5(x)) x = self.fc6(x) x = self.fc7(x) return x model = Net()
今回もモデルを定義する。
前回よりも少し、レイヤーを増やし、
エンコード、デコードを行う。できたモデルをmodelに格納
#差分の計算 -> 差分の2乗して、平均を算出する criterion = nn.MSELoss() #最適化 optimizer = optim.Adam(model.parameters() , lr = 0.00015) #1000回学習させる for epoch in range(10000): total_loss = 0 #入力データ : ランダムに発生させた3か月のデータを100回分 input_x = [] for i in range(100): index = np.random.randint(0 ,5299) input_x.append(x_train[index]) #array & 浮動小数点数に変換 input_x = np.array(input_x , dtype="float32") #Tensor形式に変換 input_x = Variable(torch.from_numpy(input_x)) #最適化の初期 optimizer.zero_grad() output = model(input_x) loss = criterion(output , input_x) loss.backward() optimizer.step() total_loss += loss.item() if (epoch+1) % 1000 == 0: print(epoch + 1 , total_loss)
今回は差分の計算方法として平均二乗誤差を使う。
読んで字のごとくだが、差分を2乗して、へいきんを算出するというものだ。
そして、最適化にはAdamを使用する。
そのあとのコードはほぼ前回と同じなので、割愛。
plt.plot(input_x.data[0].numpy() , label= "input") plt.plot(output.data[0].numpy() , label = "output") plt.legend()
モデルの中に入力されたデータと、出力されたデータの差分。
傾向は追っているが、そこまで、はっきり極点までプロットできてない。
もう少し、パラメータをいじったり、レイヤーを増やしたりしないとか…