mubaraknumann commited on
Commit
b319248
·
verified ·
1 Parent(s): f4de3f1

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +67 -55
README.md CHANGED
@@ -1,6 +1,4 @@
1
  ---
2
- license: mit
3
- pipeline_tag: image-classification
4
  tags:
5
  - cloud
6
  - weather
@@ -8,7 +6,10 @@ tags:
8
  - cloud types
9
  - wmo
10
  - cloud image classification
 
 
11
  ---
 
12
  # Genera - Cloud Image Classification Model
13
 
14
  **Version:** 1.0.0
@@ -72,18 +73,22 @@ The model was trained on the **UGCI (Ultimate Ground-level Cloud Image) dataset*
72
 
73
  ## You can install necessary packages using pip:
74
 
75
- -- pip install tensorflow numpy Pillow
76
 
77
  ## Loading the Model
78
 
79
  The model is saved in the Keras native format (.keras). You will need to provide the definitions of the custom layers (RepVGGBlock and NECALayer) when loading.
80
 
81
- # IMPORTANT: You must have the RepVGGBlock and NECALayer class definitions
82
- # available in your Python environment before running this.
 
83
 
84
- # --- CUSTOM LAYER DEFINITIONS ---
85
- # --- RepVGGBlock Class Definition ---
86
- class RepVGGBlock(layers.Layer):
 
 
 
87
  def __init__(self, in_channels, out_channels, kernel_size=3, stride=1,
88
  groups=1, deploy=False, use_se=False, **kwargs):
89
  super(RepVGGBlock, self).__init__(**kwargs)
@@ -95,7 +100,7 @@ class RepVGGBlock(layers.Layer):
95
  self._deploy_mode_internal = deploy
96
  self.config_use_se = use_se # Placeholder, not used in this version of RepVGGBlock
97
  self.actual_in_channels = None
