Родитель
							
								
									9f1f1721dc
								
							
						
					
					
						Сommit
						31fddb9d60
					
				@ -0,0 +1,577 @@
 | 
				
			||||
# Лабораторная работа №2: Обнаружение аномалий с помощью автокодировщиков
 | 
				
			||||
**Аникеев А.А; Чагин С.А. — А-02-22**
 | 
				
			||||
## Вариант 2 (номер бригады k=5) - данные WBC
 | 
				
			||||
 | 
				
			||||
### Цель работы
 | 
				
			||||
 | 
				
			||||
Получить практические навыки создания, обучения и применения искусственных нейронных сетей типа автокодировщик. 
 | 
				
			||||
Исследовать влияние архитектуры автокодировщика и количества эпох обучения на области в пространстве признаков,
 | 
				
			||||
распознаваемые автокодировщиком после обучения. Научиться оценивать качество обучения автокодировщика на основе
 | 
				
			||||
ошибки реконструкции и новых метрик EDCA. Научиться решать актуальную задачу обнаружения аномалий в данных с
 | 
				
			||||
помощью автокодировщика как одноклассового классификатора.
 | 
				
			||||
 | 
				
			||||
### Определение варианта
 | 
				
			||||
 | 
				
			||||
- Номер бригады: k = 5
 | 
				
			||||
- N = k mod 3 = 5 mod 3 = 2
 | 
				
			||||
- Вариант 2 => данные **WBC**
 | 
				
			||||
 | 
				
			||||
### Подготовка среды
 | 
				
			||||
 | 
				
			||||
```python
 | 
				
			||||
import os
 | 
				
			||||
os.chdir('/content/drive/MyDrive/Colab Notebooks')
 | 
				
			||||
```
 | 
				
			||||
 | 
				
			||||
```python
 | 
				
			||||
from google.colab import drive
 | 
				
			||||
drive.mount('/content/drive')
 | 
				
			||||
import os
 | 
				
			||||
work_dir = '/content/drive/MyDrive/Colab Notebooks/is_lab2'
 | 
				
			||||
os.makedirs(work_dir, exist_ok=True)
 | 
				
			||||
os.chdir(work_dir)
 | 
				
			||||
os.makedirs('out', exist_ok=True)
 | 
				
			||||
dataset_name = 'WBC'
 | 
				
			||||
base_url = "http://uit.mpei.ru/git/main/is_dnn/raw/branch/main/labworks/LW2/"
 | 
				
			||||
!wget -N {base_url}lab02_lib.py
 | 
				
			||||
!wget -N {base_url}data/{dataset_name}_train.txt
 | 
				
			||||
!wget -N {base_url}data/{dataset_name}_test.txt
 | 
				
			||||
!cp {dataset_name}_train.txt train.txt
 | 
				
			||||
!cp {dataset_name}_test.txt test.txt
 | 
				
			||||
print("Файлы успешно скачаны!")
 | 
				
			||||
print("Содержимое рабочей директории:")
 | 
				
			||||
!ls -la
 | 
				
			||||
```
 | 
				
			||||
 | 
				
			||||
---
 | 
				
			||||
 | 
				
			||||
## ЗАДАНИЕ 1
 | 
				
			||||
 | 
				
			||||
### Пункт №1. Импорт необходимых для работы библиотек и модулей.
 | 
				
			||||
```python
 | 
				
			||||
import numpy as np
 | 
				
			||||
import matplotlib.pyplot as plt
 | 
				
			||||
from sklearn.preprocessing import StandardScaler
 | 
				
			||||
from sklearn.datasets import make_blobs
 | 
				
			||||
import tensorflow as tf
 | 
				
			||||
from tensorflow.keras.models import Sequential
 | 
				
			||||
from tensorflow.keras.layers import Dense, Activation
 | 
				
			||||
from tensorflow.keras.optimizers import Adam
 | 
				
			||||
from tensorflow.keras.callbacks import EarlyStopping
 | 
				
			||||
import lab02_lib as lib
 | 
				
			||||
 | 
				
			||||
# Параметры для варианта 5
 | 
				
			||||
k = 5  # номер бригады
 | 
				
			||||
center_coords = (k, k)  # координаты центра (5, 5)
 | 
				
			||||
```
 | 
				
			||||
 | 
				
			||||
**Описание:** Импортируем необходимые библиотеки, модули, устанавливаются параметры для варианта 2.
 | 
				
			||||
 | 
				
			||||
### Пункт №2. Генерация индивидуального набора двумерных данных в пространстве признаков.
 | 
				
			||||
