SicheateR99 commited on
Commit
bca2e1d
·
verified ·
1 Parent(s): b1746dd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -33
app.py CHANGED
@@ -1,8 +1,6 @@
1
  import os
2
  import re
3
  import pickle
4
- import json
5
- import zipfile
6
  import numpy as np
7
  import tensorflow as tf
8
  from fastapi import FastAPI
@@ -40,7 +38,7 @@ class TextRequest(BaseModel):
40
  text: str
41
 
42
  # =========================================================
43
- # JURUS 1: BYPASS ARSITEKTUR MANUAL UNTUK NER (Anti-Error LSTM)
44
  # =========================================================
45
  def build_manual_ner_model(vocab_size=7929, max_len=64, num_classes=8):
46
  inputs = tf.keras.Input(shape=(max_len,), dtype='int32', name='tokens')
@@ -68,49 +66,49 @@ def build_manual_ner_model(vocab_size=7929, max_len=64, num_classes=8):
68
  def get_ner_model():
69
  global ner_model, vocab
70
  if ner_model is None:
71
- with open("vocab.pkl", "rb") as f:
72
  vocab = pickle.load(f)
73
- # Load kerangka manual, isi dengan weights
74
  ner_model = build_manual_ner_model()
75
  ner_model.load_weights("receipt_ner_model.keras")
76
  return ner_model, vocab
77
 
78
  # =========================================================
79
- # JURUS 2: BEDAH JSON UNTUK KLASIFIKASI (Menyelamatkan Kamus Kata)
80
  # =========================================================
81
- def patch_keras_model(original_path):
82
- patched_path = "patched_" + original_path
83
- if os.path.exists(patched_path): return patched_path
 
 
 
 
 
 
 
 
 
84
 
85
- try:
86
- with zipfile.ZipFile(original_path, 'r') as zin:
87
- with zipfile.ZipFile(patched_path, 'w') as zout:
88
- for item in zin.infolist():
89
- content = zin.read(item.filename)
90
- if item.filename == 'config.json':
91
- config_dict = json.loads(content.decode('utf-8'))
92
- def hapus_biang_kerok(d):
93
- if isinstance(d, dict):
94
- d.pop('quantization_config', None)
95
- for v in d.values(): hapus_biang_kerok(v)
96
- elif isinstance(d, list):
97
- for i in d: hapus_biang_kerok(i)
98
- hapus_biang_kerok(config_dict)
99
- content = json.dumps(config_dict).encode('utf-8')
100
- zout.writestr(item, content)
101
- return patched_path
102
- except Exception as e:
103
- print(f"Gagal membedah model: {e}")
104
- return original_path
105
 
106
  def get_clf_model():
107
  global clf_model, clf_encoder
108
  if clf_model is None:
109
  with open('penerjemah_kategori.pkl', 'rb') as file:
110
  clf_encoder = pickle.load(file)
111
- # Bedah JSON lalu load utuh agar TextVectorization bekerja
112
- patched_file = patch_keras_model("model_strukly.keras")
113
- clf_model = tf.keras.models.load_model(patched_file, compile=False)
 
 
 
 
 
 
 
 
 
 
 
114
  return clf_model, clf_encoder
115
 
116
  # =========================================================
@@ -139,7 +137,7 @@ def predict_ner(request: TextRequest):
139
 
140
  if tokens:
141
  norm_tokens = [normalize_token(t) for t in tokens]
142
- # Karena pakai arsitektur manual, mask tidak perlu dibuat eksplisit (otomatis di layer Embedding)
143
  X = np.zeros((1, MAX_SEQ_LEN), dtype=np.int32)
144
  length = min(len(norm_tokens), MAX_SEQ_LEN)
145
 
 
1
  import os
2
  import re
3
  import pickle
 
 
4
  import numpy as np
5
  import tensorflow as tf
6
  from fastapi import FastAPI
 
38
  text: str
39
 
40
  # =========================================================
41
+ # JURUS 1: BYPASS NER
42
  # =========================================================
43
  def build_manual_ner_model(vocab_size=7929, max_len=64, num_classes=8):
44
  inputs = tf.keras.Input(shape=(max_len,), dtype='int32', name='tokens')
 
66
  def get_ner_model():
67
  global ner_model, vocab
68
  if ner_model is None:
69
+ with open("data/processed/vocab.pkl", "rb") as f:
70
  vocab = pickle.load(f)
 
71
  ner_model = build_manual_ner_model()
72
  ner_model.load_weights("receipt_ner_model.keras")
73
  return ner_model, vocab
74
 
75
  # =========================================================
76
+ # JURUS 2: BYPASS KLASIFIKASI + PAKSA BANGUN KAMUS
77
  # =========================================================
78
+ def build_manual_clf_model():
79
+ inputs = tf.keras.Input(shape=(1,), dtype=tf.string, name='input_layer')
80
+ x = tf.keras.layers.TextVectorization(
81
+ max_tokens=5000,
82
+ output_sequence_length=50,
83
+ name='text_vectorization'
84
+ )(inputs)
85
+ x = tf.keras.layers.Embedding(input_dim=5000, output_dim=64, name='embedding')(x)
86
+ x = tf.keras.layers.GlobalAveragePooling1D(name='global_average_pooling1d')(x)
87
+ x = tf.keras.layers.Dense(64, activation='relu', name='dense')(x)
88
+ x = tf.keras.layers.Dropout(0.2, name='dropout')(x)
89
+ outputs = tf.keras.layers.Dense(7, activation='softmax', name='dense_1')(x)
90
 
91
+ return tf.keras.Model(inputs=inputs, outputs=outputs, name='functional')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  def get_clf_model():
94
  global clf_model, clf_encoder
95
  if clf_model is None:
96
  with open('penerjemah_kategori.pkl', 'rb') as file:
97
  clf_encoder = pickle.load(file)
98
+
99
+ clf_model = build_manual_clf_model()
100
+ clf_model.load_weights("model_strukly.keras")
101
+
102
+ # --- KODE AJAIB ANTI "Table not initialized" ---
103
+ tv_layer = clf_model.get_layer('text_vectorization')
104
+ weights = tv_layer.get_weights()
105
+ if weights:
106
+ # Ubah data bytes dari model kembali menjadi teks
107
+ vocab_list = [w.decode('utf-8') if isinstance(w, bytes) else str(w) for w in weights[0]]
108
+ # Paksa Keras membangun ulang tabelnya (Abaikan 2 token pertama: PAD dan UNK)
109
+ tv_layer.set_vocabulary(vocab_list[2:])
110
+ # -----------------------------------------------
111
+
112
  return clf_model, clf_encoder
113
 
114
  # =========================================================
 
137
 
138
  if tokens:
139
  norm_tokens = [normalize_token(t) for t in tokens]
140
+ # Inference NER pakai manual bypass, tidak perlu mask eksplisit
141
  X = np.zeros((1, MAX_SEQ_LEN), dtype=np.int32)
142
  length = min(len(norm_tokens), MAX_SEQ_LEN)
143