Skip to content

Weighted Belief updates #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 24 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
268493d
setting up each agent to store past messages from all agents
weihangzheng Feb 9, 2024
9151e24
fix loop
weihangzheng Feb 9, 2024
48345c2
adding probability model
weihangzheng Feb 9, 2024
697d21d
connected toy model weight update to nepiada pipeline
weihangzheng Feb 9, 2024
7484882
updating beliefs via weight instead of D value
weihangzheng Feb 10, 2024
eb5c51a
added base framework for model based belief updates
weihangzheng Feb 10, 2024
f39b1e2
saved model as file and loaded it into pipeline
weihangzheng Feb 11, 2024
6c06e25
code to generate and a real dataset itself
weihangzheng Feb 11, 2024
2df0b7a
added fitting of the model to the real data
weihangzheng Feb 11, 2024
aa7f8b9
harded but looking back k iterations makes the hyperplane split better
weihangzheng Feb 13, 2024
d2ca2dc
POC of hyperplane split
weihangzheng Feb 13, 2024
9232879
make tried longer stretches
weihangzheng Feb 13, 2024
15b6d72
fix stuff
weihangzheng Feb 15, 2024
811b01d
generalization comparison script
weihangzheng Feb 15, 2024
2f75e33
new model testing pipelines and datasets
weihangzheng Feb 15, 2024
35f21d3
datasets
weihangzheng Feb 15, 2024
e89e41a
k-means promising
weihangzheng Mar 7, 2024
3f19c72
feature ann
weihangzheng Mar 7, 2024
9569f01
trying constant and mixed adv
weihangzheng Mar 8, 2024
67f316d
fix online k-means
weihangzheng Mar 8, 2024
9d4c6f9
E2E works almost
weihangzheng Mar 9, 2024
6a0b629
E2E works
weihangzheng Mar 9, 2024
d47f080
plot.py
weihangzheng Apr 7, 2024
d542282
parallel batch testing
weihangzheng Apr 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added src/nepiada/adversarial_0_traj.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/nepiada/all_traj.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions src/nepiada/baseline.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,29 @@ def strip_extreme_values_and_update_beliefs(
curr_beliefs[current_agent][1] + y_pos_delta,
)

def weighted_beliefs(incoming_messages, new_beliefs, agent_name, all_agents, agent_instance):
#print(agent_name)
for target_agent in all_agents:
positions = []
for talking_agent in all_agents:
if target_agent in incoming_messages and \
talking_agent in incoming_messages[target_agent]:
positions.append(incoming_messages[target_agent][talking_agent])
else:
positions.append(None)
finalx, finaly, denom, empty = 0,0,0, True
for i in range(len(positions)):
if(positions[i] != None):
empty = False
finalx += positions[i][0]*agent_instance.truthful_weights[i]
finaly += positions[i][1]*agent_instance.truthful_weights[i]
denom += agent_instance.truthful_weights[i]
if(not empty):
new_beliefs[target_agent] = (finalx/denom, finaly/denom)
elif (agent_instance.beliefs[target_agent] is not None):
new_beliefs[target_agent] = (agent_instance.beliefs[target_agent][0], agent_instance.beliefs[target_agent][1])
#print(target_agent)
#print(positions)

def step(agent_name, agent_instance, observations, infos, env, config):

Expand All @@ -156,6 +179,7 @@ def step(agent_name, agent_instance, observations, infos, env, config):
# Incoming messages should never be None after the first step

if "incoming_messages" in infos:
"""
strip_extreme_values_and_update_beliefs(
config.D,
infos["incoming_messages"],
Expand All @@ -164,6 +188,8 @@ def step(agent_name, agent_instance, observations, infos, env, config):
agent_name,
env.agents,
)
"""
weighted_beliefs(infos["incoming_messages"], new_beliefs, agent_name, env.agents, agent_instance)

# Calculate the cost for every possible action
action_costs = {}
Expand Down
76 changes: 74 additions & 2 deletions src/nepiada/env/nepiada.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import os
import matplotlib.pyplot as plt

from utils.agent_model import *
from utils.online_k import *

def parallel_env(config: Config):
"""
Expand All @@ -25,7 +27,7 @@ def parallel_env(config: Config):
only supported in AEC environments.
"""
internal_render_mode = "human"
env = raw_env(render_mode=internal_render_mode, config=config)
env = raw_env(render_mode=None, config=config)
env = parallel_to_aec(env)
# this wrapper helps error handling for discrete action spaces
env = wrappers.AssertOutOfBoundsWrapper(env)
Expand Down Expand Up @@ -145,7 +147,7 @@ def get_observations(self):
def get_all_messages(self):
"""
The 2xNxNxN message structure returned below are the coordinates that each drone receives from a drone about another drone
observations[i][j][k] is the location that drone i is told by drone k where drone j is
incoming_all_messages[i][j][k] is the location that drone i is told by drone k where drone j is
"""
incoming_all_messages = {}
for agent_name in self.agents:
Expand Down Expand Up @@ -178,6 +180,70 @@ def get_all_messages(self):
] = incoming_communcation_messages

incoming_all_messages[agent_name] = incoming_agent_messages

for agent_name in self.agents:
#print(agent_name)
curr_agent = self.world.get_agent(agent_name)
for talking_agent in self.agents:
#print(talking_agent)
incoming_messages = []

