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

質問編集履歴

2

解決

2020/01/02 11:21

投稿

hosihosieruhu
hosihosieruhu

スコア8

title CHANGED
File without changes
body CHANGED
@@ -1,372 +1,1 @@
1
- ChainerでRNNを使って自動文章生成したいのですが、TypeError: Can't broadcastという調べてもよくわからないエラーがでます。
1
+ ChainerでRNNを使って自動文章生成したいのですが、TypeError: Can't broadcastという調べてもよくわからないエラーがでます。
2
-
3
- ソースは「Chainerで作るコンテンツ自動生成AIプログラミング入門」という本のコピペです。
4
-
5
- 環境はgoogle colabです。
6
-
7
- cudaとcupy、chainerのバージョンも合ってます
8
- プログラムは2つです
9
- 以下が用意したテキストファイルをRNNで学習させるプログラムchapt07-2.pyです。
10
- ちなみにテキストファイルは2万行の俳句です。
11
- ```
12
- import chainer
13
- import chainer.functions as F
14
- import chainer.links as L
15
- from chainer import training, datasets, iterators, optimizers
16
- from chainer.training import extensions
17
- import numpy as np
18
- import codecs
19
-
20
- batch_size = 10 # バッチサイズ10
21
- uses_device = 0 # GPU#0を使用
22
-
23
- # GPU使用時とCPU使用時でデータ形式が変わる
24
- if uses_device >= 0:
25
- import cupy as cp
26
- else:
27
- cp = np
28
-
29
- # RNNの定義をするクラス
30
- class Parses_Genarate_RNN(chainer.Chain):
31
-
32
- def __init__(self, n_words, nodes):
33
- super(Parses_Genarate_RNN, self).__init__()
34
- with self.init_scope():
35
- self.embed = L.EmbedID(n_words, n_words)
36
- self.l1 = L.LSTM(n_words, nodes)
37
- self.l2 = L.LSTM(nodes, nodes)
38
- self.l3 = L.Linear(nodes, n_words)
39
-
40
- def reset_state(self):
41
- self.l1.reset_state()
42
- self.l2.reset_state()
43
-
44
- def __call__(self, x):
45
- h0 = self.embed(x)
46
- h1 = self.l1(h0)
47
- h2 = self.l2(h1)
48
- y = self.l3(h2)
49
- return y
50
-
51
- # カスタムUpdaterのクラス
52
- class RNNUpdater(training.StandardUpdater):
53
-
54
- def __init__(self, train_iter, optimizer, device):
55
- super(RNNUpdater, self).__init__(
56
- train_iter,
57
- optimizer,
58
- device=device
59
- )
60
-
61
- def update_core(self):
62
- # 累積してゆく損失
63
- loss = 0
64
-
65
- # IteratorとOptimizerを取得
66
- train_iter = self.get_iterator('main')
67
- optimizer = self.get_optimizer('main')
68
- # ニューラルネットワークを取得
69
- model = optimizer.target
70
-
71
- # 文を一バッチ取得
72
- x = train_iter.__next__()
73
-
74
- # RNNのステータスをリセットする
75
- model.reset_state()
76
-
77
- # 分の長さだけ繰り返しRNNに学習
78
- for i in range(len(x[0])-1):
79
- # バッチ処理用の配列に
80
- batch = cp.array([s[i] for s in x], dtype=cp.int32)
81
- # 正解データ(次の文字)の配列
82
- t = cp.array([s[i+1] for s in x], dtype=cp.int32)
83
- # 全部が終端文字ならそれ以上学習する必要は無い
84
- if cp.min(batch) == 1 and cp.max(batch) == 1:
85
- break
86
- # 一つRNNを実行
87
- y = model(batch)
88
- # 結果との比較
89
- loss += F.softmax_cross_entropy(y, t)
90
-
91
- # 重みデータを一旦リセットする
92
- optimizer.target.cleargrads()
93
- # 誤差関数から逆伝播する
94
- loss.backward()
95
- # 新しい重みデータでアップデートする
96
- optimizer.update()
97
-
98
- # ファイルを読み込む
99
- s = codecs.open('all-sentences-parses.txt', 'r', 'utf8')
100
-
101
- # 全ての文
102
- sentence = []
103
-
104
- # 1行ずつ処理する
105
- line = s.readline()
106
- while line:
107
- # 一つの文
108
- one = [0] # 開始文字だけ
109
- # 行の中の単語を数字のリストにして追加
110
- one.extend(list(map(int,line.split(','))))
111
- # 行が終わったところで終端文字を入れる
112
- one.append(1)
113
- # 新しい文を追加
114
- sentence.append(one)
115
- line = s.readline()
116
- s.close()
117
-
118
- # 単語の種類
119
- n_word = max([max(l) for l in sentence]) + 1
120
-
121
- # 最長の文の長さ
122
- l_max = max([len(l) for l in sentence])
123
- # バッチ処理の都合で全て同じ長さに揃える必要がある
124
- for i in range(len(sentence)):
125
- # 足りない長さは終端文字で埋める
126
- sentence[i].extend([1]*(l_max-len(sentence[i])))
127
-
128
- # ニューラルネットワークの作成
129
- model = Parses_Genarate_RNN(n_word, 100)
130
-
131
- if uses_device >= 0:
132
- # GPUを使う
133
- chainer.cuda.get_device_from_id(0).use()
134
- chainer.cuda.check_cuda_available()
135
- # GPU用データ形式に変換
136
- model.to_gpu()
137
-
138
- # 誤差逆伝播法アルゴリズムを選択
139
- optimizer = optimizers.Adam()
140
- optimizer.setup(model)
141
-
142
- # Iteratorを作成
143
- train_iter = iterators.SerialIterator(sentence, batch_size, shuffle=False)
144
-
145
- # デバイスを選択してTrainerを作成する
146
- updater = RNNUpdater(train_iter, optimizer, device=uses_device)
147
- trainer = training.Trainer(updater, (100, 'epoch'), out="result")
148
- # 学習の進展を表示するようにする
149
- trainer.extend(extensions.ProgressBar(update_interval=1))
150
-
151
- # 機械学習を実行する
152
- trainer.run()
153
-
154
- # 学習結果を保存する
155
- chainer.serializers.save_hdf5( 'chapt07.hdf5', model )
156
- ```
157
- 以下が先ほど作成した学習結果を元に文章自動生成するプログラムchapt07-4.pyです。
158
- word2vecのモデルを使用ますが、これが壊れているという事は考えにくいです
159
- ```
160
- import torch
161
- import torchvision
162
- import torchvision.transforms as transforms
163
- from torch import nn, optim
164
- import torch.nn.functional as F
165
- from torch.utils.data import Dataset, DataLoader, TensorDataset
166
- import numpy as np
167
- import sys
168
- import codecs
169
- from gensim.models import word2vec
170
-
171
- trainset = torchvision.datasets.MNIST(root='./data',
172
- train=True,
173
- download=True,
174
- transform=transforms.ToTensor())
175
- trainloader = torch.utils.data.DataLoader(trainset,
176
- batch_size=batch_size,
177
- shuffle=True)
178
-
179
- testset = torchvision.datasets.MNIST(root='./data',
180
- train=False,
181
- download=True,
182
- transform=transforms.ToTensor())
183
- testloader = torch.utils.data.DataLoader(testset,
184
- batch_size=batch_size,
185
- shuffle=False)
186
-
187
-
188
- # GPU使用時とCPU使用時でデータ形式が変わる
189
- if uses_device >= 0:
190
- import cupy as cp
191
- import chainer.cuda
192
- else:
193
- cp = np
194
-
195
- sys.stdout = codecs.getwriter('utf_8')(sys.stdout)
196
-
197
- # RNNの定義をするクラス
198
- class Parses_Genarate_RNN(nn.Module):
199
-
200
- def __init__(self, n_words, nodes):
201
- super(Parses_Genarate_RNN, self).__init__()
202
- with self.init_scope():
203
- self.embed = L.EmbedID(n_words, n_words)
204
- self.l1 = L.LSTM(n_words, nodes)
205
- self.l2 = L.LSTM(nodes, nodes)
206
- self.l3 = L.Linear(nodes, n_words)
207
-
208
- def reset_state(self):
209
- self.l1.reset_state()
210
- self.l2.reset_state()
211
-
212
- def __call__(self, x):
213
- h0 = self.embed(x)
214
- h1 = self.l1(h0)
215
- h2 = self.l2(h1)
216
- y = self.l3(h2)
217
- return y
218
-
219
- # ファイルを読み込む
220
- w = codecs.open('all-words-parses.txt', 'r', 'utf8')
221
-
222
- # 単語の一覧
223
- words_parse = {}
224
-
225
- # 1行ずつ処理する
226
- line = w.readline()
227
- while line:
228
- # 行の中の単語をリストする
229
- l = line.split(',')
230
- if len(l) == 2:
231
- r = int(l[0].strip())
232
- if r in words_parse:
233
- words_parse[r].append(l[1].strip())
234
- else:
235
- words_parse[r] = [l[1].strip()]
236
- line = w.readline()
237
- w.close()
238
-
239
- # ニューラルネットワークの作成
240
- model = Parses_Genarate_RNN(max(words_parse.keys())+1, 20)
241
-
242
- # 学習結果を読み込む
243
- chainer.serializers.load_hdf5( 'chapt07.hdf5', model )
244
-
245
- if uses_device >= 0:
246
- # GPUを使う
247
- chainer.cuda.get_device_from_id(0).use()
248
- chainer.cuda.check_cuda_available()
249
- # GPU用データ形式に変換
250
- model.to_gpu()
251
-
252
- # 木探索で生成する最大の深さ
253
- words_max = 50
254
- # RNNの実行結果から検索する単語の数
255
- beam_w = 3
256
- # 生成した文のリスト
257
- parses = []
258
- # 木探索のスタック
259
- model_history = [model]
260
- # 現在生成中の文
261
- cur_parses = [0] # 開始文字
262
- # 現在生成中の文のスコア
263
- cur_score = []
264
- # 最大のスコア
265
- max_score = 0
266
-
267
- # 再帰関数の木探索
268
- def Tree_Traverse():
269
- global max_score
270
- # 現在の品詞を取得する
271
- cur_parse = cur_parses[-1]
272
- # 文のスコア
273
- score = np.prod(cur_score)
274
- # 現在の文の長さ
275
- deep = len(cur_parses)
276
- # 枝刈り - 単語数が5以上で最大スコアの6割以下なら、終わる
277
- if max_score > 0 and deep > 5 and max_score * 0.6 > score:
278
- return
279
- # 終了文字か、最大の文の長さ以上なら、品詞を追加して終わる
280
- if cur_parse == 1 or deep > words_max:
281
- # 文のデータをコピー
282
- data = np.array(cur_parses)
283
- # 文を追加
284
- parses.append((score, data))
285
- # 最大スコアを更新
286
- if max_score < score:
287
- max_score = score
288
- return
289
- # 現在のニューラルネットワークのステータスをコピーする
290
- cur_model = model_history[-1].copy()
291
- # 入力値を作る
292
- x = cp.array([cur_parse], dtype=cp.int32)
293
- # ニューラルネットワークに入力する
294
- y = cur_model(x)
295
- # 実行結果を正規化する
296
- z = F.softmax(y)
297
- # 結果のデータを取得
298
- result = z.data[0]
299
- if uses_device >= 0:
300
- result = chainer.cuda.to_cpu(result)
301
- # 結果を確立順に並べ替える
302
- p = np.argsort(result)[::-1]
303
- # 現在のニューラルネットワークのステータスを保存する
304
- model_history.append(cur_model)
305
- # 結果から上位のものを次の枝に回す
306
- for i in range(beam_w):
307
- # 現在生成中の文に一文字追加する
308
- cur_parses.append(p[i])
309
- # 現在生成中の文のスコアに一つ追加する
310
- cur_score.append(result[p[i]])
311
- # 再帰呼び出し
312
- Tree_Traverse()
313
- # 現在生成中の文を一つ戻す
314
- cur_parses.pop()
315
- # 現在生成中の文のスコアを一つ戻す
316
- cur_score.pop()
317
- # ニューラルネットワークのステータスを一つ戻す
318
- model_history.pop()
319
-
320
- # 木検索して文章を生成する
321
- Tree_Traverse()
322
-
323
- # Word2Vecのモデルを読み込む
324
- word_vec = word2vec.Word2Vec.load('word2vec.gensim.model')
325
-
326
- # 文章のターゲット
327
- target_str = ['元日']
328
- #target_str = ['神']
329
- #target_str = ['キリスト']
330
- #target_str = ['父','子','聖霊']
331
- #target_str = ['不思議','の','国','の','アリス']
332
- #target_str = ['三月','うさぎ','の','お茶','会']
333
- #target_str = ['女王']
334
-
335
- # 指定した品詞の単語を文章がターゲットに近づくように返す
336
- def similarity_word( parse, history ):
337
- scores = []
338
- # 品詞から候補をリスト
339
- for i in range(len(words_parse[parse])):
340
- w = words_parse[parse][i]
341
- if w in word_vec:
342
- # 候補のベクトルを履歴ベクトルに足す
343
- t = history[:]
344
- t.append(w)
345
- # ターゲットとの距離を計算
346
- sim = word_vec.n_similarity(target_str, t)
347
- scores.append((sim, w))
348
- # 結果をスコア順に並べ替える
349
- result = sorted(scores, key=lambda x: x[0])[::-1]
350
- return result[0]
351
-
352
-
353
- # スコアの高いものから順に表示する
354
- result_set = sorted(parses, key=lambda x: x[0])[::-1]
355
- # 10個または全部の少ない方の数だけ表示
356
- for i in range(min([10,len(result_set)])):
357
- # 結果を取得
358
- s, l = result_set[i]
359
- # これまで登場した単語
360
- history = []
361
- # 開始文字と終端文字を除いてループ
362
- for j in range(1,len(l)-1):
363
- score, cur_word = similarity_word(l[j], history)
364
- history.append(cur_word)
365
- sys.stdout.buffer.write(cur_word.encode('utf-8'))
366
-
367
- sys.stdout.buffer.write("\n".encode('utf-8'))
368
- sys.stdout.buffer.flush()
369
-
370
-
371
-
372
- ```