```python
 | 
				
			||||
 | 
				
			||||
print("Генерация синтетических данных с центром в (5, 5)...")
 | 
				
			||||
 | 
				
			||||
data = lib.datagen(k, k, 1000, 2)
 | 
				
			||||
 | 
				
			||||
print(f"Сгенерировано {len(data)} точек")
 | 
				
			||||
print(f"Центр данных: {center_coords}")
 | 
				
			||||
print(f"Размерность данных: {data.shape}")
 | 
				
			||||
```
 | 
				
			||||
 | 
				
			||||
**Результат выполнения:**
 | 
				
			||||
```
 | 
				
			||||
Сгенерировано 1000 точек
 | 
				
			||||
Центр данных: (5, 5)
 | 
				
			||||
Размерность данных: (1000, 2)
 | 
				
			||||
```
 | 
				
			||||
 | 
				
			||||

 | 
				
			||||
 | 
				
			||||
### Пункт №3. Создание и обучение автокодировщика AE1 простой архитектуры.
 | 
				
			||||
```python
 | 
				
			||||
print("="*50)
 | 
				
			||||
print("Обучение AE1")
 | 
				
			||||
print("="*50)
 | 
				
			||||
 | 
				
			||||
def create_simple_ae():
 | 
				
			||||
    model = Sequential()
 | 
				
			||||
    
 | 
				
			||||
    model.add(Dense(2, input_shape=(2,), activation='tanh'))
 | 
				
			||||
    
 | 
				
			||||
    model.add(Dense(1, activation='tanh'))
 | 
				
			||||
    
 | 
				
			||||
    model.add(Dense(2, activation='linear'))
 | 
				
			||||
    return model
 | 
				
			||||
 | 
				
			||||
ae1 = create_simple_ae()
 | 
				
			||||
ae1.compile(optimizer=Adam(learning_rate=0.001), loss='mse')
 | 
				
			||||
 | 
				
			||||
print("Архитектура AE1:")
 | 
				
			||||
ae1.summary()
 | 
				
			||||
 | 
				
			||||
print("\nНачало обучения AE1...")
 | 
				
			||||
history_ae1 = ae1.fit(data, data, 
 | 
				
			||||
                      epochs=1000, 
 | 
				
			||||
                      batch_size=32, 
 | 
				
			||||
                      validation_split=0.2,
 | 
				
			||||
                      verbose=1,
 | 
				
			||||
                      callbacks=[EarlyStopping(patience=300, restore_best_weights=True)])
 | 
				
			||||
 | 
				
			||||
ae1.save('out/AE1.h5')
 | 
				
			||||
 | 
				
			||||
X_pred_ae1 = ae1.predict(data)
 | 
				
			||||
reconstruction_errors_ae1 = np.mean(np.square(data - X_pred_ae1), axis=1)
 | 
				
			||||
threshold_ae1 = np.max(reconstruction_errors_ae1)
 | 
				
			||||
 | 
				
			||||
print("\nАнализ результатов AE1")
 | 
				
			||||
mse_ae1 = history_ae1.history['loss'][-1]
 | 
				
			||||
print(f"Финальная ошибка MSE AE1: {mse_ae1:.6f}")
 | 
				
			||||
print(f"Порог ошибки реконструкции AE1: {threshold_ae1:.6f}")
 | 
				
			||||
 | 
				
			||||
plt.figure(figsize=(15, 4))
 | 
				
			||||
 | 
				
			||||
plt.subplot(1, 3, 1)
 | 
				
			||||
plt.plot(history_ae1.history['loss'], label='Training Loss', color='blue')
 | 
				
			||||
plt.plot(history_ae1.history['val_loss'], label='Validation Loss', color='red')
 | 
				
			||||
plt.title('AE1: Ошибка обучения (MSE)')
 | 
				
			||||
plt.xlabel('Эпоха')
 | 
				
			||||
plt.ylabel('MSE')
 | 
				
			||||
plt.legend()
 | 
				
			||||
plt.grid(True, alpha=0.3)
 | 
				
			||||
 | 
				
			||||
plt.subplot(1, 3, 2)
 | 
				
			||||
plt.plot(reconstruction_errors_ae1, 'b-', alpha=0.7, linewidth=0.8)
 | 
				
			||||
plt.axhline(y=threshold_ae1, color='red', linestyle='--', linewidth=2, 
 | 
				
			||||
           label=f'Порог: {threshold_ae1:.2f}')
 | 
				
			||||
plt.title('AE1: Ошибки реконструкции')
 | 
				
			||||
plt.xlabel('Номер точки')
 | 
				
			||||
plt.ylabel('Ошибка реконструкции')
 | 
				
			||||
plt.legend()
 | 
				
			||||
plt.grid(True, alpha=0.3)
 | 
				
			||||
 | 
				
			||||
plt.subplot(1, 3, 3)
 | 
				
			||||
plt.hist(reconstruction_errors_ae1, bins=20, alpha=0.7, color='blue', edgecolor='black')
 | 
				
			||||
plt.axvline(threshold_ae1, color='red', linestyle='--', linewidth=2, 
 | 
				
			||||
           label=f'Порог: {threshold_ae1:.2f}')
 | 
				
			||||
plt.title('AE1: Распределение ошибок')
 | 
				
			||||
plt.xlabel('Ошибка реконструкции')
 | 
				
			||||
plt.ylabel('Частота')
 | 
				
			||||
plt.legend()
 | 
				
			||||
plt.grid(True, alpha=0.3)
 | 
				
			||||
 | 
				
			||||
plt.tight_layout()
 | 
				
			||||
plt.savefig('out/ae1_detailed_results.png', dpi=300, bbox_inches='tight')
 | 
				
			||||
plt.show()
 | 
				
			||||
 | 
				
			||||
with open('out/AE1_ire_th.txt', 'w') as f:
 | 
				
			||||
    f.write(str(threshold_ae1))
 | 
				
			||||
 | 
				
			||||
ae1_trained = ae1
 | 
				
			||||
IRE1 = reconstruction_errors_ae1
 | 
				
			||||
IREth1 = threshold_ae1
 | 
				
			||||
 | 
				
			||||
print(f"Обучение AE1 завершено!")
 | 
				
			||||
print(f"Минимальная ошибка: {np.min(IRE1):.6f}")
 | 
				
			||||
print(f"Максимальная ошибка: {np.max(IRE1):.6f}")
 | 
				
			||||
print(f"Средняя ошибка: {np.mean(IRE1):.6f}")
 | 
				
			||||
```
 | 
				
			||||
 | 
				
			||||
