回答編集履歴

1

内容の変更

2022/09/11 08:53

投稿

sigefuji
sigefuji

スコア125

test CHANGED
@@ -1,7 +1,136 @@
1
- keras場合ミニバッチごとのモデル評価戻り値は、出力値(カテゴリごとのリスト)なの
1
+ 後調べた結果、モデルの出力値を取得きる方法がわかった。
2
- このと教師データから、カテゴリごとの正解計算すればよい簡単なことがわかりました
2
+ 出力が取得できれば、カテゴリごとの正解求めることは容易
3
+ 参考書籍(下記)を参考に試した2例を参考までに掲示します。
4
+
5
+ 1.tensorflow/kerasのconv1Dモデルで学習をする場合
3
- 質問当時はこのmodel関数(?)戻りがそれ表すことがわかりませんした
6
+ 全epoch終了後,model.predictを使用して、全学習サンプル出力値を取得きる
4
- まったく普通考えでした。
7
+ 方法の問題点
8
+ ・各epoch途中の出力値は取得できず、最後のepochの値が取得できるようだ。
9
+ ・主力値の全サンプルを記憶するメモリが必要と思われる(gpuのメモリサイズに影響すると思う)
5
- よく見サンプルプログラムは、カテゴリごとの正解値は必要とせず、単にバッチ単位での正解率だけを評価しているのでわかりませんでした
10
+  各ミニバッチ評価ごと、あepochごとに取得できれば最終的に必要なct/winのカテゴリだけのメモリ良い
11
+ 使用コード例抜粋
12
+ 参考書籍6章1節(物体画像認識時系列データ処理入門第2版)
13
+
14
+ ```
15
+ # 畳み込み層
16
+ model.add(
17
+ Conv1D(filters=100, # フィルターの数は32
18
+ kernel_size=(3), # 3のフィルターを使用
19
+ padding='same', # ゼロパディングを行う
20
+ input_shape=(1,xsz), # 入力データの形状
21
+ activation='relu' # 活性化関数はReLU
22
+ ))
23
+
24
+ '''
25
+ 3. 学習する
26
+ '''
27
+ training_epochs = 100
28
+ # 学習を行って結果を出力
29
+ history = model.fit(
30
+ x_train, # 訓練データ
31
+ y_train, # 正解ラベル
32
+ epochs=training_epochs, # 学習を繰り返す回数
33
+ batch_size=batch_size, # ミニバッチのサイズ
34
+ verbose=0, # 学習の進捗状況を出力する
35
+ #validation_split= 0.2, # 検証データとして使用する割合
36
+ shuffle=True, # 検証データを抽出する際にシャッフルする
37
+ #callbacks=[early_stopping] # コールバックはリストで指定する
38
+ )
39
+ # テストデータで学習を評価するデータを取得
40
+ score = model.evaluate(x_train, y_train, verbose=1)
41
+ print('evaluate Train loss:', score[0]) # テストデータの損失を出力
42
+ print('Train accuracy:', score[1]) # テストデータの精度を出力
43
+
44
+ pred_train = model.predict(x_train) # 全訓練データの出力値を取得
45
+ ct=[0 for n in range(p_out)]
46
+ win=[0 for n in range(p_out)]
47
+ for n in range(len(x_train)):       # 全訓練データ数でループしてct/winを積算
48
+ b_y = pred_train[n].argmax()
49
+ if b_y == y_train[n]:
50
+ win[b_y] += 1
51
+ ct[b_y] += 1
52
+ print("train",ct)
53
+ print("win",win)
54
+ ```
55
+ 2.MLPクラスの場合(隠れ層と出力層のみの単純な場合)
56
+
57
+ 1サンプルの学習時に呼び出す outputs = model(x, training=True) の戻り値に出力値がセットされる。
58
+ これから普通に、最大値を選べば、予測ラベルになる。
59
+ 第1のモデルに比しての功罪
60
+ ・出力値を保存しておくメモリが不要
61
+
62
+ 次に1次元データの場合の適用例を示す
63
+ 参考書籍5章5節
64
+
65
+ ```
66
+
67
+ '''
68
+ 2. モデルの定義
69
+ '''
70
+ class MLP(tf.keras.Model):
71
+ '''多層パーセプトロン
72
+
73
+ Attributes:
74
+ l1(Dense): 隠れ層
75
+ l2(Dense): 出力層
76
+ '''
77
+ def __init__(self, hidden_dim, output_dim):
78
+ super().__init__()
79
+ self.fc1 = tf.keras.layers.Dense(hidden_dim, activation='relu')
80
+ self.dropout = tf.keras.layers.Dropout(0.5)
81
+ self.fc2 = tf.keras.layers.Dense(output_dim, activation='softmax')
82
+
83
+ def call(self, x, training=None):
84
+ x = self.fc1(x) # 第1層の出力
85
+ if training: # 訓練モードのときdropout
86
+ x = self.dropout(x)
87
+ x = self.fc2(x) # 出力層の出力
88
+ return x
89
+
90
+ '''
91
+ 4. 勾配降下アルゴリズムによるパラメーターの更新処理を行うtrain_step()関数
92
+ '''
93
+
94
+ train_loss = tf.keras.metrics.Mean()
95
+ train_accuracy = tf.keras.metrics.CategoricalAccuracy()
96
+
97
+ def train_step(x, t):
98
+ '''学習を1回行う
99
+ Returns:
100
+ ステップごとのクロスエントロピー誤差
101
+ '''
102
+ with tf.GradientTape() as tape:
103
+ outputs = model(x, training=True) # モデルに入力して順伝搬の出力値を取得
104
+ tmp_loss = loss_fn(t, outputs) # 出力値と正解ラベルの誤差
105
+ grads = tape.gradient(
106
+ tmp_loss, # 現在のステップの誤差
107
+ model.trainable_variables)
108
+ # 勾配降下法の更新式を適用してバイアス、重みを更新
109
+ optimizer.apply_gradients(zip(grads,
110
+ model.trainable_variables))
111
+
112
+ train_loss(tmp_loss)
113
+ train_accuracy(t, outputs)
114
+
115
+ ct=[0 for ot in range(p_out)]
116
+ win=[0 for ot in range(p_out)]
117
+ for bat in range(batch_size):
118
+ maxv=0
119
+ maxot=0
120
+ #print("outputs",outputs[bat,])
121
+ for ot in range(p_out):
122
+ if outputs[bat,ot] > maxv:
123
+ maxv = outputs[bat,ot]
124
+ maxot = ot
125
+ no = onehot2no(t[bat])
126
+ ct[maxot] += 1
127
+ if maxot==no:
128
+ win[maxot] += 1
129
+ return ct,win
130
+ ```
131
+ 参考情報:
132
+ cpuの利用効率であるが、例1は100%であるのに、例2はなぜか20-40%と低い。
133
+ 計算効率が何か異なるようだ。
6
134
 
7
135
 
136
+