Huy0502 commited on
Commit
cfc8c5a
·
verified ·
1 Parent(s): efeb20a

Upload 19 files

Browse files
app.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ from models import Reciept_Analyzer
4
+ from utils import find_product
5
+ import os
6
+ model = Reciept_Analyzer()
7
+
8
+ sample_images = []
9
+ for img_file in os.listdir("samples/"):
10
+ sample_images.append(os.path.join("samples", img_file))
11
+
12
+ def predict(image):
13
+ results = model.forward(image)
14
+ return results
15
+
16
+ def handle_input(image, item_name):
17
+ df = predict(image) # Phân tích hóa đơn và trả về dataframe
18
+ print(df)
19
+ result = find_product(item_name, df)
20
+ return result
21
+
22
+ # Thiết kế giao diện với Gradio
23
+ def create_interface():
24
+ with gr.Blocks() as app:
25
+ gr.Markdown("# Ứng dụng phân tích hóa đơn siêu thị")
26
+
27
+ with gr.Row():
28
+ # Cột bên trái
29
+ with gr.Column():
30
+ gr.Markdown("### Tải lên hóa đơn hoặc chọn ảnh mẫu")
31
+ image_input = gr.Image(label="Ảnh hóa đơn", type="filepath")
32
+
33
+ gr.Markdown("### Ảnh mẫu")
34
+ example = gr.Examples(
35
+ inputs=image_input,
36
+ examples=sample_images
37
+ )
38
+
39
+ # Cột bên phải
40
+ with gr.Column():
41
+ gr.Markdown("### Tìm kiếm thông tin item")
42
+ item_input = gr.Textbox(label="Tên item cần tìm")
43
+ output = gr.Textbox(label="Kết quả")
44
+
45
+ search_button = gr.Button("Tìm kiếm")
46
+ search_button.click(fn=handle_input, inputs=[image_input, item_input], outputs=output)
47
+
48
+ return app
49
+
50
+
51
+ # Chạy ứng dụng
52
+ app = create_interface()
53
+ app.launch()
models.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ import numpy as np
4
+ from ultralytics import YOLO
5
+ from transformers import AutoProcessor
6
+ from transformers import AutoModelForTokenClassification
7
+ from utils import normalize_box, unnormalize_box, draw_output, create_df
8
+ from PIL import Image, ImageDraw
9
+ from vietocr.tool.predictor import Predictor
10
+ from vietocr.tool.config import Cfg
11
+
12
+ class Reciept_Analyzer:
13
+ def __init__(self,
14
+ processor_pretrained='microsoft/layoutlmv3-base',
15
+ layoutlm_pretrained=os.path.join(
16
+ 'models', 'checkpoint'),
17
+ yolo_pretrained=os.path.join(
18
+ 'models', 'best.pt'),
19
+ vietocr_pretrained=os.path.join(
20
+ 'models', 'vietocr', 'vgg_seq2seq.pth')
21
+ ):
22
+
23
+ print("Initializing processor")
24
+ self.processor = AutoProcessor.from_pretrained(
25
+ processor_pretrained, apply_ocr=False)
26
+ print("Finished initializing processor")
27
+
28
+ print("Initializing LayoutLM model")
29
+ self.lalm_model = AutoModelForTokenClassification.from_pretrained(
30
+ layoutlm_pretrained)
31
+ print("Finished initializing LayoutLM model")
32
+
33
+ if yolo_pretrained is not None:
34
+ print("Initializing YOLO model")
35
+ self.yolo_model = YOLO(yolo_pretrained)
36
+ print("Finished initializing YOLO model")
37
+
38
+ print("Initializing VietOCR model")
39
+ config = Cfg.load_config_from_name('vgg_seq2seq')
40
+ config['weights'] = vietocr_pretrained
41
+ config['cnn']['pretrained']= False
42
+ config['device'] = 'cuda:0' if torch.cuda.is_available() else 'cpu'
43
+ self.vietocr = Predictor(config)
44
+ print("Finished initializing VietOCR model")
45
+
46
+ def forward(self, img, output_path="output", is_save_cropped_img=False):
47
+ input_image = Image.open(img)
48
+
49
+ # detection with YOLOv8
50
+ bboxes = self.yolov8_det(input_image)
51
+
52
+ # sort
53
+ sorted_bboxes = self.sort_bboxes(bboxes)
54
+
55
+ # draw bbox
56
+ image_draw = input_image.copy()
57
+ self.draw_bbox(image_draw, sorted_bboxes, output_path)
58
+
59
+ # crop images
60
+ cropped_images, normalized_boxes = self.get_cropped_images(input_image, sorted_bboxes, is_save_cropped_img, output_path)
61
+
62
+ # recognition with VietOCR
63
+ texts, mapping_bbox_texts = self.ocr(cropped_images, normalized_boxes)
64
+
65
+ # KIE with LayoutLMv3
66
+ pred_texts, pred_label, boxes = self.kie(input_image, texts, normalized_boxes, mapping_bbox_texts, output_path)
67
+
68
+ # create dataframe
69
+ return create_df(pred_texts, pred_label)
70
+
71
+
72
+ def yolov8_det(self, img):
73
+ return self.yolo_model.predict(source=img, conf=0.3, iou=0.1)[0].boxes.xyxy.int()
74
+
75
+ def sort_bboxes(self, bboxes):
76
+ bbox_list = []
77
+ for box in bboxes:
78
+ tlx, tly, brx, bry = map(int, box)
79
+ bbox_list.append([tlx, tly, brx, bry])
80
+ bbox_list.sort(key=lambda x: (x[1], x[2]))
81
+ return bbox_list
82
+
83
+ def draw_bbox(self, image_draw, bboxes, output_path):
84
+ # draw bbox
85
+ draw = ImageDraw.Draw(image_draw)
86
+ for box in bboxes:
87
+ draw.rectangle(box, outline='red', width=2)
88
+ image_draw.save(os.path.join(output_path, 'bbox.jpg'))
89
+ print(f"Exported image with bounding boxes to {os.path.join(output_path, 'bbox.jpg')}")
90
+
91
+ def get_cropped_images(self, input_image, bboxes, is_save_cropped=False, output_path="output"):
92
+ normalized_boxes = []
93
+ cropped_images = []
94
+
95
+ # OCR
96
+ if is_save_cropped:
97
+ cropped_folder = os.path.join(output_path, "cropped")
98
+ if not os.path.exists(cropped_folder):
99
+ os.makedirs(cropped_folder)
100
+ i = 0
101
+ for box in bboxes:
102
+ tlx, tly, brx, bry = map(int, box)
103
+ normalized_box = normalize_box(box, input_image.width, input_image.height)
104
+ normalized_boxes.append(normalized_box)
105
+ cropped_ = input_image.crop((tlx, tly, brx, bry))
106
+ if is_save_cropped:
107
+ cropped_.save(os.path.join(cropped_folder, f'cropped_{i}.jpg'))
108
+ i += 1
109
+ cropped_images.append(cropped_)
110
+
111
+ return cropped_images, normalized_boxes
112
+
113
+ def ocr(self, cropped_images, normalized_boxes):
114
+ mapping_bbox_texts = {}
115
+ texts = []
116
+ for img, normalized_box in zip(cropped_images, normalized_boxes):
117
+ result = self.vietocr.predict(img)
118
+ text = result.strip().replace('\n', ' ')
119
+ texts.append(text)
120
+ mapping_bbox_texts[','.join(map(str, normalized_box))] = text
121
+
122
+ return texts, mapping_bbox_texts
123
+
124
+ def kie(self, img, texts, boxes, mapping_bbox_texts, output_path):
125
+ encoding = self.processor(img, texts,
126
+ boxes=boxes,
127
+ return_offsets_mapping=True,
128
+ return_tensors='pt',
129
+ max_length=512,
130
+ padding='max_length')
131
+ offset_mapping = encoding.pop('offset_mapping')
132
+
133
+ with torch.no_grad():
134
+ outputs = self.lalm_model(**encoding)
135
+
136
+ id2label = self.lalm_model.config.id2label
137
+ logits = outputs.logits
138
+ token_boxes = encoding.bbox.squeeze().tolist()
139
+ offset_mapping = offset_mapping.squeeze().tolist()
140
+
141
+ predictions = logits.argmax(-1).squeeze().tolist()
142
+ is_subword = np.array(offset_mapping)[:, 0] != 0
143
+
144
+ true_predictions = []
145
+ true_boxes = []
146
+ true_texts = []
147
+ for idx in range(len(predictions)):
148
+ if not is_subword[idx] and token_boxes[idx] != [0, 0, 0, 0]:
149
+ true_predictions.append(id2label[predictions[idx]])
150
+ true_boxes.append(unnormalize_box(
151
+ token_boxes[idx], img.width, img.height))
152
+ true_texts.append(mapping_bbox_texts.get(
153
+ ','.join(map(str, token_boxes[idx])), ''))
154
+
155
+ if isinstance(output_path, str):
156
+ os.makedirs(output_path, exist_ok=True)
157
+ img_output = draw_output(
158
+ image=img,
159
+ true_predictions=true_predictions,
160
+ true_boxes=true_boxes
161
+ )
162
+ img_output.save(os.path.join(output_path, 'result.jpg'))
163
+ print(f"Exported result to {os.path.join(output_path, 'result.jpg')}")
164
+ return true_texts, true_predictions, true_boxes
models/best.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9a76aef7a2e063cfba3fc466a864ed10d80c460d3e87c5667cfeb5b4d67c4df0
3
+ size 207624591
models/checkpoint/config.json ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "microsoft/layoutlmv3-base",
3
+ "architectures": [
4
+ "LayoutLMv3ForTokenClassification"
5
+ ],
6
+ "attention_probs_dropout_prob": 0.1,
7
+ "bos_token_id": 0,
8
+ "classifier_dropout": null,
9
+ "coordinate_size": 128,
10
+ "eos_token_id": 2,
11
+ "has_relative_attention_bias": true,
12
+ "has_spatial_attention_bias": true,
13
+ "hidden_act": "gelu",
14
+ "hidden_dropout_prob": 0.1,
15
+ "hidden_size": 768,
16
+ "id2label": {
17
+ "0": "ADDR",
18
+ "1": "TITLE",
19
+ "2": "PRODUCT_NAME_PREFIX",
20
+ "3": "PRODUCT_NAME",
21
+ "4": "AMOUNT_PREFIX",
22
+ "5": "AMOUNT",
23
+ "6": "UNIT_PREFIX",
24
+ "7": "UNIT",
25
+ "8": "UPRICE_PREFIX",
26
+ "9": "UPRICE",
27
+ "10": "SUB_TPRICE_PREFIX",
28
+ "11": "SUB_TPRICE",
29
+ "12": "TAMOUNT_PREFIX",
30
+ "13": "TAMOUNT",
31
+ "14": "TPRICE_PREFIX",
32
+ "15": "TPRICE",
33
+ "16": "RECEMONEY_PREFIX",
34
+ "17": "RECEMONEY",
35
+ "18": "OTHER",
36
+ "19": "BILLID_PREFIX",
37
+ "20": "BILLID",
38
+ "21": "DATETIME_PREFIX",
39
+ "22": "DATETIME",
40
+ "23": "CASHIER_PREFIX",
41
+ "24": "CASHIER",
42
+ "25": "SHOP_NAME",
43
+ "26": "PHONE_PREFIX",
44
+ "27": "FPRICE_PREFIX",
45
+ "28": "FPRICE",
46
+ "29": "REMAMONEY_PREFIX",
47
+ "30": "REMAMONEY",
48
+ "31": "PHONE",
49
+ "32": "TDISCOUNT_PREFIX",
50
+ "33": "TDISCOUNT",
51
+ "34": "ADDR_PREFIX",
52
+ "35": "UDISCOUNT_PREFIX",
53
+ "36": "UDISCOUNT"
54
+ },
55
+ "initializer_range": 0.02,
56
+ "input_size": 224,
57
+ "intermediate_size": 3072,
58
+ "label2id": {
59
+ "ADDR": 0,
60
+ "ADDR_PREFIX": 34,
61
+ "AMOUNT": 5,
62
+ "AMOUNT_PREFIX": 4,
63
+ "BILLID": 20,
64
+ "BILLID_PREFIX": 19,
65
+ "CASHIER": 24,
66
+ "CASHIER_PREFIX": 23,
67
+ "DATETIME": 22,
68
+ "DATETIME_PREFIX": 21,
69
+ "FPRICE": 28,
70
+ "FPRICE_PREFIX": 27,
71
+ "OTHER": 18,
72
+ "PHONE": 31,
73
+ "PHONE_PREFIX": 26,
74
+ "PRODUCT_NAME": 3,
75
+ "PRODUCT_NAME_PREFIX": 2,
76
+ "RECEMONEY": 17,
77
+ "RECEMONEY_PREFIX": 16,
78
+ "REMAMONEY": 30,
79
+ "REMAMONEY_PREFIX": 29,
80
+ "SHOP_NAME": 25,
81
+ "SUB_TPRICE": 11,
82
+ "SUB_TPRICE_PREFIX": 10,
83
+ "TAMOUNT": 13,
84
+ "TAMOUNT_PREFIX": 12,
85
+ "TDISCOUNT": 33,
86
+ "TDISCOUNT_PREFIX": 32,
87
+ "TITLE": 1,
88
+ "TPRICE": 15,
89
+ "TPRICE_PREFIX": 14,
90
+ "UDISCOUNT": 36,
91
+ "UDISCOUNT_PREFIX": 35,
92
+ "UNIT": 7,
93
+ "UNIT_PREFIX": 6,
94
+ "UPRICE": 9,
95
+ "UPRICE_PREFIX": 8
96
+ },
97
+ "layer_norm_eps": 1e-05,
98
+ "max_2d_position_embeddings": 1024,
99
+ "max_position_embeddings": 514,
100
+ "max_rel_2d_pos": 256,
101
+ "max_rel_pos": 128,
102
+ "model_type": "layoutlmv3",
103
+ "num_attention_heads": 12,
104
+ "num_channels": 3,
105
+ "num_hidden_layers": 12,
106
+ "pad_token_id": 1,
107
+ "patch_size": 16,
108
+ "rel_2d_pos_bins": 64,
109
+ "rel_pos_bins": 32,
110
+ "second_input_size": 112,
111
+ "shape_size": 128,
112
+ "text_embed": true,
113
+ "torch_dtype": "float32",
114
+ "transformers_version": "4.27.2",
115
+ "type_vocab_size": 1,
116
+ "visual_embed": true,
117
+ "vocab_size": 50265
118
+ }
models/checkpoint/merges.txt ADDED
The diff for this file is too large to render. See raw diff
 