**Описание:** Создается автокодировщик AE1 с простой архитектурой, одним скрытым слоем с одним нейроном.
 | 
				
			||||
 | 
				
			||||
**Результаты обучения AE1:**
 | 
				
			||||
 | 
				
			||||
Финальная ошибка MSE AE1: 0.009326
 | 
				
			||||
 | 
				
			||||
Порог ошибки реконструкции AE1: 0.067896
 | 
				
			||||
 | 
				
			||||
Минимальная ошибка: 0.000035
 | 
				
			||||
 | 
				
			||||
Максимальная ошибка: 0.067896
 | 
				
			||||
 | 
				
			||||

 | 
				
			||||
 | 
				
			||||
### Пункт №4. Создание и обучение второго автокодировщика AE2 усложненной архитектуры.
 | 
				
			||||
 | 
				
			||||
```python
 | 
				
			||||
print("="*50)
 | 
				
			||||
print("Обучение AE2")
 | 
				
			||||
print("="*50)
 | 
				
			||||
 | 
				
			||||
print("Используется архитектура по умолчанию: [2-3-2-1-2-3-2]")
 | 
				
			||||
print("Количество скрытых слоев: 5")
 | 
				
			||||
print("Нейроны в скрытых слоях: 3-2-1-2-3")
 | 
				
			||||
 | 
				
			||||
def create_ae2_default():
 | 
				
			||||
    model = Sequential()
 | 
				
			||||
 | 
				
			||||
    model.add(Dense(2, input_shape=(2,), activation='tanh'))
 | 
				
			||||
 | 
				
			||||
    model.add(Dense(3, activation='tanh'))
 | 
				
			||||
    model.add(Dense(2, activation='tanh'))
 | 
				
			||||
    model.add(Dense(1, activation='tanh'))
 | 
				
			||||
    model.add(Dense(2, activation='tanh'))
 | 
				
			||||
    model.add(Dense(3, activation='tanh'))
 | 
				
			||||
 | 
				
			||||
    model.add(Dense(2, activation='linear'))
 | 
				
			||||
 | 
				
			||||
    return model
 | 
				
			||||
 | 
				
			||||
ae2 = create_ae2_default()
 | 
				
			||||
ae2.compile(optimizer=Adam(learning_rate=0.001), loss='mse')
 | 
				
			||||
 | 
				
			||||
print("\nАрхитектура AE2:")
 | 
				
			||||
ae2.summary()
 | 
				
			||||
 | 
				
			||||
print(f"\nНачало обучения AE2 (patience=300)...")
 | 
				
			||||
history_ae2 = ae2.fit(data, data,
 | 
				
			||||
                      epochs=3000,
 | 
				
			||||
                      batch_size=32,
 | 
				
			||||
                      validation_split=0.2,
 | 
				
			||||
                      verbose=1,
 | 
				
			||||
                      callbacks=[EarlyStopping(patience=300, restore_best_weights=True)])
 | 
				
			||||
 | 
				
			||||
ae2.save('out/AE2.h5')
 | 
				
			||||
 | 
				
			||||
X_pred_ae2 = ae2.predict(data)
 | 
				
			||||
reconstruction_errors_ae2 = np.mean(np.square(data - X_pred_ae2), axis=1)
 | 
				
			||||
threshold_ae2 = np.max(reconstruction_errors_ae2)
 | 
				
			||||
 | 
				
			||||
print("\n" + "="*50)
 | 
				
			||||
print("АНАЛИЗ РЕЗУЛЬТАТОВ AE2")
 | 
				
			||||
print("="*50)
 | 
				
			||||
mse_ae2 = history_ae2.history['loss'][-1]
 | 
				
			||||
print(f"Финальная ошибка MSE AE2: {mse_ae2:.6f}")
 | 
				
			||||
print(f"Порог ошибки реконструкции AE2: {threshold_ae2:.6f}")
 | 
				
			||||
 | 
				
			||||
print("\nПРОВЕРКА РЕКОМЕНДАЦИЙ:")
 | 
				
			||||
if mse_ae2 >= 0.01:
 | 
				
			||||
    print("✓ MSE_stop для AE2 соответствует рекомендации (≥ 0.01)")
 | 
				
			||||
else:
 | 
				
			||||
    print("✗ MSE_stop для AE2 слишком низкая, возможно переобучение")
 | 
				
			||||
 | 
				
			||||
plt.figure(figsize=(15, 4))
 | 
				
			||||
 | 
				
			||||
plt.subplot(1, 3, 1)
 | 
				
			||||
plt.plot(history_ae2.history['loss'], label='Training Loss', color='green', linewidth=2)
 | 
				
			||||
plt.plot(history_ae2.history['val_loss'], label='Validation Loss', color='red', linewidth=2)
 | 
				
			||||
plt.title('AE2: Динамика обучения (MSE)', fontsize=12, fontweight='bold')
 | 
				
			||||
plt.xlabel('Эпоха')
 | 
				
			||||
plt.ylabel('MSE')
 | 
				
			||||
plt.legend()
 | 
				
			||||
plt.grid(True, alpha=0.3)
 | 
				
			||||
 | 
				
			||||
plt.subplot(1, 3, 2)
 | 
				
			||||
plt.plot(reconstruction_errors_ae2, 'g-', alpha=0.7, linewidth=0.8)
 | 
				
			||||
plt.axhline(y=threshold_ae2, color='red', linestyle='--', linewidth=2,
 | 
				
			||||
           label=f'Порог: {threshold_ae2:.4f}')
 | 
				
			||||
plt.title('AE2: Ошибки реконструкции по точкам', fontsize=12, fontweight='bold')
 | 
				
			||||
plt.xlabel('Номер точки')
 | 
				
			||||
plt.ylabel('Ошибка реконструкции')
 | 
				
			||||
plt.legend()
 | 
				
			||||
plt.grid(True, alpha=0.3)
 | 
				
			||||
 | 
				
			||||
plt.subplot(1, 3, 3)
 | 
				
			||||
plt.hist(reconstruction_errors_ae2, bins=20, alpha=0.7, color='green', edgecolor='black')
 | 
				
			||||
plt.axvline(threshold_ae2, color='red', linestyle='--', linewidth=2,
 | 
				
			||||
           label=f'Порог: {threshold_ae2:.4f}')
 | 
				
			||||
plt.title('AE2: Распределение ошибок', fontsize=12, fontweight='bold')
 | 
				
			||||
plt.xlabel('Ошибка реконструкции')
 | 
				
			||||
plt.ylabel('Частота')
 | 
				
			||||
plt.legend()
 | 
				
			||||
plt.grid(True, alpha=0.3)
 | 
				
			||||
 | 
				
			||||
plt.tight_layout()
 | 
				
			||||
plt.savefig('out/ae2_detailed_results.png', dpi=300, bbox_inches='tight')
 | 
				
			||||
plt.show()
 | 
				
			||||
 | 
				
			||||
with open('out/AE2_ire_th.txt', 'w') as f:
 | 
				
			||||
    f.write(str(threshold_ae2))
 | 
				
			||||
 | 
				
			||||
ae2_trained = ae2
 | 
				
			||||
IRE2 = reconstruction_errors_ae2
 | 
				
			||||
IREth2 = threshold_ae2
 | 
				
			||||
 | 
				
			||||
print("\nДЕТАЛЬНАЯ СТАТИСТИКА AE2:")
 | 
				
			||||
print(f"Минимальная ошибка: {np.min(IRE2):.6f}")
 | 
				
			||||
print(f"Максимальная ошибка: {np.max(IRE2):.6f}")
 | 
				
			||||
print(f"Средняя ошибка: {np.mean(IRE2):.6f}")
 | 
				
			||||
print(f"Медианная ошибка: {np.median(IRE2):.6f}")
 | 
				
			||||
print(f"Стандартное отклонение: {np.std(IRE2):.6f}")
 | 
				
			||||
print(f"Количество точек с ошибкой выше порога: {np.sum(IRE2 > IREth2)}")
 | 
				
			||||
print(f"Процент точек выше порога: {np.sum(IRE2 > IREth2) / len(IRE2) * 100:.2f}%")
 | 
				
			||||
 | 
				
			||||
print(f"\nОбучение AE2 завершено!")
 | 
				
			||||
print(f"Архитектура: [2-3-2-1-2-3-2]")
 | 
				
			||||
print(f"Количество скрытых слоев: 5")
 | 
				
			||||
print(f"Нейроны в скрытых слоях: 3-2-1-2-3")
 | 
				
			||||
```
 | 
				
			||||
 | 
				
			||||