for target_agent in self.agents:
# Check if the keys exist in the nested dictionary
if agent_name in incoming_all_messages and \
target_agent in incoming_all_messages[agent_name] and \
talking_agent in incoming_all_messages[agent_name][target_agent]:

message = incoming_all_messages[agent_name][target_agent][talking_agent]
else:
# Handle the case where the key doesn't exist
# This could be a default value or a special indicator
message = None # or some default value

incoming_messages.append(message)

past = 5
agents = len(self.agents)
if(talking_agent not in curr_agent.last_messages):
curr_agent.last_messages[talking_agent] = [None]*(agents*(past-1))

curr_agent.last_messages[talking_agent].extend(incoming_messages)
if(len(curr_agent.last_messages[talking_agent]) > agents*past):
for i in range(agents):
curr_agent.last_messages[talking_agent].pop(0)

#print(curr_agent.last_messages[talking_agent])

#print(agent_name)

for agent_name in self.agents:
#print(agent_name)
curr_agent = self.world.get_agent(agent_name)
curr_agent.truthful_weights = []
#print(self.agents)
for target_agent in self.agents:
example_input = curr_agent.last_messages[target_agent]
# Check if example_input is not a list with all None elements
#print(example_input)
valid_intervals = all(any(x is not None for x in example_input[i:i+9]) for i in range(0, len(example_input), 9))
if valid_intervals:
# Determine the label based on the target_agent's name
#label = 0 if 'adversarial' in target_agent else 1
# Append example input and label to a txt file
#with open('data_1_5.txt', 'a') as file:
# file.write(f"{example_input}*{label}\n")
data_point = np.array([calculate(example_input)])
#curr_agent.model.partial_fit(processed_input.reshape(-1, 1))
curr_agent.model.partial_fit(data_point.reshape(-1, 1))
predicted_cluster = curr_agent.model.predict(data_point.reshape(-1, 1))[0]
#prob_adversarial = curr_agent.model.predict_proba([processed_input])
curr_agent.truthful_weights.append(predicted_cluster)
else:
curr_agent.truthful_weights.append(0.5) #update with midpoint 0.5 when unsure
for i in range(len(curr_agent.truthful_weights)):
if curr_agent.truthful_weights[i] == 0:
curr_agent.truthful_weights[i] = 0.1
#print(curr_agent.truthful_weights)
return incoming_all_messages

def initialize_beliefs(self):
Expand Down Expand Up @@ -271,6 +337,12 @@ def reset(self, seed=None, options=None):

self.initialize_beliefs()

for agent_name in self.agents:
curr_agent = self.world.get_agent(agent_name)
for target_argent in self.agents:
curr_agent.truthful_weights.append(1)
#print(curr_agent.truthful_weights)

print("NEPIADA INFO: Environment Reset Successful. All Checks Passed.")
return self.observations, self.infos

Expand Down
78 changes: 78 additions & 0 deletions src/nepiada/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import random
import pickle

k = 2 # Number of repetitions per agent

def preprocess_input(input_data):
processed_data = []
for item in input_data:
processed_data.extend(item if item is not None else [0, 0])
return processed_data

class AgentModel:
def __init__(self):
self.model = RandomForestClassifier(n_estimators=100)

def train(self, X, y):
self.model.fit(X, y)

def predict_proba(self, X):
return self.model.predict_proba(X)[:, 1] # Probability of being adversarial

def load_data_from_file(file_name):
X, y = [], []
with open(file_name, 'r') as file:
for line in file:
example_input_str, label_str = line.strip().split('*')
example_input = eval(example_input_str)
label = int(label_str)
processed_input = preprocess_input(example_input)
X.append(processed_input)
y.append(label)
return np.array(X), np.array(y)

# Load and preprocess the data from the file
file_name = '../tester/data.txt'
X, y = load_data_from_file(file_name)

# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

if __name__ == "__main__":
# Fit the model with the training data
agent_model = AgentModel()
agent_model.train(X_train, y_train)

# Initialize counters
correct_predictions_0, correct_predictions_1 = 0, 0
total_0, total_1 = 0, 0

for i, test_input in enumerate(X_test):
prob_adversarial = agent_model.predict_proba([test_input])[0]
predicted_label = 1 if prob_adversarial >= 0.5 else 0
actual_label = y_test[i]

if actual_label == 0:
total_0 += 1
if predicted_label == actual_label:
correct_predictions_0 += 1
elif actual_label == 1:
total_1 += 1
if predicted_label == actual_label:
correct_predictions_1 += 1

# Calculate and print accuracies
accuracy_0 = correct_predictions_0 / total_0 if total_0 != 0 else 0
accuracy_1 = correct_predictions_1 / total_1 if total_1 != 0 else 0
overall_accuracy = (correct_predictions_0 + correct_predictions_1) / len(X_test)

print(f"Model Accuracy for label 0: {accuracy_0}")
print(f"Model Accuracy for label 1: {accuracy_1}")
print(f"Overall Model Accuracy: {overall_accuracy}")

# Optionally, save the trained model
# with open('agent_model.pkl', 'wb') as file:
# pickle.dump(agent_model.model, file)
Binary file added src/nepiada/tester/agent_model.pkl
Binary file not shown.
Binary file added src/nepiada/tester/agent_model_5.pkl
Binary file not shown.
Empty file added src/nepiada/tester/data.txt
Empty file.
Loading