1

ソース

2020/01/02 11:21

投稿

hosihosieruhu
hosihosieruhu

スコア8

title CHANGED
File without changes
body CHANGED
@@ -4,4 +4,369 @@
4
4
 
5
5
  環境はgoogle colabです。
6
6
 
7
- cudaとcupy、chainerのバージョンも合ってます
7
+ cudaとcupy、chainerのバージョンも合ってます
8
+ プログラムは2つです
9
+ 以下が用意したテキストファイルをRNNで学習させるプログラムchapt07-2.pyです。
10
+ ちなみにテキストファイルは2万行の俳句です。
11
+ ```
12
+ import chainer
13
+ import chainer.functions as F
14
+ import chainer.links as L
15
+ from chainer import training, datasets, iterators, optimizers
16
+ from chainer.training import extensions
17
+ import numpy as np
18
+ import codecs
19
+
20
+ batch_size = 10 # バッチサイズ10
21
+ uses_device = 0 # GPU#0を使用
22
+
23
+ # GPU使用時とCPU使用時でデータ形式が変わる
24
+ if uses_device >= 0:
25
+ import cupy as cp
26
+ else:
27
+ cp = np
28
+
29
+ # RNNの定義をするクラス
30
+ class Parses_Genarate_RNN(chainer.Chain):
31
+
32
+ def __init__(self, n_words, nodes):
33
+ super(Parses_Genarate_RNN, self).__init__()
34
+ with self.init_scope():
35
+ self.embed = L.EmbedID(n_words, n_words)
36
+ self.l1 = L.LSTM(n_words, nodes)
37
+ self.l2 = L.LSTM(nodes, nodes)
38
+ self.l3 = L.Linear(nodes, n_words)
39
+
40
+ def reset_state(self):
41
+ self.l1.reset_state()
42
+ self.l2.reset_state()
43
+
44
+ def __call__(self, x):
45
+ h0 = self.embed(x)
46
+ h1 = self.l1(h0)
47
+ h2 = self.l2(h1)
48
+ y = self.l3(h2)
49
+ return y
50
+
51
+ # カスタムUpdaterのクラス
52
+ class RNNUpdater(training.StandardUpdater):
53
+
54
+ def __init__(self, train_iter, optimizer, device):
55
+ super(RNNUpdater, self).__init__(
56
+ train_iter,
57
+ optimizer,
58
+ device=device
59
+ )
60
+
61
+ def update_core(self):
62
+ # 累積してゆく損失
63
+ loss = 0
64
+
65
+ # IteratorとOptimizerを取得
66
+ train_iter = self.get_iterator('main')
67
+ optimizer = self.get_optimizer('main')
68
+ # ニューラルネットワークを取得
69
+ model = optimizer.target
70
+
71
+ # 文を一バッチ取得
72
+ x = train_iter.__next__()
73
+
74
+ # RNNのステータスをリセットする
75
+ model.reset_state()
76
+
77
+ # 分の長さだけ繰り返しRNNに学習
78
+ for i in range(len(x[0])-1):
79
+ # バッチ処理用の配列に
80
+ batch = cp.array([s[i] for s in x], dtype=cp.int32)
81
+ # 正解データ(次の文字)の配列
82
+ t = cp.array([s[i+1] for s in x], dtype=cp.int32)
83
+ # 全部が終端文字ならそれ以上学習する必要は無い
84
+ if cp.min(batch) == 1 and cp.max(batch) == 1:
85
+ break
86
+ # 一つRNNを実行
87
+ y = model(batch)
88
+ # 結果との比較
89
+ loss += F.softmax_cross_entropy(y, t)
90
+
91
+ # 重みデータを一旦リセットする
92
+ optimizer.target.cleargrads()
93
+ # 誤差関数から逆伝播する
94
+ loss.backward()
95
+ # 新しい重みデータでアップデートする
96
+ optimizer.update()
97
+
98
+ # ファイルを読み込む
99
+ s = codecs.open('all-sentences-parses.txt', 'r', 'utf8')
100
+
101
+ # 全ての文
102
+ sentence = []
103
+
104
+ # 1行ずつ処理する
105
+ line = s.readline()
106
+ while line:
107
+ # 一つの文
108
+ one = [0] # 開始文字だけ
109
+ # 行の中の単語を数字のリストにして追加
110
+ one.extend(list(map(int,line.split(','))))
111
+ # 行が終わったところで終端文字を入れる
112
+ one.append(1)
113
+ # 新しい文を追加
114
+ sentence.append(one)
115
+ line = s.readline()
116
+ s.close()
117
+
118
+ # 単語の種類
119
+ n_word = max([max(l) for l in sentence]) + 1
120
+
121
+ # 最長の文の長さ
122
+ l_max = max([len(l) for l in sentence])
123
+ # バッチ処理の都合で全て同じ長さに揃える必要がある
124
+ for i in range(len(sentence)):
125
+ # 足りない長さは終端文字で埋める
126
+ sentence[i].extend([1]*(l_max-len(sentence[i])))
127
+
128
+ # ニューラルネットワークの作成
129
+ model = Parses_Genarate_RNN(n_word, 100)
130
+
131
+ if uses_device >= 0:
132
+ # GPUを使う
133
+ chainer.cuda.get_device_from_id(0).use()
134
+ chainer.cuda.check_cuda_available()
135
+ # GPU用データ形式に変換
136
+ model.to_gpu()
137
+
138
+ # 誤差逆伝播法アルゴリズムを選択
139
+ optimizer = optimizers.Adam()
140
+ optimizer.setup(model)
141
+
142
+ # Iteratorを作成
143
+ train_iter = iterators.SerialIterator(sentence, batch_size, shuffle=False)
144
+
145
+ # デバイスを選択してTrainerを作成する
146
+ updater = RNNUpdater(train_iter, optimizer, device=uses_device)
147
+ trainer = training.Trainer(updater, (100, 'epoch'), out="result")
148
+ # 学習の進展を表示するようにする
149
+ trainer.extend(extensions.ProgressBar(update_interval=1))
150
+
151
+ # 機械学習を実行する
152
+ trainer.run()
153
+
154
+ # 学習結果を保存する
155
+ chainer.serializers.save_hdf5( 'chapt07.hdf5', model )
156
+ ```
157
+ 以下が先ほど作成した学習結果を元に文章自動生成するプログラムchapt07-4.pyです。
158
+ word2vecのモデルを使用ますが、これが壊れているという事は考えにくいです
159
+ ```
160
+ import torch
161
+ import torchvision
162
+ import torchvision.transforms as transforms
163
+ from torch import nn, optim
164
+ import torch.nn.functional as F
165
+ from torch.utils.data import Dataset, DataLoader, TensorDataset
166
+ import numpy as np
167
+ import sys
168
+ import codecs
169
+ from gensim.models import word2vec
170
+
171
+ trainset = torchvision.datasets.MNIST(root='./data',
172
+ train=True,
173
+ download=True,
174
+ transform=transforms.ToTensor())
175
+ trainloader = torch.utils.data.DataLoader(trainset,
176
+ batch_size=batch_size,
177
+ shuffle=True)
178
+
179
+ testset = torchvision.datasets.MNIST(root='./data',
180
+ train=False,
181
+ download=True,
182
+ transform=transforms.ToTensor())
183
+ testloader = torch.utils.data.DataLoader(testset,
184
+ batch_size=batch_size,
185
+ shuffle=False)
186
+
187
+
188
+ # GPU使用時とCPU使用時でデータ形式が変わる
189
+ if uses_device >= 0:
190
+ import cupy as cp
191
+ import chainer.cuda
192
+ else:
193
+ cp = np
194
+
195
+ sys.stdout = codecs.getwriter('utf_8')(sys.stdout)
196
+
197
+ # RNNの定義をするクラス
198
+ class Parses_Genarate_RNN(nn.Module):
199
+
200
+ def __init__(self, n_words, nodes):
201
+ super(Parses_Genarate_RNN, self).__init__()
202
+ with self.init_scope():
203
+ self.embed = L.EmbedID(n_words, n_words)
204
+ self.l1 = L.LSTM(n_words, nodes)
205
+ self.l2 = L.LSTM(nodes, nodes)
206
+ self.l3 = L.Linear(nodes, n_words)
207
+
208
+ def reset_state(self):
209
+ self.l1.reset_state()
210
+ self.l2.reset_state()
211
+
212
+ def __call__(self, x):
213
+ h0 = self.embed(x)
214
+ h1 = self.l1(h0)
215
+ h2 = self.l2(h1)
216
+ y = self.l3(h2)
217
+ return y
218
+
219
+ # ファイルを読み込む
220
+ w = codecs.open('all-words-parses.txt', 'r', 'utf8')
221
+
222
+ # 単語の一覧
223
+ words_parse = {}
224
+
225
+ # 1行ずつ処理する
226
+ line = w.readline()
227
+ while line:
228
+ # 行の中の単語をリストする
229
+ l = line.split(',')
230
+ if len(l) == 2:
231
+ r = int(l[0].strip())
232
+ if r in words_parse:
233
+ words_parse[r].append(l[1].strip())
234
+ else:
235
+ words_parse[r] = [l[1].strip()]
236
+ line = w.readline()
237
+ w.close()
238
+
239
+ # ニューラルネットワークの作成
240
+ model = Parses_Genarate_RNN(max(words_parse.keys())+1, 20)
241
+
242
+ # 学習結果を読み込む
243
+ chainer.serializers.load_hdf5( 'chapt07.hdf5', model )
244
+
245
+ if uses_device >= 0:
246
+ # GPUを使う
247
+ chainer.cuda.get_device_from_id(0).use()
248
+ chainer.cuda.check_cuda_available()
249
+ # GPU用データ形式に変換
250
+ model.to_gpu()
251
+
252
+ # 木探索で生成する最大の深さ
253
+ words_max = 50
254
+ # RNNの実行結果から検索する単語の数
255
+ beam_w = 3
256
+ # 生成した文のリスト
257
+ parses = []
258
+ # 木探索のスタック
259
+ model_history = [model]
260
+ # 現在生成中の文
261
+ cur_parses = [0] # 開始文字
262
+ # 現在生成中の文のスコア
263
+ cur_score = []
264
+ # 最大のスコア
265
+ max_score = 0
266
+
267
+ # 再帰関数の木探索
268
+ def Tree_Traverse():
269
+ global max_score
270
+ # 現在の品詞を取得する
271
+ cur_parse = cur_parses[-1]
272
+ # 文のスコア
273
+ score = np.prod(cur_score)
274
+ # 現在の文の長さ
275
+ deep = len(cur_parses)
276
+ # 枝刈り - 単語数が5以上で最大スコアの6割以下なら、終わる
277
+ if max_score > 0 and deep > 5 and max_score * 0.6 > score:
278
+ return
279
+ # 終了文字か、最大の文の長さ以上なら、品詞を追加して終わる
280
+ if cur_parse == 1 or deep > words_max:
281
+ # 文のデータをコピー
282
+ data = np.array(cur_parses)
283
+ # 文を追加
284
+ parses.append((score, data))
285
+ # 最大スコアを更新
286
+ if max_score < score:
287
+ max_score = score
288
+ return
289
+ # 現在のニューラルネットワークのステータスをコピーする
290
+ cur_model = model_history[-1].copy()
291
+ # 入力値を作る
292
+ x = cp.array([cur_parse], dtype=cp.int32)
293
+ # ニューラルネットワークに入力する
294
+ y = cur_model(x)
295
+ # 実行結果を正規化する
296
+ z = F.softmax(y)
297
+ # 結果のデータを取得
298
+ result = z.data[0]
299
+ if uses_device >= 0:
300
+ result = chainer.cuda.to_cpu(result)
301
+ # 結果を確立順に並べ替える
302
+ p = np.argsort(result)[::-1]
303
+ # 現在のニューラルネットワークのステータスを保存する
304
+ model_history.append(cur_model)
305
+ # 結果から上位のものを次の枝に回す
306
+ for i in range(beam_w):
307
+ # 現在生成中の文に一文字追加する
308
+ cur_parses.append(p[i])
309
+ # 現在生成中の文のスコアに一つ追加する
310
+ cur_score.append(result[p[i]])
311
+ # 再帰呼び出し
312
+ Tree_Traverse()
313
+ # 現在生成中の文を一つ戻す
314
+ cur_parses.pop()
315
+ # 現在生成中の文のスコアを一つ戻す
316
+ cur_score.pop()
317
+ # ニューラルネットワークのステータスを一つ戻す
318
+ model_history.pop()
319
+
320
+ # 木検索して文章を生成する
321
+ Tree_Traverse()
322
+
323
+ # Word2Vecのモデルを読み込む
324
+ word_vec = word2vec.Word2Vec.load('word2vec.gensim.model')
325
+
326
+ # 文章のターゲット
327
+ target_str = ['元日']
328
+ #target_str = ['神']
329
+ #target_str = ['キリスト']
330
+ #target_str = ['父','子','聖霊']
331
+ #target_str = ['不思議','の','国','の','アリス']
332
+ #target_str = ['三月','うさぎ','の','お茶','会']
333
+ #target_str = ['女王']
334
+
335
+ # 指定した品詞の単語を文章がターゲットに近づくように返す
336
+ def similarity_word( parse, history ):
337
+ scores = []
338
+ # 品詞から候補をリスト
339
+ for i in range(len(words_parse[parse])):
340
+ w = words_parse[parse][i]
341
+ if w in word_vec:
342
+ # 候補のベクトルを履歴ベクトルに足す
343
+ t = history[:]
344
+ t.append(w)
345
+ # ターゲットとの距離を計算
346
+ sim = word_vec.n_similarity(target_str, t)
347
+ scores.append((sim, w))
348
+ # 結果をスコア順に並べ替える
349
+ result = sorted(scores, key=lambda x: x[0])[::-1]
350
+ return result[0]
351
+
352
+
353
+ # スコアの高いものから順に表示する
354
+ result_set = sorted(parses, key=lambda x: x[0])[::-1]
355
+ # 10個または全部の少ない方の数だけ表示
356
+ for i in range(min([10,len(result_set)])):
357
+ # 結果を取得
358
+ s, l = result_set[i]
359
+ # これまで登場した単語
360
+ history = []
361
+ # 開始文字と終端文字を除いてループ
362
+ for j in range(1,len(l)-1):
363
+ score, cur_word = similarity_word(l[j], history)
364
+ history.append(cur_word)
365
+ sys.stdout.buffer.write(cur_word.encode('utf-8'))
366
+
367
+ sys.stdout.buffer.write("\n".encode('utf-8'))
368
+ sys.stdout.buffer.flush()
369
+
370
+
371
+
372
+ ```