ディープラーニングについてディープにラーニング。

思いっきり、自分が学んだことのアウトプットしていきますが、何分初心者。もし何かアドバイス等頂けましたら幸いです!

f:id:kawam0t0:20191210220816j:plain

今日もパイトーチについての学習。

今日は図形(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)f:id:kawam0t0:20191214150205p:plain

今回はエンコード、デコードでネットワークを構成。

エンコード…圧縮とかよく言われるけど、今回は、次元(ノード)の削減ってとってもらって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()

f:id:kawam0t0:20191214151743p:plain
モデルの中に入力されたデータと、出力されたデータの差分。

傾向は追っているが、そこまで、はっきり極点までプロットできてない。
もう少し、パラメータをいじったり、レイヤーを増やしたりしないとか…