decimer 2.5.0__tar.gz → 2.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/DECIMER_EfficinetNetV2_Transfomer_Trainer.py +17 -19
  2. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/Predictor_usingCheckpoints.py +11 -16
  3. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/Repack_model.py +25 -20
  4. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/Utils/Create_image_tokenizer.py +1 -1
  5. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/__init__.py +29 -32
  6. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/config.py +34 -33
  7. decimer-2.7.0/DECIMER/decimer.py +171 -0
  8. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/efficientnetv2/effnetv2_configs.py +2 -1
  9. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/efficientnetv2/effnetv2_model.py +1 -1
  10. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/efficientnetv2/hparams.py +4 -1
  11. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/efficientnetv2/utils.py +10 -4
  12. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/utils.py +28 -20
  13. {decimer-2.5.0/decimer.egg-info → decimer-2.7.0}/PKG-INFO +3 -3
  14. {decimer-2.5.0 → decimer-2.7.0}/README.md +1 -1
  15. {decimer-2.5.0 → decimer-2.7.0/decimer.egg-info}/PKG-INFO +3 -3
  16. {decimer-2.5.0 → decimer-2.7.0}/decimer.egg-info/SOURCES.txt +1 -0
  17. decimer-2.7.0/decimer.egg-info/entry_points.txt +2 -0
  18. {decimer-2.5.0 → decimer-2.7.0}/decimer.egg-info/requires.txt +1 -1
  19. {decimer-2.5.0 → decimer-2.7.0}/setup.py +55 -52
  20. decimer-2.5.0/DECIMER/decimer.py +0 -162
  21. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/Efficient_Net_encoder.py +0 -0
  22. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/Transformer_decoder.py +0 -0
  23. {decimer-2.5.0 → decimer-2.7.0}/DECIMER/Utils/Create_TFrecord_From_pickles.py +0 -0
  24. {decimer-2.5.0 → decimer-2.7.0}/LICENSE +0 -0
  25. {decimer-2.5.0 → decimer-2.7.0}/decimer.egg-info/dependency_links.txt +0 -0
  26. {decimer-2.5.0 → decimer-2.7.0}/decimer.egg-info/top_level.txt +0 -0
  27. {decimer-2.5.0 → decimer-2.7.0}/setup.cfg +0 -0
@@ -76,8 +76,8 @@ AUTO = tf.data.experimental.AUTOTUNE
76
76
 
77
77
 
78
78
  def decode_image(image_data):
79
- """Preprocess the input image for Efficient-Net and
80
- returned the preprocessed image
79
+ """Preprocess the input image for Efficient-Net and returned the
80
+ preprocessed image.
81
81
 
82
82
  Args:
83
83
  image_data (int array): Decoded image in 2D array
@@ -98,8 +98,8 @@ def decode_image(image_data):
98
98
 
99
99
 
100
100
  def read_tfrecord(example):
101
- """Read a tf record file and decodes the image and text data
102
- back into original form.
101
+ """Read a tf record file and decodes the image and text data back into
102
+ original form.
103
103
 
104
104
  Args:
105
105
  example (tf.record): single entry from tf record file
@@ -124,7 +124,7 @@ numbers = re.compile(r"(\d+)")
124
124
 
125
125
 
126
126
  def numericalSort(value):
127
- """Sorts the filenames numerically
127
+ """Sorts the filenames numerically.
128
128
 
129
129
  Args:
130
130
  value (int): numerical value of the file name
@@ -138,7 +138,7 @@ def numericalSort(value):
138
138
 
139
139
 
140
140
  def get_dataset(batch_size=BATCH_SIZE, buffered_size=BUFFER_SIZE, path=""):
141
- """Creates a batch of data rom a given dataset
141
+ """Creates a batch of data rom a given dataset.
142
142
 
143
143
  Args:
144
144
  batch_size (int, optional): number of datapoints per batch. Defaults to BATCH_SIZE.
@@ -207,8 +207,8 @@ print("Training preparation\n")
207
207
 
208
208
 
209
209
  def prepare_for_training(lr_config, encoder_config, transformer_config, verbose=0):
210
- """Preparte the model for training. initiate the learning rate, loss object, metrics
211
- and optimizer
210
+ """Preparte the model for training. initiate the learning rate, loss
211
+ object, metrics and optimizer.
212
212
 
213
213
  Args:
214
214
  lr_config (int): values for learning rate configuration
