teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

6

完全なパラメータの追記

2017/11/27 01:14

投稿

yag1kaz
yag1kaz

スコア253

answer CHANGED
@@ -147,30 +147,6 @@
147
147
  追記3(2017/11/20 19:25)
148
148
  上記は2値入力でしたので4値入力でうまくいくパターンを見つけましたので、追記しておきます。
149
149
 
150
- ```Python
151
- X = numpy.array([[0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0],[0, 0, 1,1], # 入力の記号:0がマイナス、1がプラス
152
- [0, 1, 0, 0], [0, 1, 0, 1], [0, 1, 1, 0], [0, 1, 1, 1],
153
- [1, 0, 0, 0], [1, 0, 0, 1], [1, 0, 1, 0], [1, 0, 1, 1],
154
- [1, 1, 0, 0], [1, 1, 0, 1], [1, 1, 1, 0], [1, 1, 1, 1]])
155
- T = numpy.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0], # 答えの符号:1個目が1ならプラス、
156
- [0, 1, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0], # 2個目が1ならマイナス
157
- [0, 1, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0],
158
- [1, 0, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0]])
159
- # X = numpy.array([[0, 0], [0, 1], [1, 0], [1, 1]]) # 入力の記号:0がマイナス、1がプラス
160
- # T = numpy.array([[1, 0], [0, 1], [0, 1], [1, 0]]) # 答えの符号:1個目が1ならプラス、2個目が1ならマイナス
161
- N = X.shape[0] # number of data
162
-
163
- input_size = X.shape[1]
164
- hidden_size = 2 # 2
165
- output_size = 4 # 2
166
- epsilon = 0.1 # 0.1
167
- mu = 0.5 # 0.9
168
- epoch = 200000 # 10000
169
- ```
170
-
171
- 残念ながら、[1,1,1,1]の符号判定だけは誤学習していました。パラメータとチューニングすればいけそうな感触です。
172
-
173
- 追記4
174
150
  既に不要かもしれませんが、完全な学習ができたハイパーパラメータを記載しておきます。
175
151
  ```Python
176
152
  X = numpy.array([[0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0],[0, 0, 1,1], # 入力の記号:0がマイナス、1がプラス

5

正解パラメータの追加

2017/11/27 01:14

投稿

yag1kaz
yag1kaz

スコア253

answer CHANGED
@@ -210,4 +210,40 @@
210
210
  [1 1 0 1][ 5.66085770e-03 9.94336166e-01 9.33024233e-05 9.23137346e-05]1
211
211
  [1 1 1 0][ 5.65317314e-03 9.94343241e-01 9.34888288e-05 9.24102042e-05]1
212
212
  [1 1 1 1][ 9.91126091e-01 8.87614458e-03 2.20889172e-05 2.87712893e-05]0
213
- ```
213
+ ```
214
+
215
+ mkgreiさんとのコメント欄でのやり取りで、興味がでたので、XNORを出力するMLPの重み付けパラメータの一例を記載しておきます。
216
+
217
+ 入力層+隠れ層(一層)+出力層の形での解の一例示です。
218
+
219
+ ```
220
+ <イメージ図>(※注:\はバックスラッシュ)
221
+ 入力層 隠れ層 出力層
222
+ (w11)
223
+ x1 ― ― h1
224
+ (w21)\ / (v1)
225
+ X    o1
226
+ (w12)/ \ /(v2)
227
+ x2 ― ― h2
228
+ (w22)
229
+ ```
230
+
231
+ h1 = f(w11 * x1 + w12 * x2 + b1)
232
+ h2 = f(w12 * x1 + w22 * x2 + b2)
233
+ o1 = f(v1 * h1 + v2 * h2 + b3)
234
+
235
+ fはシグモイド関数です。上記の形でMLPを表すことができます。
236
+
237
+ このときにXORを実現するパラメータの組み合わせは以下です。
238
+
239
+ w11 = 2
240
+ w12 = 2
241
+ w21 = -2
242
+ w22 = -2
243
+ b1 = -1
244
+ b2 = 3
245
+ v1 = -2
246
+ v2 = -2
247
+ b3 = 3
248
+
249
+ ここに負数があるのでreluではだめなんでしょうね。

4

完全収束したパラメータを追加

2017/11/25 10:08

投稿

yag1kaz
yag1kaz

スコア253

answer CHANGED
@@ -135,7 +135,7 @@
135
135
  ```
136
136
 
137
137
  追記2