models/checkpoint/preprocessor_config.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "apply_ocr": false,
3
+ "do_normalize": true,
4
+ "do_rescale": true,
5
+ "do_resize": true,
6
+ "feature_extractor_type": "LayoutLMv3FeatureExtractor",
7
+ "image_mean": [
8
+ 0.5,
9
+ 0.5,
10
+ 0.5
11
+ ],
12
+ "image_processor_type": "LayoutLMv3ImageProcessor",
13
+ "image_std": [
14
+ 0.5,
15
+ 0.5,
16
+ 0.5
17
+ ],
18
+ "ocr_lang": null,
19
+ "processor_class": "LayoutLMv3Processor",
20
+ "resample": 2,
21
+ "rescale_factor": 0.00392156862745098,
22
+ "size": {
23
+ "height": 224,
24
+ "width": 224
25
+ },
26
+ "tesseract_config": ""
27
+ }
models/checkpoint/pytorch_model.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:32d465ffd4cbb9b024db495cf54841f73cb717de6dba135fc8258fe9c253296f
3
+ size 503863089
models/checkpoint/rng_state.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fd747db282a4c24e2cf6e4bc50b907e598e871654c02eb66d5fe56403e68a3d8
3
+ size 14575
models/checkpoint/scheduler.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7d13d935c351b9a072808b2f35968a51ccc83f30be9b4047e7a9be1cf7fb0a97
3
+ size 627
models/checkpoint/special_tokens_map.json ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token": {
3
+ "content": "<s>",
4
+ "lstrip": false,
5
+ "normalized": true,
6
+ "rstrip": false,
7
+ "single_word": false
8
+ },
9
+ "cls_token": {
10
+ "content": "<s>",
11
+ "lstrip": false,
12
+ "normalized": true,
13
+ "rstrip": false,
14
+ "single_word": false
15
+ },
16
+ "eos_token": {
17
+ "content": "</s>",
18
+ "lstrip": false,
19
+ "normalized": true,
20
+ "rstrip": false,
21
+ "single_word": false
22
+ },
23
+ "mask_token": {
24
+ "content": "<mask>",
25
+ "lstrip": true,
26
+ "normalized": true,
27
+ "rstrip": false,
28
+ "single_word": false
29
+ },
30
+ "pad_token": {
31
+ "content": "<pad>",
32
+ "lstrip": false,
33
+ "normalized": true,
34
+ "rstrip": false,
35
+ "single_word": false
36
+ },
37
+ "sep_token": {
38
+ "content": "</s>",
39
+ "lstrip": false,
40
+ "normalized": true,
41
+ "rstrip": false,
42
+ "single_word": false
43
+ },
44
+ "unk_token": {
45
+ "content": "<unk>",
46
+ "lstrip": false,
47
+ "normalized": true,
48
+ "rstrip": false,
49
+ "single_word": false
50
+ }
51
+ }
models/checkpoint/tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
models/checkpoint/tokenizer_config.json ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": true,
3
+ "apply_ocr": false,
4
+ "bos_token": {
5
+ "__type": "AddedToken",
6
+ "content": "<s>",
7
+ "lstrip": false,
8
+ "normalized": true,
9
+ "rstrip": false,
10
+ "single_word": false
11
+ },
12
+ "cls_token": {
13
+ "__type": "AddedToken",
14
+ "content": "<s>",
15
+ "lstrip": false,
16
+ "normalized": true,
17
+ "rstrip": false,
18
+ "single_word": false
19
+ },
20
+ "cls_token_box": [
21
+ 0,
22
+ 0,
23
+ 0,
24
+ 0
25
+ ],
26
+ "eos_token": {
27
+ "__type": "AddedToken",
28
+ "content": "</s>",
29
+ "lstrip": false,
30
+ "normalized": true,
31
+ "rstrip": false,
32
+ "single_word": false
33
+ },
34
+ "errors": "replace",
35
+ "mask_token": {
36
+ "__type": "AddedToken",
37
+ "content": "<mask>",
38
+ "lstrip": true,
39
+ "normalized": true,
40
+ "rstrip": false,
41
+ "single_word": false
42
+ },
43
+ "model_max_length": 512,
44
+ "only_label_first_subword": true,
45
+ "pad_token": {
46
+ "__type": "AddedToken",
47
+ "content": "<pad>",
48
+ "lstrip": false,
49
+ "normalized": true,
50
+ "rstrip": false,
51
+ "single_word": false
52
+ },
53
+ "pad_token_box": [
54
+ 0,
55
+ 0,
56
+ 0,
57
+ 0
58
+ ],
59
+ "pad_token_label": -100,
60
+ "processor_class": "LayoutLMv3Processor",
61
+ "sep_token": {
62
+ "__type": "AddedToken",
63
+ "content": "</s>",
64
+ "lstrip": false,
65
+ "normalized": true,
66
+ "rstrip": false,
67
+ "single_word": false
68
+ },
69
+ "sep_token_box": [
70
+ 0,
71
+ 0,
72
+ 0,
73
+ 0
74
+ ],
75
+ "special_tokens_map_file": null,
76
+ "tokenizer_class": "LayoutLMv3Tokenizer",
77
+ "trim_offsets": true,
78
+ "unk_token": {
79
+ "__type": "AddedToken",
80
+ "content": "<unk>",
81
+ "lstrip": false,
82
+ "normalized": true,
83
+ "rstrip": false,
84
+ "single_word": false
85
+ }
86
+ }
models/checkpoint/trainer_state.json ADDED
@@ -0,0 +1,676 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "best_metric": 0.9322203066872333,
3
+ "best_model_checkpoint": "/content/drive/MyDrive/checkpoint_layoutlm2/checkpoint-3500",
4
+ "epoch": 26.31578947368421,
5
+ "global_step": 5000,
6
+ "is_hyper_param_search": false,
7
+ "is_local_process_zero": true,
8
+ "is_world_process_zero": true,
9
+ "log_history": [
10
+ {
11
+ "epoch": 0.53,
12
+ "eval_accuracy": 0.5655867006431259,
13
+ "eval_f1": 0.49600000000000005,
14
+ "eval_loss": 1.9622313976287842,
15
+ "eval_precision": 0.6104310803618946,
16
+ "eval_recall": 0.41769847050254916,
17
+ "eval_runtime": 31.7963,
18
+ "eval_samples_per_second": 5.976,
19
+ "eval_steps_per_second": 1.51,
20
+ "step": 100
21
+ },
22
+ {
23
+ "epoch": 1.05,
24
+ "eval_accuracy": 0.7380172309185778,
25
+ "eval_f1": 0.6739791685869665,
26
+ "eval_loss": 1.2630114555358887,
27
+ "eval_precision": 0.682471532574202,
28
+ "eval_recall": 0.6656955571740714,
29
+ "eval_runtime": 32.3716,
30
+ "eval_samples_per_second": 5.869,
31
+ "eval_steps_per_second": 1.483,
32
+ "step": 200
33
+ },
34
+ {
35
+ "epoch": 1.58,
36
+ "eval_accuracy": 0.7893459531610242,
37
+ "eval_f1": 0.7480542986425339,
38
+ "eval_loss": 0.9176977872848511,
39
+ "eval_precision": 0.7436128103634401,
40
+ "eval_recall": 0.7525491624180627,
41
+ "eval_runtime": 32.1494,
42
+ "eval_samples_per_second": 5.91,
43
+ "eval_steps_per_second": 1.493,
44
+ "step": 300
45
+ },
46
+ {
47
+ "epoch": 2.11,
48
+ "eval_accuracy": 0.8295109816769809,
49
+ "eval_f1": 0.8007957319830002,
50
+ "eval_loss": 0.7080672979354858,
51
+ "eval_precision": 0.7954014729656906,
52
+ "eval_recall": 0.8062636562272396,
53
+ "eval_runtime": 32.0545,
54
+ "eval_samples_per_second": 5.927,
55
+ "eval_steps_per_second": 1.497,
56
+ "step": 400
57
+ },
58
+ {
59
+ "epoch": 2.63,
60
+ "learning_rate": 9.666666666666667e-06,
61
+ "loss": 1.4294,
62
+ "step": 500
63
+ },
64
+ {
65
+ "epoch": 2.63,
66
+ "eval_accuracy": 0.8411600533915787,
67
+ "eval_f1": 0.8213092550790069,
68
+ "eval_loss": 0.6136476397514343,
69
+ "eval_precision": 0.814615797958087,
70
+ "eval_recall": 0.8281136198106337,
71
+ "eval_runtime": 32.0473,
72
+ "eval_samples_per_second": 5.929,
73
+ "eval_steps_per_second": 1.498,
74
+ "step": 500
75
+ },
76
+ {
77
+ "epoch": 3.16,
78
+ "eval_accuracy": 0.8741657565829389,
79
+ "eval_f1": 0.8656448866182666,
80
+ "eval_loss": 0.5390823483467102,
81
+ "eval_precision": 0.8524271844660194,
82
+ "eval_recall": 0.879278951201748,
83
+ "eval_runtime": 33.0229,
84
+ "eval_samples_per_second": 5.754,
85
+ "eval_steps_per_second": 1.454,
86
+ "step": 600
87
+ },
88
+ {
89
+ "epoch": 3.68,
90
+ "eval_accuracy": 0.8869069287707803,
91
+ "eval_f1": 0.878114599262391,
92
+ "eval_loss": 0.47398096323013306,
93
+ "eval_precision": 0.8677333333333334,
94
+ "eval_recall": 0.8887472687545521,
95
+ "eval_runtime": 32.5116,
96
+ "eval_samples_per_second": 5.844,
97
+ "eval_steps_per_second": 1.476,
98
+ "step": 700
99
+ },
100
+ {
101
+ "epoch": 4.21,
102
+ "eval_accuracy": 0.8989200339764591,
103
+ "eval_f1": 0.893278463648834,
104
+ "eval_loss": 0.4286675751209259,
105
+ "eval_precision": 0.8972992834833732,
106
+ "eval_recall": 0.8892935178441369,
107
+ "eval_runtime": 32.15,
108
+ "eval_samples_per_second": 5.91,
109
+ "eval_steps_per_second": 1.493,
110
+ "step": 800
111
+ },
112
+ {
113
+ "epoch": 4.74,
114
+ "eval_accuracy": 0.9040165028515956,
115
+ "eval_f1": 0.8944705457173835,
116
+ "eval_loss": 0.40272650122642517,
117
+ "eval_precision": 0.8877331420373027,
118
+ "eval_recall": 0.9013109978150037,
119
+ "eval_runtime": 32.2339,
120
+ "eval_samples_per_second": 5.894,
121
+ "eval_steps_per_second": 1.489,
122
+ "step": 900
123
+ },
124
+ {
125
+ "epoch": 5.26,
126
+ "learning_rate": 9.333333333333334e-06,
127
+ "loss": 0.455,
128
+ "step": 1000
129
+ },
130
+ {
131
+ "epoch": 5.26,
132
+ "eval_accuracy": 0.9131173401286252,
133
+ "eval_f1": 0.9035698147311342,
134
+ "eval_loss": 0.369215190410614,
135
+ "eval_precision": 0.8970034092948143,
136
+ "eval_recall": 0.9102330662782229,
137
+ "eval_runtime": 32.0091,
138
+ "eval_samples_per_second": 5.936,
139
+ "eval_steps_per_second": 1.5,
140
+ "step": 1000
141
+ },
142
+ {
143
+ "epoch": 5.79,
144
+ "eval_accuracy": 0.9172430530275452,
145
+ "eval_f1": 0.912167606768735,
146
+ "eval_loss": 0.36320310831069946,
147
+ "eval_precision": 0.8973049145675532,
148
+ "eval_recall": 0.9275309541150765,
149
+ "eval_runtime": 31.8391,
150
+ "eval_samples_per_second": 5.968,
151
+ "eval_steps_per_second": 1.508,
152
+ "step": 1100
153
+ },
154
+ {
155
+ "epoch": 6.32,
156
+ "eval_accuracy": 0.9166363305424099,
157
+ "eval_f1": 0.9132502018480307,
158
+ "eval_loss": 0.34437164664268494,
159
+ "eval_precision": 0.9000884173297966,
160
+ "eval_recall": 0.92680262199563,
161
+ "eval_runtime": 31.688,
162
+ "eval_samples_per_second": 5.996,
163
+ "eval_steps_per_second": 1.515,
164
+ "step": 1200
165
+ },
166
+ {
167
+ "epoch": 6.84,
168
+ "eval_accuracy": 0.924766411843223,
169
+ "eval_f1": 0.9212297616881936,
170
+ "eval_loss": 0.327307790517807,
171
+ "eval_precision": 0.920392584514722,
172
+ "eval_recall": 0.922068463219228,
173
+ "eval_runtime": 31.8134,
174
+ "eval_samples_per_second": 5.972,
175
+ "eval_steps_per_second": 1.509,
176
+ "step": 1300
177
+ },
178
+ {
179
+ "epoch": 7.37,
180
+ "eval_accuracy": 0.9242810338551146,
181
+ "eval_f1": 0.9209428830462375,
182
+ "eval_loss": 0.32373183965682983,
183
+ "eval_precision": 0.9171180931744312,
184
+ "eval_recall": 0.9247997086671522,
185
+ "eval_runtime": 32.69,
186
+ "eval_samples_per_second": 5.812,
187
+ "eval_steps_per_second": 1.468,
188
+ "step": 1400
189
+ },
190
+ {
191
+ "epoch": 7.89,
192
+ "learning_rate": 9e-06,
193
+ "loss": 0.2736,
194
+ "step": 1500
195
+ },
196
+ {
197
+ "epoch": 7.89,
198
+ "eval_accuracy": 0.9282854022570076,
199
+ "eval_f1": 0.9256823709575714,
200
+ "eval_loss": 0.31131741404533386,
201
+ "eval_precision": 0.916027812444286,
202
+ "eval_recall": 0.9355426074289876,
203
+ "eval_runtime": 32.0518,
204
+ "eval_samples_per_second": 5.928,
205
+ "eval_steps_per_second": 1.498,
206
+ "step": 1500
207
+ },
208
+ {
209
+ "epoch": 8.42,
210
+ "eval_accuracy": 0.9254944788253853,
211
+ "eval_f1": 0.9237975139614484,
212
+ "eval_loss": 0.3146894872188568,
213
+ "eval_precision": 0.9140819964349376,
214
+ "eval_recall": 0.9337217771303714,
215
+ "eval_runtime": 32.0386,
216
+ "eval_samples_per_second": 5.93,
217
+ "eval_steps_per_second": 1.498,
218
+ "step": 1600
219
+ },
220
+ {
221
+ "epoch": 8.95,
222
+ "eval_accuracy": 0.9253731343283582,
223
+ "eval_f1": 0.9235605856462767,
224
+ "eval_loss": 0.3176872134208679,
225
+ "eval_precision": 0.9113632334692431,
226
+ "eval_recall": 0.9360888565185724,
227
+ "eval_runtime": 32.1667,
228
+ "eval_samples_per_second": 5.907,
229
+ "eval_steps_per_second": 1.492,
230
+ "step": 1700
231
+ },
232
+ {
233
+ "epoch": 9.47,
234
+ "eval_accuracy": 0.9262225458075476,
235
+ "eval_f1": 0.9248316120341267,
236
+ "eval_loss": 0.3194420337677002,
237
+ "eval_precision": 0.9124579124579124,
238
+ "eval_recall": 0.9375455207574654,
239
+ "eval_runtime": 32.186,
240
+ "eval_samples_per_second": 5.903,
241
+ "eval_steps_per_second": 1.491,
242
+ "step": 1800
243
+ },
244
+ {
245
+ "epoch": 10.0,
246
+ "eval_accuracy": 0.9293775027302512,
247
+ "eval_f1": 0.9273722955381991,
248
+ "eval_loss": 0.30748510360717773,
249
+ "eval_precision": 0.9146449442181689,
250
+ "eval_recall": 0.9404588492352512,
251
+ "eval_runtime": 31.8871,
252
+ "eval_samples_per_second": 5.959,
253
+ "eval_steps_per_second": 1.505,
254
+ "step": 1900
255
+ },
256
+ {
257
+ "epoch": 10.53,
258
+ "learning_rate": 8.666666666666668e-06,
259
+ "loss": 0.2045,
260
+ "step": 2000
261
+ },
262
+ {
263
+ "epoch": 10.53,
264
+ "eval_accuracy": 0.9305909477005218,
265
+ "eval_f1": 0.928266981046522,
266
+ "eval_loss": 0.3004026710987091,
267
+ "eval_precision": 0.9246612466124661,
268
+ "eval_recall": 0.9319009468317553,
269
+ "eval_runtime": 32.044,
270
+ "eval_samples_per_second": 5.929,
271
+ "eval_steps_per_second": 1.498,
272
+ "step": 2000
273
+ },
274
+ {
275
+ "epoch": 11.05,
276
+ "eval_accuracy": 0.9284067467540347,
277
+ "eval_f1": 0.9264534623309147,
278
+ "eval_loss": 0.3036515414714813,
279
+ "eval_precision": 0.9118321283724211,
280
+ "eval_recall": 0.9415513474144209,
281
+ "eval_runtime": 31.8687,
282
+ "eval_samples_per_second": 5.962,
283
+ "eval_steps_per_second": 1.506,
284
+ "step": 2100
285
+ },
286
+ {
287
+ "epoch": 11.58,
288
+ "eval_accuracy": 0.9307122921975488,
289
+ "eval_f1": 0.9279507603186097,
290
+ "eval_loss": 0.30012640357017517,
291
+ "eval_precision": 0.9226061915046796,
292
+ "eval_recall": 0.9333576110706482,
293
+ "eval_runtime": 31.9364,
294
+ "eval_samples_per_second": 5.949,
295
+ "eval_steps_per_second": 1.503,
296
+ "step": 2200
297
+ },
298
+ {
299
+ "epoch": 12.11,
300
+ "eval_accuracy": 0.9318043926707924,
301
+ "eval_f1": 0.9303956834532375,
302
+ "eval_loss": 0.3051491975784302,
303
+ "eval_precision": 0.9191542288557214,
304
+ "eval_recall": 0.9419155134741443,
305
+ "eval_runtime": 31.9279,
306
+ "eval_samples_per_second": 5.951,
307
+ "eval_steps_per_second": 1.503,
308
+ "step": 2300
309
+ },
310
+ {
311
+ "epoch": 12.63,
312
+ "eval_accuracy": 0.9299842252153865,
313
+ "eval_f1": 0.9288619723402333,
314
+ "eval_loss": 0.31714528799057007,
315
+ "eval_precision": 0.9222760725183988,
316
+ "eval_recall": 0.9355426074289876,
317
+ "eval_runtime": 32.3661,
318
+ "eval_samples_per_second": 5.87,
319
+ "eval_steps_per_second": 1.483,
320
+ "step": 2400
321
+ },
322
+ {
323
+ "epoch": 13.16,
324
+ "learning_rate": 8.333333333333334e-06,
325
+ "loss": 0.1678,
326
+ "step": 2500
327
+ },
328
+ {
329
+ "epoch": 13.16,
330
+ "eval_accuracy": 0.9279213687659265,
331
+ "eval_f1": 0.9271131805157592,
332
+ "eval_loss": 0.321869432926178,
333
+ "eval_precision": 0.9120859760394644,
334
+ "eval_recall": 0.9426438455935907,
335
+ "eval_runtime": 32.586,
336
+ "eval_samples_per_second": 5.831,
337
+ "eval_steps_per_second": 1.473,
338
+ "step": 2500
339
+ },
340
+ {
341
+ "epoch": 13.68,
342
+ "eval_accuracy": 0.9273146462807912,
343
+ "eval_f1": 0.9248711689720641,
344
+ "eval_loss": 0.3112223446369171,
345
+ "eval_precision": 0.9184772849703717,
346
+ "eval_recall": 0.9313546977421704,
347
+ "eval_runtime": 32.4269,
348
+ "eval_samples_per_second": 5.859,
349
+ "eval_steps_per_second": 1.48,
350
+ "step": 2600
351
+ },
352
+ {
353
+ "epoch": 14.21,
354
+ "eval_accuracy": 0.92901346923917,
355
+ "eval_f1": 0.9273105820584773,
356
+ "eval_loss": 0.3135831654071808,
357
+ "eval_precision": 0.922052205220522,
358
+ "eval_recall": 0.9326292789512017,
359
+ "eval_runtime": 31.2652,
360
+ "eval_samples_per_second": 6.077,
361
+ "eval_steps_per_second": 1.535,
362
+ "step": 2700
363
+ },
364
+ {
365
+ "epoch": 14.74,
366
+ "eval_accuracy": 0.9296201917243053,
367
+ "eval_f1": 0.9286809124515373,
368
+ "eval_loss": 0.3137897551059723,
369
+ "eval_precision": 0.9198071084122165,
370
+ "eval_recall": 0.937727603787327,
371
+ "eval_runtime": 31.2737,
372
+ "eval_samples_per_second": 6.075,
373
+ "eval_steps_per_second": 1.535,
374
+ "step": 2800
375
+ },
376
+ {
377
+ "epoch": 15.26,
378
+ "eval_accuracy": 0.93313918213809,
379
+ "eval_f1": 0.9307971014492753,
380
+ "eval_loss": 0.3145933747291565,
381
+ "eval_precision": 0.9260994953136266,
382
+ "eval_recall": 0.9355426074289876,
383
+ "eval_runtime": 32.3029,
384
+ "eval_samples_per_second": 5.882,
385
+ "eval_steps_per_second": 1.486,
386
+ "step": 2900
387
+ },
388
+ {
389
+ "epoch": 15.79,
390
+ "learning_rate": 8.000000000000001e-06,
391
+ "loss": 0.1404,
392
+ "step": 3000
393
+ },
394
+ {
395
+ "epoch": 15.79,
396
+ "eval_accuracy": 0.9296201917243053,
397
+ "eval_f1": 0.9290786516853932,
398
+ "eval_loss": 0.31863638758659363,
399
+ "eval_precision": 0.917450736729984,
400
+ "eval_recall": 0.9410050983248361,
401
+ "eval_runtime": 31.4449,
402
+ "eval_samples_per_second": 6.042,
403
+ "eval_steps_per_second": 1.526,
404
+ "step": 3000
405
+ },
406
+ {
407
+ "epoch": 16.32,
408
+ "eval_accuracy": 0.9314403591797112,
409
+ "eval_f1": 0.929384143037746,
410
+ "eval_loss": 0.3153584599494934,
411
+ "eval_precision": 0.9218917950555356,
412
+ "eval_recall": 0.9369992716678806,
413
+ "eval_runtime": 31.167,
414
+ "eval_samples_per_second": 6.096,
415
+ "eval_steps_per_second": 1.54,
416
+ "step": 3100
417
+ },
418
+ {
419
+ "epoch": 16.84,
420
+ "eval_accuracy": 0.9273146462807912,
421
+ "eval_f1": 0.926561797752809,
422
+ "eval_loss": 0.34182220697402954,
423
+ "eval_precision": 0.9149653825670158,
424
+ "eval_recall": 0.9384559359067735,
425
+ "eval_runtime": 31.6096,
426
+ "eval_samples_per_second": 6.011,
427
+ "eval_steps_per_second": 1.519,
428
+ "step": 3200
429
+ },
430
+ {
431
+ "epoch": 17.37,
432
+ "eval_accuracy": 0.925009100837277,
433
+ "eval_f1": 0.9233380986418871,
434
+ "eval_loss": 0.35532286763191223,
435
+ "eval_precision": 0.9064912280701755,
436
+ "eval_recall": 0.9408230152949745,
437
+ "eval_runtime": 32.7011,
438
+ "eval_samples_per_second": 5.81,
439
+ "eval_steps_per_second": 1.468,
440
+ "step": 3300
441
+ },
442
+ {
443
+ "epoch": 17.89,
444
+ "eval_accuracy": 0.9294988472272783,
445
+ "eval_f1": 0.9289882395188078,
446
+ "eval_loss": 0.339712530374527,
447
+ "eval_precision": 0.9162387108199044,
448
+ "eval_recall": 0.9420975965040058,
449
+ "eval_runtime": 31.1932,
450
+ "eval_samples_per_second": 6.091,
451
+ "eval_steps_per_second": 1.539,
452
+ "step": 3400
453
+ },
454
+ {
455
+ "epoch": 18.42,
456
+ "learning_rate": 7.666666666666667e-06,
457
+ "loss": 0.1174,
458
+ "step": 3500
459
+ },
460
+ {
461
+ "epoch": 18.42,
462
+ "eval_accuracy": 0.9322897706589006,
463
+ "eval_f1": 0.9322203066872333,
464
+ "eval_loss": 0.32590094208717346,
465
+ "eval_precision": 0.929101103273648,
466
+ "eval_recall": 0.935360524399126,
467
+ "eval_runtime": 31.3047,
468
+ "eval_samples_per_second": 6.069,
469
+ "eval_steps_per_second": 1.533,
470
+ "step": 3500
471
+ },
472
+ {
473
+ "epoch": 18.95,
474
+ "eval_accuracy": 0.9299842252153865,
475
+ "eval_f1": 0.9293038316243929,
476
+ "eval_loss": 0.330241322517395,
477
+ "eval_precision": 0.9182367579097049,
478
+ "eval_recall": 0.9406409322651129,
479
+ "eval_runtime": 31.3595,
480
+ "eval_samples_per_second": 6.059,
481
+ "eval_steps_per_second": 1.531,
482
+ "step": 3600
483
+ },
484
+ {
485
+ "epoch": 19.47,
486
+ "eval_accuracy": 0.9303482587064676,
487
+ "eval_f1": 0.9284752759580005,
488
+ "eval_loss": 0.33720284700393677,
489
+ "eval_precision": 0.9154132012033268,
490
+ "eval_recall": 0.9419155134741443,
491
+ "eval_runtime": 32.5529,
492
+ "eval_samples_per_second": 5.837,
493
+ "eval_steps_per_second": 1.475,
494
+ "step": 3700
495
+ },
496
+ {
497
+ "epoch": 20.0,
498
+ "eval_accuracy": 0.9305909477005218,
499
+ "eval_f1": 0.9294531038832327,
500
+ "eval_loss": 0.33688944578170776,
501
+ "eval_precision": 0.9199215266630997,
502
+ "eval_recall": 0.9391842680262199,
503
+ "eval_runtime": 31.1686,
504
+ "eval_samples_per_second": 6.096,
505
+ "eval_steps_per_second": 1.54,
506
+ "step": 3800
507
+ },
508
+ {
509
+ "epoch": 20.53,
510
+ "eval_accuracy": 0.9302269142094406,
511
+ "eval_f1": 0.9289775291038715,
512
+ "eval_loss": 0.33882710337638855,
513
+ "eval_precision": 0.9209160851672928,
514
+ "eval_recall": 0.9371813546977422,
515
+ "eval_runtime": 31.4744,
516
+ "eval_samples_per_second": 6.037,
517
+ "eval_steps_per_second": 1.525,
518
+ "step": 3900
519
+ },
520
+ {
521
+ "epoch": 21.05,
522
+ "learning_rate": 7.333333333333333e-06,
523
+ "loss": 0.0978,
524
+ "step": 4000
525
+ },
526
+ {
527
+ "epoch": 21.05,
528
+ "eval_accuracy": 0.9297415362213324,
529
+ "eval_f1": 0.9305718144979739,
530
+ "eval_loss": 0.34309884905815125,
531
+ "eval_precision": 0.9205415998574737,
532
+ "eval_recall": 0.9408230152949745,
533
+ "eval_runtime": 31.0896,
534
+ "eval_samples_per_second": 6.111,
535
+ "eval_steps_per_second": 1.544,
536
+ "step": 4000
537
+ },
538
+ {
539
+ "epoch": 21.58,
540
+ "eval_accuracy": 0.9313190146826842,
541
+ "eval_f1": 0.9312798342790237,
542
+ "eval_loss": 0.3530495762825012,
543
+ "eval_precision": 0.9214043842452326,
544
+ "eval_recall": 0.9413692643845594,
545
+ "eval_runtime": 32.1875,
546
+ "eval_samples_per_second": 5.903,
547
+ "eval_steps_per_second": 1.491,
548
+ "step": 4100
549
+ },
550
+ {
551
+ "epoch": 22.11,
552
+ "eval_accuracy": 0.9325324596529547,
553
+ "eval_f1": 0.932169845268082,
554
+ "eval_loss": 0.34749624133110046,
555
+ "eval_precision": 0.9212304409672831,
556
+ "eval_recall": 0.9433721777130372,
557
+ "eval_runtime": 31.1794,
558
+ "eval_samples_per_second": 6.094,
559
+ "eval_steps_per_second": 1.539,
560
+ "step": 4200
561
+ },
562
+ {
563
+ "epoch": 22.63,
564
+ "eval_accuracy": 0.9302269142094406,
565
+ "eval_f1": 0.9302577040908272,
566
+ "eval_loss": 0.35649344325065613,
567
+ "eval_precision": 0.9207991437745273,
568
+ "eval_recall": 0.9399126001456665,
569
+ "eval_runtime": 32.3866,
570
+ "eval_samples_per_second": 5.867,
571
+ "eval_steps_per_second": 1.482,
572
+ "step": 4300
573
+ },
574
+ {
575
+ "epoch": 23.16,
576
+ "eval_accuracy": 0.9326538041499818,
577
+ "eval_f1": 0.9312274368231047,
578
+ "eval_loss": 0.35333752632141113,
579
+ "eval_precision": 0.9232283464566929,
580
+ "eval_recall": 0.9393663510560816,
581
+ "eval_runtime": 31.2877,
582
+ "eval_samples_per_second": 6.073,
583
+ "eval_steps_per_second": 1.534,
584
+ "step": 4400
585
+ },
586
+ {
587
+ "epoch": 23.68,
588
+ "learning_rate": 7e-06,
589
+ "loss": 0.0822,
590
+ "step": 4500
591
+ },
592
+ {
593
+ "epoch": 23.68,
594
+ "eval_accuracy": 0.9333818711321441,
595
+ "eval_f1": 0.932110421724665,
596
+ "eval_loss": 0.3559868335723877,
597
+ "eval_precision": 0.9207674542547521,
598
+ "eval_recall": 0.9437363437727604,
599
+ "eval_runtime": 31.1716,
600
+ "eval_samples_per_second": 6.095,
601
+ "eval_steps_per_second": 1.54,
602
+ "step": 4500
603
+ },
604
+ {
605
+ "epoch": 24.21,
606
+ "eval_accuracy": 0.9337459046232254,
607
+ "eval_f1": 0.932995750067818,
608
+ "eval_loss": 0.3473477065563202,
609
+ "eval_precision": 0.9267109753906951,
610
+ "eval_recall": 0.9393663510560816,
611
+ "eval_runtime": 31.2203,
612
+ "eval_samples_per_second": 6.086,
613
+ "eval_steps_per_second": 1.537,
614
+ "step": 4600
615
+ },
616
+ {
617
+ "epoch": 24.74,
618
+ "eval_accuracy": 0.9287707802451158,
619
+ "eval_f1": 0.9275258194881005,
620
+ "eval_loss": 0.3723868131637573,
621
+ "eval_precision": 0.9151160730108099,
622
+ "eval_recall": 0.9402767662053897,
623
+ "eval_runtime": 32.4085,
624
+ "eval_samples_per_second": 5.863,
625
+ "eval_steps_per_second": 1.481,
626
+ "step": 4700
627
+ },
628
+ {
629
+ "epoch": 25.26,
630
+ "eval_accuracy": 0.9327751486470088,
631
+ "eval_f1": 0.9308232750855701,
632
+ "eval_loss": 0.3668186068534851,
633
+ "eval_precision": 0.9210338680926916,
634
+ "eval_recall": 0.9408230152949745,
635
+ "eval_runtime": 31.1822,
636
+ "eval_samples_per_second": 6.093,
637
+ "eval_steps_per_second": 1.539,
638
+ "step": 4800
639
+ },
640
+ {
641
+ "epoch": 25.79,
642
+ "eval_accuracy": 0.9342312826113336,
643
+ "eval_f1": 0.932900432900433,
644
+ "eval_loss": 0.35110706090927124,
645
+ "eval_precision": 0.9242315939957112,
646
+ "eval_recall": 0.9417334304442826,
647
+ "eval_runtime": 31.632,
648
+ "eval_samples_per_second": 6.007,
649
+ "eval_steps_per_second": 1.517,
650
+ "step": 4900
651
+ },
652
+ {
653
+ "epoch": 26.32,
654
+ "learning_rate": 6.666666666666667e-06,
655
+ "loss": 0.0685,
656
+ "step": 5000
657
+ },
658
+ {
659
+ "epoch": 26.32,
660
+ "eval_accuracy": 0.9322897706589006,
661
+ "eval_f1": 0.9301610276822869,
662
+ "eval_loss": 0.349013090133667,
663
+ "eval_precision": 0.9243078029485796,
664
+ "eval_recall": 0.9360888565185724,
665
+ "eval_runtime": 31.5377,
666
+ "eval_samples_per_second": 6.025,
667
+ "eval_steps_per_second": 1.522,
668
+ "step": 5000
669
+ }
670
+ ],
671
+ "max_steps": 15000,
672
+ "num_train_epochs": 79,
673
+ "total_flos": 5296004751249408.0,
674
+ "trial_name": null,
675
+ "trial_params": null
676
+ }
models/checkpoint/training_args.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fbf7fbdb5e11561aca8ea9af246554c6be453feb7f1de7fb0526ab1162afd7e0
3
+ size 3643
models/checkpoint/vocab.json ADDED
The diff for this file is too large to render. See raw diff
 
