ARCS6 AR6-REV.24062600
読み取り中…
検索中…
一致する文字列を見つけられません
FeedforwardNeuralNet3.hh
[詳解]
1
8//
9// Copyright (C) 2011-2020 Yokokura, Yuki
10// This program is free software;
11// you can redistribute it and/or modify it under the terms of the FreeBSD License.
12// For details, see the License.txt file.
13
14#ifndef FEEDFORWARDNEURALNET3
15#define FEEDFORWARDNEURALNET3
16
17#include <cassert>
18#include <array>
19#include <string>
20#include "Matrix.hh"
21#include "NeuralNetParamDef.hh"
23#include "FrameGraphics.hh"
24#include "CuiPlot.hh"
25
26// ARCS組込み用マクロ
27#ifdef ARCS_IN
28 // ARCSに組み込まれる場合
29 #include "ARCSassert.hh"
30 #include "ARCSeventlog.hh"
31#else
32 // ARCSに組み込まれない場合
33 #define arcs_assert(a) (assert(a))
34 #define PassedLog()
35 #define EventLog(a)
36 #define EventLogVar(a)
37#endif
38
39namespace ARCS { // ARCS名前空間
41 // 下記のテンプレートの実装はとてもアホっぽいが,
42 // C++17ではテンプレートパラメータにローカルなstructも配列も渡せないし,
43 // パラメータパックは展開めんどくせーし,という言い訳をここに書いておく
47 template <
48 typename DsName, // データセットクラス名
49 size_t InSize, // 入力層のサイズ
50 size_t HidSize, // 隠れ層のサイズ
51 size_t OutSize, // 出力層のサイズ
52 size_t MinbatSize, // ミニバッチサイズ
53 size_t MinbatNum, // ミニバッチ数
54 size_t Epoch, // エポック数
55 size_t EpochDisp, // エポックループ表示数
56 ActvFunc InFunc, // 入力層の活性化関数
57 ActvFunc HidFunc, // 隠れ層の活性化関数
58 ActvFunc OutFunc, // 出力層の活性化関数
59 NnInitTypes InitType, // 重み初期化のタイプ
60 NnDescentTypes GradDesType, // 勾配降下法のタイプ
61 NnDropout DropOutEnable, // ドロップアウトイネーブル
62 NnShuffle DsShfl // エポック毎のデータセットシャッフル
63 >
65 public:
68 : InputLayer(), HiddenLayer(), OutputLayer(),
69 X(), ZIn(), ZHid(), Y(), D(), WDeltaOut(), WDeltaHid(), WDeltaIn(),
70 EpochNumbers(), TrainLoss(), TestLoss(),
71 XTest(), ZInTest(), ZHidTest(), YTest(), DTest(),
72 zin(), zhid()
73 {
74 PassedLog();
75 }
76
80 : InputLayer(r.InputLayer), HiddenLayer(r.HiddenLayer), OutputLayer(r.OutputLayer),
81 X(r.X), ZIn(r.ZIn), ZHid(r.ZHid), Y(r.Y), D(r.D), WDeltaOut(r.WDeltaOut), WDeltaHid(r.WDeltaHid), WDeltaIn(r.WDeltaIn),
82 EpochNumbers(r.EpochNumbers), TrainLoss(r.TrainLoss), TestLoss(r.TestLoss),
83 XTest(r.XTest), ZInTest(r.ZInTest), ZHidTest(r.ZHidTest), YTest(r.YTest), DTest(r.DTest),
84 zin(r.zin), zhid(r.zhid)
85 {
86
87 }
88
93
95 void InitWeight(void){
96 InputLayer.InitWeight(InSize); // 入力層の重み行列の乱数による初期化
97 HiddenLayer.InitWeight(InSize); // 内部層の重み行列の乱数による初期化
98 OutputLayer.InitWeight(HidSize);// 出力層の重み行列の乱数による初期化
99 }
100
104 void SetGainOfMomentumSGD(double epsilon, double alpha){
105 InputLayer.SetGainOfMomentumSGD(epsilon, alpha);
106 HiddenLayer.SetGainOfMomentumSGD(epsilon, alpha);
107 OutputLayer.SetGainOfMomentumSGD(epsilon, alpha);
108 }
109
112 void SetDropoutRate(double DropoutRate){
113 InputLayer.SetDropoutRate(DropoutRate);
114 HiddenLayer.SetDropoutRate(DropoutRate);
115 OutputLayer.SetDropoutRate(DropoutRate);
116 }
117
120 void Train(DsName& Datasets){
121 InitWeight(); // 重み行列の初期化
122 InputLayer.NomalizeDataset(Datasets.MeasuredData); // データセットの正規化(標準化)
123 Datasets.GetMeasuredBatchData(Datasets.FinalMinbatNum, XTest); // 最後のミニバッチをテスト入力データとして取得
124 Datasets.GetClassBatchData(Datasets.FinalMinbatNum, DTest); // 最後のミニバッチをテスト目標データとして取得
125
126 // 誤差逆伝播法のエポック数分のループ
127 printf("\nBackpropagation Training:\n");
128 printf("Epoch : Train Loss [dB] Test Loss [dB]\n");
129 for(size_t i = 0; i < Epoch; ++i){
130 // ミニバッチ数分のループ
131 for(size_t j = 0; j < MinbatNum; ++j){
132 // 訓練データの準備
133 Datasets.GetMeasuredBatchData(j + 1, X);// ミニバッチ分の入力データを取得
134 Datasets.GetClassBatchData(j + 1, D); // ミニバッチ分の目標データを取得
135
136 // ドロップアウトの準備
137 InputLayer.CalcDropout();
138 HiddenLayer.CalcDropout();
139
140 // 順伝播計算
141 InputLayer.CalcForwardForTraining(X, ZIn); // 入力層の順伝播計算
142 HiddenLayer.CalcForwardForTraining(ZIn, ZHid); // 内部層の順伝播計算
143 OutputLayer.CalcForwardForTraining(ZHid, Y); // 出力層の順伝播計算
144
145 // 逆伝播による誤差行列計算
146 OutputLayer.CalcDeltaForOutputLayer(Y, D, WDeltaOut); // 出力層の逆伝播計算
147 HiddenLayer.CalcDelta(WDeltaOut, WDeltaHid); // 内部層の逆伝播計算
148 InputLayer.CalcDelta(WDeltaHid, WDeltaIn); // 入力層の逆伝播計算
149
150 // 重み行列の更新
151 InputLayer.UpdateWeight(X); // 入力層の重み更新
152 HiddenLayer.UpdateWeight(ZIn); // 内部層の重み更新
153 OutputLayer.UpdateWeight(ZHid); // 出力層の重み更新
154 }
155 if constexpr(DsShfl == NnShuffle::ENABLE) Datasets.ShuffleDatasets(); // データセットのシャッフル
156
157 // テストデータの順伝播計算
158 InputLayer.CalcForwardForEstimation(XTest, ZInTest); // 入力層の順伝播計算
159 HiddenLayer.CalcForwardForEstimation(ZInTest, ZHidTest);// 内部層の順伝播計算
160 OutputLayer.CalcForwardForEstimation(ZHidTest, YTest); // 出力層の順伝播計算
161
162 // 学習曲線評価用のデータ保持
163 EpochNumbers[i] = i;
164 TrainLoss[i] = 10.0*log10(OutputLayer.GetLoss(Y, D)); // 訓練誤差
165 TestLoss[i] = 10.0*log10(OutputLayer.GetLoss(YTest, DTest));// テスト誤差
166
167 // エポック毎の訓練誤差とテスト誤差の表示
168 if(i % (Epoch/EpochDisp) == 0){
169 printf("%5lu : % 16.8f, % 16.8f\n", i, TrainLoss[i], TestLoss[i]);
170 }
171 }
172 }
173
175 void DispWeight(void){
176 printf("\nWeight Matrices of All Layers:\n");
177 InputLayer.DispWeight(); // 入力層の重みの表示
178 HiddenLayer.DispWeight(); // 内部層の重みの表示
179 OutputLayer.DispWeight(); // 出力層の重みの表示
180 }
181
183 void DispBias(void){
184 printf("\nBias Vectors of All Layers:\n");
185 InputLayer.DispBias();
186 HiddenLayer.DispBias();
187 OutputLayer.DispBias();
188 }
189
191 void DispSettings(void){
192 printf("\nNeural Network Settings:\n");
193 InputLayer.DispSettings();
194 HiddenLayer.DispSettings();
195 OutputLayer.DispSettings();
196 }
197
200 printf("\nFinal Test Data Comfirmation:\n");
201 PrintMatrix(YTest, "% g"); // 順伝播出力値
202 PrintMatrix(DTest, "% g"); // 正解値
203 }
204
209 void WriteLeaningCurvePNG(const std::string& FileName, const int Ymin, const int Ymax){
210 // 学習曲線のグラフの表示
211 FrameGraphics FG(GRAPH_WIDTH, GRAPH_HEIGHT);
212 CuiPlot Plot(FG, 0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);
213 Plot.SetAxisLabels("Epoch Number", "Errors 10log10 [dB]");
214 Plot.SetRanges(0, Epoch, (double)Ymin, (double)Ymax);
215 Plot.SetGridLabelFormat("%5.0f", "%2.1f");
216 Plot.DrawAxis();
217 Plot.DrawLegend(1, "Training", FGcolors::CYAN);
218 Plot.DrawLegend(2, "Test", FGcolors::MAGENTA);
219 Plot.Plot(EpochNumbers, TrainLoss, CuiPlotTypes::PLOT_BOLDSTAIRS, FGcolors::CYAN);
220 Plot.Plot(EpochNumbers, TestLoss, CuiPlotTypes::PLOT_BOLDSTAIRS, FGcolors::MAGENTA);
221 FG.SavePngImageFile(FileName);
222 }
223
228 // 順伝播計算
229 Matrix<1,InSize> xn = x; // 正規化用
230 InputLayer.NormalizeInput(xn); // 入力データの正規化(標準化)
231 InputLayer.CalcForwardForEstimation(xn, zin); // 入力層の順伝播計算
232 HiddenLayer.CalcForwardForEstimation(zin, zhid);// 内部層の順伝播計算
233 OutputLayer.CalcForwardForEstimation(zhid, y); // 出力層の順伝播計算
234 }
235
238 void SaveWeightAndBias(const std::string& FileName){
239 InputLayer.SaveWeightAndBias(FileName + "-InputLayerW.csv", FileName + "-InputLayerb.csv");
240 HiddenLayer.SaveWeightAndBias(FileName + "-HiddenLayerW.csv", FileName + "-HiddenLayerb.csv");
241 OutputLayer.SaveWeightAndBias(FileName + "-OutputLayerW.csv", FileName + "-OutputLayerb.csv");
242 }
243
246 void LoadWeightAndBias(const std::string& FileName){
247 InputLayer.LoadWeightAndBias(FileName + "-InputLayerW.csv", FileName + "-InputLayerb.csv");
248 HiddenLayer.LoadWeightAndBias(FileName + "-HiddenLayerW.csv", FileName + "-HiddenLayerb.csv");
249 OutputLayer.LoadWeightAndBias(FileName + "-OutputLayerW.csv", FileName + "-OutputLayerb.csv");
250 }
251
254 void SaveSettings(const std::string& FileName){
255 InputLayer.SaveSettings(FileName + "-InputLayerSet.csv");
256 HiddenLayer.SaveSettings(FileName + "-HiddenLayerSet.csv");
257 OutputLayer.SaveSettings(FileName + "-OutputLayerSet.csv");
258 }
259
262 void LoadSettings(const std::string& FileName){
263 InputLayer.LoadSettings(FileName + "-InputLayerSet.csv");
264 HiddenLayer.LoadSettings(FileName + "-HiddenLayerSet.csv");
265 OutputLayer.LoadSettings(FileName + "-OutputLayerSet.csv");
266 }
267
268 private:
270 const FeedforwardNeuralNet3& operator=(const FeedforwardNeuralNet3&) = delete;
271
272 // 学習曲線グラフの設定
273 static constexpr int GRAPH_WIDTH = 1000;
274 static constexpr int GRAPH_HEIGHT = 500;
275
276 // 3層ニューラルネットワーク
280
281 // 誤差逆伝播用の変数
290 std::array<double, Epoch> EpochNumbers;
291 std::array<double, Epoch> TrainLoss;
292 std::array<double, Epoch> TestLoss;
293
294 // テストデータ用の変数
300
301 // 推定計算用の変数
302 Matrix<1,InSize> zin;
303 Matrix<1,HidSize> zhid;
304 };
305
306}
307
308#endif
309
ARCS イベントログクラス
#define PassedLog()
イベントログ用マクロ(ファイルと行番号のみ記録版)
Definition ARCSeventlog.hh:26
ARCS用ASSERTクラス
CuiPlot(新型きゅいプロットV2)
単層パーセプトロンクラス
行列/ベクトル計算クラス(テンプレート版)
#define PrintMatrix(a, b)
行列要素表示マクロ(フォーマット指定あり版)
Definition Matrix.hh:35
ActvFunc
活性化関数のタイプの定義
Definition ActivationFunctions.hh:35
フレームグラフィックスクラスV2(新型テンプレート版)
ニューラルネットワークパラメータ定義ファイル
NnInitTypes
重み初期化のタイプの定義
Definition NeuralNetParamDef.hh:19
NnShuffle
エポック毎にデータセットをシャッフルするかどうか
Definition NeuralNetParamDef.hh:41
NnDropout
ドロップアウトの定義
Definition NeuralNetParamDef.hh:35
NnDescentTypes
勾配降下法のタイプの定義
Definition NeuralNetParamDef.hh:25
CuiPlot(新型きゅいプロットV2)
Definition CuiPlot.hh:54
void SetRanges(double xmin, double xmax, double ymin, double ymax)
グラフの範囲を設定する関数
Definition CuiPlot.hh:130
void Plot(const double x, const double y, const CuiPlotTypes type, const uint32_t color)
1点のデータをプロットする関数(バイナリ色データ版)
Definition CuiPlot.hh:250
void SetGridLabelFormat(const std::string &xformat, const std::string &yformat)
グリッドラベルの書式を設定する関数
Definition CuiPlot.hh:153
void SetAxisLabels(const std::string &xlabel, const std::string &ylabel)
軸ラベルを設定する関数
Definition CuiPlot.hh:145
void DrawAxis(void)
グラフの軸を描画する関数
Definition CuiPlot.hh:170
void DrawLegend(size_t i, const std::string &name, const FGcolors &color)
凡例を描画する関数
Definition CuiPlot.hh:188
多層パーセプトロンクラス3層版
Definition FeedforwardNeuralNet3.hh:64
void WriteLeaningCurvePNG(const std::string &FileName, const int Ymin, const int Ymax)
学習曲線グラフのPNG画像ファイルを書き出す関数
Definition FeedforwardNeuralNet3.hh:209
FeedforwardNeuralNet3(FeedforwardNeuralNet3 &&r)
ムーブコンストラクタ
Definition FeedforwardNeuralNet3.hh:79
void DispFinalTestData(void)
最後の学習結果を使った順伝播出力値と正解値の確認
Definition FeedforwardNeuralNet3.hh:199
void SetGainOfMomentumSGD(double epsilon, double alpha)
モーメンタム確率的勾配降下法の更新ゲイン(学習率)の設定
Definition FeedforwardNeuralNet3.hh:104
void LoadWeightAndBias(const std::string &FileName)
CSVファイルから各レイヤの重み行列とバイアスベクトルに読み込む関数
Definition FeedforwardNeuralNet3.hh:246
void LoadSettings(const std::string &FileName)
CSVファイルから各レイヤのパーセプトロンの設定値を読み込む関数
Definition FeedforwardNeuralNet3.hh:262
FeedforwardNeuralNet3()
コンストラクタ
Definition FeedforwardNeuralNet3.hh:67
void Train(DsName &Datasets)
誤差逆伝播法による訓練をする関数
Definition FeedforwardNeuralNet3.hh:120
~FeedforwardNeuralNet3()
デストラクタ
Definition FeedforwardNeuralNet3.hh:90
void InitWeight(void)
重み行列の初期化
Definition FeedforwardNeuralNet3.hh:95
void SaveSettings(const std::string &FileName)
各レイヤのパーセプトロンの設定値をCSVファイルとして保存する関数
Definition FeedforwardNeuralNet3.hh:254
void DispBias(void)
バイアスベクトルの表示
Definition FeedforwardNeuralNet3.hh:183
void Estimate(const Matrix< 1, InSize > &x, Matrix< 1, OutSize > &y)
訓練済みニューラルネットワークを使った推定計算
Definition FeedforwardNeuralNet3.hh:227
void DispSettings(void)
パーセプトロン設定値の表示
Definition FeedforwardNeuralNet3.hh:191
void DispWeight(void)
重み行列の表示
Definition FeedforwardNeuralNet3.hh:175
void SetDropoutRate(double DropoutRate)
ドロップアウト率の設定
Definition FeedforwardNeuralNet3.hh:112
void SaveWeightAndBias(const std::string &FileName)
各レイヤの重み行列とバイアスベクトルをCSVファイルとして保存する関数
Definition FeedforwardNeuralNet3.hh:238
フレームグラフィックスクラス(新型テンプレート版)
Definition FrameGraphics.hh:91
void SavePngImageFile(const std::string &FileName)
PNG画像ファイルを保存する関数
Definition FrameGraphics.hh:200
行列/ベクトル計算クラス(テンプレート版)
Definition Matrix.hh:44
単層パーセプトロンクラス
Definition SingleLayerPerceptron.hh:59
void UpdateWeight(const Matrix< M, N > &Zprev)
重み行列とバイアスベクトルの更新
Definition SingleLayerPerceptron.hh:263
void DispSettings(void)
パーセプトロン設定値の表示
Definition SingleLayerPerceptron.hh:287
void SaveSettings(const std::string &SettingName)
パーセプトロンの設定をCSVファイルに保存する関数
Definition SingleLayerPerceptron.hh:356
void InitWeight(size_t Nprev)
重み行列の初期化
Definition SingleLayerPerceptron.hh:100
void LoadWeightAndBias(const std::string &WeightName, const std::string &BiasName)
重み行列とバイアスベクトルをCSVファイルとして入力する関数
Definition SingleLayerPerceptron.hh:349
void CalcForwardForTraining(const Matrix< 1, N > &zprev, Matrix< 1, P > &z)
順伝播計算(ベクトル入出力訓練版)
Definition SingleLayerPerceptron.hh:173
void SetGainOfMomentumSGD(double epsilon, double alpha)
モーメンタム確率的勾配降下法の更新ゲイン(学習率)の設定
Definition SingleLayerPerceptron.hh:120
void NormalizeInput(Matrix< 1, P > &x)
入力データの正規化(標準化)
Definition SingleLayerPerceptron.hh:334
void NomalizeDataset(Matrix< NN, MM > &x)
生計測データセットの正規化(標準化)
Definition SingleLayerPerceptron.hh:326
void SaveWeightAndBias(const std::string &WeightName, const std::string &BiasName)
重み行列とバイアスベクトルをCSVファイルとして出力する関数
Definition SingleLayerPerceptron.hh:341
void CalcDropout(void)
ドロップアウトマスクの計算
Definition SingleLayerPerceptron.hh:245
void DispBias(void)
バイアスベクトルの表示
Definition SingleLayerPerceptron.hh:282
void CalcForwardForEstimation(const Matrix< 1, N > &zprev, Matrix< 1, P > &z)
順伝播計算(ベクトル入出力推定版)
Definition SingleLayerPerceptron.hh:186
void SetDropoutRate(double DropoutRate)
ドロップアウト率の設定
Definition SingleLayerPerceptron.hh:166
double GetLoss(const Matrix< M, P > &Y, const Matrix< M, P > &D)
訓練/テスト誤差を返す関数
Definition SingleLayerPerceptron.hh:301
void CalcDeltaForOutputLayer(const Matrix< M, P > &Y, const Matrix< M, P > &D, Matrix< M, N > &WDelta)
出力層用の誤差行列の計算
Definition SingleLayerPerceptron.hh:239
void CalcDelta(const Matrix< M, P > &WDeltaNext, Matrix< M, N > &WDelta)
入力層と内部層(隠れ層)用の誤差行列の計算
Definition SingleLayerPerceptron.hh:225
void DispWeight(void)
重み行列の表示
Definition SingleLayerPerceptron.hh:277
void LoadSettings(const std::string &SettingName)
CSVファイルからパーセプトロンの設定を読み込む関数
Definition SingleLayerPerceptron.hh:364