138
- 手元で確認しましたら、
138
+ 手元で確認しましたら、2値入力の符号計算については、
139
139
  epsilon = 0.1
140
140
  mu = 0.5
141
141
  で10000回で良好な結果が得られました。
@@ -168,4 +168,46 @@
168
168
  epoch = 200000 # 10000
169
169
  ```
170
170
 
171
- 残念ながら、[1,1,1,1]の符号判定だけは誤学習していました。パラメータとチューニングすればいけそうな感触です。
171
+ 残念ながら、[1,1,1,1]の符号判定だけは誤学習していました。パラメータとチューニングすればいけそうな感触です。
172
+
173
+ 追記4
174
+ 既に不要かもしれませんが、完全な学習ができたハイパーパラメータを記載しておきます。
175
+ ```Python
176
+ X = numpy.array([[0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0],[0, 0, 1,1], # 入力の記号:0がマイナス、1がプラス
177
+ [0, 1, 0, 0], [0, 1, 0, 1], [0, 1, 1, 0], [0, 1, 1, 1],
178
+ [1, 0, 0, 0], [1, 0, 0, 1], [1, 0, 1, 0], [1, 0, 1, 1],
179
+ [1, 1, 0, 0], [1, 1, 0, 1], [1, 1, 1, 0], [1, 1, 1, 1]])
180
+ T = numpy.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0], # 答えの符号:1個目が1ならプラス、
181
+ [0, 1, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0], # 2個目が1ならマイナス
182
+ [0, 1, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0],
183
+ [1, 0, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0]])
184
+ # X = numpy.array([[0, 0], [0, 1], [1, 0], [1, 1]]) # 入力の記号:0がマイナス、1がプラス
185
+ # T = numpy.array([[1, 0], [0, 1], [0, 1], [1, 0]]) # 答えの符号:1個目が1ならプラス、2個目が1ならマイナス
186
+ N = X.shape[0] # number of data
187
+
188
+ input_size = X.shape[1]
189
+ hidden_size = 6 # 2
190
+ output_size = 4 # 2
191
+ epsilon = 0.3 # 0.1
192
+ mu = 0.5 # 0.9
193
+ epoch = 100000 # 10000
194
+ ```
195
+ 学習結果は以下となります。
196
+ ```
197
+ [0 0 0 0][ 0.9946526 0.00533347 0.00283314 0.00259751]0
198
+ [0 0 0 1][ 3.35769941e-03 9.96644302e-01 5.56622699e-04 6.70592964e-04]1
199
+ [0 0 1 0][ 3.33927080e-03 9.96660884e-01 5.59857461e-04 6.70702223e-04]1
200
+ [0 0 1 1][ 9.96596879e-01 3.40821671e-03 2.22956843e-04 3.25614771e-04]0
201
+ [0 1 0 0][ 3.27048326e-03 9.96728618e-01 5.64677142e-04 6.74756067e-04]1
202
+ [0 1 0 1][ 9.96570795e-01 3.43393502e-03 2.23697557e-04 3.26314940e-04]0
203
+ [0 1 1 0][ 9.96504986e-01 3.49893558e-03 2.25097803e-04 3.27462076e-04]0
204
+ [0 1 1 1][ 5.66155206e-03 9.94335298e-01 9.34340392e-05 9.24230822e-05]1
205
+ [1 0 0 0][ 3.31009107e-03 9.96690587e-01 5.56904682e-04 6.68238304e-04]1
206
+ [1 0 0 1][ 9.96573108e-01 3.43220946e-03 2.22530928e-04 3.25064048e-04]0
207
+ [1 0 1 0][ 9.96511494e-01 3.49322967e-03 2.23526919e-04 3.25795278e-04]0
208
+ [1 0 1 1][ 5.66332128e-03 9.94333992e-01 9.32042942e-05 9.22570059e-05]1
209
+ [1 1 0 0][ 9.96481951e-01 3.52230033e-03 2.24429722e-04 3.26645683e-04]0
210
+ [1 1 0 1][ 5.66085770e-03 9.94336166e-01 9.33024233e-05 9.23137346e-05]1
211
+ [1 1 1 0][ 5.65317314e-03 9.94343241e-01 9.34888288e-05 9.24102042e-05]1
212
+ [1 1 1 1][ 9.91126091e-01 8.87614458e-03 2.20889172e-05 2.87712893e-05]0
213
+ ```

3

4値入力である程度うまくいくパターンを記載

2017/11/22 01:59

投稿

yag1kaz
yag1kaz

スコア253

answer CHANGED
@@ -142,4 +142,30 @@
142
142
  [0 0][ 0.94077065 0.05854585]0
143
143
  [0 1][ 0.05252437 0.94818359]1
144
144
  [1 0][ 0.05249829 0.94820941]1
145
- [1 1][ 0.94447755 0.05472062]0
145
+ [1 1][ 0.94447755 0.05472062]0
146
+
147
+ 追記3(2017/11/20 19:25)
148
+ 上記は2値入力でしたので4値入力でうまくいくパターンを見つけましたので、追記しておきます。
149
+
150
+ ```Python
151
+ X = numpy.array([[0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0],[0, 0, 1,1], # 入力の記号:0がマイナス、1がプラス
152
+ [0, 1, 0, 0], [0, 1, 0, 1], [0, 1, 1, 0], [0, 1, 1, 1],
153
+ [1, 0, 0, 0], [1, 0, 0, 1], [1, 0, 1, 0], [1, 0, 1, 1],
154
+ [1, 1, 0, 0], [1, 1, 0, 1], [1, 1, 1, 0], [1, 1, 1, 1]])
155
+ T = numpy.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0], # 答えの符号:1個目が1ならプラス、
156
+ [0, 1, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0], # 2個目が1ならマイナス
157
+ [0, 1, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0],
158
+ [1, 0, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0]])
159
+ # X = numpy.array([[0, 0], [0, 1], [1, 0], [1, 1]]) # 入力の記号:0がマイナス、1がプラス
160
+ # T = numpy.array([[1, 0], [0, 1], [0, 1], [1, 0]]) # 答えの符号:1個目が1ならプラス、2個目が1ならマイナス
161
+ N = X.shape[0] # number of data
162
+
163
+ input_size = X.shape[1]
164
+ hidden_size = 2 # 2
165
+ output_size = 4 # 2
166
+ epsilon = 0.1 # 0.1
167
+ mu = 0.5 # 0.9
168
+ epoch = 200000 # 10000
169
+ ```
170
+
171
+ 残念ながら、[1,1,1,1]の符号判定だけは誤学習していました。パラメータとチューニングすればいけそうな感触です。

2

Python2->3対応分の修正とPython3で良好な結果を得るためのパラメータ検証の追記

2017/11/20 10:31

投稿

yag1kaz
yag1kaz

スコア253

answer CHANGED
@@ -128,8 +128,18 @@
128
128
  y = Y[i, :]
129
129
  c = C[i]
130
130
 
131
- print x
131
+ print(x)
132
- print y
132
+ print(y)
133
- print c
133
+ print(c)
134
- print ""
134
+ print("")
135
- ```
135
+ ```
136
+
137
+ 追記2
138
+ 手元で確認しましたら、
139
+ epsilon = 0.1
140
+ mu = 0.5
141
+ で10000回で良好な結果が得られました。
142
+ [0 0][ 0.94077065 0.05854585]0
143
+ [0 1][ 0.05252437 0.94818359]1
144
+ [1 0][ 0.05249829 0.94820941]1
145
+ [1 1][ 0.94447755 0.05472062]0

1

実際のサンプルコードが存在するサイトへのリンクとサンプルコードを追記しました。

2017/11/20 05:08

投稿

yag1kaz
yag1kaz

スコア253

answer CHANGED
@@ -1,3 +1,135 @@
1
1
  mkgreiさんの答えにヒントを得ていますが、入力値の符号を取り出して、答えの符号だけを目的関数とする学習器を別に用意させることで解決できそうです。
2
2
 
3
- 同一NNの各層に追加の符号学習専用の入力層、中間層、出力層を用意する、といいかえてもよいと思います。
3
+ 同一NNの各層に追加の符号学習専用の入力層、中間層、出力層を用意する、といいかえてもよいと思います。
4
+
5
+ <追記>
6
+ 以下の記事が参考になると思います。
7
+ https://qiita.com/ta-ka/items/bcdfd2d9903146c51dcb
8
+ リンク先ページの削除されていると参考にできなくなるとおもいますので、コード部分のみ転記しておきます。(記載先の例で示されている学習率で十分かどうかは確認をお願いいたします。)
9
+
10
+ neuralnetwork.py
11
+ ```python
12
+ import numpy
13
+ import math
14
+ import random
15
+ from matplotlib import pyplot
16
+
17
+ class Neural:
18
+
19
+ # constructor
20
+ def __init__(self, n_input, n_hidden, n_output):
21
+ self.hidden_weight = numpy.random.random_sample((n_hidden, n_input + 1))
22
+ self.output_weight = numpy.random.random_sample((n_output, n_hidden + 1))
23
+ self.hidden_momentum = numpy.zeros((n_hidden, n_input + 1))
24
+ self.output_momentum = numpy.zeros((n_output, n_hidden + 1))
25
+
26
+
27
+ # public method
28
+ def train(self, X, T, epsilon, mu, epoch):
29
+ self.error = numpy.zeros(epoch)
30
+ N = X.shape[0]
31
+ for epo in range(epoch):
32
+ for i in range(N):
33
+ x = X[i, :]
34
+ t = T[i, :]
35
+
36
+ self.__update_weight(x, t, epsilon, mu)
37
+
38
+ self.error[epo] = self.__calc_error(X, T)
39
+
40
+
41
+ def predict(self, X):
42
+ N = X.shape[0]
43
+ C = numpy.zeros(N).astype('int')
44
+ Y = numpy.zeros((N, X.shape[1]))
45
+ for i in range(N):
46
+ x = X[i, :]
47
+ z, y = self.__forward(x)
48
+
49
+ Y[i] = y
50
+ C[i] = y.argmax()
51
+
52
+ return (C, Y)
53
+
54
+
55
+ def error_graph(self):
56
+ pyplot.ylim(0.0, 2.0)
57
+ pyplot.plot(numpy.arange(0, self.error.shape[0]), self.error)
58
+ pyplot.show()
59
+
60
+
61
+ # private method
62
+ def __sigmoid(self, arr):
63
+ return numpy.vectorize(lambda x: 1.0 / (1.0 + math.exp(-x)))(arr)
64
+
65
+
66
+ def __forward(self, x):
67
+ # z: output in hidden layer, y: output in output layer
68
+ z = self.__sigmoid(self.hidden_weight.dot(numpy.r_[numpy.array([1]), x]))
69
+ y = self.__sigmoid(self.output_weight.dot(numpy.r_[numpy.array([1]), z]))
70
+
71
+ return (z, y)
72
+
73
+ def __update_weight(self, x, t, epsilon, mu):
74
+ z, y = self.__forward(x)
75
+
76
+ # update output_weight
77
+ output_delta = (y - t) * y * (1.0 - y)
78
+ _output_weight = self.output_weight
79
+ self.output_weight -= epsilon * output_delta.reshape((-1, 1)) * numpy.r_[numpy.array([1]), z] - mu * self.output_momentum
80
+ self.output_momentum = self.output_weight - _output_weight
81
+
82
+ # update hidden_weight
83
+ hidden_delta = (self.output_weight[:, 1:].T.dot(output_delta)) * z * (1.0 - z)
84
+ _hidden_weight = self.hidden_weight
85
+ self.hidden_weight -= epsilon * hidden_delta.reshape((-1, 1)) * numpy.r_[numpy.array([1]), x]
86
+ self.hidden_momentum = self.hidden_weight - _hidden_weight
87
+
88
+
89
+ def __calc_error(self, X, T):
90
+ N = X.shape[0]
91
+ err = 0.0
92
+ for i in range(N):
93
+ x = X[i, :]
94
+ t = T[i, :]
95
+
96
+ z, y = self.__forward(x)
97
+ err += (y - t).dot((y - t).reshape((-1, 1))) / 2.0
98
+
99
+ return err
100
+
101
+ ```
102
+
103
+ main.py
104
+ ```python
105
+ from neuralnetwork import *
106
+
107
+ if __name__ == '__main__':
108
+
109
+ X = numpy.array([[0, 0], [0, 1], [1, 0], [1, 1]])
110
+ T = numpy.array([[1, 0], [0, 1], [0, 1], [1, 0]])
111
+ N = X.shape[0] # number of data
112
+
113
+ input_size = X.shape[1]
114
+ hidden_size = 2
115
+ output_size = 2
116
+ epsilon = 0.1
117
+ mu = 0.9
118
+ epoch = 10000
119
+
120
+ nn = Neural(input_size, hidden_size, output_size)
121
+ nn.train(X, T, epsilon, mu, epoch)
122
+ nn.error_graph()
123
+
124
+ C, Y = nn.predict(X)
125
+
126
+ for i in range(N):
127
+ x = X[i, :]
128
+ y = Y[i, :]
129
+ c = C[i]
130
+
131
+ print x
132
+ print y
133
+ print c
134
+ print ""
135
+ ```