/
soft_3
/
Lab_CIS
Обзор
Документация
Войти
/
soft_3
/
Lab_CIS
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
CodeLab1
263 строки
10 KB
soft_3
update CodeLab1
24 окт 2025, 12:43
24 окт 2025, 12:43
e413581
Код
Авторство
О чём код?
import tensorflow as tf import tensorflow_datasets as tfds from tensorflow.keras import layers, models, applications import matplotlib.pyplot as plt import numpy as np from sklearn.metrics import classification_report, confusion_matrix import seaborn as sns import gc # Для очистки памяти # Убедимся, что используем GPU print("GPU доступен:", tf.config.list_physical_devices('GPU')) # Очистка памяти от предыдущих запусков tf.keras.backend.clear_session() gc.collect() # ## 4. Предобработка данных # Загрузка датасета CIFAR-10 (x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data() # Преобразование меток в one-hot encoding y_train = tf.keras.utils.to_categorical(y_train, 10) y_test = tf.keras.utils.to_categorical(y_test, 10) # Определим размер изображения. IMG_SIZE = 128 # Функция для изменения размера и нормализации изображений # Средние и стандартные отклонения для CIFAR-10 CIFAR10_MEAN = np.array([0.4914, 0.4822, 0.4465]) CIFAR10_STD = np.array([0.2470, 0.2435, 0.2616]) def preprocess_image(image, label): # image — это uint8 [0, 255] image = tf.image.resize(image, (IMG_SIZE, IMG_SIZE)) # Преобразуем в float32 image = tf.cast(image, tf.float32) # Применяем ImageNet-нормализацию image = tf.keras.applications.efficientnet.preprocess_input(image) return image, label # Создаем tf.data.Dataset train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)) test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test)) # Применяем преобразования train_dataset = train_dataset.map(preprocess_image, num_parallel_calls=tf.data.AUTOTUNE) test_dataset = test_dataset.map(preprocess_image, num_parallel_calls=tf.data.AUTOTUNE) # Настройка для производительности BATCH_SIZE = 16 train_dataset = train_dataset.batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE) test_dataset = test_dataset.batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE) # Удаляем исходные массивы, чтобы освободить память del x_train, y_train, x_test, y_test gc.collect() # ## 5. Архитектура модели # %% # Загрузка предобученной модели EfficientNetB0 без головы base_model = tf.keras.applications.EfficientNetB0( include_top=False, weights='imagenet', input_shape=(IMG_SIZE, IMG_SIZE, 3) ) # Заморозка базовой модели (Feature Extraction) base_model.trainable = False # Добавление собственных слоев сверху inputs = tf.keras.Input(shape=(IMG_SIZE, IMG_SIZE, 3)) x = base_model(inputs, training=False) x = layers.GlobalAveragePooling2D()(x) x = layers.Dropout(0.2)(x) # Добавляем Dropout для регуляризации outputs = layers.Dense(10, activation='softmax')(x) model = tf.keras.Model(inputs, outputs) # Компиляция модели model.compile( optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'] ) model.summary() # ## 6. Гиперпараметры обучения # %% # Гиперпараметры EPOCHS_FE = 10 # Эпохи для Feature Extraction EPOCHS_FT = 10 # Эпохи для Fine-Tuning LEARNING_RATE_FT = 1e-5 # Очень низкий LR для Fine-Tuning # ## 7. Обучение (Часть 1: Feature Extraction) # %% print("\n--- Начало обучения (Feature Extraction) ---") history_fe = model.fit( train_dataset, epochs=EPOCHS_FE, validation_data=test_dataset, verbose=1 # Выводим прогресс для контроля ) # ## 8. Тонкая настройка (Часть 2: Fine-Tuning) # %% print("\n--- Начало тонкой настройки (Fine-Tuning) ---") # Разморозка верхних слоев базовой модели base_model.trainable = True # Заморозим первые N слоев, а верхние - разморозим # Разморозим последние 20 слоев (можно настроить) fine_tune_at = len(base_model.layers) - 20 for layer in base_model.layers[:fine_tune_at]: layer.trainable = False # Перекомпиляция модели с очень низким learning rate model.compile( optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE_FT), loss='categorical_crossentropy', metrics=['accuracy'] ) # Продолжение обучения history_ft = model.fit( train_dataset, epochs=EPOCHS_FT, initial_epoch=history_fe.epoch[-1], # Начинаем с последней эпохи FE validation_data=test_dataset, verbose=1 ) # ## 9. Визуализация результатов и оценка # %% # Объединяем историю обучения acc = history_fe.history['accuracy'] + history_ft.history['accuracy'] val_acc = history_fe.history['val_accuracy'] + history_ft.history['val_accuracy'] loss = history_fe.history['loss'] + history_ft.history['loss'] val_loss = history_fe.history['val_loss'] + history_ft.history['val_loss'] plt.figure(figsize=(12, 4)) plt.subplot(1, 2, 1) plt.plot(acc, label='Training Accuracy') plt.plot(val_acc, label='Validation Accuracy') plt.axvline(x=len(history_fe.history['accuracy'])-1, c='r', linestyle='--', label='Fine-Tuning Start') plt.legend(loc='lower right') plt.title('Training and Validation Accuracy') plt.subplot(1, 2, 2) plt.plot(loss, label='Training Loss') plt.plot(val_loss, label='Validation Loss') plt.axvline(x=len(history_fe.history['loss'])-1, c='r', linestyle='--', label='Fine-Tuning Start') plt.legend(loc='upper right') plt.title('Training and Validation Loss') plt.show() # ## 10. Результаты на тестовой выборке # %% # Оценка на тестовом наборе test_loss, test_accuracy = model.evaluate(test_dataset, verbose=0) print(f'\nТочность на тестовой выборке после тонкой настройки: {test_accuracy:.4f}') # Предсказания для построения матрицы ошибок y_pred = model.predict(test_dataset) y_pred_classes = np.argmax(y_pred, axis=1) # Поскольку мы используем tf.data.Dataset, нужно собрать истинные метки y_true_classes = [] for _, labels_batch in test_dataset: y_true_classes.extend(np.argmax(labels_batch.numpy(), axis=1)) y_true_classes = np.array(y_true_classes) # Матрица ошибок cm = confusion_matrix(y_true_classes, y_pred_classes) plt.figure(figsize=(10, 8)) sns.heatmap(cm, annot=True, fmt='d', cmap='Blues') plt.title('Confusion Matrix') plt.ylabel('Истинные метки') plt.xlabel('Предсказанные метки') plt.show() # Отчет о классификации class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] print(classification_report(y_true_classes, y_pred_classes, target_names=class_names)) # ## 11. Анализ ошибок (примеры) # %% # Собираем все данные для анализа all_images = [] all_labels = [] for images_batch, labels_batch in test_dataset: all_images.extend(images_batch.numpy()) all_labels.extend(labels_batch.numpy()) all_images = np.array(all_images) all_labels = np.array(all_labels) # Находим индексы неправильно классифицированных изображений wrong_indices = np.where(y_true_classes != y_pred_classes)[0] # Функция для обратного масштабирования изображений (для визуализации) def denormalize_image(image): # Применяем обратную нормализацию для CIFAR-10 image = image * CIFAR10_STD + CIFAR10_MEAN # Ограничиваем значения в диапазоне [0, 1] image = np.clip(image, 0, 1) return image # Выводим 5 примеров ошибок fig, axes = plt.subplots(1, 5, figsize=(15, 3)) for i, idx in enumerate(wrong_indices[:5]): ax = axes[i] # Обратное масштабирование для визуализации img_for_plot = denormalize_image(all_images[idx]) ax.imshow(img_for_plot) true_label = class_names[np.argmax(all_labels[idx])] pred_label = class_names[y_pred_classes[idx]] ax.set_title(f"True: {true_label}\nPred: {pred_label}", color='red') ax.axis('off') plt.suptitle("Примеры неправильной классификации") plt.show() # ## 12. Выводы # %% # Анализ результатов print("\n=== ВЫВОДЫ ===") print(f"1. Итоговая точность на тестовой выборке: {test_accuracy:.4f}") print(f"2. Точность после Feature Extraction: {history_fe.history['val_accuracy'][-1]:.4f}") print(f"3. Прирост точности после Fine-Tuning: {test_accuracy - history_fe.history['val_accuracy'][-1]:.4f}") # Проверка на переобучение if abs(test_accuracy - val_acc[-1]) > 0.05: print("4. Возможны признаки переобучения (разница между train и val accuracy > 5%).") else: print("4. Переобучения не наблюдается.") print("5. Модель показала хорошие результаты, несмотря на ограничения по памяти.") print("6. Ключевые оптимизации: использование меньшего разрешения (128x128), уменьшение batch_size (16), использование tf.data.Dataset.") # Очистка памяти в конце tf.keras.backend.clear_session() gc.collect()