98
-
99
  self.rbr_dense_conv = layers.Conv2D(
100
  filters=self.config_out_channels, kernel_size=self.config_kernel_size,
101
  strides=self.config_strides_val, padding='same',
@@ -201,10 +206,11 @@ class RepVGGBlock(layers.Layer):
201
  return config
202
  @classmethod
203
  def from_config(cls, config): return cls(**config)
204
- # --- End of RepVGGBlock ---
 
 
205
 
206
- # --- NECALayer Class Definition ---
207
- class NECALayer(layers.Layer):
208
  def __init__(self, channels, gamma=2, b=1, **kwargs):
209
  super(NECALayer, self).__init__(**kwargs)
210
  self.channels = channels
@@ -220,7 +226,7 @@ class NECALayer(layers.Layer):
220
  self.gap = layers.GlobalAveragePooling2D(keepdims=True)
221
  self.conv1d = layers.Conv1D(filters=1, kernel_size=kernel_size_for_conv1d, padding='same', use_bias=False, name=self.name + '_eca_conv1d')
222
  self.sigmoid = layers.Activation('sigmoid')
223
-
224
  def call(self, inputs):
225
  if self.channels != inputs.shape[-1]: raise ValueError(f"Input channels {inputs.shape[-1]} != layer channels {self.channels} for {self.name}")
226
  x = self.gap(inputs)
@@ -238,36 +244,40 @@ class NECALayer(layers.Layer):
238
  return config
239
  @classmethod
240
  def from_config(cls, config): return cls(**config)
241
- # --- End of NECALayer ---
242
- # --- END OF CUSTOM LAYER DEFINITIONS ---
243
 
244
- import tensorflow as tf
245
- from tensorflow import keras
246
 
247
- MODEL_FILE = 'path/to/your/repvgg_neca_deploy_final.keras' # Replace with actual path
248
- LABEL_MAPPING_FILE = 'path/to/your/label_mapping.json' # Replace with actual path
249
 
250
- custom_objects = {'RepVGGBlock': RepVGGBlock, 'NECALayer': NECALayer}
251
- loaded_model = tf.keras.models.load_model(MODEL_FILE, custom_objects=custom_objects, compile=False)
252
- print("Model loaded successfully!")
253
- loaded_model.summary() # Optional: to see the loaded architecture
 
 
 
 
 
 
254
 
255
  # Load label mapping
256
- import json
257
- with open(LABEL_MAPPING_FILE, 'r') as f:
258
- label_map_data = json.load(f)
259
- int_to_label = {int(k): v for k, v in label_map_data['int_to_label'].items()}
260
 
261
  **Making Predictions**
262
- from PIL import Image
263
- import numpy as np
264
-
265
- def preprocess_image_for_prediction(image_path_or_pil_image, target_size=(299, 299)):
266
- if isinstance(image_path_or_pil_image, str):
267
- img = Image.open(image_path_or_pil_image)
268
- else: # Assuming PIL image
269
- img = image_path_or_pil_image
270
 
 
 
 
 
 
 
271
  img = img.convert('RGB') # Ensure 3 channels
272
  img = img.resize(target_size)
273
  img_array = np.array(img, dtype=np.float32)
@@ -275,24 +285,24 @@ def preprocess_image_for_prediction(image_path_or_pil_image, target_size=(299, 2
275
  img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
276
  return img_array
277
 
278
- # Example prediction:
279
- image_path = 'path/to/your/cloud_image.jpg' # Replace with your image path
280
- input_tensor = preprocess_image_for_prediction(image_path)
281
- predictions = loaded_model.predict(input_tensor)
282
- predicted_probabilities = predictions[0]
283
-
284
- # Get top prediction
285
- predicted_class_index = np.argmax(predicted_probabilities)
286
- predicted_class_name = int_to_label.get(predicted_class_index, "Unknown Class")
287
- confidence = predicted_probabilities[predicted_class_index]
288
-
289
- print(f"Predicted Cloud Type: {predicted_class_name}")
290
- print(f"Confidence: {confidence*100:.2f}%")
291
-
292
- # Display all class probabilities (optional)
293
- for i, prob in enumerate(predicted_probabilities):
294
- class_name = int_to_label.get(i, f"Class_{i}")
295
- print(f"- {class_name}: {prob*100:.2f}%")
296
 
297
  ## 4. Training Procedure
298
  Dataset: UGCI
@@ -347,6 +357,8 @@ Random Contrast adjustments (factor 0.3)
347
 
348
  Framework: TensorFlow/Keras
349
 
 
 
350
  Optimizer: AdamW (learning_rate=1e-4, weight_decay=5e-5)
351
 
352
  Loss Function: Sparse Categorical Crossentropy
@@ -361,7 +373,7 @@ EarlyStopping (monitoring val_loss, patience 20, restore_best_weights=True)
361
 
362
  ReduceLROnPlateau (monitoring val_loss, patience 10)
363
 
364
- Epochs: Trained for up to 150 epochs (EarlyStopping intervened). The best model was restored from Epoch 171 of the final run (adjust if different).
365
 
366
  Batch Size: 32
367
 
@@ -468,4 +480,4 @@ This project, including the model weights and source code, is licensed under the
468
 
469
  ## 11. Acknowledgements
470
 
471
- This work was inspired by the methodologies presented in "Improved RepVGG ground-based cloud image classification with attention convolution" by Shi et al. (2024).
 
1
  ---
 
 
2
  tags:
3
  - cloud
4
  - weather
 
6
  - cloud types
7
  - wmo
8
  - cloud image classification
9
+ license: mit
10
+ pipeline_tag: image-classification
11
  ---
12
+
13
  # Genera - Cloud Image Classification Model
14
 
15
  **Version:** 1.0.0
 
73
 
74
  ## You can install necessary packages using pip:
75
 
76
+ pip install tensorflow numpy Pillow
77
 
78
  ## Loading the Model
79
 
80
  The model is saved in the Keras native format (.keras). You will need to provide the definitions of the custom layers (RepVGGBlock and NECALayer) when loading.
81
 
82
+ **IMPORTANT: You must have the RepVGGBlock and NECALayer class definitions available in your Python environment before running this.**
83
+
84
+ **--- CUSTOM LAYER DEFINITIONS ---**
85
 
86
+
87
+ **--- RepVGGBlock Class Definition ---**
88
+
89
+
90
+
91
+ class RepVGGBlock(layers.Layer):
92
  def __init__(self, in_channels, out_channels, kernel_size=3, stride=1,
93
  groups=1, deploy=False, use_se=False, **kwargs):
94
  super(RepVGGBlock, self).__init__(**kwargs)
 
100
  self._deploy_mode_internal = deploy
101
  self.config_use_se = use_se # Placeholder, not used in this version of RepVGGBlock
102
  self.actual_in_channels = None
103
+
104
  self.rbr_dense_conv = layers.Conv2D(
105
  filters=self.config_out_channels, kernel_size=self.config_kernel_size,
106
  strides=self.config_strides_val, padding='same',
 
206
  return config
207
  @classmethod
208
  def from_config(cls, config): return cls(**config)
209
+ **--- End of RepVGGBlock ---**
210
+
211
+ **--- NECALayer Class Definition ---**
212
 
213
+ class NECALayer(layers.Layer):
 
214
  def __init__(self, channels, gamma=2, b=1, **kwargs):
215
  super(NECALayer, self).__init__(**kwargs)
216
  self.channels = channels
 
226
  self.gap = layers.GlobalAveragePooling2D(keepdims=True)
227
  self.conv1d = layers.Conv1D(filters=1, kernel_size=kernel_size_for_conv1d, padding='same', use_bias=False, name=self.name + '_eca_conv1d')
228
  self.sigmoid = layers.Activation('sigmoid')
229
+
230
  def call(self, inputs):
231
  if self.channels != inputs.shape[-1]: raise ValueError(f"Input channels {inputs.shape[-1]} != layer channels {self.channels} for {self.name}")
232
  x = self.gap(inputs)
 
244
  return config
245
  @classmethod
246
  def from_config(cls, config): return cls(**config)
247
+
248
+ **--- End of NECALayer ---**
249
 
 
 
250
 
251
+ **--- END OF CUSTOM LAYER DEFINITIONS ---**
 
252
 
253
+ import tensorflow as tf
254
+ from tensorflow import keras
255
+
256
+ MODEL_FILE = 'path/to/your/repvgg_neca_deploy_final.keras' # Replace with actual path
257
+ LABEL_MAPPING_FILE = 'path/to/your/label_mapping.json' # Replace with actual path
258
+
259
+ custom_objects = {'RepVGGBlock': RepVGGBlock, 'NECALayer': NECALayer}
260
+ loaded_model = tf.keras.models.load_model(MODEL_FILE, custom_objects=custom_objects, compile=False)
261
+ print("Model loaded successfully!")
262
+ loaded_model.summary() # Optional: to see the loaded architecture
263
 
264
  # Load label mapping
265
+ import json
266
+ with open(LABEL_MAPPING_FILE, 'r') as f:
267
+ label_map_data = json.load(f)
268
+ int_to_label = {int(k): v for k, v in label_map_data['int_to_label'].items()}
269
 
270
  **Making Predictions**
271
+
272
+ from PIL import Image
273
+ import numpy as np
 
 
 
 
 
274
 
275
+ def preprocess_image_for_prediction(image_path_or_pil_image, target_size=(299, 299)):
276
+ if isinstance(image_path_or_pil_image, str):
277
+ img = Image.open(image_path_or_pil_image)
278
+ else: # Assuming PIL image
279
+ img = image_path_or_pil_image
280
+
281
  img = img.convert('RGB') # Ensure 3 channels
282
  img = img.resize(target_size)
283
  img_array = np.array(img, dtype=np.float32)
 
285
  img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
286
  return img_array
287
 
288
+ # Example prediction:
289
+ image_path = 'path/to/your/cloud_image.jpg' # Replace with your image path
290
+ input_tensor = preprocess_image_for_prediction(image_path)
291
+ predictions = loaded_model.predict(input_tensor)
292
+ predicted_probabilities = predictions[0]
293
+
294
+ # Get top prediction
295
+ predicted_class_index = np.argmax(predicted_probabilities)
296
+ predicted_class_name = int_to_label.get(predicted_class_index, "Unknown Class")
297
+ confidence = predicted_probabilities[predicted_class_index]
298
+
299
+ print(f"Predicted Cloud Type: {predicted_class_name}")
300
+ print(f"Confidence: {confidence*100:.2f}%")
301
+
302
+ # Display all class probabilities (optional)
303
+ for i, prob in enumerate(predicted_probabilities):
304
+ class_name = int_to_label.get(i, f"Class_{i}")
305
+ print(f"- {class_name}: {prob*100:.2f}%")
306
 
307
  ## 4. Training Procedure
308
  Dataset: UGCI
 
357
 
358
  Framework: TensorFlow/Keras
359
 
360
+ Compute - Nvidia A100 GPU (Google Colab)
361
+
362
  Optimizer: AdamW (learning_rate=1e-4, weight_decay=5e-5)
363
 
364
  Loss Function: Sparse Categorical Crossentropy
 
373
 
374
  ReduceLROnPlateau (monitoring val_loss, patience 10)
375
 
376
+ Epochs: Trained for 200 epochs (~7 hours) (EarlyStopping intervened). The best model was restored from Epoch 171 of the final run.
377
 
378
  Batch Size: 32
379
 
 
480
 
481
  ## 11. Acknowledgements
482
 
483
+ This work was inspired by the methodologies presented in "Improved RepVGG ground-based cloud image classification with attention convolution" by Shi et al. (2024).