frameworks

This commit is contained in:
Junior
2024-03-06 22:40:09 +08:00
parent a0500f5111
commit ea146f8302
5 changed files with 296 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
import numpy as np
from GEO_parameters import GEO_Parameters
import torch
class GEOEnv:
def __init__(self, num_satellite = 1, num_carrier_wave = 100, num_beam = 1, num_user_dim = 32, delt_t =5, dataset = "month_2.txt", max_intervals = 8):
self.action_space = num_carrier_wave
self.user_space_dim = num_user_dim
self.user_space = num_user_dim * num_user_dim
self.delt_t = delt_t
self.beams = num_beam
self.satellite = num_satellite
self.steps_before_termination = 0
self.datas = []
self.dataset = dataset
self.num_data = len(self.datas)
self.state = np.zeros((self.action_space+1, self.user_space_dim, self.user_space_dim), dtype=np.uint8)
self.max_intervals = 8
def load_data(self):
with open(self.dataset, 'r') as f:
self.datas = f.readlines()
self.num_data = len(self.datas)
def compute_state(self, index):
# state = self.state.copy()
self.state[-1] = np.zeros_like(self.state[-1])
[date_t, beam_type, user, ap] = self.datas[index].split('\t')
user = int(user)
ap = int(ap)
beam_type = int(beam_type)
i = user//10
j = user%10
t = 0
if ap == 0:
t = beam_type
else:
t = -beam_type
self.state[-1][i][j] = t
return self.state
def compute_reward(self, action):
assert type(action) == int
assert action >= 0 and action < self.action_space
# 功率暂时不用
# 频谱效率
axis2_sum = np.sum(self.state, axis= 2)
matrix_sum = np.sum(axis2_sum, axis=1)
if (matrix_sum)
t = 0.0
for i in range(self.action_space):
if matrix_sum[i] == 0:
t += 1/self.action_space
else:
t += 1/self.action_space * matrix_sum[i]/self.max_intervals
# 用户满意率,即action所在的信道的最大可用带宽的满足程度
b = 0.0
acquire = matrix_sum[-1]
supply = self.max_intervals - matrix_sum[action]
b = min(1.0, acquire/supply)
# 如果用户被拒绝了会有一个非常大的惩罚
if abs(b) < 1e-7 or supply <= 0:
b = -1.0
# 载波共用的惩罚
c:float = 0
# 暂时不动
return t + b
def renew_environment():
pass
def step(self, action):
self.state = self.compute_state(self.steps_before_termination)
reward = self.compute_reward(action)
# self.pre
if __name__ == "__main__":
e = GEOEnv()
e.load_data()
print(len(e.datas))
state = e.compute_state(0)
print(state)
state[1][1][2] = 4
t = e.compute_reward(state, 1)
print(t)
+13
View File
@@ -0,0 +1,13 @@
import numpy as np
import matplotlib.pyplot as plt
class GEO_Parameters:
Mc = 0
state_dim = 0
def __init__(self, Mc, state_dim):
# M_c代表的是载波的数量
# state_dim 代表的是数据的维度
# 32 * 32 代表的
GEO_Parameters.Mc = Mc
GEO_Parameters.state_dim = state_dim
+155
View File
@@ -1,6 +1,15 @@
from collections import deque
import numpy as np
import torch
import GEO_parameters
from Replay_memory import Memory, Transaction
from model import Net
import torch.nn.functional as f
import matplotlib.pyplot as plt
from GEO_parameters import GEO_Parameters
def dev0(a, b):
a = a.detach().numpy()
@@ -23,3 +32,149 @@ def hard_update(target, source):
class DeepQNetwork:
def __init__(self, cap, n_actions, n_states, learning_rate, reward_decay, e_greedy, replace_target_iter, batch_size,e_greedy_increment=None):
self.memory = Memory(cap)
self.batch = None
self.state_batch = batch_size
self.action_batch = None
self.reward_batch = None
self.non_final_next_states = None
self.expected_state_action_values = None
self.state_action_values = None
self.n_states = n_states
self.n_actions = n_actions
self.lr = learning_rate
self.gamma = reward_decay
self.epsilon_max = e_greedy
self.replace_target_iter = replace_target_iter
self.batch_size = batch_size
self.epsilon_decay = e_greedy_increment
self.epsilon = 0 if e_greedy_increment is None else self.epsilon_max
self.learn_step_counter = 1
self.counter = GEO_parameters.state_dim
self.main_q_network = Net(n_states, n_actions) # 输入的nstates 应该是M_c+1
self.target_q_network = Net(n_states, n_actions)
self.optimizer = torch.optim.Adam(self.main_q_network.parameters(), self.lr)
self.cost_his = []
self.weight_dir = 'weight_DQN'
def replay(self):
if self.learn_step_counter % self.replace_target_iter == 0:
self.update_target_q_network()
if len(self.memory) <self.batch_size:
return
self.batch, self.state_batch, self.action_batch, self.reward_batch, self.non_final_next_states = self.make_mini_batch()
self.expected_state_action_values = self.get_expected_state_action_values()
self.update_main_q_network()
self.epsilon *= 0.9998
self.learn_step_counter += 1
def make_mini_batch(self):
transitions = self.memory.sample(self.batch_size)
batch = Transaction(*zip(*transitions))
state_batch = torch.cat(batch.state)
action_batch = torch.cat(batch.action)
reward_batch = torch.cat(batch.reward)
non_final_next_states = torch.cat([s for s in batch.next_state if s is not None])
return batch, state_batch, action_batch, reward_batch, non_final_next_states
def get_expected_state_action_values(self):
self.main_q_network.eval()
self.target_q_network.eval()
self.state_action_values = self.main_q_network
non_final_mask = torch.ByteTensor(tuple(map(lambda x : x is not None, self.batch.next_state))).bool()
next_state_values = torch.zeros(self.batch_size)
a_m = torch.zeros(self.batch_size).type(torch.LongTensor)
a_m[non_final_mask] = self.main_q_network(self.non_final_next_states).detach().max(1)[1]
a_m_non_final_next_states = a_m[non_final_mask].view(-1, 1)
next_state_values[non_final_mask] = self.target_q_network(
self.non_final_next_states
).gather(1, a_m_non_final_next_states).detach().squeeze()
expected_state_action_values = self.reward_batch + self.gamma * next_state_values.view(-1, 1)
return expected_state_action_values
def decide_action(self, state):
# self.epsilon = 0.5 * (1 / (self.epsilon + 1))
if self.epsilon < np.random.uniform():
self.main_q_network.eval()
with torch.no_grad():
action = self.main_q_network(state).detach().max(1)[1]
else:
action = self.LongTenser([np.random.randint(0, self.n_actions)])
return action.view(1, 1)
def update_main_q_network(self):
self.main_q_network.train()
loss = f.mse_loss(self.state_action_values, self.expected_state_action_values, reduction = 'mean')
self.cost_his.append(loss.item())
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
def update_target_q_network(self):
self.target_q_network.load_state_dict(self.main_q_network.state_dict())
def plot_cost(self):
plt.plot(np.arange(len(self.cost_his)), self.cost_his)
plt.xlabel('training step')
plt.ylabel('cost')
plt.show()
def binary(self, q):
self.counter = GEO_Parameters.state_dim - 1
t = torch.unsqueeze(q.max(1)[1], 1)
temp = torch.zeros_like(t)
temp_extend = temp.repeat(1, GEO_Parameters.state_dim)
n = temp
while torch.logical_not(torch.eq(n, t)):
t1 = t % 2
t2 = t >> 1
numColumns = temp_extend.shape[1]
new_tensor_left = temp_extend[:, :self.counter]
new_tensor_right = temp_extend[:, self.counter+1:numColumns]
temp_extend = torch.cat([new_tensor_left, new_tensor_right], 1)
self.counter -= 1
a1 = temp_extend
a1 = a1.float()
return a1
def load_weight_from_pkl(self, file_name):
checkpoint = torch.load(file_name)
self.main_q_network.load_state_dict(checkpoint['main_q_network_state_dict'])
self.target_q_network.load_state_dict(checkpoint['target_q_network_state_dict'])
self.optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
self.cost_his = checkpoint['loss']
def save_weight_to_pkl(self, file_name):
torch.save({
# 'epoch': epochs,
'main_q_network_state_dict': self.main_q_network.state_dict(),
'target_q_network_state_dict': self.target_q_network.state_dict(),
'optimizer_state_dict': self.optimizer.state_dict(),
'loss': self.cost_his,
}, file_name)
def update_replay_buffer(self, state, action, reward, next_state):
self.memory.push(state, action, reward, next_state)
+29
View File
@@ -0,0 +1,29 @@
from dqn import DeepQNetwork
from GEOEnv import GEOEnv
import matplotlib.pyplot as pyplot
class DRL:
def __init__(self, num_episodes):
self.env = GEOEnv()
self.agent = DeepQNetwork()
self.steps = 0
def interact(self, state):
action = self.agent.decide_action(state)
next_state, reward, done = self.env.step(action)
self.agent.update_replay_buffer(state, action, reward, next_state)
state = next_state
self.steps += 1
# update epsilon
return state, reward, done
def episodic_learn(self):
for episode in range(self.agent.max_episodes):
state = self.env.reset()
done = False
self.steps = 0
+5
View File
@@ -10,6 +10,11 @@ M = 16
class Net(nn.Module):
def __init__(self, n_input_channels, n_actions):
## input channels 是数据的输入的维度
## 每个状态是一个
## N * N * (M_c + 1)的tensor
## 其中 N * N 代表的是用户的数量 如果有1000个用户 大概为32
## 第M_c个matrix代表的是当前用户的申请或是离开
super(Net, self).__init__()
self.conv1 = nn.Conv2d(in_channels=n_input_channels, out_channels=16, kernel_size=5, stride=1, padding=0)
self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, stride=1, padding=0)