acverma commited on
Commit
3e11b40
1 Parent(s): c900483
Files changed (1) hide show
  1. app.py +78 -55
app.py CHANGED
@@ -20,13 +20,13 @@ os.system('pip install torch==1.8.0+cu101 torchvision==0.9.0+cu101 -f https://do
20
  os.system('pip install -q detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu101/torch1.8/index.html')
21
  os.system('pip install -q pytesseract')
22
 
23
- #!pip install gradio
24
 
25
- #!pip install -q git+https://github.com/huggingface/transformers.git
26
 
27
- #!pip install h5py
28
 
29
- #!pip install -q datasets seqeval
30
 
31
  import gradio as gr
32
 
@@ -42,19 +42,16 @@ from transformers import AutoProcessor
42
  from datasets import Features, Sequence, ClassLabel, Value, Array2D, Array3D
43
  from datasets import load_dataset # this dataset uses the new Image feature :)
44
 
45
- from transformers import LayoutLMv3ForTokenClassification
46
- from transformers import AutoModelForTokenClassification
47
 
48
  #import cv2
49
  from PIL import Image, ImageDraw, ImageFont
50
 
51
- dataset = load_dataset("nielsr/funsd-layoutlmv3")
52
-
53
- example = dataset["test"][0]
54
 
55
- #image_path = "/root/.cache/huggingface/datasets/nielsr___funsd-layoutlmv3/funsd/1.0.0/0e3f4efdfd59aa1c3b4952c517894f7b1fc4d75c12ef01bcc8626a69e41c1bb9/funsd-layoutlmv3-test.arrow"
56
 
57
- image_path = '/root/.cache/huggingface/datasets/nielsr___funsd-layoutlmv3/funsd/1.0.0/0e3f4efdfd59aa1c3b4952c517894f7b1fc4d75c12ef01bcc8626a69e41c1bb9'
58
 
59
  example = dataset["test"][0]
60
  example["image"].save("example1.png")
@@ -65,22 +62,23 @@ example1["image"].save("example2.png")
65
  example2 = dataset["test"][2]
66
  example2["image"].save("example3.png")
67
 
68
- example2["image"]
69
 
70
- #Image.open(dataset[2][image_path]).convert("RGB").save("example1.png")
71
- #Image.open(dataset[1]["image_path"]).convert("RGB").save("example2.png")
72
- #Image.open(dataset[0]["image_path"]).convert("RGB").save("example3.png")
73
 
74
  words, boxes, ner_tags = example["tokens"], example["bboxes"], example["ner_tags"]
75
 
76
  features = dataset["test"].features
77
 
78
  column_names = dataset["test"].column_names
 
79
  image_column_name = "image"
80
  text_column_name = "tokens"
81
  boxes_column_name = "bboxes"
82
  label_column_name = "ner_tags"
83
 
 
 
84
  def get_label_list(labels):
85
  unique_labels = set()
86
  for label in labels:
@@ -100,24 +98,34 @@ else:
100
  label2id = {v: k for k,v in enumerate(label_list)}
101
  num_labels = len(label_list)
102
 
103
- label2color = {'question':'blue', 'answer':'green', 'header':'orange', 'other':'violet'}
 
 
 
 
 
 
104
 
105
- def prepare_examples(examples):
106
- images = examples[image_column_name]
107
- words = examples[text_column_name]
108
- boxes = examples[boxes_column_name]
109
- word_labels = examples[label_column_name]
110
 
111
- encoding = processor(images, words, boxes=boxes, word_labels=word_labels,
112
- truncation=True, padding="max_length")
 
 
 
 
 
113
 
114
- return encoding
 
 
 
 
115
 
116
- processor = AutoProcessor.from_pretrained("microsoft/layoutlmv3-base", apply_ocr=False)
 
117
 
118
- model = LayoutLMv3ForTokenClassification.from_pretrained("microsoft/layoutlmv3-base",
119
- id2label=id2label,
120
- label2id=label2id)
121
 
122
  # we need to define custom features for `set_format` (used later on) to work properly
123
  features = Features({
@@ -128,22 +136,44 @@ features = Features({
128
  'labels': Sequence(feature=Value(dtype='int64')),
129
  })
130
 
131
- eval_dataset = dataset["test"].map(
132
- prepare_examples,
133
- batched=True,
134
- remove_columns=column_names,
135
- features=features,
136
- )
137
 
138
- def unnormalize_box(bbox, width, height):
139
- return [
140
- width * (bbox[0] / 1000),
141
- height * (bbox[1] / 1000),
142
- width * (bbox[2] / 1000),
143
- height * (bbox[3] / 1000),
144
- ]
145
 
146
- def process_image(image):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
  print(type(image))
149
  width, height = image.size
@@ -157,11 +187,6 @@ def process_image(image):
157
  print(k,v.shape)
158
 
159
  # encode
160
- #encoding = processor(image, truncation=True, return_offsets_mapping=True, return_tensors="pt")
161
- #offset_mapping = encoding.pop('offset_mapping')
162
-
163
- #encoding = processor(image, words, truncation=True,boxes=boxes, word_labels=word_labels,return_offsets_mapping=True, return_tensors="pt")
164
- #offset_mapping = encoding.pop('offset_mapping')
165
 
166
  encoding = processor(image, truncation=True,boxes=boxes, word_labels=word_labels,return_offsets_mapping=True, return_tensors="pt")
167
  offset_mapping = encoding.pop('offset_mapping')
@@ -185,11 +210,7 @@ def process_image(image):
185
  token_boxes = encoding.bbox.squeeze().tolist()
186
  width, height = image.size
187
 
188
- #true_predictions = [model.config.id2label[pred] for pred, label in zip(predictions, labels) if label != - 100]
189
- #true_labels = [model.config.id2label[label] for prediction, label in zip(predictions, labels) if label != -100]
190
- #true_boxes = [unnormalize_box(box, width, height) for box, label in zip(token_boxes, labels) if label != -100]
191
-
192
-
193
  # only keep non-subword predictions
194
  is_subword = np.array(offset_mapping.squeeze().tolist())[:,0] != 0
195
  true_predictions = [id2label[pred] for idx, pred in enumerate(predictions) if not is_subword[idx]]
@@ -205,7 +226,7 @@ def process_image(image):
205
 
206
  return image
207
 
208
- title = "DocumentAI - Extraction of Key Information using LayoutLMv3 model"
209
  description = "Extraction of Form or Invoice Extraction - We use Microsoft's LayoutLMv3 trained on Invoice Dataset to predict the Biller Name, Biller Address, Biller post_code, Due_date, GST, Invoice_date, Invoice_number, Subtotal and Total. To use it, simply upload an image or use the example image below. Results will show up in a few seconds."
210
 
211
  article="<b>References</b><br>[1] Y. Xu et al., “LayoutLMv3: Pre-training for Document AI with Unified Text and Image Masking.” 2022. <a href='https://arxiv.org/abs/2204.08387'>Paper Link</a><br>[2] <a href='https://github.com/NielsRogge/Transformers-Tutorials/tree/master/LayoutLMv3'>LayoutLMv3 training and inference</a>"
@@ -216,7 +237,7 @@ css = """.output_image, .input_image {height: 600px !important}"""
216
 
217
  iface = gr.Interface(fn=process_image,
218
  inputs=gr.inputs.Image(type="pil"),
219
- outputs=gr.outputs.Image(type="pil", label="annotated predict image"),
220
  title=title,
221
  description=description,
222
  article=article,
@@ -225,4 +246,6 @@ iface = gr.Interface(fn=process_image,
225
  analytics_enabled = True, enable_queue=True
226
  )
227
 
228
- iface.launch(inline=False, share=False, debug=False)
 
 
 
20
  os.system('pip install -q detectron2 -f https://dl.fbaipublicfiles.com/detectron2/wheels/cu101/torch1.8/index.html')
21
  os.system('pip install -q pytesseract')
22
 
23
+ !pip install gradio
24
 
25
+ !pip install -q git+https://github.com/huggingface/transformers.git
26
 
27
+ !pip install h5py
28
 
29
+ !pip install -q datasets seqeval
30
 
31
  import gradio as gr
32
 
 
42
  from datasets import Features, Sequence, ClassLabel, Value, Array2D, Array3D
43
  from datasets import load_dataset # this dataset uses the new Image feature :)
44
 
45
+ from transformers import LayoutLMv3Processor, LayoutLMv3ForTokenClassification
 
46
 
47
  #import cv2
48
  from PIL import Image, ImageDraw, ImageFont
49
 
50
+ processor = LayoutLMv3Processor.from_pretrained("microsoft/layoutlmv3-base",apply_ocr = True)
 
 
51
 
52
+ model = LayoutLMv3ForTokenClassification.from_pretrained("microsoft/layoutlmv3-base")
53
 
54
+ dataset = load_dataset("nielsr/funsd-layoutlmv3")
55
 
56
  example = dataset["test"][0]
57
  example["image"].save("example1.png")
 
62
  example2 = dataset["test"][2]
63
  example2["image"].save("example3.png")
64
 
65
+ #example2["image"]
66
 
67
+ labels = dataset["test"].features['ner_tags'].feature.names
 
 
68
 
69
  words, boxes, ner_tags = example["tokens"], example["bboxes"], example["ner_tags"]
70
 
71
  features = dataset["test"].features
72
 
73
  column_names = dataset["test"].column_names
74
+
75
  image_column_name = "image"
76
  text_column_name = "tokens"
77
  boxes_column_name = "bboxes"
78
  label_column_name = "ner_tags"
79
 
80
+ # In the event the labels are not a `Sequence[ClassLabel]`, we will need to go through the dataset to get the
81
+ # unique labels.
82
  def get_label_list(labels):
83
  unique_labels = set()
84
  for label in labels:
 
98
  label2id = {v: k for k,v in enumerate(label_list)}
99
  num_labels = len(label_list)
100
 
101
+ def get_label_list(labels):
102
+ unique_labels = set()
103
+ for label in labels:
104
+ unique_labels = unique_labels | set(label)
105
+ label_list = list(unique_labels)
106
+ label_list.sort()
107
+ return label_list
108
 
109
+ label2color = {'question':'blue', 'answer':'green', 'header':'orange', 'other':'violet'}
 
 
 
 
110
 
111
+ def unnormalize_box(bbox, width, height):
112
+ return [
113
+ width * (bbox[0] / 1000),
114
+ height * (bbox[1] / 1000),
115
+ width * (bbox[2] / 1000),
116
+ height * (bbox[3] / 1000),
117
+ ]
118
 
119
+ #def prepare_examples(examples):
120
+ # images = examples[image_column_name]
121
+ # words = examples[text_column_name]
122
+ # boxes = examples[boxes_column_name]
123
+ # word_labels = examples[label_column_name]
124
 
125
+ # encoding = processor(images, words, boxes=boxes, word_labels=word_labels,
126
+ # truncation=True, padding="max_length")
127
 
128
+ # return encoding
 
 
129
 
130
  # we need to define custom features for `set_format` (used later on) to work properly
131
  features = Features({
 
136
  'labels': Sequence(feature=Value(dtype='int64')),
137
  })
138
 
139
+ def process_image(image):
140
+ width, height = image.size
 
 
 
 
141
 
142
+ # encode
143
+ encoding = processor(image, truncation=True, return_offsets_mapping=True, return_tensors="pt")
144
+ offset_mapping = encoding.pop('offset_mapping')
 
 
 
 
145
 
146
+ # forward pass
147
+ outputs = model(**encoding)
148
+
149
+ # get predictions
150
+ predictions = outputs.logits.argmax(-1).squeeze().tolist()
151
+ token_boxes = encoding.bbox.squeeze().tolist()
152
+
153
+ # only keep non-subword predictions
154
+ is_subword = np.array(offset_mapping.squeeze().tolist())[:,0] != 0
155
+ true_predictions = [id2label[pred] for idx, pred in enumerate(predictions) if not is_subword[idx]]
156
+ true_boxes = [unnormalize_box(box, width, height) for idx, box in enumerate(token_boxes) if not is_subword[idx]]
157
+
158
+ # draw predictions over the image
159
+ draw = ImageDraw.Draw(image)
160
+ font = ImageFont.load_default()
161
+
162
+ def iob_to_label(label):
163
+ label = label[2:]
164
+ if not label:
165
+ return 'other'
166
+ return label
167
+
168
+ label2color = {'question':'blue', 'answer':'green', 'header':'orange', 'other':'violet'}
169
+ for prediction, box in zip(true_predictions, true_boxes):
170
+ predicted_label = iob_to_label(prediction) #.lower()
171
+ draw.rectangle(box, outline=label2color[predicted_label])
172
+ draw.text((box[0]+10, box[1]-10), text=predicted_label, fill=label2color[predicted_label], font=font)
173
+
174
+ return image
175
+
176
+ #def process_image(image):
177
 
178
  print(type(image))
179
  width, height = image.size
 
187
  print(k,v.shape)
188
 
189
  # encode
 
 
 
 
 
190
 
191
  encoding = processor(image, truncation=True,boxes=boxes, word_labels=word_labels,return_offsets_mapping=True, return_tensors="pt")
192
  offset_mapping = encoding.pop('offset_mapping')
 
210
  token_boxes = encoding.bbox.squeeze().tolist()
211
  width, height = image.size
212
 
213
+
 
 
 
 
214
  # only keep non-subword predictions
215
  is_subword = np.array(offset_mapping.squeeze().tolist())[:,0] != 0
216
  true_predictions = [id2label[pred] for idx, pred in enumerate(predictions) if not is_subword[idx]]
 
226
 
227
  return image
228
 
229
+ title = "DocumentAI - Extraction using LayoutLMv3 model"
230
  description = "Extraction of Form or Invoice Extraction - We use Microsoft's LayoutLMv3 trained on Invoice Dataset to predict the Biller Name, Biller Address, Biller post_code, Due_date, GST, Invoice_date, Invoice_number, Subtotal and Total. To use it, simply upload an image or use the example image below. Results will show up in a few seconds."
231
 
232
  article="<b>References</b><br>[1] Y. Xu et al., “LayoutLMv3: Pre-training for Document AI with Unified Text and Image Masking.” 2022. <a href='https://arxiv.org/abs/2204.08387'>Paper Link</a><br>[2] <a href='https://github.com/NielsRogge/Transformers-Tutorials/tree/master/LayoutLMv3'>LayoutLMv3 training and inference</a>"
 
237
 
238
  iface = gr.Interface(fn=process_image,
239
  inputs=gr.inputs.Image(type="pil"),
240
+ outputs=gr.outputs.Image(type="pil", label="annotated image"),
241
  title=title,
242
  description=description,
243
  article=article,
 
246
  analytics_enabled = True, enable_queue=True
247
  )
248
 
249
+ #iface.launch(inline=False, share=False, debug=False)
250
+
251
+ iface.launch(inline=False)