File size: 6,540 Bytes
068b166 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# Set random seed for reproducibility
np.random.seed(42)
torch.manual_seed(42)
# Number of samples per superhero
N_per_class = 200
# List of female superheroes
superheroes = ['Wonder Woman', 'Captain Marvel', 'Black Widow', 'Storm', 'Supergirl']
# Total number of classes
num_classes = len(superheroes)
# Total number of samples
N = N_per_class * num_classes
# Number of original features
D = 5 # Strength, Speed, Intelligence, Durability, Energy Projection
# Update the total number of features after adding the interaction term
total_features = D + 1 # Original features plus the interaction term
# Initialize feature matrix X and label vector y
X = np.zeros((N, total_features))
y = np.zeros(N, dtype=int)
# Define the mean and standard deviation for each feature per superhero
# Features: [Strength, Speed, Intelligence, Durability, Energy Projection]
superhero_stats = {
'Wonder Woman': {
'mean': [9, 9, 8, 9, 8],
'std': [0.5, 0.5, 0.5, 0.5, 0.5]
},
'Captain Marvel': {
'mean': [10, 9, 7, 10, 10],
'std': [0.5, 0.5, 0.5, 0.5, 0.5]
},
'Black Widow': {
'mean': [5, 7, 8, 6, 2],
'std': [0.5, 0.5, 0.5, 0.5, 0.5]
},
'Storm': {
'mean': [6, 7, 8, 6, 9],
'std': [0.5, 0.5, 0.5, 0.5, 0.5]
},
'Supergirl': {
'mean': [10, 10, 8, 10, 9],
'std': [0.5, 0.5, 0.5, 0.5, 0.5]
},
}
# Generate synthetic data for each superhero with non-linear relationships
for idx, hero in enumerate(superheroes):
start = idx * N_per_class
end = (idx + 1) * N_per_class
means = superhero_stats[hero]['mean']
stds = superhero_stats[hero]['std']
X_hero = np.random.normal(means, stds, (N_per_class, D))
# Ensure feature values are within reasonable ranges before computing interaction
X_hero = np.clip(X_hero, 1, 10)
# Introduce non-linear feature interactions
interaction_term = np.sin(X_hero[:, 1]) * np.log(X_hero[:, 4]) # Interaction between Speed and Energy Projection
X_hero = np.hstack((X_hero, interaction_term.reshape(-1, 1)))
X[start:end] = X_hero
y[start:end] = idx
# Ensure all feature values are within reasonable ranges
X[:, :D] = np.clip(X[:, :D], 1, 10)
# Shuffle the dataset
X, y = shuffle(X, y, random_state=42)
# Normalize the features
scaler = StandardScaler()
X = scaler.fit_transform(X)
# Split data into training and test sets
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42)
# Convert data to torch tensors
X_train_tensor = torch.from_numpy(X_train).float()
y_train_tensor = torch.from_numpy(y_train).long()
X_test_tensor = torch.from_numpy(X_test).float()
y_test_tensor = torch.from_numpy(y_test).long()
# Random prediction function
def random_prediction(X):
num_samples = X.shape[0]
random_preds = np.random.randint(num_classes, size=num_samples)
return random_preds
# Random prediction and evaluation
random_preds = random_prediction(X_test)
random_accuracy = (random_preds == y_test).sum() / y_test.size
print('Random Prediction Accuracy: {:.2f}%'.format(100 * random_accuracy))
# Define Linear Model
class LinearModel(nn.Module):
def __init__(self, input_dim, output_dim):
super(LinearModel, self).__init__()
self.linear = nn.Linear(input_dim, output_dim)
def forward(self, x):
return self.linear(x)
# Initialize Linear Model
input_dim = total_features
output_dim = num_classes
linear_model = LinearModel(input_dim, output_dim)
# Loss and optimizer for Linear Model
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(linear_model.parameters(), lr=0.01, weight_decay=1e-4)
# Training the Linear Model
num_epochs = 100
for epoch in range(num_epochs):
linear_model.train()
outputs = linear_model(X_train_tensor)
loss = criterion(outputs, y_train_tensor)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 20 == 0:
print('Linear Model - Epoch [{}/{}], Loss: {:.4f}'.format(
epoch + 1, num_epochs, loss.item()))
# Evaluate Linear Model
linear_model.eval()
with torch.no_grad():
outputs = linear_model(X_test_tensor)
_, predicted = torch.max(outputs.data, 1)
linear_accuracy = (predicted == y_test_tensor).sum().item() / y_test_tensor.size(0)
print('Linear Model Accuracy: {:.2f}%'.format(100 * linear_accuracy))
# Define Neural Network Model with regularization
class NeuralNet(nn.Module):
def __init__(self, input_dim, hidden_dims, output_dim):
super(NeuralNet, self).__init__()
layers = []
in_dim = input_dim
for h_dim in hidden_dims:
layers.append(nn.Linear(in_dim, h_dim))
layers.append(nn.ReLU())
layers.append(nn.BatchNorm1d(h_dim))
layers.append(nn.Dropout(0.3))
in_dim = h_dim
layers.append(nn.Linear(in_dim, output_dim))
self.model = nn.Sequential(*layers)
def forward(self, x):
return self.model(x)
# Initialize Neural Network Model
hidden_dims = [128, 64, 32]
neural_model = NeuralNet(input_dim, hidden_dims, output_dim)
# Loss and optimizer for Neural Network Model
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(neural_model.parameters(), lr=0.001, weight_decay=1e-4)
# Training the Neural Network Model
num_epochs = 200
for epoch in range(num_epochs):
neural_model.train()
outputs = neural_model(X_train_tensor)
loss = criterion(outputs, y_train_tensor)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 20 == 0:
print('Neural Network - Epoch [{}/{}], Loss: {:.4f}'.format(
epoch + 1, num_epochs, loss.item()))
# Evaluate Neural Network Model
neural_model.eval()
with torch.no_grad():
outputs = neural_model(X_test_tensor)
_, predicted = torch.max(outputs.data, 1)
neural_accuracy = (predicted == y_test_tensor).sum().item() / y_test_tensor.size(0)
print('Neural Network Model Accuracy: {:.2f}%'.format(100 * neural_accuracy))
# Summary of Accuracies
print("\nSummary of Accuracies:")
print('Random Prediction Accuracy: {:.2f}%'.format(100 * random_accuracy))
print('Linear Model Accuracy: {:.2f}%'.format(100 * linear_accuracy))
print('Neural Network Model Accuracy: {:.2f}%'.format(100 * neural_accuracy))
|