**Описание:** Создается автокодировщик AE2 с усложненной архитектурой, 5 скрытых слоев с нейронами: 3, 2, 1, 2, 3.
 | 
				
			||||
 | 
				
			||||
**Результаты обучения AE2:**
 | 
				
			||||
 | 
				
			||||
Финальная ошибка MSE AE2: 0.004915
 | 
				
			||||
 | 
				
			||||
Порог ошибки реконструкции AE2: 0.044551
 | 
				
			||||
 | 
				
			||||
Минимальная ошибка: 0.000000
 | 
				
			||||
 | 
				
			||||
Максимальная ошибка: 0.044551
 | 
				
			||||
 | 
				
			||||
Средняя ошибка: 0.004790
 | 
				
			||||
 | 
				
			||||
Медианная ошибка: 0.002186
 | 
				
			||||
 | 
				
			||||
Стандартное отклонение: 0.006661
 | 
				
			||||
 | 
				
			||||
Количество точек с ошибкой выше порога: 0
 | 
				
			||||
 | 
				
			||||
Процент точек выше порога: 0.00%
 | 
				
			||||
 | 
				
			||||

 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
### Пункт №5. Характеристики качества обучения EDCA.
 | 
				
			||||
```python
 | 
				
			||||
print("="*70)
 | 
				
			||||
print("РАСЧЕТ ХАРАКТЕРИСТИК КАЧЕСТВА ОБУЧЕНИЯ EDCA")
 | 
				
			||||
print("="*70)
 | 
				
			||||
 | 
				
			||||
numb_square = 20
 | 
				
			||||
 | 
				
			||||
print("\n" + "="*30)
 | 
				
			||||
print("РАСЧЕТ ДЛЯ AE1")
 | 
				
			||||
print("="*30)
 | 
				
			||||
xx, yy, Z1 = lib.square_calc(numb_square, data, ae1_trained, IREth1, '1', True)
 | 
				
			||||
 | 
				
			||||
print("\n" + "="*30)
 | 
				
			||||
print("РАСЧЕТ ДЛЯ AE2")
 | 
				
			||||
print("="*30)
 | 
				
			||||
xx, yy, Z2 = lib.square_calc(numb_square, data, ae2_trained, IREth2, '2', True)
 | 
				
			||||
 | 
				
			||||
print("\n" + "="*50)
 | 
				
			||||
print("СРАВНЕНИЕ ОБЛАСТЕЙ АППРОКСИМАЦИИ AE1 И AE2")
 | 
				
			||||
print("="*50)
 | 
				
			||||
lib.plot2in1(data, xx, yy, Z1, Z2)
 | 
				
			||||
```
 | 
				
			||||
 | 
				
			||||