models/vietocr/vgg_seq2seq.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0921503a41375a0584268e23ef3d414ea478a8fe8777865c7745d38f2d0bc5db
3
+ size 89575371
models/vietocr/vgg_transformer.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:870475e8e72564e6732d896b79b3369faefa1440c8fa0ea68d11b2eefadd7721
3
+ size 26877952
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ #paddleocr==2.9.1
2
+ #paddlepaddle==2.6.2
3
+ #torch==2.5.1
4
+ #torchvision==0.20.1
5
+ vietocr==0.3.13
6
+ ultralytics==8.3.65
7
+ huggingface-hub==0.27.1
8
+ datasets==2.10.0
9
+ seqeval==1.2.2
10
+ transformers==4.48.1
utils.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from datasets import load_metric
3
+ from PIL import ImageDraw, ImageFont
4
+ import pandas as pd
5
+
6
+
7
+ metric = load_metric("seqeval")
8
+
9
+
10
+ def unnormalize_box(bbox, width, height):
11
+ return [
12
+ width * (bbox[0] / 1000),
13
+ height * (bbox[1] / 1000),
14
+ width * (bbox[2] / 1000),
15
+ height * (bbox[3] / 1000)
16
+ ]
17
+
18
+
19
+ def normalize_box(bbox, width, height):
20
+ return [
21
+ int((bbox[0] / width) * 1000),
22
+ int((bbox[1] / height) * 1000),
23
+ int((bbox[2] / width) * 1000),
24
+ int((bbox[3] / height) * 1000)
25
+ ]
26
+
27
+
28
+ def draw_output(image, true_predictions, true_boxes):
29
+ def iob_to_label(label):
30
+ label = label
31
+ if not label:
32
+ return 'other'
33
+ return label
34
+
35
+ # width, height = image.size
36
+
37
+ # predictions = logits.argmax(-1).squeeze().tolist()
38
+ # is_subword = np.array(offset_mapping)[:,0] != 0
39
+ # true_predictions = [id2label[pred] for idx, pred in enumerate(predictions) if not is_subword[idx]]
40
+ # true_boxes = [unnormalize_box(box, width, height) for idx, box in enumerate(token_boxes) if not is_subword[idx]]
41
+
42
+ # draw
43
+ draw = ImageDraw.Draw(image)
44
+ font = ImageFont.load_default()
45
+
46
+ for prediction, box in zip(true_predictions, true_boxes):
47
+ predicted_label = iob_to_label(prediction).lower()
48
+ draw.rectangle(box, outline='red')
49
+ draw.text((box[0] + 10, box[1] - 10),
50
+ text=predicted_label, fill='red', font=font)
51
+
52
+ return image
53
+
54
+
55
+ def create_df(true_texts,
56
+ true_predictions,
57
+ chosen_labels=['SHOP_NAME', 'ADDR', 'TITLE', 'PHONE',
58
+ 'PRODUCT_NAME', 'AMOUNT', 'UNIT', 'UPRICE', 'SUB_TPRICE', 'UDISCOUNT',
59
+ 'TAMOUNT', 'TPRICE', 'FPRICE', 'TDISCOUNT',
60
+ 'RECEMONEY', 'REMAMONEY',
61
+ 'BILLID', 'DATETIME', 'CASHIER']
62
+ ):
63
+
64
+ data = {'text': [], 'class_label': [], 'product_id': []}
65
+ product_id = -1
66
+ for text, prediction in zip(true_texts, true_predictions):
67
+ if prediction not in chosen_labels:
68
+ continue
69
+
70
+ if prediction == 'PRODUCT_NAME':
71
+ product_id += 1
72
+
73
+
74
+ if prediction in ['AMOUNT', 'UNIT', 'UDISCOUNT', 'UPRICE', 'SUB_TPRICE',
75
+ 'UDISCOUNT', 'TAMOUNT', 'TPRICE', 'FPRICE', 'TDISCOUNT',
76
+ 'RECEMONEY', 'REMAMONEY']:
77
+ text = reformat(text)
78
+
79
+
80
+ if prediction in ['AMOUNT', 'SUB_TPRICE', 'UPRICE', 'PRODUCT_NAME']:
81
+ data['product_id'].append(product_id)
82
+ else:
83
+ data['product_id'].append('')
84
+
85
+
86
+ data['class_label'].append(prediction)
87
+ data['text'].append(text)
88
+
89
+
90
+ df = pd.DataFrame(data)
91
+
92
+ return df
93
+
94
+
95
+ def reformat(text: str):
96
+ try:
97
+ text = text.replace('.', '').replace(',', '').replace(':', '').replace('/', '').replace('|', '').replace(
98
+ '\\', '').replace(')', '').replace('(', '').replace('-', '').replace(';', '').replace('_', '')
99
+ return int(text)
100
+ except:
101
+ return text
102
+
103
+ def find_product(product_name, df):
104
+ product_name = product_name.lower()
105
+ product_df = df[df['class_label'] == 'PRODUCT_NAME']
106
+ mask = product_df['text'].str.lower().str.contains(product_name, case=False, na=False)
107
+ if mask.any():
108
+ product_id = product_df.loc[mask, 'product_id'].iloc[0]
109
+ product_info = df[df['product_id'] == product_id]
110
+
111
+ prod_name = product_info.loc[product_info['class_label'] == 'PRODUCT_NAME', 'text'].iloc[0]
112
+
113
+ try:
114
+ amount = product_info.loc[product_info['class_label'] == 'AMOUNT', 'text'].iloc[0]
115
+ except:
116
+ print("Error: cannot find amount")
117
+ amount = ''
118
+
119
+ try:
120
+ uprice = product_info.loc[product_info['class_label'] == 'UPRICE', 'text'].iloc[0]
121
+ except:
122
+ print("Error: cannot find unit price")
123
+ uprice = ''
124
+
125
+ try:
126
+ sub_tprice = product_info.loc[product_info['class_label'] == 'SUB_TPRICE', 'text'].iloc[0]
127
+ except:
128
+ print("Error: cannot find sub total price")
129
+ sub_tprice = ''
130
+
131
+ #print("Sản phẩm: ", product_info.loc[product_info['class_label'] == 'PRODUCT_NAME', 'text'].iloc[0])
132
+ #print("Số lượng: ", product_info.loc[product_info['class_label'] == 'AMOUNT', 'text'].iloc[0])
133
+ #print("Đơn giá: ", product_info.loc[product_info['class_label'] == 'UPRICE', 'text'].iloc[0])
134
+ #print("Thành tiền: ", product_info.loc[product_info['class_label'] == 'SUB_TPRICE', 'text'].iloc[0])
135
+ return f"Sản phẩm: {prod_name}\n Số lượng: {amount}\n Đơn giá: {uprice}\n Thành tiền: {sub_tprice}"
136
+ else:
137
+ #print("Không tìm thấy item nào phù hợp.")
138
+ return "Không tìm thấy item nào phù hợp."
139
+ #return result = product_df['text'].str.contains(product_name, case=False, na=False).any()
140
+ #return product_df[product_df['text'].str.contains(product_name, case=False, na=False)]