24
24
import numpy as np
25
25
26
26
import paddle
27
- from paddle .metric import Accuracy
28
27
import paddle .nn as nn
29
28
30
29
from datasets import load_dataset
31
-
32
30
from paddlenlp .data import Pad , Stack , Tuple , Dict
33
31
from paddlenlp .transformers import AutoModelForMultipleChoice , AutoTokenizer
34
32
from paddlenlp .transformers import LinearDecayWithWarmup
@@ -140,19 +138,64 @@ def set_seed(args):
140
138
paddle .seed (args .seed )
141
139
142
140
141
+ def calc_global_pred_results (logits ):
142
+ logits = np .array (logits )
143
+ # [num_choices, tag_size]
144
+ logits = np .transpose (logits )
145
+ tmp = []
146
+ for i , row in enumerate (logits ):
147
+ for j , col in enumerate (row ):
148
+ tmp .append ((i , j , col ))
149
+ else :
150
+ choice = set (range (i + 1 ))
151
+ blanks = set (range (j + 1 ))
152
+ tmp = sorted (tmp , key = lambda x : x [2 ], reverse = True )
153
+ results = []
154
+ for i , j , v in tmp :
155
+ if (j in blanks ) and (i in choice ):
156
+ results .append ((i , j ))
157
+ blanks .remove (j )
158
+ choice .remove (i )
159
+ results = sorted (results , key = lambda x : x [1 ], reverse = False )
160
+ results = [i for i , j in results ]
161
+ return results
162
+
163
+
143
164
@paddle .no_grad ()
144
- def evaluate (model , loss_fct , metric , data_loader ):
165
+ def evaluate (model , data_loader , do_predict = False ):
145
166
model .eval ()
146
- metric .reset ()
167
+ right_num , total_num = 0 , 0
168
+ all_results = []
147
169
for step , batch in enumerate (data_loader ):
148
- input_ids , segment_ids , labels = batch
170
+ if do_predict :
171
+ input_ids , segment_ids , example_ids = batch
172
+ else :
173
+ input_ids , segment_ids , labels , example_ids = batch
149
174
logits = model (input_ids = input_ids , token_type_ids = segment_ids )
150
- loss = loss_fct (logits , labels )
151
- correct = metric .compute (logits , labels )
152
- metric .update (correct )
153
- res = metric .accumulate ()
175
+ batch_num = example_ids .shape [0 ]
176
+ l = 0
177
+ r = batch_num - 1
178
+ batch_results = []
179
+ for i in range (batch_num - 1 ):
180
+ if example_ids [i ] != example_ids [i + 1 ]:
181
+ r = i
182
+ batch_results .extend (
183
+ calc_global_pred_results (logits [l :r + 1 , :]))
184
+ l = i + 1
185
+ if l <= batch_num - 1 :
186
+ batch_results .extend (
187
+ calc_global_pred_results (logits [l :batch_num , :]))
188
+ if do_predict :
189
+ all_results .extend (batch_results )
190
+ else :
191
+ right_num += np .sum (np .array (batch_results ) == labels .numpy ())
192
+ total_num += labels .shape [0 ]
154
193
model .train ()
155
- return res
194
+ if not do_predict :
195
+ acc = right_num / total_num
196
+ print ("acc" , right_num , total_num , acc )
197
+ return acc
198
+ return all_results
156
199
157
200
158
201
def run (args ):
@@ -242,9 +285,14 @@ def add_tokens_for_around(tokens, pos, num_tokens):
242
285
num_tokens = max_tokens_for_doc - 5
243
286
num_examples = len (examples .data ["candidates" ])
244
287
if do_predict :
245
- result = {"input_ids" : [], "token_type_ids" : []}
288
+ result = {"input_ids" : [], "token_type_ids" : [], "example_ids" : [] }
246
289
else :
247
- result = {"input_ids" : [], "token_type_ids" : [], "labels" : []}
290
+ result = {
291
+ "input_ids" : [],
292
+ "token_type_ids" : [],
293
+ "labels" : [],
294
+ "example_ids" : []
295
+ }
248
296
for idx in range (num_examples ):
249
297
candidate = 0
250
298
options = examples .data ['candidates' ][idx ]
@@ -316,6 +364,7 @@ def add_tokens_for_around(tokens, pos, num_tokens):
316
364
# Final shape of input_ids: [batch_size, num_choices, seq_len]
317
365
result ["input_ids" ].append (new_data ["input_ids" ])
318
366
result ["token_type_ids" ].append (new_data ["token_type_ids" ])
367
+ result ["example_ids" ].append (idx )
319
368
if not do_predict :
320
369
label = examples .data ["answers" ][idx ]["candidate_id" ][
321
370
candidate ]
@@ -350,7 +399,8 @@ def add_tokens_for_around(tokens, pos, num_tokens):
350
399
batchify_fn = lambda samples , fn = Dict ({
351
400
'input_ids' : Pad (axis = 1 , pad_val = tokenizer .pad_token_id ), # input
352
401
'token_type_ids' : Pad (axis = 1 , pad_val = tokenizer .pad_token_type_id ), # segment
353
- 'labels' : Stack (dtype = "int64" ) # label
402
+ 'labels' : Stack (dtype = "int64" ), # label
403
+ 'example_ids' : Stack (dtype = "int64" ), # example id
354
404
}): fn (samples )
355
405
356
406
train_batch_sampler = paddle .io .DistributedBatchSampler (
@@ -397,15 +447,14 @@ def add_tokens_for_around(tokens, pos, num_tokens):
397
447
grad_clip = grad_clip )
398
448
399
449
loss_fct = nn .CrossEntropyLoss ()
400
- metric = Accuracy ()
401
450
402
451
model .train ()
403
452
global_step = 0
404
453
best_acc = 0.0
405
454
tic_train = time .time ()
406
455
for epoch in range (args .num_train_epochs ):
407
456
for step , batch in enumerate (train_data_loader ):
408
- input_ids , segment_ids , labels = batch
457
+ input_ids , segment_ids , labels , example_ids = batch
409
458
logits = model (input_ids = input_ids , token_type_ids = segment_ids )
410
459
loss = loss_fct (logits , labels )
411
460
if args .gradient_accumulation_steps > 1 :
@@ -424,7 +473,7 @@ def add_tokens_for_around(tokens, pos, num_tokens):
424
473
args .logging_steps / (time .time () - tic_train )))
425
474
tic_train = time .time ()
426
475
tic_eval = time .time ()
427
- acc = evaluate (model , loss_fct , metric , dev_data_loader )
476
+ acc = evaluate (model , dev_data_loader )
428
477
print ("eval acc: %.5f, eval done total : %s s" %
429
478
(acc , time .time () - tic_eval ))
430
479
if paddle .distributed .get_rank () == 0 and acc > best_acc :
@@ -445,13 +494,13 @@ def add_tokens_for_around(tokens, pos, num_tokens):
445
494
batch_size = len (test_ds ),
446
495
remove_columns = column_names ,
447
496
num_proc = 1 )
448
-
449
497
test_batch_sampler = paddle .io .BatchSampler (
450
498
test_ds , batch_size = args .eval_batch_size , shuffle = False )
451
499
452
500
batchify_fn = lambda samples , fn = Dict ({
453
501
'input_ids' : Pad (axis = 1 , pad_val = tokenizer .pad_token_id ), # input
454
502
'token_type_ids' : Pad (axis = 1 , pad_val = tokenizer .pad_token_type_id ), # segment
503
+ 'example_ids' : Stack (dtype = "int64" ), # example id
455
504
}): fn (samples )
456
505
457
506
test_data_loader = paddle .io .DataLoader (
@@ -462,15 +511,10 @@ def add_tokens_for_around(tokens, pos, num_tokens):
462
511
463
512
result = {}
464
513
idx = 623377
465
- for step , batch in enumerate (test_data_loader ):
466
- input_ids , segment_ids = batch
467
- with paddle .no_grad ():
468
- logits = model (input_ids , segment_ids )
469
- preds = paddle .argmax (logits , axis = 1 ).numpy ().tolist ()
470
- for pred in preds :
471
- result ["#idiom" + str (idx )] = pred
472
- idx += 1
473
-
514
+ preds = evaluate (model , test_data_loader , do_predict = True )
515
+ for pred in preds :
516
+ result ["#idiom" + str (idx )] = pred
517
+ idx += 1
474
518
if not os .path .exists (args .output_dir ):
475
519
os .makedirs (args .output_dir )
476
520
with open (
0 commit comments