**Оценка качества AE1:**
 | 
				
			||||
 | 
				
			||||
IDEAL = 0. Excess:  0.0
 | 
				
			||||
 | 
				
			||||
IDEAL = 0. Deficit:  0.7777777777777778
 | 
				
			||||
 | 
				
			||||
IDEAL = 1. Coating:  0.2222222222222222
 | 
				
			||||
 | 
				
			||||
summa:  1.0
 | 
				
			||||
 | 
				
			||||
IDEAL = 1. Extrapolation precision (Approx):  4.5
 | 
				
			||||
 | 
				
			||||
**Оценка качества AE2:**
 | 
				
			||||
 | 
				
			||||
IDEAL = 0. Excess:  0.2222222222222222
 | 
				
			||||
 | 
				
			||||
IDEAL = 0. Deficit:  0.6111111111111112
 | 
				
			||||
 | 
				
			||||
IDEAL = 1. Coating:  0.3888888888888889
 | 
				
			||||
 | 
				
			||||
summa:  1.0
 | 
				
			||||
 | 
				
			||||
IDEAL = 1. Extrapolation precision (Approx):  1.6363636363636365
 | 
				
			||||
 | 
				
			||||

 | 
				
			||||
 | 
				
			||||

 | 
				
			||||
 | 
				
			||||

 | 
				
			||||
 | 
				
			||||

 | 
				
			||||
 | 
				
			||||

 | 
				
			||||
 | 
				
			||||
