a
This commit is contained in:
@@ -892,39 +892,7 @@
|
||||
"id": "decaf5cb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMG_128 = (128, 128)\n",
|
||||
"\n",
|
||||
"# Rebuild datasets at 128x128\n",
|
||||
"train_ds_128 = tf.keras.utils.image_dataset_from_directory(\n",
|
||||
" train_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=IMG_128)\n",
|
||||
"val_ds_128 = tf.keras.utils.image_dataset_from_directory(\n",
|
||||
" val_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=IMG_128)\n",
|
||||
"\n",
|
||||
"train_ds_128 = (train_ds_128.map(augment_and_mix, num_parallel_calls=AUTOTUNE)\n",
|
||||
" .map(preprocess_fn, num_parallel_calls=AUTOTUNE)\n",
|
||||
" .map(add_sample_weight, num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\n",
|
||||
"val_ds_128 = (val_ds_128.map(lambda img, lbl: (preprocess_input(tf.cast(img, tf.float32)), lbl), num_parallel_calls=AUTOTUNE)\n",
|
||||
" .map(lambda img, lbl: (img, tf.one_hot(lbl, NUM_CLASSES)), num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\n",
|
||||
"\n",
|
||||
"EPOCHS_P1 = 25\n",
|
||||
"steps_per_epoch = tf.data.experimental.cardinality(train_ds_128).numpy() or 100\n",
|
||||
"total_steps = steps_per_epoch * EPOCHS_P1\n",
|
||||
"warmup_steps = steps_per_epoch * 3 # 3 epoch warmup\n",
|
||||
"\n",
|
||||
"lr_schedule_p1 = WarmupCosineDecay(warmup_steps, total_steps, peak_lr=1e-3, min_lr=1e-5)\n",
|
||||
"\n",
|
||||
"model.compile(\n",
|
||||
" optimizer=AdamW(\n",
|
||||
" learning_rate=lr_schedule_p1, weight_decay=1e-4),\n",
|
||||
" loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True, label_smoothing=0.15),\n",
|
||||
" metrics=['accuracy']\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(\"Phase 1: Head training at 128×128...\")\n",
|
||||
"history_1 = model.fit(train_ds_128, validation_data=val_ds_128,\n",
|
||||
" epochs=EPOCHS_P1, callbacks=make_callbacks())\n"
|
||||
]
|
||||
"source": "IMG_128 = (128, 128)\n\n# Rebuild datasets at 128x128\ntrain_ds_128 = tf.keras.utils.image_dataset_from_directory(\n train_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=IMG_128)\nval_ds_128 = tf.keras.utils.image_dataset_from_directory(\n val_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=IMG_128)\n\ntrain_ds_128 = (train_ds_128.map(augment_and_mix, num_parallel_calls=AUTOTUNE)\n .map(preprocess_fn, num_parallel_calls=AUTOTUNE)\n .map(add_sample_weight, num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\nval_ds_128 = (val_ds_128.map(lambda img, lbl: (preprocess_input(tf.cast(img, tf.float32)), lbl), num_parallel_calls=AUTOTUNE)\n .map(lambda img, lbl: (img, tf.one_hot(lbl, NUM_CLASSES)), num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\n\nEPOCHS_P1 = 25\ncard = tf.data.experimental.cardinality(train_ds_128).numpy()\nsteps_per_epoch = card if card > 0 else 100\ntotal_steps = steps_per_epoch * EPOCHS_P1\nwarmup_steps = steps_per_epoch * 3 # 3 epoch warmup\n\nlr_schedule_p1 = WarmupCosineDecay(warmup_steps, total_steps, peak_lr=1e-3, min_lr=1e-5)\n\nmodel.compile(\n optimizer=AdamW(\n learning_rate=lr_schedule_p1, weight_decay=1e-4),\n loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True, label_smoothing=0.15),\n metrics=['accuracy']\n)\n\nprint(\"Phase 1: Head training at 128×128...\")\nhistory_1 = model.fit(train_ds_128, validation_data=val_ds_128,\n epochs=EPOCHS_P1, callbacks=make_callbacks())"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -943,44 +911,7 @@
|
||||
"id": "fd7fb926",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMG_192 = (192, 192)\n",
|
||||
"\n",
|
||||
"train_ds_192 = tf.keras.utils.image_dataset_from_directory(\n",
|
||||
" train_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=IMG_192)\n",
|
||||
"val_ds_192 = tf.keras.utils.image_dataset_from_directory(\n",
|
||||
" val_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=IMG_192)\n",
|
||||
"\n",
|
||||
"train_ds_192 = (train_ds_192.map(augment_and_mix, num_parallel_calls=AUTOTUNE)\n",
|
||||
" .map(preprocess_fn, num_parallel_calls=AUTOTUNE)\n",
|
||||
" .map(add_sample_weight, num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\n",
|
||||
"val_ds_192 = (val_ds_192.map(lambda img, lbl: (preprocess_input(tf.cast(img, tf.float32)), lbl), num_parallel_calls=AUTOTUNE)\n",
|
||||
" .map(lambda img, lbl: (img, tf.one_hot(lbl, NUM_CLASSES)), num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\n",
|
||||
"\n",
|
||||
"# Unfreeze top 100 layers\n",
|
||||
"base_model.trainable = True\n",
|
||||
"for layer in base_model.layers[:-100]:\n",
|
||||
" layer.trainable = False\n",
|
||||
"\n",
|
||||
"EPOCHS_P2 = 30\n",
|
||||
"steps_p2 = tf.data.experimental.cardinality(train_ds_192).numpy() or 100\n",
|
||||
"total_p2 = steps_p2 * EPOCHS_P2\n",
|
||||
"warmup_p2 = steps_p2 * 2\n",
|
||||
"\n",
|
||||
"lr_schedule_p2 = WarmupCosineDecay(warmup_p2, total_p2, peak_lr=5e-4, min_lr=1e-6)\n",
|
||||
"\n",
|
||||
"model.compile(\n",
|
||||
" optimizer=AdamW(\n",
|
||||
" learning_rate=lr_schedule_p2, weight_decay=1e-4),\n",
|
||||
" loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True, label_smoothing=0.15),\n",
|
||||
" metrics=['accuracy']\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(\"Phase 2: Fine-tuning top 100 layers at 192×192...\")\n",
|
||||
"history_2 = model.fit(train_ds_192, validation_data=val_ds_192,\n",
|
||||
" epochs=EPOCHS_P1 + EPOCHS_P2, initial_epoch=history_1.epoch[-1] + 1,\n",
|
||||
" callbacks=make_callbacks())\n"
|
||||
]
|
||||
"source": "IMG_192 = (192, 192)\n\ntrain_ds_192 = tf.keras.utils.image_dataset_from_directory(\n train_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=IMG_192)\nval_ds_192 = tf.keras.utils.image_dataset_from_directory(\n val_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=IMG_192)\n\ntrain_ds_192 = (train_ds_192.map(augment_and_mix, num_parallel_calls=AUTOTUNE)\n .map(preprocess_fn, num_parallel_calls=AUTOTUNE)\n .map(add_sample_weight, num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\nval_ds_192 = (val_ds_192.map(lambda img, lbl: (preprocess_input(tf.cast(img, tf.float32)), lbl), num_parallel_calls=AUTOTUNE)\n .map(lambda img, lbl: (img, tf.one_hot(lbl, NUM_CLASSES)), num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\n\n# Unfreeze top 100 layers\nbase_model.trainable = True\nfor layer in base_model.layers[:-100]:\n layer.trainable = False\n\nEPOCHS_P2 = 30\ncard_p2 = tf.data.experimental.cardinality(train_ds_192).numpy()\nsteps_p2 = card_p2 if card_p2 > 0 else 100\ntotal_p2 = steps_p2 * EPOCHS_P2\nwarmup_p2 = steps_p2 * 2\n\nlr_schedule_p2 = WarmupCosineDecay(warmup_p2, total_p2, peak_lr=5e-4, min_lr=1e-6)\n\nmodel.compile(\n optimizer=AdamW(\n learning_rate=lr_schedule_p2, weight_decay=1e-4),\n loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True, label_smoothing=0.15),\n metrics=['accuracy']\n)\n\nprint(\"Phase 2: Fine-tuning top 100 layers at 192×192...\")\nhistory_2 = model.fit(train_ds_192, validation_data=val_ds_192,\n epochs=EPOCHS_P1 + EPOCHS_P2, initial_epoch=history_1.epoch[-1] + 1,\n callbacks=make_callbacks())"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -1000,43 +931,7 @@
|
||||
"id": "14115063",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"img_size = IMG_SIZE # (224, 224)\n",
|
||||
"\n",
|
||||
"train_ds_full = tf.keras.utils.image_dataset_from_directory(\n",
|
||||
" train_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=img_size)\n",
|
||||
"val_ds_full = tf.keras.utils.image_dataset_from_directory(\n",
|
||||
" val_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=img_size)\n",
|
||||
"\n",
|
||||
"train_ds_full = (train_ds_full.map(augment_and_mix, num_parallel_calls=AUTOTUNE)\n",
|
||||
" .map(preprocess_fn, num_parallel_calls=AUTOTUNE)\n",
|
||||
" .map(add_sample_weight, num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\n",
|
||||
"val_ds_full = (val_ds_full.map(lambda img, lbl: (preprocess_input(tf.cast(img, tf.float32)), lbl), num_parallel_calls=AUTOTUNE)\n",
|
||||
" .map(lambda img, lbl: (img, tf.one_hot(lbl, NUM_CLASSES)), num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\n",
|
||||
"\n",
|
||||
"# Full unfreeze\n",
|
||||
"for layer in base_model.layers:\n",
|
||||
" layer.trainable = True\n",
|
||||
"\n",
|
||||
"EPOCHS_P3 = 30\n",
|
||||
"steps_p3 = tf.data.experimental.cardinality(train_ds_full).numpy() or 100\n",
|
||||
"total_p3 = steps_p3 * EPOCHS_P3\n",
|
||||
"warmup_p3 = steps_p3 * 2\n",
|
||||
"\n",
|
||||
"lr_schedule_p3 = WarmupCosineDecay(warmup_p3, total_p3, peak_lr=1e-4, min_lr=1e-7)\n",
|
||||
"\n",
|
||||
"model.compile(\n",
|
||||
" optimizer=AdamW(\n",
|
||||
" learning_rate=lr_schedule_p3, weight_decay=1e-4),\n",
|
||||
" loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True, label_smoothing=0.10),\n",
|
||||
" metrics=['accuracy']\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(\"Phase 3: Full fine-tuning at 224×224...\")\n",
|
||||
"history_3 = model.fit(train_ds_full, validation_data=val_ds_full,\n",
|
||||
" epochs=EPOCHS_P1 + EPOCHS_P2 + EPOCHS_P3, initial_epoch=(history_2.epoch[-1] + 1) if history_2.epoch else EPOCHS_P1 + EPOCHS_P2,\n",
|
||||
" callbacks=make_callbacks())\n"
|
||||
]
|
||||
"source": "img_size = IMG_SIZE # (224, 224)\n\ntrain_ds_full = tf.keras.utils.image_dataset_from_directory(\n train_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=img_size)\nval_ds_full = tf.keras.utils.image_dataset_from_directory(\n val_dir, shuffle=True, batch_size=BATCH_SIZE, image_size=img_size)\n\ntrain_ds_full = (train_ds_full.map(augment_and_mix, num_parallel_calls=AUTOTUNE)\n .map(preprocess_fn, num_parallel_calls=AUTOTUNE)\n .map(add_sample_weight, num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\nval_ds_full = (val_ds_full.map(lambda img, lbl: (preprocess_input(tf.cast(img, tf.float32)), lbl), num_parallel_calls=AUTOTUNE)\n .map(lambda img, lbl: (img, tf.one_hot(lbl, NUM_CLASSES)), num_parallel_calls=AUTOTUNE).prefetch(AUTOTUNE))\n\n# Full unfreeze\nfor layer in base_model.layers:\n layer.trainable = True\n\nEPOCHS_P3 = 30\ncard_p3 = tf.data.experimental.cardinality(train_ds_full).numpy()\nsteps_p3 = card_p3 if card_p3 > 0 else 100\ntotal_p3 = steps_p3 * EPOCHS_P3\nwarmup_p3 = steps_p3 * 2\n\nlr_schedule_p3 = WarmupCosineDecay(warmup_p3, total_p3, peak_lr=1e-4, min_lr=1e-7)\n\nmodel.compile(\n optimizer=AdamW(\n learning_rate=lr_schedule_p3, weight_decay=1e-4),\n loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True, label_smoothing=0.10),\n metrics=['accuracy']\n)\n\nprint(\"Phase 3: Full fine-tuning at 224×224...\")\nhistory_3 = model.fit(train_ds_full, validation_data=val_ds_full,\n epochs=EPOCHS_P1 + EPOCHS_P2 + EPOCHS_P3, initial_epoch=(history_2.epoch[-1] + 1) if history_2.epoch else EPOCHS_P1 + EPOCHS_P2,\n callbacks=make_callbacks())"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -1577,4 +1472,4 @@
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user