mirror of
https://github.com/wassname/Deep-reinforcement-learning-with-pytorch.git
synced 2026-09-09 11:13:45 +08:00
130 lines
4.6 KiB
Python
130 lines
4.6 KiB
Python
import numpy as np
|
|
from gridworld import GridWorld
|
|
|
|
def softmax(x):
|
|
'''Compute softmax values of array x.
|
|
|
|
@param x the input array
|
|
@return the softmax array
|
|
'''
|
|
return np.exp(x - np.max(x)) / np.sum(np.exp(x - np.max(x)))
|
|
|
|
|
|
def update_critic(utility_matrix, observation, new_observation,
|
|
reward, alpha, gamma, done):
|
|
'''Return the updated utility matrix
|
|
|
|
@param utility_matrix the matrix before the update
|
|
@param observation the state obsrved at t
|
|
@param new_observation the state observed at t+1
|
|
@param reward the reward observed after the action
|
|
@param alpha the step size (learning rate)
|
|
@param gamma the discount factor
|
|
@return the updated utility matrix
|
|
@return the estimation error delta
|
|
'''
|
|
u = utility_matrix[observation[0], observation[1]]
|
|
u_t1 = utility_matrix[new_observation[0], new_observation[1]]
|
|
delta = reward + ((gamma * u_t1) - u)
|
|
utility_matrix[observation[0], observation[1]] += alpha * delta
|
|
return utility_matrix, delta
|
|
|
|
def update_actor(state_action_matrix, observation, action, delta, beta_matrix=None):
|
|
'''Return the updated state-action matrix
|
|
|
|
@param state_action_matrix the matrix before the update
|
|
@param observation the state obsrved at t
|
|
@param action taken at time t
|
|
@param delta the estimation error returned by the critic
|
|
@param beta_matrix a visit counter for each state-action pair
|
|
@return the updated matrix
|
|
'''
|
|
col = observation[1] + (observation[0]*4)
|
|
if beta_matrix is None: beta = 1
|
|
else: beta = 1 / beta_matrix[action,col]
|
|
state_action_matrix[action, col] += beta * delta
|
|
return state_action_matrix
|
|
|
|
def main():
|
|
|
|
env = GridWorld(3, 4)
|
|
|
|
#Define the state matrix
|
|
state_matrix = np.zeros((3,4))
|
|
state_matrix[0, 3] = 1
|
|
state_matrix[1, 3] = 1
|
|
state_matrix[1, 1] = -1
|
|
print("State Matrix:")
|
|
print(state_matrix)
|
|
|
|
#Define the reward matrix
|
|
reward_matrix = np.full((3,4), -0.04)
|
|
reward_matrix[0, 3] = 1
|
|
reward_matrix[1, 3] = -1
|
|
print("Reward Matrix:")
|
|
print(reward_matrix)
|
|
|
|
#Define the transition matrix
|
|
transition_matrix = np.array([[0.8, 0.1, 0.0, 0.1],
|
|
[0.1, 0.8, 0.1, 0.0],
|
|
[0.0, 0.1, 0.8, 0.1],
|
|
[0.1, 0.0, 0.1, 0.8]])
|
|
|
|
state_action_matrix = np.random.random((4,12))
|
|
print("State-Action Matrix:")
|
|
print(state_action_matrix)
|
|
|
|
env.setStateMatrix(state_matrix)
|
|
env.setRewardMatrix(reward_matrix)
|
|
env.setTransitionMatrix(transition_matrix)
|
|
|
|
utility_matrix = np.zeros((3,4))
|
|
print("Utility Matrix:")
|
|
print(utility_matrix)
|
|
|
|
gamma = 0.999
|
|
alpha = 0.001 #constant step size
|
|
beta_matrix = np.zeros((4,12))
|
|
tot_epoch = 300000
|
|
print_epoch = 1000
|
|
|
|
for epoch in range(tot_epoch):
|
|
#Reset and return the first observation
|
|
observation = env.reset(exploring_starts=True)
|
|
for step in range(1000):
|
|
#Estimating the action through Softmax
|
|
col = observation[1] + (observation[0]*4)
|
|
action_array = state_action_matrix[:, col]
|
|
action_distribution = softmax(action_array)
|
|
action = np.random.choice(4, 1, p=action_distribution)
|
|
#To enable the beta parameter, enable the libe below
|
|
#and add beta_matrix=beta_matrix in the update actor function
|
|
#beta_matrix[action,col] += 1 #increment the counter
|
|
#Move one step in the environment and get obs and reward
|
|
new_observation, reward, done = env.step(action)
|
|
utility_matrix, delta = update_critic(utility_matrix, observation,
|
|
new_observation, reward, alpha, gamma, done)
|
|
state_action_matrix = update_actor(state_action_matrix, observation,
|
|
action, delta, beta_matrix=None)
|
|
observation = new_observation
|
|
if done: break
|
|
|
|
|
|
if(epoch % print_epoch == 0):
|
|
print("")
|
|
print("Utility matrix after " + str(epoch+1) + " iterations:")
|
|
print(utility_matrix)
|
|
print("")
|
|
print("State-Action matrix after " + str(epoch+1) + " iterations:")
|
|
print(state_action_matrix)
|
|
#Time to check the utility matrix obtained
|
|
print("Utility matrix after " + str(tot_epoch) + " iterations:")
|
|
print(utility_matrix)
|
|
print("State-Action matrix after " + str(tot_epoch) + " iterations:")
|
|
print(state_action_matrix)
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|