**ВЫВОД О ПРИГОДНОСТИ AE1 И AE2 ДЛЯ ОБНАРУЖЕНИЯ АНОМАЛИЙ**
 | 
				
			||||
 | 
				
			||||
На основе анализа характеристик EDCA можно сделать следующие выводы:
 | 
				
			||||
AE1 (простая архитектура [2-1-2]):
 | 
				
			||||
 | 
				
			||||
НЕ ПРИГОДЕН для качественного обнаружения аномалий по следующим причинам:
 | 
				
			||||
 | 
				
			||||
    Deficit = 0.78 - критически высокое значение, что означает, что автокодировщик пропускает 78% обучающих данных и не распознает их как нормальные
 | 
				
			||||
 | 
				
			||||
    Coating = 0.22 - чрезвычайно низкое значение, автокодировщик охватывает только 22% области обучающих данных
 | 
				
			||||
 | 
				
			||||
    Approx = 4.5 - значительно превышает идеальное значение 1, что свидетельствует о очень плохой аппроксимации данных
 | 
				
			||||
 | 
				
			||||
Положительный аспект: Excess = 0.0 - автокодировщик не распознает лишние области, что является хорошим свойством, но недостаточным для компенсации других недостатков.
 | 
				
			||||
AE2 (архитектура [2-3-2-1-2-3-2]):
 | 
				
			||||
 | 
				
			||||
ТРЕБУЕТ СУЩЕСТВЕННОГО УЛУЧШЕНИЯ и в текущем состоянии не пригоден для качественного обнаружения аномалий:
 | 
				
			||||
 | 
				
			||||
    Excess = 0.22 - автокодировщик распознает 22% лишних областей, что может приводить к пропуску аномалий
 | 
				
			||||
 | 
				
			||||
    Deficit = 0.61 - все еще высокое значение, 61% данных не распознается как нормальные
 | 
				
			||||
 | 
				
			||||
    Coating = 0.39 - низкое покрытие, только 39% обучающих данных охватывается областью распознавания
 | 
				
			||||
 | 
				
			||||
    Approx = 1.64 - лучше чем у AE1, но все еще далеко от идеального значения 1
 | 
				
			||||
 | 
				
			||||
ОБЩИЙ ВЫВОД:
 | 
				
			||||
 | 
				
			||||
Оба автокодировщика демонстрируют недостаточное качество аппроксимации обучающих данных. AE1 слишком прост и не способен adequately выучить распределение данных, в то время как AE2, хотя и показывает улучшение, все еще требует значительной доработки архитектуры и параметров обучения для достижения приемлемого качества обнаружения аномалий.
 | 
				
			||||
 | 
				
			||||
Рекомендация: Необходимо создать улучшенный автокодировщик AE3 с более сложной архитектурой, увеличить количество эпох обучения и оптимизировать гиперпараметры для достижения значений EDCA, близких к идеальным (Excess ≈ 0, Deficit ≈ 0, Coating ≈ 1, Approx ≈ 1).
 | 
				
			||||
 | 
				
			||||
### Пункт №6. Улучшение автокодировщика АЕ2.
 | 
				
			||||
 | 
				
			||||
**Анализ проблем текущего AE2:**
 | 
				
			||||
 | 
				
			||||
• Excess = 0.22 - слишком много лишних областей
 | 
				
			||||
 | 
				
			||||
• Deficit = 0.61 - пропускает много нормальных данных
 | 
				
			||||
 | 
				
			||||
• Coating = 0.39 - плохое покрытие обучающих данных
 | 
				
			||||
 | 
				
			||||
• Approx = 1.64 - требует улучшения аппроксимации
 | 
				
			||||
 | 
				
			||||
**Стратегия улучшения AE2:**
 | 
				
			||||
 | 
				
			||||
