2
$\begingroup$

I'm currently trying to develop an RL that will teach itself to play the popular fighting game "Tekken 7". I initially had the idea of teaching it to play generally- against actual opponents with various levels of difficulty- but the idea proved to be rather complex. I've liquefied the goal down to "get a non-active standing opponent to 0 health as fast as possible".

I have some experience with premade OpenAI environments, and tried making my own environment for this specific purpouse, but this proved to be rather difficult as there was no user friendly documentation.

Below is a DQN that was coded along with the help of a YouTube tutorial

import numpy as np
from tensorflow.keras.layers import Dense, Activation
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import Adam


class ReplayBuffer(object):
    def __init__(self, max_size, input_shape, n_actions, discrete=False):
        self.mem_size = max_size#memory size dictated
        self.discrete = discrete#determines a number of discrete values that can be inputted
        self.state_memory = np.zeros((self.memsize, input_shape))
        self.new_state_memory = np.zeros((self.mem_size, input_shape))
        dtype = np.int8 if self.discrete else np.float32
        self.action_memory = np.zeros((self.mem_size, n_actions))
        self.reward_memory = np.zeros(self.mem_size)
        self.terminal_memory = np.zeros(self.mem_size, dtype = np.float32)


    def store_transition(self, state, action, reward, state, done):
        index = self.mem_cntr % self.mem_size
        self.state_memory[index] = state
        self.new_state_memory[index] = state_
        self.reward_memory[index] = reward
        self.terminal_memory[index] = 1 - int(done)
        if self.discrete:
            actions = np.zeros(self.action_memory.shape[1])
            self.action_memory[index] = actions
        else:
            self.action_memory[index] = action
        self.mem_cntr += 1


    def sample_buffer(self, batch_size):
        max_mem = min(self.mem_cntr, self.mem_size)
        batch = np.random.choice(max_mem, batch_size)

        states = self,state_memory[batch]
        states_ = self.new_state_memory[batch]
        rewards = self.reward_memory[batch]
        actions = self.action_memory[batch]
        terminal = self.terminal_memory[batch]

        return states, actions, rewards, states_, terminal


    def build_dqn(lr, n_actions, input_dims, fcl_dims, fc2_dims):
        model = Sequential([
                    Dense (fcl_dims, input_shape = (input_dims, )),
                    Activation('relu')
                    Dense(fc2_dims),
                    Activation('relu')
                    Dense(n_actions)])

        model.comile(optimizer = Adam(lr = lr), loss = 'mse')

        return model

    class Agent(object):
        def __init__(self, alpha, gamma, n_actions, epsilon, batch_size,
                     input_dims, epsilon_dec=0.996, epsilon_end=0.01,
                     mem_size = 1000000, fname = 'dqn_model.h5'):
            self.action_space = [i for i in range(n_actions)]
            self.n_actions = n_actions
            self.gamma = gamma
            self.epsilon = epsilon
            self.epsilon_dec = epsilon_dec
            self.epsilon_min = eps_end
            self.batch_size = batch_size
            self.model_file = fname

            self.memory = ReplayBuffer(mem_size, input_dims, n_actions,
                                       discrete = True)
            self.q_eval = build_dqn(alpha, n_actions, input_dims, 256, 256)

        def remember(self, state, action, reward, new_state, done):
            self.memory.store_transition(state, action, reward, new_state, done)

        def choose_action(self, state):
            state = state[np.newaxis, :]
            rand = np.random.radnom()
            if rand < self.epsilon:
                action = np.random.choice(self.action_space)
            else:
                actions = slef.q.eval.predict(state)
                action = np.argmax(actions)

            return action

        def learn(self):#temporal difference learning, delta between steps \
            #and learns from this
            #
            #using numpy.zero approach, only drawback \
            #is that batch size of memory must be full before learning
            if self.memory.mem_cntr < self.batch_size:
                return
            state, action, reward, new_state, done = \
                                    self.memory.sample_buffer(self.batch_size)


            action_values = np.arary(self.action_space, dtype = np.int8)
            action_indices = np.dot(action, action_values)

            q_eval = self.q_eval.predict(state)
            q_next = self.q_eval.predict(new_state)

            q_target = q.eval.copy()

            batch_index = np.arrange(self.batch_size, dtype = np.int32)

            q_target[batch_index, action_indices] = reward + \
                                    self.gamma*np.max(q_next, axis=1)*done

            _ = self.q_eval.fit(state, q_target, verbose=0)

            self.epsilon = self.epsilon*epsilon_dec if self.epsilon > \
                           self.epsilon_min else self.epsilon_min

            def save_model(self):
                self.q_eval.save(self.model.file)

            def load_model(self):
                self.q_eval = load.model(self.model_file)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.