Day 4:
Day 4のまとめとDay 4の問題演習->Day 4の実装演習のサマリーの考察という順番
【強化学習】
長期的に報酬を最大化できるように環境のなかで行動を選択できるエージェントを作ることを目標とする機械学習の一分野行動の結果として与えられる利益(報酬)をもとに、行動を決定する原理を改善していく仕組み。
【強化学習の例】
強化学習の応用例:
環境:会社の販売促進部エージェント:プロフィールと購入履歴に基づいて、キャンペーンメールを送る顧客を決めるソフトウェアである。
行動:顧客ごとに送信、非送信のふたつの行動を選ぶことになる。
報酬:キャンペーンのコストという負の報酬とキャンペーンで生み出されると推測される売上という正の報酬を受ける。
環境について完璧な知識があれば、最適な行動を決定することは可能。
しかし、強化学習においては、完璧なは入手できていないという前提。
次のトレードオフが生じる。
過去の経験上、うまくいく行動だけをとっていては、最良の行動を見つけることはできない。
しかし、未知の行動を常にとっていると、過去の経験は生かせない。
【強化学習のイメージ】
環境: 状態 S
エージェント: 方策 Π、価値 V
行動価値関数 Q(s,a)
方策関数 Π(s,a)
強化学習の歴史:冬の時代があったが、計算速度の増大が追い風となった。関数近似法と、Q学習を組み合わせる手法の登場
Q学習:行動価値関数を、行動する毎に更新することにより学習を進める方法
関数近似法:価値関数や方策関数を関数近似する手法のこと
行動価値関数を表す関数としては、状態価値関数と行動価値関数の2種類がある
・ある状態の価値に注目する場合は、状態価値関数状態
・価値を組み合わせた価値に注目する場合は、行動価値関数
方策関数: 方策ベースの強化学習手法において、ある状態でどのような行動を採るのかの確率を与える関数 Π(s,a)
方策反復法方策をモデル化して最適化する手法
$θ^{t+1}$ = $θ^{t}$ + $εΔJ(θ)$
Jとは?:方策の良さ
定義方法:
平均報酬・割引報酬和。
【Alpha Go】
Alpha Go LeeとAlpha Go zero
RollOutPolicy: NNではなく線形の方策関数探索中に高速に着手確率を出すために使用される。
モンテカルロ木探索: 具体的には、現局面から末端局面までPlayOutと呼ばれるランダムシミュレーションを多数回行い、その勝敗を集計して着手の優劣を決定する。
【AlphaGoZero】
1、教師あり学習を一切行わず、強化学習のみで作成
2、特徴入力からヒューリスティックな要素を排除し、石の配置のみにした
3、PolicyNetとValueNetを1つのネットワークに統合した
4、Residual Net(後述)を導入した
5、モンテカルロ木探索からRollOutシミュレーションをなくした
ResidualNetwork: ネットワークにショートカット構造を追加して、勾配の爆発、消失を抑える効果を狙ったもの。
【Residual Blockの工夫】
Bottleneck: 1×1KernelのConvolutionを利用し、1層目で次元削減を行って3層目で次元を復元する3層構造にし、2層のものと比べて計算量はほぼ同じだが1層増やせるメリットがある。
PreActivation: ResidualBlockの並びをBatchNorm→ReLU→Convolution→BatchNorm→ReLU→Convolution→Addとすることにより性能が上昇したとするもの。
【Network構造の工夫】
WideResNet: ConvolutionのFilter数をk倍にしたResNet。1倍→k倍xブロック→2*k倍yブロックと段階的に幅を増やしていくのが一般的。Filter数を増やすことにより、浅い層数でも深い層数のものと同等以上の精度となり、またGPUをより効率的に使用できるため学習も早い
PyramidNet: WideResNetで幅が広がった直後の層に過度の負担がかかり精度を落とす原因となっているとし、段階的にではなく、各層でFilter数を増やしていくResNet。
【軽量化・高速化技術】
分散深層学習: 深層学習は多くのデータを使用したり、パラメータ調整のために多くの時間を使用したりするため、高速な計算が求められる。複数の計算資源(ワーカー)を使用し、並列的にニューラルネットを構成することで、効率の良い学習を行いたい。データ並列化、モデル並列化、GPUによる高速技術は不可欠である。
データ並列化:
・親モデルを各ワーカーに子モデルとしてコピー
・データを分割し、各ワーカーごとに計算させる
データ並列化の同期型:
各ワーカーが計算が終わるのを待ち、全ワーカーの勾配が出たところで勾配の平均を計算し、親モデルのパラメータを更新する。
データ並列化の非同期型:
各ワーカーはお互いの計算を待たず、各子モデルごとに更新を行う。学習が終わった子モデルはパラメータサーバにPushされる。新たに学習を始める時は、パラメータサーバからPopしたモデルに対して学習していく。
同期型と非同期型の比較:処理のスピードは、お互いのワーカーの計算を待たない非同期型の方が早い。非同期型は最新のモデルのパラメータを利用できないので、学習が不安定になりやすい(Stale Gradient Problem)
現在は同期型の方が精度が良いことが多いので、主流となっている。
モデル並列化: 親モデルを各ワーカーに分割し、それぞれのモデルを学習させる。モデルのパラメータ数が多いほど、スピードアップの効率も向上する。全てのデータで学習が終わった後で、一つのモデルに復元。モデルが大きい時はモデル並列化を、データが大きい時はデータ並列化をすると良い。
【GPUによる高速化】
GPGPU (General-purpose on GPU):元々の使用目的であるグラフィック以外の用途で使用されるGPUの総称
CPU:高性能なコアが少数。複雑で連続的な処理が得意
GPU:比較的低性能なコアが多数。簡単な並列処理が得意。ニューラルネットの学習は単純な行列演算が多いので、高速化が可能
CUDA
・GPU上で並列コンピューティングを行うためのプラットフォーム
・NVIDIA社が開発しているGPUのみで使用可能。
・Deep Learning用に提供されているので、使いやすい
モデルの軽量化:モデルの精度を維持しつつパラメータや演算回数を低減する手法の総称。
高メモリ負荷は高い演算性能が求められる。通常は低メモリ低演算性能での利用が必要とされるIotなど。モデルの軽量化は計算の高速化と省メモリ化を行うためモバイル,IoT 機器と相性が良い手法になる。
軽量化の手法代表的な手法
量子化、蒸留、プルーニング
量子化(Quantization):ネットワークが大きくなると大量のパラメータが必要なり学習や推論に多くのメモリと演算処理が必要。通常のパラメータの64bit 浮動小数点を32 bit など下位の精度に落とすことでメモリと演算処理の削減を行う。利点は計算の高速化、省メモリ化。欠点は精度の低下。
省メモリ化: ニューロンの重みを浮動小数点のbit数を少なくし、有効桁数を下げることでニューロンのメモリサイズを小さくすることができ、多くのメモリを消費するモデルのメモリ使用量を抑えることができる。
蒸留(Distillation): 精度の高いモデルはニューロンの規模が大きなモデルになっているため、推論に多くのメモリと演算処理が必要。規模の大きなモデルの知識を使い軽量なモデルの作成を行う。蒸留によって少ない学習回数でより精度の良いモデルを作成することができる。
モデルの簡約化: 学習済みの精度の高いモデルの知識を軽量なモデルへ継承させる。知識の継承により、軽量でありながら複雑なモデルに匹敵する精度のモデルを得ることが期待できる。
教師モデルと生徒モデル: 教師モデルの重みを固定し生徒モデルの重みを更新していく。誤差は教師モデルと生徒モデルのそれぞれの誤差を使い重みを更新していく。
プルーニング(Pruning): ネットワークが大きくなると大量のパラメータなるがすべてのニューロンの計算が精度に寄与しているわけではない。モデルの精度に寄与が少ないニューロンを削減することでモデルの軽量化、高速化が見込まれる。計算の高速化寄与の少ないニュローンの削減を行いモデルの圧縮を行うことで高速化に計算を行うことができる。ニューロンの削減の手法は重みが閾値以下の場合ニューロンを削減し、再学習を行う。閾値を高くするとニューロンは大きく削減できるが精度も減少する。
【MobileNet】
Depthwise ConvolutionとPointwise Convolutionの組み合わせで軽量化を実現。Depthwise Separable Convolutionという手法を用いて計算量を削減している。通常の畳込みが空間方向とチャネル方向の計算を同時に行うのに対して、Depthwise Separable ConvolutionではそれらをDepthwise ConvolutionとPointwise Convolutionと呼ばれる演算によって個別に行う。
Depthwise Convolution: 入力マップのチャネルごとに畳み込みを実施。出力マップをそれらと結合(入力マップのチャネル数と同じになる)
・通常の畳み込みカーネルは全ての層にかかっていることを考えると計算量が大幅に削減可能
・各層ごとの畳み込みなので層間の関係性は全く考慮されない。通常はPointwise Convolution畳み込みとセットで使うことで解決
Pointwise Convolution: 1 x 1 convとも呼ばれる(正確には1 x 1 x c)。入力マップのポイントごとに畳み込みを実施。出力マップ(チャネル数)はフィルタ数分だけ作成可能(任意のサイズが指定可能)。
(答)普通の畳み込みだと、H x W x $D_{K}$ x $D_{K}$ x C x M 必要だが、Depthwise Convolution だと、それをM(フィルター数)で割る。Pointwise Convolutionだとそれを、D x Dで割る。
(い)H x W x C x $D_{K}$ x $D_{K}$
(う)H x W x C x M
尚、入力マップは、H x W x Cとする。
【DenseNet】
Resnetを更に改良したもの。
畳み込み層とプーリング層の間にDense BlockとTransition Layerを交互に挟み込むモデルです。 これらを挟み込み事で、最適化が必要なパラメータ数を大幅に削減することができ、これにより学習効率をあげることが出来る。
Transition Layer: 特徴マップのサイズを変更し、ダウンサンプリングを行うため、Transition Layerと呼ばれる層でDence blockをつなぐ。
【Batch Norm以外の正規化】
Batch Norm: ミニバッチに含まれるsampleの同一チャネルが同一分布に従うよう正規化。Layer Norm: それぞれのsampleの全てのpixelsが同一分布に従うよう正規化。バッチサイズが十分に確保できない場合の対策として、全チャンネルに跨って平均・分散をとるのがLayer Normalization。
Instance Norm: さらにchannelも同一分布に従うよう正規化。
【Wavenet】音声生成モデル
時系列データに対して畳み込み(Dilated convolution)を適用する
Wavenetのメインアイディア(CNNだが、RNNと同じような機能がある)
・過去のある時刻までの範囲の全ての信号を入力として取り、次の時刻の信号を予測する
・時系列データに対して畳み込み(Dilated convolution)を適用する
・層が深くなるにつれて畳み込むリンクを離す(= dilated)
・Causal convolutionとdilated convolutionの組み合わせ。
・受容野を簡単に増やすことができるという利点がある
(答)(あ)Dilated causal convolution
A Dilated Causal Convolution is a causal convolution where the filter is applied over an area larger than its length by skipping input values with a certain step. A dilated causal convolution effectively allows the network to have very large receptive fields with just a few layers.
(答)(b)大きな畳み込みフィルタを小さな畳み込みフィルタグループで近似することではなく、Sparseな畳み込みにより、トレードオフを改善する。
Sparseな畳み込み:チャネルごとにカーネルサイズを変更してパラメータ数を減らす工夫
GoogLeNet:2014年のILSVRC優勝モデル ⁃ Inceptionモジュール (Global Average Pooling ⁃ Auxiliary loss)
Inceptionモジュール: 小さなネットワークを1つのモジュールとして定義し、モジュールの積み重ねでネットワークを構成。Sparseな畳み込みにより、表現能力とパラメータ数のトレードオフを改善。1x1畳み込みによる次元削減。
(答)(a)
AuxiliaryLossで計算量を抑えていない。他のは正しい。
GoogLeNetの学習では,ネットワークの途中から分岐させたサブネットワークにおいてもクラス分類を行い、AuxiliaryLossを追加することが行われている。これにより,ネットワークの中間層に直接誤差を伝搬させることで、勾配消失を防ぐとともにネットワークの正則化を実現している。
(答) (あ)(a)勾配消失 (い)(a) Identity
参考:
Identity Mappings in Deep Residual Networks
(答)(a) 追加の層で変換が不要でもweightを0にすれば良い。
Residual Networks (ResNet):2015年のILSVRC優勝モデル
Residualモジュール: Backpropagation時にショートカットを通じて 直接勾配が下層に伝わることで深いネットワークでも 効率的な学習が可能
(答)(d)
aはnon-maximum suppression(NMS)を使えば可能。bは2が最大ではない
cは確信度誤差と位置特定誤差の重み付き和が正しい。
YOLOとSSDの大きな違いは、YOLOがBounding Boxの出力を出力層だけで行っていたのに対し、SSDではCNNの複数の層から物体のBounding Boxを出力する点。
(答)(a)誤差関数は同じ。
ROI(候補領域)Pooling:任意サイズの領域をプーリングして、固定サイズの出力をするのが目的。普通のMax Poolingと同様に誤差逆伝播可能。
CNNベースの物体検出器は物体候補領域をあらかじめ求める。Faster R-CNNでは、Regional Proposal Networkで、Selective Searchに代わって、ROIを探す。Faster R-CNNでは、End to Endの学習が可能になり、処理が高速化した。
【Seq2seq】
・Sequenceを入力として、Sequenceを出力する。
・Encoder-Decoderモデルと呼ばれる。
・RNNが連結したものと見てよい
・Decoderのアウトプット側に正解をあてれば、教師あり学習がend-to-endで行える。
例
翻訳(英語→日本語)
音声認識(波形→テキスト)
チャットボット(テキスト→テキスト)
Seq2seq の理解に必要なもの
RNN:再帰的
LSTM:RNNの問題点を解決
Teacher Forcing: 正解ラベルを直接Decoderの入力にする方法。Teacher Forcing を適用すると、連鎖的に誤差が大きくなるのを防ぐことができる。学習が安定し、収束が早くなるというメリットがあるが、逆に評価時は前の時刻にDecoderが生成したものが使われるため、学習時と分布が異なってしまうというデメリットもある。
BLEU: 機械翻訳の分野において最も一般的な自動評価基準の一つで、予め用意した複数の参照訳と、機械翻訳モデルが出力した訳のn-gramのマッチ率に基づく指標。BLEUスコアは、現在最も広く使われている機械翻訳の指標。
Scheduled Sampling(Teacher Forcingの拡張)
ターゲット系列を入力とするか生成された結果を入力とするかを確率的にサンプリングする。二つの方法を混ぜる。
lecture_chap1_exercise_public.ipynb
PackedSequence: RNN入力に必要な前処理(RNNが扱えるようにする)。入力バッチのテンソルをこのPackedSequenceのインスタンスに変換してからRNNに入力することで、パディング部分の計算を省略することができるため、効率的な計算が可能になる。
パディング->転置->PackedSequenceの順
packed = pack_padded_sequence(padded, lengths=lengths)
テンソルに戻すには(RNNの出力に対して適用する)、pad_packed_sequenceを使う。
output, _length = pad_packed_sequence(output)
【Transformer】
・Seq2seq と同じく、Encoder-Decoderモデル
・RNNやCNNを使用せず、Attentionのみを用いるSeq2Seqモデル
・並列化がしやすく、訓練時間が削減できる
・RNNをベースにしたEncoder-Decoder翻訳モデルでは文長が長くなると表現力が足りなく問題があったが、それを改善
アーキテクチャ:
Attention(辞書オブジェクトの機能と同じ)日本語では注意機構
全結合層(Feed Forwardという所で、全結合層に渡す)
Encoder と Decoder
Encoder側:
・Input Embedding
・Positional Encoding(単語ベクトルに単語の位置を追加)
RNNを使ってないので、文字の位置情報を保存できないので。そのため最初に位置情報を付加
・Multi-Head Attention(複数のヘッドで行うDot Product Attention)
複数個のscaled dot product attentionを使う, self-target attention
・Add & Norm
Add:Residual Connection
入出力の差分を学習
効果:学習・テストエラーの低減
Norm:Layer Normalization
入力を平均 0、分散 1 に正則化
効果:学習の高速化
・Feed Forward(単語の位置ごとに独立処理する全結合)
・Add & Norm
Decoder側:
・Output Embedding
・Positional Encoding
・Masked Multi-Head Attention(未来の単語を見ないようマスク)
・self attentionとsource-target attentionの二種類
・Add & Norm
・Multi-Head Attention
self attentionとsource-target attentionの二種類
・Add & Norm
・Feed Forward
・Add & Norm
・Linear
・Softmax
・Output Probabilities
注意機構には二種類ある
1.source target attention
ソース(KeyとValueにわかれる)とターゲット(Query)
Queryはデコーダーの隠れ層から来る
ソースはエンコーダーの隠れ層から来る
2. self-attention
query, Key, Valueが同じ場所から来る。入力をすべて同じにして、
学習的にに注意個所をを決めていく。局所的な位置しか参照できないCNNと異なり、系列内の任意の位置の情報を参照することを可能にする。
lecture_chap2_exercise_public.ipynb
outputs, attns = self.attention(q_s, k_s, v_s, attn_mask=attn_mask.repeat(n_head, 1, 1))
内部モジュール的には、self attention でも、source target attentionも同じ。q_s, k_s, v_sがどういう値を取るかによって、self attentionかsource target attentionかが決まる。語彙に含める単語の最低出現回数を変えてみたが、それほど大きな影響はなかった。
語彙に含める単語の最低出現回数 = 3の時
train_bleu: 37.62 valid_loss: 18.61 valid_bleu: 35.77
語彙に含める単語の最低出現回数 = 2の時
train_bleu: 37.92 valid_loss: 19.04 valid_bleu: 35.70
語彙に含める単語の最低出現回数 = 1の時
train_bleu: 37.67 valid_loss: 22.01 valid_bleu: 35.06
【物体検知】
入力画像->物体検出器->タスク(物体の種類、位置、サイズ)
物体の中心位置だけ、高い確率が出力するように学習する。
中心位置の重複する物体は検出出来ない。-> 様々なサイズ、縦横比のアンカーボックスを用意し、アンカーボックス毎に、認識を行う。アンカーサイズのサイズは、例えば、学習データに含まれる物体のサイズをクラスタリングする事で求める。
カテゴリー・位置・サイズをアンカーに出力するように構成する。更に物体のサイズごとに物体検出するように構成することがある。
Yolo(You Only Look Once):
・画像認識を回帰問題に落とし込み、画像の領域推定と分類を同時に行うことを実現した。
・予め画像全体をグリッド分割しておき、各領域ごとに物体のクラスとbounding boxを求める
・CNN
SSD(Single Shot Detector)
・end2end のトレーニングが可能
・様々なスケールの特徴を利用し、アスペクト比ごとに識別するマルチスケール(特徴マップ)
・回帰を使う
・CNN
YOLOとSSDの違いは?:YOLOとSSDの大きな違いは、YOLOがBounding Boxの出力を出力層だけで行っていたのに対し、SSDではCNNの複数の層から物体のBounding Boxを出力する点。
R-CNNの問題点: 検出が遅い
Fast R-CNN:
・R-CNNより精度がよい
・multi-task-lossによりシステム全体を一回で学習(Back Propagationが全層に適用できるようになった)
・RoI pooling layer(Selective Searchにより探す)
Faster R-CNN:CNNベースの物体検出器は物体候補領域をあらかじめ求める。Faster R-CNNでは、Regional Proposal Network(RPN)で、Selective Searchに代わって、ROIを探す。Faster R-CNNでは、End to Endの学習が可能になり、処理が高速化した。
Fast R-CNNとFaster R-CNNの違いは?:Faster R-CNNは end2endの学習が可能。またRPNでROI(候補領域)を探すのも違う所。
(答)(d)
aはnon-maximum suppression(NMS)を使えば可能。bは2が最大ではない
cは確信度誤差と位置特定誤差の重み付き和が正しい。
【セグメンテーションーション】: Segmentation is the process of partitioning a digital image into multiple segments.
【セマンティック・セグメンテーション】Semantic Segmentation:
画像のピクセルをどの物体クラス(カテゴリー)に属するかで分類する方法。画像上の全ピクセルをクラスに分類する。
(例)U-NET
(応用)自動運転
参考:
U-Net: Convolutional Networks for Biomedical Image Segmentation
代表的な評価指標:per-pixel accuracyとIoU
あるクラスに対して:
True Positive (TP)
False Positive (FP)
True Negative (TN)
False Negative (FN)
を計算する。
-
IoU = Intersection/Union = TP/(TP + FP +FN)
2つの領域がどれくらい重なっているかを表す指標 -
per-pixel accuracy = (TP + TN)/(TP + TN +FP +FN)
混同行列の正解率にあたる。これはたまに問題が起こる。
【為替データの扱い】
為替データの予測ということであるが、データは得られるだろうが、モデルを決めないといけない。LSTMで、EURUSDの予想をしてみた。2019年度の一年間のデータを取った。データはHistData.comから取る。最初から、最後まで自分でやるのは初めてだったか、かなり勉強になった。
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.layers import Dense, Flatten, Conv2D, Activation, Dropout
from tensorflow.keras import Model
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM
from keras import optimizers
from keras.optimizers import Adam
from keras import losses
from keras.layers import Dense, Activation
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
data1= pd.read_csv('drive/My Drive/FX/1/DAT_MT_EURUSD_M1_2019.csv', names = ["date", "time", "open", "high", "low", "close", "volume"])
datetime1 = data1["date"] + "." + data1["time"]
data2 = pd.to_datetime(datetime1, format = "%Y.%m.%d.%H:%M")
data2
data1["datetime"] = data2
data1
timeindex1 = data1.set_index('datetime', inplace=True)
data2 = data1['open'].resample("30T").first()
1分ごとのデータを取ったが、リサンプリングより、30分毎のデータに変えた。またデータの前処理でnanの値のところは、前の値と同じになるようにした。時系列のデータは平均を取るより、このような扱いの方がいいと思う。その後、MinMaxScalerでスケーリングを行った。
#データの欠損値を前の値で埋める
data3 = pd.DataFrame(data2, columns = ["open"])
data4 = data3.fillna(method='ffill')
from sklearn.preprocessing import MinMaxScaler
y = np.array(data4['open'])
# 標準化
scaler = MinMaxScaler(feature_range=(0, 1))
y1 = y.reshape(-1, 1)
y = scaler.fit_transform(y1)
x = np.arange(len(y))
input_len = 4
X, Y = [], []
for i, _ in enumerate(x):
if (i+input_len+1 >= len(x)):
break
X.append(y[i:i+input_len])
Y.append(y[i+input_len+1][0])
split_index = int(len(X)*0.7)
# 学習・テスト用データに分割
train_x = X[:split_index]
train_y = Y[:split_index]
test_x = X[split_index:]
test_y = Y[split_index:]
train_x = np.array(train_x).reshape(len(train_x), -1,1)
test_x = np.array(test_x).reshape(len(test_x), -1,1)
train_y = np.array(train_y).reshape(len(train_y),-1,1)
test_y = np.array(test_y).reshape(len(test_y),-1,1)
train_x = np.asarray(train_x)
train_y = np.asarray(train_y)
test_x = np.asarray(test_x)
test_y = np.asarray(test_y)
train_x = np.array(train_x).reshape(len(train_x), -1, 1)
test_x = np.array(test_x).reshape(len(test_x), -1, 1)
train_y = np.array(train_y).reshape(len(train_y))
test_y = np.array(test_y).reshape(len(test_y))
# RNNの初期化
model = tf.keras.Sequential()
# 最初のLSTMとDropoutの追加
model.add(LSTM(50, return_sequences = True))
model.add(Dropout(0.2))
# 二番目のLSTMとDropoutの追加
model.add(LSTM(50, return_sequences = True))
model.add(Dropout(0.2))
# 三番目のLSTMとDropoutの追加
model.add(LSTM(50, return_sequences = True))
model.add(Dropout(0.2))
# 四番目のLSTMとDropoutの追加
model.add(LSTM(50))
model.add(Dropout(0.2))
# 出力層の追加
model.add(Dense(1))
# 学習のためのRNNモデルを設定
model.compile(optimizer = 'adam', loss = 'mean_squared_error')
# RNNモデルを学習させる
model.fit(train_x, train_y, epochs = 10, batch_size = 32)
# モデルの評価
score = model.evaluate(test_x, test_y)
score
損失関数は回帰なので、MSEを使った。
# ラベルなどの設定
df = pd.DataFrame(data4.index.values, columns = ["datetime2"])
label_x = df.to_numpy()
label_x = label_x[len(y)-len(test_y):]
test_y = scaler.inverse_transform(np.array(test_y).reshape(-1,1))
test_y = test_y.reshape(len(test_y))
# 予測値の抽出
predict_y = model.predict(test_x)
# 元の値に戻す
predict_y = scaler.inverse_transform(predict_y)
fig, ax = plt.subplots()
ax.plot(label_x, predict_y, label="prediction", color="red")
ax.plot(label_x, test_y, label="raw data", color="blue")
plt.tick_params(axis='x', which='major', labelsize=6)
ax.legend()
plt.show()