• Увеличение количества эпох обучения с 3000 до 5000
 | 
				
			||||
 | 
				
			||||
• Увеличение patience с 300 до 400
 | 
				
			||||
 | 
				
			||||
• Уменьшение learning rate с 0.001 до 0.0005
 | 
				
			||||
 | 
				
			||||
• Уменьшение batch size с 32 до 16
 | 
				
			||||
 | 
				
			||||
```python
 | 
				
			||||
print("="*70)
 | 
				
			||||
print("УЛУЧШЕНИЕ АВТОКОДИРОВЩИКА AE2 - ПОВТОРНОЕ ОБУЧЕНИЕ")
 | 
				
			||||
print("="*70)
 | 
				
			||||
 | 
				
			||||
def create_ae2_improved():
 | 
				
			||||
    model = Sequential()
 | 
				
			||||
    
 | 
				
			||||
    model.add(Dense(2, input_shape=(2,), activation='tanh'))
 | 
				
			||||
    
 | 
				
			||||
    model.add(Dense(3, activation='tanh'))
 | 
				
			||||
    model.add(Dense(2, activation='tanh'))
 | 
				
			||||
    model.add(Dense(1, activation='tanh'))
 | 
				
			||||
    model.add(Dense(2, activation='tanh'))
 | 
				
			||||
    model.add(Dense(3, activation='tanh'))
 | 
				
			||||
    
 | 
				
			||||
    model.add(Dense(2, activation='linear'))
 | 
				
			||||
    
 | 
				
			||||
    return model
 | 
				
			||||
 | 
				
			||||
ae2_improved = create_ae2_improved()
 | 
				
			||||
ae2_improved.compile(optimizer=Adam(learning_rate=0.0005), loss='mse')
 | 
				
			||||
 | 
				
			||||
print("\nАрхитектура AE2 (улучшенный): [2-3-2-1-2-3-2]")
 | 
				
			||||
print("Количество скрытых слоев: 5")
 | 
				
			||||
ae2_improved.summary()
 | 
				
			||||
 | 
				
			||||
print(f"\nНачало обучения улучшенного AE2 (5000 эпох, patience=400)...")
 | 
				
			||||
history_ae2_improved = ae2_improved.fit(data, data, 
 | 
				
			||||
                      epochs=5000, 
 | 
				
			||||
                      batch_size=16,
 | 
				
			||||
                      validation_split=0.2,
 | 
				
			||||
                      verbose=1,
 | 
				
			||||
                      callbacks=[EarlyStopping(patience=400, restore_best_weights=True)])
 | 
				
			||||
 | 
				
			||||
ae2_improved.save('out/AE2_improved.h5')
 | 
				
			||||
 | 
				
			||||
X_pred_ae2_improved = ae2_improved.predict(data)
 | 
				
			||||
reconstruction_errors_ae2_improved = np.mean(np.square(data - X_pred_ae2_improved), axis=1)
 | 
				
			||||
threshold_ae2_improved = np.max(reconstruction_errors_ae2_improved)
 | 
				
			||||
 | 
				
			||||
print("\n" + "="*50)
 | 
				
			||||
print("АНАЛИЗ РЕЗУЛЬТАТОВ УЛУЧШЕННОГО AE2")
 | 
				
			||||
print("="*50)
 | 
				
			||||
mse_ae2_improved = history_ae2_improved.history['loss'][-1]
 | 
				
			||||
print(f"Финальная ошибка MSE улучшенного AE2: {mse_ae2_improved:.6f}")
 | 
				
			||||
print(f"Порог ошибки реконструкции улучшенного AE2: {threshold_ae2_improved:.6f}")
 | 
				
			||||
 | 
				
			||||
plt.figure(figsize=(15, 4))
 | 
				
			||||
 | 
				
			||||
plt.subplot(1, 3, 1)
 | 
				
			||||
plt.plot(history_ae2_improved.history['loss'], label='Training Loss', color='green', linewidth=2)
 | 
				
			||||
plt.plot(history_ae2_improved.history['val_loss'], label='Validation Loss', color='red', linewidth=2)
 | 
				
			||||
plt.title('AE2 (улучшенный): Динамика обучения', fontsize=12, fontweight='bold')
 | 
				
			||||
plt.xlabel('Эпоха')
 | 
				
			||||
plt.ylabel('MSE')
 | 
				
			||||
plt.legend()
 | 
				
			||||
plt.grid(True, alpha=0.3)
 | 
				
			||||
 | 
				
			||||
plt.subplot(1, 3, 2)
 | 
				
			||||
plt.plot(reconstruction_errors_ae2_improved, 'green', alpha=0.7, linewidth=0.8)
 | 
				
			||||
plt.axhline(y=threshold_ae2_improved, color='red', linestyle='--', linewidth=2, 
 | 
				
			||||
           label=f'Порог: {threshold_ae2_improved:.4f}')
 | 
				
			||||
plt.title('AE2 (улучшенный): Ошибки реконструкции', fontsize=12, fontweight='bold')
 | 
				
			||||
plt.xlabel('Номер точки')
 | 
				
			||||
plt.ylabel('Ошибка реконструкции')
 | 
				
			||||
plt.legend()
 | 
				
			||||
plt.grid(True, alpha=0.3)
 | 
				
			||||
 | 
				
			||||
plt.subplot(1, 3, 3)
 | 
				
			||||
plt.hist(reconstruction_errors_ae2_improved, bins=20, alpha=0.7, color='green', edgecolor='black')
 | 
				
			||||
plt.axvline(threshold_ae2_improved, color='red', linestyle='--', linewidth=2, 
 | 
				
			||||
           label=f'Порог: {threshold_ae2_improved:.4f}')
 | 
				
			||||
plt.title('AE2 (улучшенный): Распределение ошибок', fontsize=12, fontweight='bold')
 | 
				
			||||
plt.xlabel('Ошибка реконструкции')
 | 
				
			||||
plt.ylabel('Частота')
 | 
				
			||||
plt.legend()
 | 
				
			||||
plt.grid(True, alpha=0.3)
 | 
				
			||||
 | 
				
			||||
plt.tight_layout()
 | 
				
			||||
plt.savefig('out/ae2_improved_results.png', dpi=300, bbox_inches='tight')
 | 
				
			||||
plt.show()
 | 
				
			||||
 | 
				
			||||
ae2_trained = ae2_improved
 | 
				
			||||
IRE2 = reconstruction_errors_ae2_improved
 | 
				
			||||
IREth2 = threshold_ae2_improved
 | 
				
			||||
 | 
				
			||||
print(f"\nОбучение улучшенного AE2 завершено!")
 | 
				
			||||
print(f"Количество фактических эпох: {len(history_ae2_improved.history['loss'])}")
 | 
				
			||||
```
 | 
				
			||||
 | 
				
			||||
