Как решить проблему плохой точности с классом меньшинства в глубоком обучении?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как решить проблему плохой точности с классом меньшинства в глубоком обучении?

Сообщение Anonymous »

Я учусь в магистратуре и хочу создать систему обнаружения аномалий на основе Autoencoder для извлечения признаков и CNN для мультиклассификации, но я столкнулся с проблемой в результатах при выполнении моего кода [проблема: когда я выполняю этот код на CICIDS, я получаю кайф результат по всем метрикам, но на NSL_KDD результаты для класса с большим количеством экземпляров дают высокую точность по всем метрикам, но в классах с небольшим количеством экземпляров дают плохие результаты.
Я использовал 2 набора данных CICIDS2017,NSL_KDD
Набор данных предварительно обработан и разделен на две ветви: одна для обучения, а дисбаланс в этом наборе данных обработан с использованием SMOTE, а другой набор тестовых данных.
пожалуйста, помогите мне решить эту проблему. Мне потребовался месяц, чтобы решить ее, но мне это не удалось.
`This is the code:
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
import random

# ضبط SEED لضمان النتائج المتكررة
SEED = 42
def set_seed(seed):
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
np.random.seed(seed)
random.seed(seed)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False

set_seed(SEED)

# تعريف نموذج Autoencoder مع Attention
class AutoencoderWithAttention(nn.Module):
def __init__(self, input_dim, encoding_dim):
super(AutoencoderWithAttention, self).__init__()
self.encoder = nn.Sequential(
nn.Linear(input_dim, 256),
nn.ReLU(),
nn.Linear(256, 128),
nn.ReLU(),
nn.Linear(128, encoding_dim)
)
self.attention = nn.Sequential(
nn.Linear(encoding_dim, encoding_dim),
nn.Tanh(),
nn.Linear(encoding_dim, 1),
nn.Softmax(dim=1)
)
self.decoder = nn.Sequential(
nn.Linear(encoding_dim, 128),
nn.ReLU(),
nn.Linear(128, 256),
nn.ReLU(),
nn.Linear(256, input_dim)
)

def forward(self, x):
encoded = self.encoder(x)
attention_weights = self.attention(encoded)
attended_features = encoded * attention_weights
decoded = self.decoder(attended_features)
return decoded, attended_features

# تعريف CNN مع تحسين الأبعاد
class CNNClassifier(nn.Module):
def __init__(self, input_dim, num_classes):
super(CNNClassifier, self).__init__()
self.reshape_dim = int(np.ceil(np.sqrt(input_dim)))
self.pad_size = self.reshape_dim * self.reshape_dim - input_dim

self.features = nn.Sequential(
nn.Conv2d(1, 32, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, kernel_size=3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
)
self.flat_features = 64 * (self.reshape_dim // 4) * (self.reshape_dim // 4)
self.classifier = nn.Sequential(
nn.Linear(self.flat_features, 128),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(128, num_classes)
)

def forward(self, x):
batch_size = x.size(0)
if self.pad_size > 0:
padding = torch.zeros(batch_size, self.pad_size, device=x.device)
x = torch.cat([x, padding], dim=1)
x = x.view(-1, 1, self.reshape_dim, self.reshape_dim)
x = self.features(x)
x = x.view(-1, self.flat_features)
x = self.classifier(x)
return x

def train_and_evaluate_with_attention(resampled_data_, testing_df):
scaler = StandardScaler()
X_train = resampled_data_.drop('Class', axis=1).values
y_train = resampled_data_['Class'].values
X_test = testing_df.drop('Class', axis=1).values
y_test = testing_df['Class'].values

# Standardization
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

X_train_tensor = torch.FloatTensor(X_train_scaled)
X_test_tensor = torch.FloatTensor(X_test_scaled)
y_train_tensor = torch.LongTensor(y_train.astype(np.int64))
y_test_tensor = torch.LongTensor(y_test.astype(np.int64))

train_dataset = TensorDataset(X_train_tensor, y_train_tensor)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, generator=torch.Generator().manual_seed(SEED))

input_dim = X_train.shape[1]
encoding_dim = int(np.ceil(np.sqrt(input_dim)) ** 2)

# تدريب Autoencoder
autoencoder = AutoencoderWithAttention(input_dim, encoding_dim)
criterion_ae = nn.MSELoss()
optimizer_ae = optim.Adam(autoencoder.parameters(), lr=0.001, weight_decay=1e-5) # إضافة weight_decay لـ L2 regularization

print("Training Autoencoder...")
for epoch in range(20):
total_loss = 0
for batch_X, _ in train_loader:
optimizer_ae.zero_grad()
decoded, _ = autoencoder(batch_X)
loss = criterion_ae(decoded, batch_X)
loss.backward()
optimizer_ae.step()
total_loss += loss.item()

print(f"Epoch [{epoch+1}/20], Autoencoder Loss: {total_loss / len(train_loader):.4f}")

with torch.no_grad():
_, train_encoded = autoencoder(X_train_tensor)
_, test_encoded = autoencoder(X_test_tensor)

# عرض بعض الميزات المستخرجة
print("\n=== Extracted Features from Autoencoder ===")
print("First few features of training data:", train_encoded[:5].cpu().numpy())

# تدريب CNN
num_classes = len(np.unique(y_train))
cnn = CNNClassifier(encoding_dim, num_classes)

# إضافة weight_decay لـ L2 regularization
class_weights = torch.tensor([1.0 / y_train_tensor.bincount() for i in range(num_classes)], dtype=torch.float32).to(torch.device("cpu"))
criterion_cnn = nn.CrossEntropyLoss(weight=class_weights)
optimizer_cnn = optim.Adam(cnn.parameters(), lr=0.001, weight_decay=1e-5) # إضافة weight_decay لـ L2 regularization

train_encoded_dataset = TensorDataset(train_encoded, y_train_tensor)
train_encoded_loader = DataLoader(train_encoded_dataset, batch_size=64, shuffle=True, generator=torch.Generator().manual_seed(SEED))

print("\nTraining CNN...")
for epoch in range(30):
total_loss = 0
for batch_X, batch_y in train_encoded_loader:
optimizer_cnn.zero_grad()
outputs = cnn(batch_X)
loss = criterion_cnn(outputs, batch_y)
loss.backward()
optimizer_cnn.step()
total_loss += loss.item()

print(f"Epoch [{epoch+1}/30], CNN Loss: {total_loss / len(train_encoded_loader):.4f}")

autoencoder.eval()
cnn.eval()
with torch.no_grad():
test_outputs = cnn(test_encoded)
_, predicted = torch.max(test_outputs.data, 1)

y_pred = predicted.numpy()
print("\n=== Classification Report ===")
print(classification_report(y_test, y_pred))

plt.figure(figsize=(10, 8))
conf_matrix = confusion_matrix(y_test, y_pred)
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues')
plt.title('Confusion Matrix')
plt.ylabel('True Label')
plt.xlabel('Predicted Label')
plt.show()

return autoencoder, cnn

# استدعاء الدالة مع البيانات المخصصة
autoencoder_with_attention, cnn = train_and_evaluate_with_attention(resampled_data_, testing_df)

the results on sample data from CICIDS-2017:
precision recall f1-score support

0 1.00 1.00 1.00 8703
1 1.00 1.00 1.00 4870
2 1.00 1.00 1.00 5382

accuracy 1.00 18955
macro avg 1.00 1.00 1.00 18955
weighted avg 1.00 1.00 1.00 18955

the result on NSL_KDD:
precision recall f1-score support

0 1.00 1.00 1.00 8271
1 1.00 0.97 0.98 12042
2 0.96 0.99 0.98 2037
3 0.39 0.95 0.55 183
4 0.15 0.73 0.24 11

accuracy 0.98 22544
macro avg 0.70 0.93 0.75 22544
weighted avg 0.99 0.98 0.98 22544`


Подробнее здесь: https://stackoverflow.com/questions/792 ... p-learning
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»