@@ -239,20 +239,18 @@ def prepare_for_training(lr_config, encoder_config, transformer_config, verbose=
239
239
  train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(
240
240
  name="train_accuracy", dtype=tf.float32
241
241
  )
242
- """
243
- validation_loss = tf.keras.metrics.Mean(
244
- name="validation_loss", dtype=tf.float32
245
- )
246
- validation_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(
247
- name="validation_accuracy", dtype=tf.float32
248
- )
242
+ """validation_loss = tf.keras.metrics.Mean(
243
+
244
+ name="validation_loss", dtype=tf.float32 ) validation_accuracy =
245
+ tf.keras.metrics.SparseCategoricalAccuracy(
246
+ name="validation_accuracy", dtype=tf.float32 )
249
247
  """
250
248
  # Declare the learning rate schedule (try this as actual lr schedule and list...)
251
249
  lr_scheduler = config.CustomSchedule(
252
250
  transformer_config["d_model"], lr_config["warm_steps"]
253
251
  )
254
252
 
255
- # Instiate an optimizer
253
+ # Instantiate an optimizer
256
254
  optimizer = tf.keras.optimizers.Adam(
257
255
  lr_scheduler, beta_1=0.9, beta_2=0.98, epsilon=1e-9
258
256
  )
@@ -325,9 +323,9 @@ if ckpt_manager.latest_checkpoint:
325
323
  start_epoch = int(ckpt_manager.latest_checkpoint.split("-")[-1])
326
324
 
327
325
 
328
- # Main training step fucntion
326
+ # Main training step function
329
327
  def train_step(image_batch, selfies_batch):
330
- """Main training step function
328
+ """Main training step function.
331
329
 
332
330
  Args:
333
331
  image_batch (float array): Input image batch
@@ -378,7 +376,7 @@ def dist_train_step(image_batch, selfies_batch):
378
376
 
379
377
 
380
378
  """
381
- # Main validation step fucntion
379
+ # Main validation step function
382
380
  def validation_step(image_batch, selfies_batch):
383
381
 
384
382
  selfies_batch_input = selfies_batch[:, :-1]
@@ -45,7 +45,7 @@ tokenizer = pickle.load(
45
45
 
46
46
  max_length = 302
47
47
 
48
- # Image partameters
48
+ # Image parameters
49
49
  IMG_EMB_DIM = (16, 16, 512)
50
50
  IMG_EMB_DIM = (IMG_EMB_DIM[0] * IMG_EMB_DIM[1], IMG_EMB_DIM[2])
51
51
  IMG_SHAPE = (512, 512, 3)
@@ -130,9 +130,8 @@ class DECIMER_Predictor(tf.Module):
130
130
  self.max_length = max_length
131
131
 
132
132
  def __call__(self, Decoded_image):
133
- """
134
- Run the DECIMER predictor model when called.
135
- Usage of predict_SMILES or predict_SMILES_with_confidence is recommended instead
133
+ """Run the DECIMER predictor model when called. Usage of predict_SMILES
134
+ or predict_SMILES_with_confidence is recommended instead.
136
135
 
137
136
  Args:
138
137
  Decoded_image (_type_): output of config.decode_image
@@ -180,9 +179,8 @@ class DECIMER_Predictor(tf.Module):
180
179
 
181
180
 
182
181
  def detokenize_output(predicted_array: tf.Tensor) -> str:
183
- """
184
- This function takes the predicted array of tokens and returns the predicted SMILES
185
- string.
182
+ """This function takes the predicted array of tokens and returns the
183
+ predicted SMILES string.
186
184
 
187
185
  Args:
188
186
  predicted_array (tf.Tensor): Transformer Decoder output array (predicted tokens)
@@ -203,11 +201,10 @@ def detokenize_output_add_confidence(
203
201
  predicted_array: tf.Tensor,
204
202
  confidence_array: tf.Tensor,
205
203
  ) -> List[Tuple[str, float]]:
206
- """
207
- This function takes the predicted array of tokens as well as the confidence values
208
- returned by the Transformer Decoder and returns a list of tuples
209
- that contain each token of the predicted SMILES string and the confidence
210
- value.
204
+ """This function takes the predicted array of tokens as well as the
205
+ confidence values returned by the Transformer Decoder and returns a list of
206
+ tuples that contain each token of the predicted SMILES string and the
207
+ confidence value.
211
208
 
212
209
  Args:
213
210
  predicted_array (tf.Tensor): Transformer Decoder output array (predicted tokens)
@@ -234,8 +231,7 @@ DECIMER = DECIMER_Predictor(encoder, tokenizer, transformer, MAX_LEN)
234
231
 
235
232
 
236
233
  def predict_SMILES_with_confidence(image_path: str) -> List[Tuple[str, float]]:
237
- """
238
- This function takes an image path (str) and returns a list of tuples
234
+ """This function takes an image path (str) and returns a list of tuples
239
235
  that contain each token of the predicted SMILES string and the confidence
240
236
  level from the last layer of the Transformer decoder.
241
237
 
@@ -255,8 +251,7 @@ def predict_SMILES_with_confidence(image_path: str) -> List[Tuple[str, float]]:
255
251
 
256
252
 
257
253
  def predict_SMILES(image_path: str) -> str:
258
- """
259
- This function takes an image path (str) and returns the SMILES
254
+ """This function takes an image path (str) and returns the SMILES
260
255
  representation of the depicted molecule (str).
261
256
 
262
257
  Args:
@@ -87,9 +87,8 @@ if ckpt_manager.latest_checkpoint:
87
87
 
88
88
 
89
89
  def detokenize_output(predicted_array: tf.Tensor) -> str:
90
- """
91
- This function takes the predicted array of tokens and returns the predicted SMILES
92
- string.
90
+ """This function takes the predicted array of tokens and returns the
91
+ predicted SMILES string.
93
92
 
94
93
  Args:
95
94
  predicted_array (tf.Tensor): Transformer Decoder output array (predicted tokens)
@@ -110,11 +109,10 @@ def detokenize_output_add_confidence(
110
109
  predicted_array: tf.Tensor,
111
110
  confidence_array: tf.Tensor,
112
111
  ) -> List[Tuple[str, float]]:
113
- """
114
- This function takes the predicted array of tokens as well as the confidence values
115
- returned by the Transformer Decoder and returns a list of tuples
116
- that contain each token of the predicted SMILES string and the confidence
117
- value.
112
+ """This function takes the predicted array of tokens as well as the
113
+ confidence values returned by the Transformer Decoder and returns a list of
114
+ tuples that contain each token of the predicted SMILES string and the
115
+ confidence value.
118
116
 
119
117
  Args:
120
118
  predicted_array (tf.Tensor): Transformer Decoder output array (predicted tokens)
@@ -137,18 +135,22 @@ def detokenize_output_add_confidence(
137
135
 
138
136
 
139
137
  class DECIMER_Predictor(tf.Module):
140
- """This is a class which takes care of inference. It loads the saved checkpoint and the necessary
141
- tokenizers. The inference begins with the start token (<start>) and ends when the end token(<end>)
142
- is met. This class can only work with tf.Tensor objects. The strings shoul gets transformed into np.arrays
143
- before feeding them into this class.
138
+ """This is a class which takes care of inference.
139
+
140
+ It loads the saved checkpoint and the necessary tokenizers. The
141
+ inference begins with the start token (<start>) and ends when the
142
+ end token(<end>) is met. This class can only work with tf.Tensor
143
+ objects. The strings should get transformed into np.arrays before
144
+ feeding them into this class.
144
145
  """
145
146
 
146
147
  def __init__(self, encoder, tokenizer, transformer, max_length):
147
- """Load the tokenizers, the maximum input and output length and the model.
148
+ """Load the tokenizers, the maximum input and output length and the
149
+ model.
148
150
 
149
151
  Args:
150
152
  encoder (tf.keras.model): The encoder model
151
- tokenizer (tf.keras.tokenizer): Output tokenizer, defines which charater is assigned to what token
153
+ tokenizer (tf.keras.tokenizer): Output tokenizer, defines which character is assigned to what token
152
154
  transformer (tf.keras.model): The transformer model
153
155
  max_length (int): Maximum length of a string which can get predicted
154
156
  """
@@ -158,8 +160,8 @@ class DECIMER_Predictor(tf.Module):
158
160
  self.max_length = max_length
159
161
 
160
162
  def __call__(self, Decoded_image):
161
- """This fuction takes in the Decoded image as input and
162
- makes the predicted list of tokens and return the tokens as tf.Tensor array.
163
+ """This function takes in the Decoded image as input and makes the
164
+ predicted list of tokens and return the tokens as tf.Tensor array.
163
165
  Before feeding the input array we must define start and the end tokens.
164
166
 
165
167
  Args:
@@ -211,7 +213,9 @@ DECIMER = DECIMER_Predictor(encoder, tokenizer, transformer, MAX_LEN)
211
213
 
212
214
 
213
215
  class ExportDECIMERPredictor(tf.Module):
214
- """This class wraps the inference class into a module into tf.Module sub-class, with a tf.function on the __call__ method.
216
+ """This class wraps the inference class into a module into tf.Module sub-
217
+ class, with a tf.function on the __call__ method.
218
+
215
219
  So we could export the model as a tf.saved_model.
216
220
  """
217
221
 
@@ -221,9 +225,10 @@ class ExportDECIMERPredictor(tf.Module):
221
225
 
222
226
  @tf.function
223
227
  def __call__(self, Decoded_Image):
224
- """This fucntion calls the __call__function from the translator class.
225
- In the tf.function only the output sentence is returned.
226
- Thanks to the non-strict execution in tf.function any unnecessary values are never computed.
228
+ """This function calls the __call__function from the translator class.
229
+ In the tf.function only the output sentence is returned. Thanks to the
230
+ non-strict execution in tf.function any unnecessary values are never
231
+ computed.
227
232
 
228
233
  Args:
229
234
  sentence (tf.Tensor[tf.int32]): Input array in tf.Easgertensor format.
@@ -70,7 +70,7 @@ def data_loader(Smiles_Path):
70
70
  all_img_name = []
71
71
 
72
72
  for line in smiles.split("\n"):
73
- # Split the ID and SMILES to seperate tokens
73
+ # Split the ID and SMILES to separate tokens
74
74
  tokens = line.split(",")
75
75
 
76
76
  image_id = str(tokens[0]) + ".png"
@@ -1,32 +1,29 @@
1
- # -*- coding: utf-8 -*-
2
- """
3
- DECIMER V2.4.0 Python Package.
4
- ============================
5
-
6
- This repository contains DECIMER-V2,Deep lEarning for Chemical ImagE Recognition) project
7
- was launched to address the OCSR problem with the latest computational intelligence methods
8
- to provide an automated open-source software solution.
9
-
10
-
11
- Typical usage example:
12
-
13
- from decimer import predict_SMILES
14
-
15
- # Chemical depiction to SMILES translation
16
- image_path = "path/to/imagefile"
17
- SMILES = predict_SMILES(image_path)
18
- print(SMILES)
19
-
20
- For comments, bug reports or feature ideas,
21
- please raise a issue on the Github repository.
22
-
23
- """
24
-
25
- __version__ = "2.4.0"
26
-
27
- __all__ = [
28
- "DECIMER",
29
- ]
30
-
31
-
32
- from .decimer import predict_SMILES, predict_SMILES_with_confidence
1
+ # -*- coding: utf-8 -*-
2
+ """DECIMER V2.6.0 Python Package. ============================
3
+
4
+ This repository contains DECIMER-V2,Deep lEarning for Chemical ImagE Recognition) project
5
+ was launched to address the OCSR problem with the latest computational intelligence methods
6
+ to provide an automated open-source software solution.
7
+
8
+
9
+ Typical usage example:
10
+
11
+ from decimer import predict_SMILES
12
+
13
+ # Chemical depiction to SMILES translation
14
+ image_path = "path/to/imagefile"
15
+ SMILES = predict_SMILES(image_path)
16
+ print(SMILES)
17
+
18
+ For comments, bug reports or feature ideas,
19
+ please raise a issue on the Github repository.
20
+ """
21
+
22
+ __version__ = "2.6.0"
23
+
24
+ __all__ = [
25
+ "DECIMER",
26
+ ]
27
+
28
+
29
+ from .decimer import predict_SMILES
@@ -20,9 +20,10 @@ TARGET_DTYPE = tf.float32
20
20
 
21
21
 
22
22
  def resize_byratio(image):
23
- """
24
- This function takes a Pillow Image object and will resize the image by 512 x 512
25
- To upscale or to downscale the image LANCZOS resampling method is used.
23
+ """This function takes a Pillow Image object and will resize the image by
24
+ 512 x 512 To upscale or to downscale the image LANCZOS resampling method is
25
+ used.
26
+
26
27
  with the new pillow version the antialias is turned on when using LANCZOS.
27
28
  Args: PIL.Image
28
29
  Returns: PIL.Image
@@ -35,10 +36,10 @@ def resize_byratio(image):
35
36
 
36
37
 
37
38
  def central_square_image(image):
38
- """
39
- This function takes a Pillow Image object and will add white padding
40
- so that the image has a square shape with the width/height of the longest side
39
+ """This function takes a Pillow Image object and will add white padding so
40
+ that the image has a square shape with the width/height of the longest side
41
41
  of the original image.
42
+
42
43
  Args: PIL.Image
43
44
  Returns: PIL.Image
44
45
  """
@@ -59,6 +60,7 @@ def central_square_image(image):
59
60
  def delete_empty_borders(image):
60
61
  """This function takes a Pillow Image object, converts it to grayscale and
61
62
  deletes white space at the borders.
63
+
62
64
  Args: PIL.Image
63
65
  Returns: PIL.Image
64
66
  """
@@ -132,8 +134,8 @@ def get_bnw_image(image):
132
134
 
133
135
 
134
136
  def increase_contrast(image):
135
- """
136
- This function increases the contrast of an image input.
137
+ """This function increases the contrast of an image input.
138
+
137
139
  Args: PIL.Image
138
140
  Returns: PIL.Image
139
141
  """
@@ -153,8 +155,9 @@ def increase_contrast(image):
153
155
 
154
156
 
155
157
  def get_resize(image):
156
- """
157
- This function used to decide how to resize a given image without losing much information.
158
+ """This function used to decide how to resize a given image without losing
159
+ much information.
160
+
158
161
  Args: PIL.Image
159
162
  Returns: PIL.Image
160
163
  """
@@ -172,8 +175,8 @@ def get_resize(image):
172
175
 
173
176
 
174
177
  def increase_brightness(image):
175
- """
176
- This function adjusts the brightness of the given image.
178
+ """This function adjusts the brightness of the given image.
179
+
177
180
  Args: PIL.Image
178
181
  Returns: PIL.Image
179
182
  """
@@ -183,8 +186,8 @@ def increase_brightness(image):
183
186
 
184
187
 
185
188
  def decode_image(image_path: str):
186
- """
187
- Loads an image and preprocesses the input image in several steps to get the image ready for DECIMER input.
189
+ """Loads an image and preprocesses the input image in several steps to get
190
+ the image ready for DECIMER input.
188
191
 
189
192
  Args:
190
193
  image_path (str): path of input image
@@ -207,9 +210,7 @@ def decode_image(image_path: str):
207
210
 
208
211
 
209
212
  class Config:
210
- """
211
- Configuration class
212
- """
213
+ """Configuration class."""
213
214
 
214
215
  def __init__(
215
216
  self,
@@ -227,11 +228,11 @@ class Config:
227
228
  do_permute=False,
228
229
  pretrained_weights=None,
229
230
  ):
230
- """This functions initializes the Efficient-Net V2 encoder with user defined
231
- configurations.
231
+ """This functions initializes the Efficient-Net V2 encoder with user
232
+ defined configurations.
232
233
 
233
234
  Args:
234
- image_embedding_dim (int): Embedding dimention of the input image
235
+ image_embedding_dim (int): Embedding dimension of the input image
235
236
  preprocessing_fn (method): Efficient Net preprocessing function for input image
236
237
  backbone_fn (method): Calls Efficient-Net V2 as backbone for encoder
237
238
  image_shape (int): Shape of the input image
@@ -257,9 +258,8 @@ class Config:
257
258
  image_embedding_dim,
258
259
  rate=0.1,
259
260
  ):
260
- """This functions initializes the Transformer model as decoder with user defined
261
- configurations.
262
-
261
+ """This functions initializes the Transformer model as decoder with
262
+ user defined configurations.
263
263
 
264
264
  Args:
265
265
  vocab_len (int): Total number of words in the input vocabulary
@@ -267,7 +267,7 @@ class Config:
267
267
  n_transformer_layers (int): Number of layers present in the transformer model
268
268
  transformer_d_dff (int): Transformer feed forward upwards projection size
269
269
  transformer_n_heads (int): Number of heads present in the transformer model
270
- image_embedding_dim (int): Total number of dimension the image gets embeddeded
270
+ image_embedding_dim (int): Total number of dimension the image gets embedded
271
271
  dropout_rate (float, optional): Fraction of the input units to drop. Defaults to 0.1.
272
272
  """
273
273
  self.transformer_config = dict(
@@ -281,7 +281,7 @@ class Config:
281
281
  )
282
282
 
283
283
  def initialize_lr_config(self, warm_steps, n_epochs):
284
- """This function sets the configuration to initialize learning rate
284
+ """This function sets the configuration to initialize learning rate.
285
285
 
286
286
  Args:
287
287
  warm_steps (int): Number of steps The learning rate is increased
@@ -294,7 +294,7 @@ class Config:
294
294
 
295
295
 
296
296
  class CustomSchedule(tf.keras.optimizers.schedules.LearningRateSchedule):
297
- """Custom schedule for learning rate used during training
297
+ """Custom schedule for learning rate used during training.
298
298
 
299
299
  Args:
300
300
  tf (_type_): keras learning rate schedule
@@ -316,9 +316,9 @@ class CustomSchedule(tf.keras.optimizers.schedules.LearningRateSchedule):
316
316
 
317
317
 
318
318
  def prepare_models(encoder_config, transformer_config, replica_batch_size, verbose=0):
319
- """This function is used to initiate the Encoder and the Transformer with appropriate
320
- configs set by the user. After initiating the models this function returns the Encoder,Transformer
321
- and the optimizer.
319
+ """This function is used to initiate the Encoder and the Transformer with
320
+ appropriate configs set by the user. After initiating the models this
321
+ function returns the Encoder,Transformer and the optimizer.
322
322
 
323
323
  Args:
324
324
  encoder_config ([type]): Encoder configuration set by user in the config class.
@@ -330,7 +330,7 @@ def prepare_models(encoder_config, transformer_config, replica_batch_size, verbo
330
330
  [type]: Optimizer, Encoder model and the Transformer
331
331
  """
332
332
 
333
- # Instiate an optimizer
333
+ # Instantiate an optimizer
334
334
  optimizer = tf.keras.optimizers.Adam(learning_rate=0.00051)
335
335
 
336
336
  # Instantiate the encoder model
@@ -353,9 +353,10 @@ def prepare_models(encoder_config, transformer_config, replica_batch_size, verbo
353
353
 
354
354
  # Downloads the model and unzips the file downloaded, if the model is not present on the working directory.
355
355
  def download_trained_weights(model_url: str, model_path: str, verbose=1):
356
- """This function downloads the trained models and tokenizers to a default location.
357
- After downloading the zipped file the function unzips the file automatically.
358
- If the model exists on the default location this function will not work.
356
+ """This function downloads the trained models and tokenizers to a default
357
+ location. After downloading the zipped file the function unzips the file
358
+ automatically. If the model exists on the default location this function
359
+ will not work.
359
360
 
360
361
  Args:
361
362
  model_url (str): trained model url for downloading.
@@ -0,0 +1,171 @@
1
+ import logging
2
+ import os
3
+ import pickle
4
+ import sys
5
+ from typing import List
6
+ from typing import Tuple
7
+
8
+ import pystow
9
+ import tensorflow as tf
10
+
11
+ import DECIMER.config as config
12
+ import DECIMER.utils as utils
13
+
14
+ # Silence tensorflow model loading warnings.
15
+ logging.getLogger("absl").setLevel("ERROR")
16
+
17
+ # Silence tensorflow errors - not recommended if your model is not working properly.
18
+ os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
19
+
20
+ # Set the absolute path
21
+ HERE = os.path.dirname(os.path.abspath(__file__))
22
+
23
+ # Set model to run on default GPU and allow memory to grow as much as needed.
24
+ # This allows us to run multiple instances of inference in the same GPU.
25
+ os.environ["CUDA_VISIBLE_DEVICES"] = "0"
26
+ gpus = tf.config.experimental.list_physical_devices("GPU")
27
+ for gpu in gpus:
28
+ tf.config.experimental.set_memory_growth(gpu, True)
29
+
30
+ # Set path
31
+ default_path = pystow.join("DECIMER-V2")
32
+
33
+ model_urls = {
34
+ "DECIMER": "https://zenodo.org/record/8300489/files/models.zip",
35
+ "DECIMER_HandDrawn": "https://zenodo.org/records/10781330/files/DECIMER_HandDrawn_model.zip",
36
+ }
37
+
38
+
39
+ def get_models(model_urls: dict):
40
+ """Download and load models from the provided URLs.
41
+
42
+ This function downloads models from the provided URLs to a default location,
43
+ then loads tokenizers and TensorFlow saved models.
44
+
45
+ Args:
46
+ model_urls (dict): A dictionary containing model names as keys and their corresponding URLs as values.
47
+
48
+ Returns:
49
+ tuple: A tuple containing loaded tokenizer and TensorFlow saved models.
50
+ - tokenizer (object): Tokenizer for DECIMER model.
51
+ - DECIMER_V2 (tf.saved_model): TensorFlow saved model for DECIMER.
52
+ - DECIMER_Hand_drawn (tf.saved_model): TensorFlow saved model for DECIMER HandDrawn.
53
+ """
54
+ # Download models to a default location
55
+ model_paths = utils.ensure_models(default_path=default_path, model_urls=model_urls)
56
+
57
+ # Load tokenizers
58
+ tokenizer_path = os.path.join(
59
+ model_paths["DECIMER"], "assets", "tokenizer_SMILES.pkl"
60
+ )
61
+ tokenizer = pickle.load(open(tokenizer_path, "rb"))
62
+
63
+ # Load DECIMER models
64
+ DECIMER_V2 = tf.saved_model.load(model_paths["DECIMER"])
65
+ DECIMER_Hand_drawn = tf.saved_model.load(model_paths["DECIMER_HandDrawn"])
66
+
67
+ return tokenizer, DECIMER_V2, DECIMER_Hand_drawn
68
+
69
+
70
+ tokenizer, DECIMER_V2, DECIMER_Hand_drawn = get_models(model_urls)
71
+
72
+
73
+ def detokenize_output(predicted_array: int) -> str:
74
+ """This function takes the predicted tokens from the DECIMER model and
75
+ returns the decoded SMILES string.
76
+
77
+ Args:
78
+ predicted_array (int): Predicted tokens from DECIMER
79
+
80
+ Returns:
81
+ (str): SMILES representation of the molecule
82
+ """
83
+ outputs = [tokenizer.index_word[i] for i in predicted_array[0].numpy()]
84
+ prediction = (
85
+ "".join([str(elem) for elem in outputs])
86
+ .replace("<start>", "")
87
+ .replace("<end>", "")
88
+ )
89
+ return prediction
90
+
91
+
92
+ def detokenize_output_add_confidence(
93
+ predicted_array: tf.Tensor,
94
+ confidence_array: tf.Tensor,
95
+ ) -> List[Tuple[str, float]]:
96
+ """This function takes the predicted array of tokens as well as the
97
+ confidence values returned by the Transformer Decoder and returns a list of
98
+ tuples that contain each token of the predicted SMILES string and the
99
+ confidence value.
100
+
101
+ Args:
102
+ predicted_array (tf.Tensor): Transformer Decoder output array (predicted tokens)
103
+
104
+ Returns:
105
+ str: SMILES string
106
+ """
107
+ prediction_with_confidence = [
108
+ (
109
+ tokenizer.index_word[predicted_array[0].numpy()[i]],
110
+ confidence_array[i].numpy(),
111
+ )
112
+ for i in range(len(confidence_array))
113
+ ]
114
+ # remove start and end tokens
115
+ prediction_with_confidence_ = prediction_with_confidence[1:-1]
116
+
117
+ decoded_prediction_with_confidence = list(
118
+ [(utils.decoder(tok), conf) for tok, conf in prediction_with_confidence_]
119
+ )
120
+
121
+ return decoded_prediction_with_confidence
122
+
123
+
124
+ def predict_SMILES(
125
+ image_path: str, confidence: bool = False, hand_drawn: bool = False
126
+ ) -> str:
127
+ """Predicts SMILES representation of a molecule depicted in the given image.
128
+
129
+ Args:
130
+ image_path (str): Path of chemical structure depiction image
131
+ confidence (bool): Flag to indicate whether to return confidence values along with SMILES prediction
132
+ hand_drawn (bool): Flag to indicate whether the molecule in the image is hand-drawn
133
+
134
+ Returns:
135
+ str: SMILES representation of the molecule in the input image, optionally with confidence values
136
+ """
137
+ chemical_structure = config.decode_image(image_path)
138
+
139
+ model = DECIMER_Hand_drawn if hand_drawn else DECIMER_V2
140
+ predicted_tokens, confidence_values = model(tf.constant(chemical_structure))
141
+
142
+ predicted_SMILES = utils.decoder(detokenize_output(predicted_tokens))
143
+
144
+ if confidence:
145
+ predicted_SMILES_with_confidence = detokenize_output_add_confidence(
146
+ predicted_tokens, confidence_values
147
+ )
148
+ return predicted_SMILES, predicted_SMILES_with_confidence
149
+
150
+ return predicted_SMILES
151
+
152
+
153
+ def main():
154
+ """This function take the path of the image as user input and returns the
155
+ predicted SMILES as output in CLI.
156
+
157
+ Agrs:
158
+ str: image_path
159
+
160
+ Returns:
161
+ str: predicted SMILES
162
+ """
163
+ if len(sys.argv) != 2:
164
+ print("Usage: {} $image_path".format(sys.argv[0]))
165
+ else:
166
+ SMILES = predict_SMILES(sys.argv[1])
167
+ print(SMILES)
168
+
169
+
170
+ if __name__ == "__main__":
171
+ main()
@@ -63,7 +63,8 @@ class BlockDecoder(object):
63
63
  return "_".join(args)
64
64
 
65
65
  def decode(self, string_list):
66
- """Decodes a list of string notations to specify blocks inside the network.
66
+ """Decodes a list of string notations to specify blocks inside the
67
+ network.
67
68
 
68
69
  Args:
69
70
  string_list: a list of strings, each string is a notation of block.
@@ -180,7 +180,7 @@ class MBConvBlock(tf.keras.layers.Layer):
180
180
 
181
181
  self.endpoints = None
182
182
 
183
- # Builds the block accordings to arguments.
183
+ # Builds the block according to arguments.
184
184
  self._build()
185
185
 
186
186
  @property
@@ -158,7 +158,10 @@ class Config(dict):
158
158
  yaml.dump(self.as_dict(), f, default_flow_style=False)
159
159
 
160
160
  def parse_from_str(self, config_str: Text) -> Dict[Any, Any]:
161
- """Parse a string like 'x.y=1,x.z=2' to nested dict {x: {y: 1, z: 2}}."""
161
+ """Parse a string like 'x.y=1,x.z=2' to nested dict {x: {y: 1, z:
162
+
163
+ 2}}.
164
+ """
162
165
  if not config_str:
163
166
  return {}
164
167
  config_dict = {}
@@ -192,7 +192,8 @@ class TpuBatchNormalization(tf.keras.layers.BatchNormalization):
192
192
  super().__init__(fused=fused, **kwargs)
193
193
 
194
194
  def _moments(self, inputs, reduction_axes, keep_dims):
195
- """Compute the mean and variance: it overrides the original _moments."""
195
+ """Compute the mean and variance: it overrides the original
196
+ _moments."""
196
197
  shard_mean, shard_variance = super()._moments(
197
198
  inputs, reduction_axes, keep_dims=keep_dims
198
199
  )
@@ -222,7 +223,8 @@ class TpuBatchNormalization(tf.keras.layers.BatchNormalization):
222
223
 
223
224
 
224
225
  class BatchNormalization(tf.keras.layers.BatchNormalization):
225
- """Fixed default name of BatchNormalization to match TpuBatchNormalization."""
226
+ """Fixed default name of BatchNormalization to match
227
+ TpuBatchNormalization."""
226
228
 
227
229
  def __init__(self, **kwargs):
228
230
  if not kwargs.get("name", None):
@@ -371,7 +373,10 @@ def get_tpu_host_call(global_step, model_dir, iterations_per_loop):
371
373
  return None # No summaries to write.
372
374
 
373
375
  def host_call_fn(global_step, *args):
374
- """Training host call. Creates summaries for training metrics."""
376
+ """Training host call.
377
+
378
+ Creates summaries for training metrics.
379
+ """
375
380
  gs = global_step[0]
376
381
  with tf.summary.create_file_writer(
377
382
  model_dir, max_queue=iterations_per_loop
@@ -594,7 +599,8 @@ def restore_tf2_ckpt(model, ckpt_path_or_file, skip_mismatch=True, exclude_layer
594
599
 
595
600
 
596
601
  class ReuableBackupAndRestore(tf.keras.callbacks.experimental.BackupAndRestore):
597
- """A BackupAndRestore callback that can be used across multiple model.fit()s."""
602
+ """A BackupAndRestore callback that can be used across multiple
603
+ model.fit()s."""
598
604
 
599
605
  def on_train_end(self, logs=None):
600
606
  # don't delete the backup, so it can be used for future model.fit()s
@@ -63,27 +63,35 @@ def decoder(predictions):
63
63
  return modified
64
64
 
65
65
 
66
- def ensure_model(
67
- default_path: str,
68
- model_url: str = "https://zenodo.org/record/8300489/files/models.zip",
69
- ):
70
- """Function to ensure model is present locally
66
+ def ensure_models(default_path: str, model_urls: dict) -> dict:
67
+ """Function to ensure models are present locally.
71
68
 
72
- Convenient function to ensure model download before usage
69
+ Convenient function to ensure model downloads before usage
73
70
 
74
71
  Args:
75
- default path (str): default path for DECIMER data
76
- model_url (str): trained model url for downloading
77
- """
72
+ default_path (str): Default path for model data
73
+ model_urls (dict): Dictionary containing model names as keys and their corresponding URLs as values
78
74
 
79
- model_path = os.path.join(default_path.as_posix(), "DECIMER_model")
80
- print(model_path)
81
-
82
- if (
83
- os.path.exists(model_path)
84
- and os.stat(os.path.join(model_path, "saved_model.pb")).st_size != 28080309
85
- ):
86
- shutil.rmtree(model_path)
87
- config.download_trained_weights(model_url, default_path)
88
- elif not os.path.exists(model_path):
89
- config.download_trained_weights(model_url, default_path)
75
+ Returns:
76
+ dict: A dictionary containing model names as keys and their local paths as values
77
+ """
78
+ model_paths = {}
79
+ # Store st_size of each model
80
+ model_sizes = {
81
+ "DECIMER": 28080309,
82
+ "DECIMER_HandDrawn": 28080328,
83
+ }
84
+ for model_name, model_url in model_urls.items():
85
+ model_path = os.path.join(default_path, f"{model_name}_model")
86
+ if os.path.exists(model_path) and os.stat(
87
+ os.path.join(model_path, "saved_model.pb")
88
+ ).st_size != model_sizes.get(model_name):
89
+ print(f"Working with model {model_name}")
90
+ shutil.rmtree(model_path)
91
+ config.download_trained_weights(model_url, default_path)
92
+ elif not os.path.exists(model_path):
93
+ config.download_trained_weights(model_url, default_path)
94
+
95
+ # Store the model path
96
+ model_paths[model_name] = model_path
97
+ return model_paths
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: decimer
3
- Version: 2.5.0
4
- Summary: DECIMER 2.4.0: Deep Learning for Chemical Image Recognition using Efficient-Net V2 + Transformer
3
+ Version: 2.7.0
4
+ Summary: DECIMER 2.6.0: Deep Learning for Chemical Image Recognition using Efficient-Net V2 + Transformer
5
5
  Home-page: https://github.com/Kohulan/DECIMER-Image_Transformer
6
6
  Author: Kohulan Rajan
7
7
  Author-email: kohulan.rajan@uni-jena.de
@@ -111,7 +111,7 @@ print(SMILES)
111
111
  - This project is licensed under the MIT License - see the [LICENSE](https://raw.githubusercontent.com/Kohulan/DECIMER-Image_Transformer/master/LICENSE?token=AHKLIF3EULMCUKCFUHIPBMDARSMDO) file for details
112
112
 
113
113
  ## Citation
114
- - Rajan K, Brinkhaus HO, Agea MI, Zielesny A, Steinbeck C (2023) DECIMER.ai - An open platform for automated optical chemical structure identification, segmentation and recognition in scientific publications. ChemRxiv. doi: https://10.26434/chemrxiv-2023-xhcx9
114
+ - Rajan K, Brinkhaus HO, Agea MI, Zielesny A, Steinbeck C DECIMER.ai - An open platform for automated optical chemical structure identification, segmentation and recognition in scientific publications. Nat. Commun. 14, 5045 (2023). https://doi.org/10.1038/s41467-023-40782-0
115
115
  - Rajan, K., Zielesny, A. & Steinbeck, C. DECIMER 1.0: deep learning for chemical image recognition using transformers. J Cheminform 13, 61 (2021). https://doi.org/10.1186/s13321-021-00538-8
116
116
 
117
117
  ## References
@@ -87,7 +87,7 @@ print(SMILES)
87
87
  - This project is licensed under the MIT License - see the [LICENSE](https://raw.githubusercontent.com/Kohulan/DECIMER-Image_Transformer/master/LICENSE?token=AHKLIF3EULMCUKCFUHIPBMDARSMDO) file for details
88
88
 
89
89
  ## Citation
90
- - Rajan K, Brinkhaus HO, Agea MI, Zielesny A, Steinbeck C (2023) DECIMER.ai - An open platform for automated optical chemical structure identification, segmentation and recognition in scientific publications. ChemRxiv. doi: https://10.26434/chemrxiv-2023-xhcx9
90
+ - Rajan K, Brinkhaus HO, Agea MI, Zielesny A, Steinbeck C DECIMER.ai - An open platform for automated optical chemical structure identification, segmentation and recognition in scientific publications. Nat. Commun. 14, 5045 (2023). https://doi.org/10.1038/s41467-023-40782-0
91
91
  - Rajan, K., Zielesny, A. & Steinbeck, C. DECIMER 1.0: deep learning for chemical image recognition using transformers. J Cheminform 13, 61 (2021). https://doi.org/10.1186/s13321-021-00538-8
92
92
 
93
93
  ## References
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: decimer
3
- Version: 2.5.0
4
- Summary: DECIMER 2.4.0: Deep Learning for Chemical Image Recognition using Efficient-Net V2 + Transformer
3
+ Version: 2.7.0
4
+ Summary: DECIMER 2.6.0: Deep Learning for Chemical Image Recognition using Efficient-Net V2 + Transformer
5
5
  Home-page: https://github.com/Kohulan/DECIMER-Image_Transformer
6
6
  Author: Kohulan Rajan
7
7
  Author-email: kohulan.rajan@uni-jena.de
@@ -111,7 +111,7 @@ print(SMILES)
111
111
  - This project is licensed under the MIT License - see the [LICENSE](https://raw.githubusercontent.com/Kohulan/DECIMER-Image_Transformer/master/LICENSE?token=AHKLIF3EULMCUKCFUHIPBMDARSMDO) file for details
112
112
 
113
113
  ## Citation
114
- - Rajan K, Brinkhaus HO, Agea MI, Zielesny A, Steinbeck C (2023) DECIMER.ai - An open platform for automated optical chemical structure identification, segmentation and recognition in scientific publications. ChemRxiv. doi: https://10.26434/chemrxiv-2023-xhcx9
114
+ - Rajan K, Brinkhaus HO, Agea MI, Zielesny A, Steinbeck C DECIMER.ai - An open platform for automated optical chemical structure identification, segmentation and recognition in scientific publications. Nat. Commun. 14, 5045 (2023). https://doi.org/10.1038/s41467-023-40782-0
115
115
  - Rajan, K., Zielesny, A. & Steinbeck, C. DECIMER 1.0: deep learning for chemical image recognition using transformers. J Cheminform 13, 61 (2021). https://doi.org/10.1186/s13321-021-00538-8
116
116
 
117
117
  ## References
@@ -19,5 +19,6 @@ DECIMER/efficientnetv2/utils.py
19
19
  decimer.egg-info/PKG-INFO
20
20
  decimer.egg-info/SOURCES.txt
21
21
  decimer.egg-info/dependency_links.txt
22
+ decimer.egg-info/entry_points.txt
22
23
  decimer.egg-info/requires.txt
23
24
  decimer.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ decimer = DECIMER.decimer:main
@@ -1,4 +1,4 @@
1
- tensorflow==2.12.0
1
+ tensorflow<=2.15.0,>=2.12.0
2
2
  opencv-python
3
3
  pystow
4
4
  pillow-heif
@@ -1,52 +1,55 @@
1
- #!/usr/bin/env python
2
- import platform
3
-
4
- import setuptools
5
-
6
- if (
7
- platform.processor() == "arm" or platform.processor() == "i386"
8
- ) and platform.system() == "Darwin":
9
- tensorflow_os = "tensorflow-macos>=2.10.0"
10
- else:
11
- tensorflow_os = "tensorflow==2.12.0"
12
-
13
- with open("README.md", "r") as fh:
14
- long_description = fh.read()
15
-
16
- setuptools.setup(
17
- name="decimer",
18
- version="2.5.0",
19
- author="Kohulan Rajan",
20
- author_email="kohulan.rajan@uni-jena.de",
21
- maintainer="Kohulan Rajan, Otto Brinkhaus ",
22
- maintainer_email="kohulan.rajan@uni-jena.de, otto.brinkhaus@uni-jena.de",
23
- description="DECIMER 2.4.0: Deep Learning for Chemical Image Recognition using Efficient-Net V2 + Transformer",
24
- long_description=long_description,
25
- long_description_content_type="text/markdown",
26
- url="https://github.com/Kohulan/DECIMER-Image_Transformer",
27
- packages=setuptools.find_packages(),
28
- license="MIT",
29
- install_requires=[
30
- tensorflow_os,
31
- "opencv-python",
32
- "pystow",
33
- "pillow-heif",
34
- "efficientnet",
35
- "selfies",
36
- "pyyaml",
37
- ],
38
- package_data={"DECIMER": ["repack/*.*", "efficientnetv2/*.*", "Utils/*.*"]},
39
- classifiers=[
40
- "Programming Language :: Python :: 3",
41
- "Programming Language :: Python :: 3.5",
42
- "Programming Language :: Python :: 3.6",
43
- "Programming Language :: Python :: 3.7",
44
- "Programming Language :: Python :: 3.8",
45
- "Programming Language :: Python :: 3.9",
46
- "Programming Language :: Python :: 3.10",
47
- "Programming Language :: Python :: 3 :: Only",
48
- "License :: OSI Approved :: MIT License",
49
- "Operating System :: OS Independent",
50
- ],
51
- python_requires=">=3.5",
52
- )
1
+ #!/usr/bin/env python
2
+ import platform
3
+
4
+ import setuptools
5
+
6
+ if (
7
+ platform.processor() == "arm" or platform.processor() == "i386"
8
+ ) and platform.system() == "Darwin":
9
+ tensorflow_os = "tensorflow-macos>=2.10.0,<=2.15.0"
10
+ else:
11
+ tensorflow_os = "tensorflow>=2.12.0,<=2.15.0"
12
+
13
+ with open("README.md", "r") as fh:
14
+ long_description = fh.read()
15
+
16
+ setuptools.setup(
17
+ name="decimer",
18
+ version="2.7.0",
19
+ author="Kohulan Rajan",
20
+ author_email="kohulan.rajan@uni-jena.de",
21
+ maintainer="Kohulan Rajan, Otto Brinkhaus ",
22
+ maintainer_email="kohulan.rajan@uni-jena.de, otto.brinkhaus@uni-jena.de",
23
+ description="DECIMER 2.6.0: Deep Learning for Chemical Image Recognition using Efficient-Net V2 + Transformer",
24
+ long_description=long_description,
25
+ long_description_content_type="text/markdown",
26
+ entry_points={
27
+ "console_scripts": ["decimer = DECIMER.decimer:main"],
28
+ },
29
+ url="https://github.com/Kohulan/DECIMER-Image_Transformer",
30
+ packages=setuptools.find_packages(),
31
+ license="MIT",
32
+ install_requires=[
33
+ tensorflow_os,
34
+ "opencv-python",
35
+ "pystow",
36
+ "pillow-heif",
37
+ "efficientnet",
38
+ "selfies",
39
+ "pyyaml",
40
+ ],
41
+ package_data={"DECIMER": ["repack/*.*", "efficientnetv2/*.*", "Utils/*.*"]},
42
+ classifiers=[
43
+ "Programming Language :: Python :: 3",
44
+ "Programming Language :: Python :: 3.5",
45
+ "Programming Language :: Python :: 3.6",
46
+ "Programming Language :: Python :: 3.7",
47
+ "Programming Language :: Python :: 3.8",
48
+ "Programming Language :: Python :: 3.9",
49
+ "Programming Language :: Python :: 3.10",
50
+ "Programming Language :: Python :: 3 :: Only",
51
+ "License :: OSI Approved :: MIT License",
52
+ "Operating System :: OS Independent",
53
+ ],
54
+ python_requires=">=3.5",
55
+ )
@@ -1,162 +0,0 @@
1
- import logging
2
- import os
3
- import pickle
4
- import sys
5
- from typing import List
6
- from typing import Tuple
7
-
8
- import pystow
9
- import tensorflow as tf
10
-
11
- import DECIMER.config as config
12
- import DECIMER.utils as utils
13
-
14
- # Silence tensorflow model loading warnings.
15
- logging.getLogger("absl").setLevel("ERROR")
16
-
17
- # Silence tensorflow errors - not recommended if your model is not working properly.
18
- os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
19
-
20
- # Set the absolute path
21
- HERE = os.path.dirname(os.path.abspath(__file__))
22
-
23
- # Set model to run on default GPU and allow memory to grow as much as needed.
24
- # This allows us to run multiple instances of inference in the same GPU.
25
- os.environ["CUDA_VISIBLE_DEVICES"] = "0"
26
- gpus = tf.config.experimental.list_physical_devices("GPU")
27
- for gpu in gpus:
28
- tf.config.experimental.set_memory_growth(gpu, True)
29
-
30
- # Set path
31
- default_path = pystow.join("DECIMER-V2")
32
-
33
- # download models to a default location
34
- utils.ensure_model(default_path=default_path)
35
-
36
- # Load important pickle files which consists the tokenizers and the maxlength setting
37
- tokenizer = pickle.load(
38
- open(
39
- os.path.join(
40
- default_path.as_posix(), "DECIMER_model", "assets", "tokenizer_SMILES.pkl"
41
- ),
42
- "rb",
43
- )
44
- )
45
-
46
-
47
- def main():
48
- """
49
- This function take the path of the image as user input
50
- and returns the predicted SMILES as output in CLI.
51
-
52
- Agrs:
53
- str: image_path
54
-
55
- Returns:
56
- str: predicted SMILES
57
-
58
- """
59
- if len(sys.argv) != 2:
60
- print("Usage: {} $image_path".format(sys.argv[0]))
61
- else:
62
- SMILES = predict_SMILES(sys.argv[1])
63
- print(SMILES)
64
-
65
-
66
- def detokenize_output(predicted_array: int) -> str:
67
- """
68
- This function takes the predited tokens from the DECIMER model
69
- and returns the decoded SMILES string.
70
-
71
- Args:
72
- predicted_array (int): Predicted tokens from DECIMER
73
-
74
- Returns:
75
- (str): SMILES representation of the molecule
76
- """
77
- outputs = [tokenizer.index_word[i] for i in predicted_array[0].numpy()]
78
- prediction = (
79
- "".join([str(elem) for elem in outputs])
80
- .replace("<start>", "")
81
- .replace("<end>", "")
82
- )
83
- return prediction
84
-
85
-
86
- def detokenize_output_add_confidence(
87
- predicted_array: tf.Tensor,
88
- confidence_array: tf.Tensor,
89
- ) -> List[Tuple[str, float]]:
90
- """
91
- This function takes the predicted array of tokens as well as the confidence values
92
- returned by the Transformer Decoder and returns a list of tuples
93
- that contain each token of the predicted SMILES string and the confidence
94
- value.
95
-
96
- Args:
97
- predicted_array (tf.Tensor): Transformer Decoder output array (predicted tokens)
98
-
99
- Returns:
100
- str: SMILES string
101
- """
102
- prediction_with_confidence = [
103
- (
104
- tokenizer.index_word[predicted_array[0].numpy()[i]],
105
- confidence_array[i].numpy(),
106
- )
107
- for i in range(len(confidence_array))
108
- ]
109
- # remove start and end tokens
110
- prediction_with_confidence_ = prediction_with_confidence[1:-1]
111
-
112
- decoded_prediction_with_confidence = list(
113
- [(utils.decoder(tok), conf) for tok, conf in prediction_with_confidence_]
114
- )
115
- decoded_prediction_with_confidence.append(prediction_with_confidence_[-1])
116
- return decoded_prediction_with_confidence
117
-
118
-
119
- # Load DECIMER model_packed
120
- DECIMER_V2 = tf.saved_model.load(default_path.as_posix() + "/DECIMER_model/")
121
-
122
-
123
- def predict_SMILES(image_path: str) -> str:
124
- """
125
- This function takes an image path (str) and returns the SMILES
126
- representation of the depicted molecule (str).
127
-
128
- Args:
129
- image_path (str): Path of chemical structure depiction image
130
-
131
- Returns:
132
- (str): SMILES representation of the molecule in the input image
133
- """
134
- chemical_structure = config.decode_image(image_path)
135
- predicted_tokens, _ = DECIMER_V2(chemical_structure)
136
- predicted_SMILES = utils.decoder(detokenize_output(predicted_tokens))
137
- return predicted_SMILES
138
-
139
-
140
- def predict_SMILES_with_confidence(image_path: str) -> List[Tuple[str, float]]:
141
- """
142
- This function takes an image path (str) and returns a list of tuples
143
- that contain each token of the predicted SMILES string and the confidence
144
- level from the last layer of the Transformer decoder.
145
-
146
- Args:
147
- image_path (str): Path of chemical structure depiction image
148
-
149
- Returns:
150
- (List[Tuple[str, float]]): Tuples that contain the tokens and the confidence
151
- values of the predicted SMILES
152
- """
153
- decodedImage = config.decode_image(image_path)
154
- predicted_tokens, confidence_values = DECIMER_V2(tf.constant(decodedImage))
155
- predicted_SMILES_with_confidence = detokenize_output_add_confidence(
156
- predicted_tokens, confidence_values
157
- )
158
- return predicted_SMILES_with_confidence
159
-
160
-
161
- if __name__ == "__main__":
162
- main()
File without changes
File without changes