**Описание:** Создается улучшенный автокодировщик AE2.
 | 
				
			||||
 | 
				
			||||
**АНАЛИЗ РЕЗУЛЬТАТОВ УЛУЧШЕННОГО AE2:**
 | 
				
			||||
 | 
				
			||||
Финальная ошибка MSE улучшенного AE2: 0.005074
 | 
				
			||||
 | 
				
			||||
Порог ошибки реконструкции улучшенного AE2: 0.060338
 | 
				
			||||
 | 
				
			||||
Количество фактических эпох: 5000
 | 
				
			||||
 | 
				
			||||

 | 
				
			||||
 | 
				
			||||
### Пункт №7. Подобрали подходящие параметры автокодировщика.
 | 
				
			||||
 | 
				
			||||
**Оценка качества AE2**
 | 
				
			||||
 | 
				
			||||
IDEAL = 0. Excess:  0.4111111111111112
 | 
				
			||||
 | 
				
			||||
IDEAL = 0. Deficit:  0.5
 | 
				
			||||
 | 
				
			||||
IDEAL = 1. Coating:  0.5
 | 
				
			||||
 | 
				
			||||
summa:  1.0
 | 
				
			||||
 | 
				
			||||
IDEAL = 1. Extrapolation precision (Approx):  0.9
 | 
				
			||||
 | 
				
			||||
AE2 (улучшенная архитектура [2-3-2-1-2-3-2]):
 | 
				
			||||
 | 
				
			||||
    Excess = 0.41 - УХУДШЕНИЕ: распознает 41% лишних областей, но это не так много
 | 
				
			||||
 | 
				
			||||
    Deficit = 0.50 - УЛУЧШЕНИЕ: пропускает 50% данных (было 41%)
 | 
				
			||||
 | 
				
			||||
    Coating = 0.50 - УЛУЧШЕНИЕ: охватывает 50% данных (было 39%)
 | 
				
			||||
 | 
				
			||||
    Approx = 0.90 - ЗНАЧИТЕЛЬНОЕ УЛУЧШЕНИЕ: близко к идеалу 1.0
 | 
				
			||||
 | 
				
			||||
**Описание:** AE2 после улучшения стал значительно лучше по основным метрикам аппроксимации.
 | 
				
			||||
 | 
				
			||||
### Пункт №7. Создание тестовой выборки.
 | 
				
			||||
 | 
				
			||||
					Загрузка…
					
					
				
		Ссылка в новой задаче