1- import tensorflow as tf
2- from tensorflow .keras import layers , Model
31
42
53def build_model (
64 num_classes : int ,
75 input_shape : tuple = (224 , 224 , 3 ),
8- load_weights : bool = True , # FIX: set False in tests to skip 29MB download
9- ) -> Model :
6+ load_weights : bool = True ,
7+ ):
108 """
119 Build a plant disease classifier using EfficientNetB0 transfer learning.
1210
1311 Args:
1412 num_classes: number of output classes (38 for full PlantVillage)
1513 input_shape: image dimensions expected by the model
16- load_weights: load ImageNet weights (True for training, False for tests/CI)
14+ load_weights: load ImageNet weights. Set False in tests/CI to skip download.
1715
1816 Returns:
19- Compiled-ready Keras Model
17+ Keras Model (not yet compiled — call model.compile() after)
2018 """
19+ import tensorflow as tf # lazy import
20+ from tensorflow .keras import layers , Model
21+
2122 weights = "imagenet" if load_weights else None
2223
2324 base = tf .keras .applications .EfficientNetB0 (
@@ -28,7 +29,6 @@ def build_model(
2829 base .trainable = False # freeze backbone — train only the head first
2930
3031 inputs = tf .keras .Input (shape = input_shape )
31-
3232 # EfficientNet expects pixel values in [0, 255] — do NOT rescale to [0, 1]
3333 x = base (inputs , training = False )
3434 x = layers .GlobalAveragePooling2D ()(x )
@@ -42,17 +42,10 @@ def build_model(
4242 return model
4343
4444
45- def unfreeze_top_layers (model : Model , num_layers : int = 20 ) -> Model :
45+ def unfreeze_top_layers (model , num_layers : int = 20 ):
4646 """
4747 Fine-tune: unfreeze the top N layers of EfficientNetB0 after initial training.
4848 Call after the head has converged (~epoch 10-15), then retrain with low LR (1e-5).
49-
50- Args:
51- model: the trained model from build_model()
52- num_layers: how many layers from the top of EfficientNetB0 to unfreeze
53-
54- Returns:
55- model with top N backbone layers set to trainable
5649 """
5750 base = model .layers [1 ] # EfficientNetB0 is the second layer
5851 base .trainable = True
0 commit comments