Skip to content

Commit fa6ff8e

Browse files
authored
fix: fix some bugs in knowledge base (microsoft#378)
* fix a bug in dig_recognizer * fix some bug in rag * fix a ci error
1 parent c1d94b5 commit fa6ff8e

File tree

6 files changed

+102
-9
lines changed

6 files changed

+102
-9
lines changed

rdagent/app/kaggle/loop.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def __init__(self, PROP_SETTING: BasePropSetting):
4141
if PROP_SETTING.knowledge_base != ""
4242
else None
4343
)
44-
logger.log_object(knowledge_base, tag="knowledge_base")
44+
logger.log_object(knowledge_base.__dict__, tag="knowledge_base")
4545

4646
self.hypothesis_gen: HypothesisGen = import_class(PROP_SETTING.hypothesis_gen)(scen)
4747
logger.log_object(self.hypothesis_gen, tag="hypothesis generator")

rdagent/core/knowledge_base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ def load(self) -> None:
1414
if self.path is not None and self.path.exists():
1515
with self.path.open("rb") as f:
1616
self.__dict__.update(
17-
pickle.load(f).__dict__,
17+
pickle.load(f),
1818
) # TODO: because we need to align with init function, we need a less hacky way to do this
1919

2020
def dump(self) -> None:
2121
if self.path is not None:
2222
self.path.parent.mkdir(parents=True, exist_ok=True)
23-
pickle.dump(self, self.path.open("wb"))
23+
pickle.dump(self.__dict__, self.path.open("wb"))
2424
else:
2525
logger.warning("KnowledgeBase path is not set, dump failed.")

rdagent/scenarios/kaggle/experiment/digit-recognizer_template/fea_share_preprocess.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,6 @@ def clean_and_impute_data(X_train, X_valid, X_test):
5757
then imputes missing values using the mean strategy.
5858
Also removes duplicate columns.
5959
"""
60-
# Replace inf and -inf with NaNa
61-
X_train.replace([np.inf, -np.inf], np.nan, inplace=True)
62-
X_valid.replace([np.inf, -np.inf], np.nan, inplace=True)
63-
X_test.replace([np.inf, -np.inf], np.nan, inplace=True)
64-
6560
# Impute missing values
6661
imputer = SimpleImputer(strategy="mean")
6762
X_train = pd.DataFrame(imputer.fit_transform(X_train), columns=X_train.columns)
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import pandas as pd
2+
import torch
3+
import torch.nn as nn
4+
import torch.nn.functional as F
5+
import torch.optim as optim
6+
from torch.utils.data import DataLoader, TensorDataset
7+
8+
9+
# Define the neural network model with Batch Normalization
10+
class NeuralNetwork(nn.Module):
11+
def __init__(self, input_channels, num_classes):
12+
super(NeuralNetwork, self).__init__()
13+
self.conv1 = nn.Conv2d(in_channels=input_channels, out_channels=30, kernel_size=(3, 3), stride=2)
14+
self.dropout1 = nn.Dropout(0.5)
15+
self.conv2 = nn.Conv2d(in_channels=30, out_channels=30, kernel_size=(3, 3), stride=2)
16+
self.dropout2 = nn.Dropout(0.5)
17+
self.flatten = nn.Flatten()
18+
self.fc1 = nn.Linear(30 * 6 * 6, 128) # Adjust based on your input size
19+
self.fc2 = nn.Linear(128, num_classes)
20+
21+
def forward(self, x):
22+
x = F.relu(self.conv1(x))
23+
x = self.dropout1(x)
24+
x = F.relu(self.conv2(x))
25+
x = self.dropout2(x)
26+
x = self.flatten(x)
27+
x = F.relu(self.fc1(x))
28+
x = F.softmax(self.fc2(x), dim=1)
29+
return x
30+
31+
32+
def fit(X_train: pd.DataFrame, y_train: pd.DataFrame, X_valid: pd.DataFrame, y_valid: pd.DataFrame):
33+
# Convert data to PyTorch tensors and reshape it for convolutional layers
34+
X_train_tensor = (
35+
torch.tensor(X_train.values, dtype=torch.float32).view(-1, 1, 28, 28).to(device)
36+
) # Reshape and move to GPU
37+
y_train_tensor = torch.tensor(y_train.values, dtype=torch.long).to(device)
38+
X_valid_tensor = torch.tensor(X_valid.values, dtype=torch.float32).view(-1, 1, 28, 28).to(device)
39+
y_valid_tensor = torch.tensor(y_valid.values, dtype=torch.long).to(device)
40+
41+
# Create datasets and dataloaders
42+
train_dataset = TensorDataset(X_train_tensor, y_train_tensor)
43+
valid_dataset = TensorDataset(X_valid_tensor, y_valid_tensor)
44+
train_loader = DataLoader(train_dataset, batch_size=128, shuffle=True)
45+
valid_loader = DataLoader(valid_dataset, batch_size=128, shuffle=False)
46+
47+
# Initialize the model, loss function and optimizer
48+
model = NeuralNetwork(input_channels=1, num_classes=len(set(y_train))).to(device)
49+
criterion = nn.CrossEntropyLoss().to(device)
50+
optimizer = optim.Adam(model.parameters(), lr=0.0005)
51+
52+
# Train the model
53+
num_epochs = 400
54+
for epoch in range(num_epochs):
55+
model.train()
56+
for X_batch, y_batch in train_loader:
57+
optimizer.zero_grad()
58+
outputs = model(X_batch)
59+
loss = criterion(outputs, y_batch)
60+
loss.backward()
61+
optimizer.step()
62+
63+
# Validate the model
64+
model.eval()
65+
valid_loss = 0
66+
correct = 0
67+
with torch.no_grad():
68+
for X_batch, y_batch in valid_loader:
69+
outputs = model(X_batch)
70+
valid_loss += criterion(outputs, y_batch).item()
71+
_, predicted = torch.max(outputs, 1)
72+
correct += (predicted == y_batch).sum().item()
73+
74+
accuracy = correct / len(valid_loader.dataset)
75+
print(f"Epoch {epoch+1}/{num_epochs}, Validation Accuracy: {accuracy:.4f}")
76+
77+
return model
78+
79+
80+
def predict(model, X):
81+
X_tensor = torch.tensor(X.values, dtype=torch.float32).view(-1, 1, 28, 28).to(device)
82+
model.eval()
83+
with torch.no_grad():
84+
outputs = model(X_tensor)
85+
_, predicted = torch.max(outputs, 1)
86+
return predicted.cpu().numpy().reshape(-1, 1)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import pandas as pd
2+
3+
4+
def select(X: pd.DataFrame) -> pd.DataFrame:
5+
"""
6+
Select relevant features. To be used in fit & predict function.
7+
"""
8+
# For now, we assume all features are relevant. This can be expanded to feature selection logic.
9+
if X.columns.nlevels == 1:
10+
return X
11+
X.columns = ["_".join(str(col)).strip() for col in X.columns.values]
12+
return X

rdagent/scenarios/kaggle/experiment/digit-recognizer_template/train.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,6 @@ def import_module_from_path(module_name, module_path):
8383

8484
# TODO: fix selection
8585
print(X_valid_selected.columns)
86-
y_test_pred = model_l[min_index][1](model_l[min_index][0], model_l[min_index][2].select(X_test))
86+
y_test_pred = model_l[min_index][1](model_l[min_index][0], model_l[min_index][2].select(X_test)).flatten()
8787
submission_result = pd.DataFrame({"ImageId": ids, "Label": y_test_pred})
8888
submission_result.to_csv("submission.csv", index=False)

0 commit comments

Comments
 (0)