Beispiel #1
0
    def __init__(self,
                 init_model=None,
                 row=8,
                 column=8,
                 batch_size=200,
                 buffer_size=10000,
                 epochs=5,
                 game_batch_num=100,
                 n_games=1,
                 check_freq=10,
                 lr_multiplier=1.0,
                 use_gpu=True):
        self.row = row
        self.column = column
        self.init_model = init_model
        self.policy_network = PolicyNetwork(model_file=init_model,
                                            width=column,
                                            height=row)

        self.batch_size = batch_size
        self.buffer_size = buffer_size
        self.buffer = deque(maxlen=self.buffer_size)
        self.epochs = epochs
        self.game_batch_num = game_batch_num
        self.n_games = n_games

        self.kl_targ = 0.02  # the target value of KL Divergence
        self.lr_multiplier = lr_multiplier  # adjust the learning rate of the optimization algorithm
        self.check_freq = check_freq  # check every few game rounds to see if the algorithm is improving

        self.use_gpu = use_gpu
Beispiel #2
0
    def __init__(self, stock_code, chart_data, training_data=None,
                 min_trading_unit=1, max_trading_unit=2,
                 delayed_reward_threshold=0.05, l_rate=0.01):
        self.stock_code = stock_code 
        self.chart_data = chart_data

        # 환경 객체
        self.environment = Environment(chart_data)
        
        # 에이전트 객체
        self.agent = Agent(self.environment,
                           min_trading_unit=min_trading_unit,
                           max_trading_unit=max_trading_unit,
                           delayed_reward_threshold=delayed_reward_threshold)

        # 학습 데이터
        self.training_data = training_data 
        self.sample = None      # 여기서 sample도 training_data와 같이 17차원
        self.training_data_idx = -1

        # 정책 신경망의 Input layer에 들어오는 입력의 크기 또는 특징의 수(17) = 학습 데이터의 크기(15) + 에이전트 상태의 크기(2)
        # TODO self.training_data.shape의 [1]이 왜 학습 데이터의 크기인지 확인
        # TODO <해결> shape가 2차원이면 (n,15)일 것이고, 여기서 행은 전체 갯수이고, 열의 갯수가 학습 데이터의 크기로 들어갈 특징의 갯수일 것이다.
        #            shape가 2차원인 이유는 policy_network.py에서 설명했다.
        #              --> "Sequential 클래스의 predict() 함수는 여러 샘플을 한번에 받아서 신경망의 출력을 반환한다. 
        #                   하나의 샘플에 대한 결과만을 받고 싶어도 입력값을 샘플의 배열로 구성해야하기 때문에 2차원 배열로 재구성한다."
        self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM
        # 정책 신경망 객체
        self.policy_network = PolicyNetwork(
            input_dim=self.num_features, output_dim=self.agent.NUM_ACTIONS, l_rate=l_rate)
        
        # 가시화기 객체 (에포크마다 투자 결과 가시화)
        self.visualizer = Visualizer()  
Beispiel #3
0
 def __init__(self,
              stock_code,
              chart_data,
              training_data=None,
              min_trading_unit=1,
              max_trading_unit=2,
              delayed_reward_threshold=.05,
              lr=0.01):
     self.stock_code = stock_code  # 종목코드
     # 차트 데이터
     self.chart_data = chart_data
     # 환경
     self.environment = Environment(stock_code, chart_data)  # 환경 객체
     # 에이전트 객체
     self.agent = Agent(self.environment,
                        min_trading_unit=min_trading_unit,
                        max_trading_unit=max_trading_unit,
                        delayed_reward_threshold=delayed_reward_threshold)
     # 학습 데이터 매칭
     self.training_data = training_data  # 학습 데이터
     # 샘플 초기 상태
     self.sample = None
     # 현재 학습 데이터 인덱스
     self.training_data_idx = -1
     # 입력은 환경에서 발생하는 모든 요소를 반영한다.
     # 정책 신경망; 입력 크기 = 학습 데이터의 크기 + 에이전트 상태 크기
     self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM
     # 정첵 신경멍 객체 생성 및 매칭, 입력 계층 갯수, 출력 갯수, 학습률을 넣어 준다.
     self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                         output_dim=self.agent.NUM_ACTIONS,
                                         lr=lr)
     self.visualizer = Visualizer()  # 가시화 모듈
    def __init__(self,
                 coin_code,
                 coin_chart,
                 training_data=None,
                 model_ver=None,
                 min_trading_unit=1,
                 max_trading_unit=2,
                 delayed_reward_threshold=.05,
                 start_date=None,
                 end_date=None,
                 lr=0.01):

        self.coin_code = coin_code
        self.coin_chart = coin_chart

        self.environment = Environment(coin_chart)
        self.agent = Agent(self.environment,
                           min_trading_unit=min_trading_unit,
                           max_trading_unit=max_trading_unit,
                           delayed_reward_threshold=delayed_reward_threshold)

        self.training_data = training_data
        self.sample = None
        self.training_data_idx = -1

        self.model_ver = model_ver
        self.start_date = start_date
        self.end_date = end_date

        self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM
        self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                            output_dim=self.agent.NUM_ACTIONS,
                                            lr=lr,
                                            load_weight=self.model_ver)
Beispiel #5
0
    def __init__(self,
                 coin_code,
                 coin_chart,
                 training_data=None,
                 min_trading_unit=1,
                 max_trading_unit=2,
                 delayed_reward_threshold=.05,
                 lr=0.01):

        self.coin_code = coin_code
        self.coin_chart = coin_chart

        self.environment = Environment(coin_chart)
        self.agent = Agent(self.environment,
                           min_trading_unit=min_trading_unit,
                           max_trading_unit=max_trading_unit,
                           delayed_reward_threshold=delayed_reward_threshold)

        self.training_data = training_data
        self.sample = None
        self.training_data_idx = -1

        self.num_features = self.training_data.shape[
            1] + self.agent.STATE_DIM  # -1 # input_dim = 15 + 2 = 17
        self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                            output_dim=self.agent.NUM_ACTIONS,
                                            lr=lr)

        self.visualizer = Visualizer()
 def __init__(self,
              stock_code,
              chart_data,
              training_data=None,
              min_trading_unit=1,
              max_trading_unit=2,
              delayed_reward_threshold=.05,
              lr=0.01,
              tax=False):
     self.stock_code = stock_code  # Stock code
     self.chart_data = chart_data
     self.environment = Environment(chart_data)  # Environment object
     self.tax = tax
     # Agent object
     self.agent = Agent(self.environment,
                        min_trading_unit=min_trading_unit,
                        max_trading_unit=max_trading_unit,
                        delayed_reward_threshold=delayed_reward_threshold,
                        tax=tax)
     self.training_data = training_data  # Training data
     self.sample = None
     self.training_data_idx = -1
     # Policy neural network; Input size = size of training data + agent state size
     self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM
     self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                         output_dim=self.agent.NUM_ACTIONS,
                                         lr=lr)
     self.visualizer = Visualizer()  # Visualization module
Beispiel #7
0
 def __init__(self,
              stock_code,
              chart_data,
              training_data=None,
              min_trading_unit=1,
              max_trading_unit=2,
              delayed_reward_threshold=.05,
              lr=0.01):
     self.stock_code = stock_code  # 종목코드
     self.chart_data = chart_data
     self.environment = Environment(chart_data)  # 환경 객체
     # 에이전트 객체
     self.agent = Agent(self.environment,
                        min_trading_unit=min_trading_unit,
                        max_trading_unit=max_trading_unit,
                        delayed_reward_threshold=delayed_reward_threshold)
     self.training_data = training_data  # 학습 데이터
     self.samples = None
     self.training_data_idx = -1
     # 정책 신경망; 입력 크기 = 학습 데이터의 크기 + 에이전트 상태 크기
     self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM
     self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                         output_dim=self.agent.NUM_ACTIONS,
                                         lr=lr)
     self.visualizer = Visualizer()  # 가시화 모듈
Beispiel #8
0
 def __init__(self,
              stock_code,
              chart_data,
              training_data=None,
              min_trading_unit=1,
              max_trading_unit=2,
              delayed_reward_threshold=.05,
              lr=0.01):
     self.stock_code = stock_code  # 종목코드
     self.chart_data = chart_data
     self.environment = Environment(chart_data)  # 환경 객체
     # Environment 클래스는 차트 데이터를 순서대로 읽으면서 주가, 거래량 등의 환경을 제공한다.
     # 에이전트 객체
     self.agent = Agent(self.environment,
                        min_trading_unit=min_trading_unit,
                        max_trading_unit=max_trading_unit,
                        delayed_reward_threshold=delayed_reward_threshold)
     self.training_data = training_data  # 학습 데이터. 학습에 사용할 특징(feature)들을 포함한다.
     self.sample = None
     self.training_data_idx = -1
     # 정책 신경망; 입력 크기(17개) = 학습 데이터의 크기(15개) + 에이전트 상태 크기(2개)
     self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM
     self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                         output_dim=self.agent.NUM_ACTIONS,
                                         lr=lr)
     self.visualizer = Visualizer()  # 가시화 모듈
    def __init__(self,
                 stock_code,
                 chart_data,
                 training_data=None,
                 min_trading_unit=1,
                 max_trading_unit=2,
                 delayed_reward_threshold=0.05,
                 l_rate=0.01):

        self.stock_code = stock_code
        self.chart_data = chart_data

        self.environment = Environment(chart_data)

        self.agent = Agent(self.environment,
                           min_trading_unit=min_trading_unit,
                           max_trading_unit=max_trading_unit,
                           delayed_reward_threshold=delayed_reward_threshold)

        self.training_data = training_data
        self.sample = None
        self.training_data_idx = -1

        self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM

        self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                            output_dim=self.agent.NUM_ACTIONS,
                                            l_rate=l_rate)

        self.visualizer = Visualizer()
Beispiel #10
0
def main():
    # device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    device = torch.device("cpu")
    print("Device is: %s" % device)
    env = gym.make("CartPole-v1")
    steps = 500
    n = 200
    g = 0.99
    pi = PolicyNetwork(4, 256, 256, 2).to(device)

    optimizer = torch.optim.Adam(pi.parameters(), lr=1e-4)
    print("The action space for Cartpole is: %s" % env.action_space)
    gf = gfunc1
    returns = np.zeros(n)
    for i in range(200):
        mu = np.mean(returns[:i])
        std = np.std(returns[:i])
        if np.isnan(mu): mu = 0
        if np.isnan(std): std = 0
        loss, G = batch_roll_out(env, pi, g, steps, device, gf)
        returns[i] = G
        # how should I do gradient descent on the data;
        print("Iteration: %s; Loss: %s" % (i, loss))
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    testPolicy(env, pi, device, g)
    plot_return(returns, n)
    env.close()
Beispiel #11
0
    def _policy(self, board):
        '''Output the probability of different positions according to the board information.
        In this AlphaZero version, use the value network to judge the current situation.

        Input: Board state
        Output: An iterator of (action, probability) and a score for the current board state.
        '''
        policy_network = PolicyNetwork(width=board.row, height=board.column, model_file=self.model_file, use_gpu=self.use_gpu)
        return policy_network.policy_fn(board)
Beispiel #12
0
    def __init__(self, learning_rate, input_channels):
        super(Train, self).__init__()

        self.learning_rate = learning_rate
        self.batch_size = batch_size
        self.epochs = epochs
        self.reset()
        self.network = PolicyNetwork(input_channels)
        self.parameters = self.network.parameters()
        self.optimizer = optim.Adam(self.parameters, lr=self.learning_rate)
Beispiel #13
0
    def __init__(self, state_size, action_size, seed):
        self.state_size = state_size
        self.action_size = action_size
        self.seed = random.seed(seed)

        # Our policy network
        self.local_network = PolicyNetwork(state_size, action_size,
                                           seed).to(device)
        self.target_network = PolicyNetwork(state_size, action_size,
                                            seed).to(device)
        self.optimizer = optim.Adam(self.local_network.parameters(), lr=LR)

        # Replay memory
        self.memory = ReplayBuffer(action_size, BUFFER_SIZE, BATCH_SIZE, seed)
        # Initialize timestep
        self.t_step = 0
    def __init__(self,
                 stock_code,
                 chart_data,
                 training_data=None,
                 policy_model_path=None,
                 value_model_path=None,
                 lr=0.001,
                 discount_factor=0.5,
                 start_epsilon=0,
                 num_past_input=0,
                 load_weight_and_learn=False):
        self.stock_code = stock_code  # 종목코드
        self.chart_data = chart_data
        self.environment = Environment(chart_data)  # 환경 객체
        # 에이전트 객체
        self.agent = Agent(self.environment)
        self.training_data = training_data  # 학습 데이터
        self.training_data_idx = -1
        self.state = None
        self.action_size = self.agent.NUM_ACTIONS
        self.discount_factor = discount_factor
        self.start_epsilon = start_epsilon
        self.num_past_input = num_past_input
        self.load_weight_and_learn = load_weight_and_learn

        # 정책/가치 신경망; 입력 크기 = 학습 데이터의 크기 #+ 에이전트 상태 크기
        self.num_features = self.training_data.shape[1] * (
            1 + num_past_input)  #+ self.agent.STATE_DIM
        self.policy_network_obj = PolicyNetwork(
            input_dim=self.num_features,
            output_dim=self.agent.NUM_ACTIONS,
            lr=lr)
        if load_weight_and_learn is True:
            self.policy_network_obj.model = load_model(policy_model_path)
            self.policy_network = self.policy_network_obj.model
        else:
            self.policy_network = self.policy_network_obj.make_model()
        self.value_network_obj = ValueNetwork(input_dim=self.num_features,
                                              lr=lr)
        if load_weight_and_learn is True:
            self.value_network_obj.model = load_model(value_model_path)
            self.value_network = self.value_network_obj.model
        else:
            self.value_network = self.value_network_obj.make_model()
        self.policy_updater = self.policy_optimizer()
        self.value_updater = self.value_optimizer()
    def __init__(self, alpha, input_size, output_size):

        self.buffer = Buffer()

        self.value_network = ValueNetwork(alpha,
                                          input_size=input_size,
                                          output_size=1)

        self.policy_network = PolicyNetwork(0.0001,
                                            input_size=input_size,
                                            output_size=output_size)

        self.old_policy_network = PolicyNetwork(0.0001,
                                                input_size=input_size,
                                                output_size=output_size)

        # store policy state
        self.buffer.store_parameters(self.policy_network.state_dict())

        self.avg_rewards = []
Beispiel #16
0
class Train(nn.Module):
    def __init__(self, learning_rate, input_channels):
        super(Train, self).__init__()

        self.learning_rate = learning_rate
        self.batch_size = batch_size
        self.epochs = epochs
        self.reset()
        self.network = PolicyNetwork(input_channels)
        self.parameters = self.network.parameters()
        self.optimizer = optim.Adam(self.parameters, lr=self.learning_rate)

    def reset(self):
        self.wealth = 1e6
        self.loss = 0
        self.total_reward = 0
        self.wealth_history = []
        self.return_history = []

    def updateSummary(self, loss):
        self.loss += loss
        reward = -1 * loss
        self.wealth = self.wealth * math.exp(reward)
        self.total_reward += reward
        self.wealth_history.append(self.wealth)
        self.return_history.append(math.exp(reward))

    def getBatch(self, data, target, batch):
        start_pos = batch * self.batch_size
        end_pos = start_pos + self.batch_size
        x = torch.from_numpy(data[start_pos:end_pos]).float()
        y = torch.from_numpy(target[start_pos:end_pos]).float()
        # x = x.view(x.shape[0],x.shape[1]*x.shape[2])
        # y = y.view(y.shape[0],1)

        #Normalizing X by the last real day price
        x = x / x[-1][-1][-2]
        return x, y

    def loss_function(self, w1, w2, y):
        transaction_cost = 1 - torch.sum(
            torch.abs(w2 - w1)) * transaction_commission
        portfolio_return = torch.sum(w2 * y)
        loss = -1 * torch.log(portfolio_return * transaction_cost)
        loss = torch.mean(loss)
        return loss
def train_models(configs):
    device = "/gpu:0" if USE_GPU else "/cpu:0"
    network_scope = TASK_TYPE
    list_of_tasks = TASK_LIST
    scene_scopes = list_of_tasks.keys()
    for config_dict in configs:
        config = Configuration(**config_dict)
        print("training with config=%s" % (str(config)))
        # build the model graph
        model = PolicyNetwork(config,
                              device=device,
                              network_scope=network_scope,
                              scene_scopes=scene_scopes)
        sess_config = tf.ConfigProto(log_device_placement=False, allow_soft_placement=True)
        threads = create_threads(config, model, network_scope, list_of_tasks)
        with tf.Session(config=sess_config) as session:
            train_model(model, session, config, threads, config_dict['logdir'], config_dict['weight_root'])
        tf.reset_default_graph()
def evaluate():
    device = "/gpu:0" if USE_GPU else "/cpu:0"
    network_scope = TASK_TYPE
    list_of_tasks = TASK_LIST
    scene_scopes = list_of_tasks.keys()
    weight_root = args.weight_root
    config = Configuration(**vars(args))
    print("evaluating with config=%s" % (str(config)))
    model = PolicyNetwork(config,
                          device=device,
                          network_scope=network_scope,
                          scene_scopes=scene_scopes)
    sess_config = tf.ConfigProto(log_device_placement=False, allow_soft_placement=True)
    with tf.Session(config=sess_config) as session:
        weight_path = weight_root + '/modelv1'
        saver = tf.train.Saver()
        checkpoint = tf.train.get_checkpoint_state(weight_root)
        assert saver and checkpoint and checkpoint.model_checkpoint_path, weight_path + " doesn't exist"
        saver.restore(session, checkpoint.model_checkpoint_path)
        evaluate_model(session, config, model)
Beispiel #19
0
class PolicyLearner:
    def __init__(self,
                 stock_code,
                 chart_data,
                 training_data=None,
                 min_trading_unit=1,
                 max_trading_unit=2,
                 delayed_reward_threshold=.05,
                 lr=0.01):
        self.stock_code = stock_code  # 종목코드
        self.chart_data = chart_data
        self.environment = Environment(chart_data)  # 환경 객체
        # Environment 클래스는 차트 데이터를 순서대로 읽으면서 주가, 거래량 등의 환경을 제공한다.
        # 에이전트 객체
        self.agent = Agent(self.environment,
                           min_trading_unit=min_trading_unit,
                           max_trading_unit=max_trading_unit,
                           delayed_reward_threshold=delayed_reward_threshold)
        self.training_data = training_data  # 학습 데이터. 학습에 사용할 특징(feature)들을 포함한다.
        self.sample = None
        self.training_data_idx = -1
        # 정책 신경망; 입력 크기(17개) = 학습 데이터의 크기(15개) + 에이전트 상태 크기(2개)
        self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM
        self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                            output_dim=self.agent.NUM_ACTIONS,
                                            lr=lr)
        self.visualizer = Visualizer()  # 가시화 모듈

    def reset(self):  # 에포크 초기화 함수 부분
        self.sample = None
        self.training_data_idx = -1  # 학습 데이터를 읽어가면서 이 값은 1씩 증가

    def fit(  #학습 함수 선언 부분. 핵심 함수이다.
            # num_epoches : 수행할 반복 학습의 전체 횟수. (너무 크게 잡으면 학습 소요 시간이 너무 길어짐)
            # max_memory : 배치 학습 데이터를 만들기 위해 과거 데이터를 저장할 배열.
            # balance : 에이전트의 초기 투자 자본금을 정해주기 위한 인자
            # discount_factor : 지연 보상이 발생했을 때 그 이전 지연 보상이 발생한 시점과 현재 지연 보상이 발생한
            # 시점 사이에서 수행한 행동들 전체에 현재의 지연 보상을 적용한다.
            # 과거로 갈수록 현재 지연 보상을 적용할 판단 근거가 흐려지기 때문에 먼 과걱의 행동일수록 할인 요인을
            # 적용하여 지연 보상을 약하게 적용한다.
            # start_epsilon : 초기 탐험 비율. 학습이 전혀 되어 있지 않은 초기에는 탐험 비율을 크게 해서
            # 더 많은 탐험, 즉 무작위 투자를 수행하도록 해야 한다. 탐험을 통해 특정 상황에서 좋은 행동과
            # 그렇지 않은 행동을 결정하기 위한 경험을 쌓는다.
            # learning : 학습 유무를 정하는 boolean 값. 학습을 마치면 학습된 정책 신경망 모델이 만들어지는데,
            # 이렇게 학습을 해서 정책 신경망 모델을 만들고자 한다면 learning을 True로,
            # 학습된 모델을 가지고 투자 시뮬레이션만 하려 한다면 learning을 False로 준다.
            self,
            num_epoches=1000,
            max_memory=60,
            balance=10000000,
            discount_factor=0,
            start_epsilon=.5,
            learning=True):
        logger.info(
            "LR: {lr}, DF: {discount_factor}, "
            "TU: [{min_trading_unit}, {max_trading_unit}], "
            "DRT: {delayed_reward_threshold}".format(
                lr=self.policy_network.lr,
                discount_factor=discount_factor,
                min_trading_unit=self.agent.min_trading_unit,
                max_trading_unit=self.agent.max_trading_unit,
                delayed_reward_threshold=self.agent.delayed_reward_threshold))

        # 가시화 준비
        # 차트 데이터는 변하지 않으므로 미리 가시화
        self.visualizer.prepare(self.environment.chart_data)

        # 가시화 결과 저장할 폴더 준비
        epoch_summary_dir = os.path.join(  # 폴더의 경로를 변수로 저장
            settings.BASE_DIR, 'epoch_summary/%s/epoch_summary_%s' %
            (self.stock_code, settings.timestr))
        if not os.path.isdir(
                epoch_summary_dir):  # 해당 경로가 없으면 이 경로를 구성하는 폴더들을 생성
            os.makedirs(epoch_summary_dir)

        # 에이전트 초기 자본금 설정
        self.agent.set_balance(balance)

        # 학습에 대한 정보 초기화
        max_portfolio_value = 0
        epoch_win_cnt = 0

        # 학습 반복
        for epoch in range(num_epoches):
            # 에포크 관련 정보 초기화
            loss = 0.  # 정책 신경망의 결과가 학습 데이터와 얼마나 차이가 있는지를 저장하는 변수. 학습 중 줄어드는게 좋음.
            itr_cnt = 0  # 수행한 에포크 수를 저장
            win_cnt = 0  # 수행한 에포크 중에서 수익이 발생한 에포크 수를 저장. 포트폴리오 가치가 초기 자본금보다 높아진 에포크 수.
            exploration_cnt = 0  # 무작위 투자를 수행한 횟수. epsilon이 0.1이고 100번의 투자 결정이 있으면 약 10번의 무작위 투자를 함
            batch_size = 0
            pos_learning_cnt = 0  # 수익이 발생하여 긍정적 지연 보상을 준 수
            neg_learning_cnt = 0  # 손실이 발생하여 부정적 지연 보상을 준 수

            # 메모리 초기화
            # 메모리 리스트에 저장하는 데이터는 샘플, 행동, 즉시보상, 정책 신경망의 출력, 포트폴리오 가치,
            # 보유 주식 수, 탐험 위치, 학습 위치이다.
            memory_sample = []
            memory_action = []
            memory_reward = []
            memory_prob = []
            memory_pv = []
            memory_num_stocks = []
            memory_exp_idx = []
            memory_learning_idx = []

            # 환경, 에이전트, 정책 신경망 초기화
            self.environment.reset()
            self.agent.reset()
            self.policy_network.reset()
            self.reset()

            # 가시화 초기화
            self.visualizer.clear([0, len(self.chart_data)
                                   ])  # 2, 3, 4번째 차트를 초기화함. x축 데이터 범위를 파라미터로

            # 학습을 진행할 수록 탐험 비율 감소
            # 무작위 투자 비율인 epsilon 값을 정함
            # fit() 함수의 인자로 넘어오는 최초 무작위 투자 비율인 start_epsilon 값에 현재 epoch 수에 학습 진행률을 곱해서 정함
            # ex) start_epsilon이 0.3이면 첫 번째 에포크에서는 30%의 확률로 무작위 투자를 진행함.
            # 수행할 에포크 수가 100이라고 했을 때, 50번째 에포크에서는 0.3 * (1 - 49/99) = 0.51
            if learning:
                epsilon = start_epsilon * (1. - float(epoch) /
                                           (num_epoches - 1))
            else:
                epsilon = 0

            while True:
                # 샘플 생성
                next_sample = self._build_sample()
                if next_sample is None:  # 마지막까지 데이터를 다 읽은 것이므로 반복문 종료
                    break

                # 정책 신경망 또는 탐험에 의한 행동 결정
                # 매수와 매도 중 하나를 결정. 이 행동 결정은 무작위 투자 비율인 epsilon 값의 확률로 무작위로 하거나
                # 그렇지 않은 경우 정책 신경망의 출력을 통해 결정된다. 정책 신경망의 출력은 매수를 했을 때와 매도를 했을 때의
                # 포트폴리오 가치를 높일 확률을 의미한다. 즉 매수에 대한 정책 신경망 출력이 매도에 대한 출력보다 높으면 매수, 반대는 매도
                # decide_action() 함수가 반환하는 값은 세 가지.
                # 결정한 행동인 action, 결정에 대한 확신도인 confidence, 무작위 투자 유무인 exploration.
                action, confidence, exploration = self.agent.decide_action(
                    self.policy_network, self.sample, epsilon)

                # 결정한 행동을 수행하고 (act 함수) 즉시 보상과 지연 보상 획득 (act가 반환함)
                immediate_reward, delayed_reward = self.agent.act(
                    action, confidence)

                # 행동 및 행동에 대한 결과를 기억 (메모리에 저장)
                memory_sample.append(next_sample)  # 각 데이터를 메모리에 추가
                memory_action.append(action)
                memory_reward.append(immediate_reward)
                memory_pv.append(self.agent.portfolio_value)
                memory_num_stocks.append(self.agent.num_stocks)
                memory = [
                    (  # 학습데이터의 샘플, 에이전트 행동, 즉시보상, 포트폴리오 가치, 보유 주식 수를 저장하는 배열
                        memory_sample[i], memory_action[i], memory_reward[i])
                    for i in list(range(len(memory_action)))[-max_memory:]
                ]
                if exploration:  # 무작위 투자로 행동을 결정한 경우에 현재의 인덱스를 memory_exp_idx에 저장
                    memory_exp_idx.append(itr_cnt)
                    memory_prob.append(
                        [np.nan] * Agent.NUM_ACTIONS
                    )  # memory_prob은 정책 신경망의 출력을 그대로 저장하는 배열
                    # 무작위 투자에서는 정책 신경망의 출력이 없기 때문에 NumPy의 Not A Number(nan) 값을 넣어줌
                else:  # 무작위 투자가 아닌 경우 정책 신경망의 출력을 그대로 저장
                    memory_prob.append(self.policy_network.prob)
                # 메모리 변수들의 목적은 (1) 학습에서 배치 학습 데이터로 사용 (2) 가시화기에서 차트를 그릴 때 사용

                # 반복에 대한 정보 갱신
                batch_size += 1  # 배치 크기
                itr_cnt += 1  # 반복 카운팅 횟수
                exploration_cnt += 1 if exploration else 0  # 무작위 투자 횟수 (탐험을 한 경우에만)
                win_cnt += 1 if delayed_reward > 0 else 0  # 수익이 발생한 횟수를 증가시킴 (지연 보상이 0보다 큰 경우에만)

                # 지연 보상이 발생한 경우 학습을 수행하는 부분
                # 학습 모드이고 지연 보상이 존재할 경우 정책 신경망 갱신
                # 학습 없이 메모리가 최대 크기만큼 다 찼을 경우 즉시 보상으로 지연 보상을 대체하여 학습을 진행
                if delayed_reward == 0 and batch_size >= max_memory:
                    delayed_reward = immediate_reward
                    self.agent.base_portfolio_value = self.agent.portfolio_value
                if learning and delayed_reward != 0:
                    # 배치 학습 데이터 크기
                    batch_size = min(
                        batch_size, max_memory
                    )  # 배치 데이터 크기는 memory 변수의 크기인 max_memory보다는 작아야 함
                    # 배치 학습 데이터 생성
                    x, y = self._get_batch(memory, batch_size, discount_factor,
                                           delayed_reward)
                    if len(x) > 0:  # 긍정 학습과 부정 학습 횟수 세기
                        if delayed_reward > 0:
                            pos_learning_cnt += 1
                        else:
                            neg_learning_cnt += 1
                        # 정책 신경망 갱신
                        loss += self.policy_network.train_on_batch(
                            x, y)  # 준비한 배치 데이터로 학습을 진행함
                        memory_learning_idx.append([itr_cnt, delayed_reward
                                                    ])  # 학습이 진행된 인덱스를 저장함
                    batch_size = 0  # 학습이 진행되었으니 배치 데이터 크기를 초기화함

            # 에포크 관련 정보 가시화
            num_epoches_digit = len(str(
                num_epoches))  # 총 에포크 수의 문자열 길이를 확인함. 총 에포크 수가 1000이면 길이는 4
            epoch_str = str(epoch + 1).rjust(
                num_epoches_digit, '0'
            )  # 현재 에포크 수를 4자리 문자열로 만들어 줌. 첫 에포크는 1 -> 0001로 문자열을 자리수에 맞게 정렬

            self.visualizer.plot(epoch_str=epoch_str,
                                 num_epoches=num_epoches,
                                 epsilon=epsilon,
                                 action_list=Agent.ACTIONS,
                                 actions=memory_action,
                                 num_stocks=memory_num_stocks,
                                 outvals=memory_prob,
                                 exps=memory_exp_idx,
                                 learning=memory_learning_idx,
                                 initial_balance=self.agent.initial_balance,
                                 pvs=memory_pv)
            self.visualizer.save(
                os.path.join(  #가시화한 에포크 수행 결과를 파일로 저장함
                    epoch_summary_dir,
                    'epoch_summary_%s_%s.png' % (settings.timestr, epoch_str)))

            # 에포크 관련 정보 로그 기록
            # 총 에포크 중에서 몇 번째 에포크를 수행했는지, 탐험률, 탐험 횟수, 매수 횟수, 매도 횟수, 관망 횟수,
            # 보유 주식 수, 포트폴리오 가치, 긍정적 학습 횟수, 부정적 학습 횟수, 학습 손실을 로그로 남긴다.
            if pos_learning_cnt + neg_learning_cnt > 0:
                loss /= pos_learning_cnt + neg_learning_cnt
            logger.info(
                "[Epoch %s/%s]\tEpsilon:%.4f\t#Expl.:%d/%d\t"
                "#Buy:%d\t#Sell:%d\t#Hold:%d\t"
                "#Stocks:%d\tPV:%s\t"
                "POS:%s\tNEG:%s\tLoss:%10.6f" %
                (epoch_str, num_epoches, epsilon, exploration_cnt, itr_cnt,
                 self.agent.num_buy, self.agent.num_sell, self.agent.num_hold,
                 self.agent.num_stocks,
                 locale.currency(self.agent.portfolio_value, grouping=True),
                 pos_learning_cnt, neg_learning_cnt, loss))

            # 학습 관련 정보 갱신
            # 하나의 에포크 수행이 완료되었기 때문에 전체 학습에 대한 통계 정보를 갱신한다.
            # 관리하고 있는 학습 통계 정보는 달성한 최대 포트 폴리오 가치 max_portfolio_value와 쉭이 발생한 에포크의 수 epoch_win_cnt이다.
            max_portfolio_value = max(max_portfolio_value,
                                      self.agent.portfolio_value)
            if self.agent.portfolio_value > self.agent.initial_balance:
                epoch_win_cnt += 1
        # 여기 까지가 학습 반복 for문의 코드 블록이다.

        # 학습 관련 정보 로그 기록
        logger.info("Max PV: %s, \t # Win: %d" % (locale.currency(
            max_portfolio_value, grouping=True), epoch_win_cnt))

    def _get_batch(self, memory, batch_size, discount_factor,
                   delayed_reward):  # 미니 배치 데이터 생성
        x = np.zeros(
            (batch_size, 1, self.num_features))  # x는 일련의 학습 데이터 및 에이전트 상태
        # x 배열의 형태는 배치 데이터 크기, 학습 데이터 특징 크기로 2차원으로 구성됨.
        y = np.full((batch_size, self.agent.NUM_ACTIONS), 0.5)  # y는 일련의 지연 보상
        # y 배열의 형태는 배치 데이터 크기, 정책 신경망이 결정하는 에이전트 행동의 수. 2차원으로. 0.5 일괄적으로 채워둠.

        for i, (sample, action,
                reward) in enumerate(reversed(memory[-batch_size:])):
            x[i] = np.array(sample).reshape(
                (-1, 1, self.num_features))  # 특징벡터 지정
            y[i, action] = (delayed_reward +
                            1) / 2  # 지연 보상으로 정답(레이블)을 설정하여 학습 데이터 구성
            # 지연 보상이 1인 경우 1로, -1인 경우 0으로 레이블을 지정
            if discount_factor > 0:
                y[i, action] *= discount_factor**i  # 할인 요인이 있을 경우
        return x, y

    # 학습 데이터를 구성하는 샘플 하나를 생성하는 함수
    def _build_sample(self):
        self.environment.observe()  # 차트 데이터의 현재 인덱스에서 다음 인덱스 데이터를 읽음
        if len(self.training_data
               ) > self.training_data_idx + 1:  # 학습 데이터의 다음 인덱스가 존재하는지 확인
            self.training_data_idx += 1
            self.sample = self.training_data.iloc[
                self.training_data_idx].tolist()  # 인덱스의 데이터를 받아와서 sample로 저장
            self.sample.extend(
                self.agent.get_states())  # sample에 에이전트 상태를 15개에서 +2개하여 17개로.
            return self.sample
        return None

    # 학습된 정책 신경망 모델로 주식투자 시뮬레이션을 진행
    def trade(self, model_path=None, balance=2000000):
        if model_path is None:
            return
        self.policy_network.load_model(
            model_path=model_path)  # 학습된 신경망 모델을 정책 신경망 객체의 load_model로 적용
        self.fit(balance=balance, num_epoches=1, learning=False)
Beispiel #20
0
 def load_model(self):
     return PolicyNetwork.load(self.model_file)
Beispiel #21
0
class PolicyLearner:
    def __init__(self,
                 stock_code,
                 chart_data,
                 training_data=None,
                 min_trading_unit=1,
                 max_trading_unit=2,
                 delayed_reward_threshold=.05,
                 lr=0.01):
        self.stock_code = stock_code  # 종목코드
        self.chart_data = chart_data
        self.environment = Environment(chart_data)  # 환경 객체
        # 에이전트 객체
        self.agent = Agent(self.environment,
                           min_trading_unit=min_trading_unit,
                           max_trading_unit=max_trading_unit,
                           delayed_reward_threshold=delayed_reward_threshold)
        self.training_data = training_data  # 학습 데이터
        self.samples = None
        self.training_data_idx = -1
        # 정책 신경망; 입력 크기 = 학습 데이터의 크기 + 에이전트 상태 크기
        self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM
        self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                            output_dim=self.agent.NUM_ACTIONS,
                                            lr=lr)
        self.visualizer = Visualizer()  # 가시화 모듈

    def reset(self):
        self.sample = None
        self.training_data_idx = -1

    def fit(self,
            num_epoches=1000,
            max_memory=60,
            balance=10000000,
            discount_factor=0,
            start_epsilon=.5,
            learning=True,
            index_change_rate=0):
        logger.info(
            "LR: {lr}, DF: {discount_factor}, "
            "TU: [{min_trading_unit}, {max_trading_unit}], "
            "DRT: {delayed_reward_threshold}".format(
                lr=self.policy_network.lr,
                discount_factor=discount_factor,
                min_trading_unit=self.agent.min_trading_unit,
                max_trading_unit=self.agent.max_trading_unit,
                delayed_reward_threshold=self.agent.delayed_reward_threshold))

        # 가시화 준비
        # 차트 데이터는 변하지 않으므로 미리 가시화
        self.visualizer.prepare(self.environment.chart_data)

        # 가시화 결과 저장할 폴더 준비
        epoch_summary_dir = os.path.join(
            settings.BASE_DIR, 'epoch_summary/%s/epoch_summary_%s' %
            (self.stock_code, settings.timestr))
        if not os.path.isdir(epoch_summary_dir):
            os.makedirs(epoch_summary_dir)

        # 에이전트 초기 자본금 설정
        self.agent.set_balance(balance)

        # 학습에 대한 정보 초기화
        max_portfolio_value = 0
        epoch_win_cnt = 0

        # 학습 반복
        for epoch in range(num_epoches):
            # 에포크 관련 정보 초기화
            loss = 0.
            itr_cnt = 0
            win_cnt = 0
            exploration_cnt = 0
            batch_size = 0
            pos_learning_cnt = 0
            neg_learning_cnt = 0

            # 메모리 초기화
            memory_sample = []
            memory_action = []
            memory_reward = []
            memory_prob = []
            memory_pv = []
            memory_num_stocks = []
            memory_exp_idx = []
            memory_learning_idx = []

            # 환경, 에이전트, 정책 신경망 초기화
            self.environment.reset()
            self.agent.reset()
            self.policy_network.reset()
            self.reset()

            # 가시화 초기화
            self.visualizer.clear([0, len(self.chart_data)])

            # 학습을 진행할 수록 탐험 비율 감소
            if learning:
                epsilon = start_epsilon * (1. - float(epoch) /
                                           (num_epoches - 1))
            else:
                epsilon = 0

            while True:
                # 샘플 생성
                next_sample = self._build_sample()
                if next_sample is None:
                    break

                # 정책 신경망 또는 탐험에 의한 행동 결정
                action, confidence, exploration = self.agent.decide_action(
                    self.policy_network, self.sample, epsilon)

                # 결정한 행동을 수행하고 즉시 보상과 지연 보상 획득
                immediate_reward, delayed_reward = self.agent.act(
                    action, confidence)

                # 행동 및 행동에 대한 결과를 기억
                memory_sample.append(next_sample)
                memory_action.append(action)
                memory_reward.append(immediate_reward)
                memory_pv.append(self.agent.portfolio_value)
                memory_num_stocks.append(self.agent.num_stocks)
                memory = [
                    (memory_sample[i], memory_action[i], memory_reward[i])
                    for i in list(range(len(memory_action)))[-max_memory:]
                ]
                if exploration:
                    memory_exp_idx.append(itr_cnt)
                    memory_prob.append([np.nan] * Agent.NUM_ACTIONS)
                else:
                    memory_prob.append(self.policy_network.prob)

                # 반복에 대한 정보 갱신
                batch_size += 1
                itr_cnt += 1
                exploration_cnt += 1 if exploration else 0
                win_cnt += 1 if delayed_reward > 0 else 0

                # 학습 모드이고 지연 보상이 존재할 경우 정책 신경망 갱신
                if delayed_reward == 0 and batch_size >= max_memory:
                    delayed_reward = immediate_reward
                    self.agent.base_portfolio_value = self.agent.portfolio_value
                if learning and delayed_reward != 0:
                    # 배치 학습 데이터 크기
                    batch_size = min(batch_size, max_memory)
                    # 배치 학습 데이터 생성
                    x, y = self._get_batch(memory, batch_size, discount_factor,
                                           delayed_reward)
                    if len(x) > 0:
                        if delayed_reward > 0:
                            pos_learning_cnt += 1
                        else:
                            neg_learning_cnt += 1
                        # 정책 신경망 갱신
                        loss += self.policy_network.train_on_batch(x, y)
                        memory_learning_idx.append([itr_cnt, delayed_reward])
                    batch_size = 0

            # 에포크 관련 정보 가시화
            num_epoches_digit = len(str(num_epoches))
            epoch_str = str(epoch + 1).rjust(num_epoches_digit, '0')

            self.visualizer.plot(epoch_str=epoch_str,
                                 num_epoches=num_epoches,
                                 epsilon=epsilon,
                                 action_list=Agent.ACTIONS,
                                 actions=memory_action,
                                 num_stocks=memory_num_stocks,
                                 outvals=memory_prob,
                                 exps=memory_exp_idx,
                                 learning=memory_learning_idx,
                                 initial_balance=self.agent.initial_balance,
                                 pvs=memory_pv)
            self.visualizer.save(
                os.path.join(
                    epoch_summary_dir,
                    'epoch_summary_%s_%s.png' % (settings.timestr, epoch_str)))

            # 에포크 관련 정보 로그 기록
            if pos_learning_cnt + neg_learning_cnt > 0:
                loss /= pos_learning_cnt + neg_learning_cnt
            logger.info(
                "[Epoch %s/%s]\tEpsilon:%.4f\t#Expl.:%d/%d\t"
                "#Buy:%d\t#Sell:%d\t#Hold:%d\t"
                "#Stocks:%d\tPV:%s\t"
                "POS:%s\tNEG:%s\tLoss:%10.6f" %
                (epoch_str, num_epoches, epsilon, exploration_cnt, itr_cnt,
                 self.agent.num_buy, self.agent.num_sell, self.agent.num_hold,
                 self.agent.num_stocks,
                 locale.currency(self.agent.portfolio_value, grouping=True),
                 pos_learning_cnt, neg_learning_cnt, loss))

            # 학습 관련 정보 갱신
            max_portfolio_value = max(max_portfolio_value,
                                      self.agent.portfolio_value)
            if self.agent.portfolio_value > self.agent.initial_balance:
                epoch_win_cnt += 1

        #수익율 계산
        profit = (max_portfolio_value - balance) / balance * 100

        # 학습 관련 정보 로그 기록
        if 0:
            logger.info("Max PV: %s, \t # Win: %d" % (locale.currency(
                max_portfolio_value, grouping=True), epoch_win_cnt))
        else:
            logger.info(
                "Max PV: %s, \t #Profit: %.2f, \t #Win: %d, \t  # Index : %.2f"
                % (locale.currency(max_portfolio_value, grouping=True), profit,
                   epoch_win_cnt, index_change_rate))

    def _get_batch(self, memory, batch_size, discount_factor, delayed_reward):
        x = np.zeros((batch_size, 1, self.num_features))
        y = np.full((batch_size, self.agent.NUM_ACTIONS), 0.5)

        for i, (sample, action,
                reward) in enumerate(reversed(memory[-batch_size:])):
            x[i] = np.array(sample).reshape((-1, 1, self.num_features))
            y[i, action] = (delayed_reward + 1) / 2
            if discount_factor > 0:
                y[i, action] *= discount_factor**i
        return x, y

    def _build_sample(self):
        self.environment.observe()
        if len(self.training_data) > self.training_data_idx + 1:
            self.training_data_idx += 1
            self.sample = self.training_data.iloc[
                self.training_data_idx].tolist()
            self.sample.extend(self.agent.get_states())
            return self.sample
        return None

    def trade(self, model_path=None, balance=2000000, index_change_rate=0):
        if model_path is None:
            return
        self.policy_network.load_model(model_path=model_path)
        self.fit(balance=balance,
                 num_epoches=1,
                 learning=False,
                 index_change_rate=index_change_rate)
class PolicyLearner:
    def __init__(self,
                 coin_code,
                 coin_chart,
                 training_data=None,
                 model_ver=None,
                 min_trading_unit=1,
                 max_trading_unit=2,
                 delayed_reward_threshold=.05,
                 start_date=None,
                 end_date=None,
                 lr=0.01):

        self.coin_code = coin_code
        self.coin_chart = coin_chart

        self.environment = Environment(coin_chart)
        self.agent = Agent(self.environment,
                           min_trading_unit=min_trading_unit,
                           max_trading_unit=max_trading_unit,
                           delayed_reward_threshold=delayed_reward_threshold)

        self.training_data = training_data
        self.sample = None
        self.training_data_idx = -1

        self.model_ver = model_ver
        self.start_date = start_date
        self.end_date = end_date

        self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM
        self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                            output_dim=self.agent.NUM_ACTIONS,
                                            lr=lr,
                                            load_weight=self.model_ver)

#        self.visualizer = Visualizer()

    def reset(self):
        self.sample = None
        self.training_data_idx = -1

    def fit(self,
            num_epoches=1000,
            max_memory=60,
            balance=10000000,
            discount_factor=0,
            start_epsilon=.5,
            learning=True):

        logger.info(
            "Learning Rate: {lr}, Discount Factor: {discount_factor}, "
            "Trading Unit: [{min_trading_unit}, {max_trading_unit}], "
            "Delayed Reward threshold: {delayed_reward_threshold}, "
            "Training period: [{start_date} ~ {end_date}]".format(
                lr=self.policy_network.lr,
                discount_factor=discount_factor,
                min_trading_unit=self.agent.min_trading_unit,
                max_trading_unit=self.agent.max_trading_unit,
                delayed_reward_threshold=self.agent.delayed_reward_threshold,
                start_date=self.start_date,
                end_date=self.end_date))

        #        self.visualizer.prepare(self.environment.coin_chart)
        epoch_summary_dir = os.path.join(
            settings.BASE_DIR, 'epoch_summary/%s/epoch_summary_%s' %
            (self.coin_code, settings.timestr))
        if not os.path.isdir(epoch_summary_dir):
            os.makedirs(epoch_summary_dir)

        self.agent.set_balance(balance)

        max_portfolio_value = 0
        epoch_win_cnt = 0

        for epoch in range(num_epoches):
            #            loss = 0.
            accuracy = 0.
            itr_cnt = 0
            win_cnt = 0
            exploration_cnt = 0
            batch_size = 0
            pos_learning_cnt = 0
            neg_learning_cnt = 0

            memory_sample = []
            memory_action = []
            memory_reward = []
            memory_prob = []
            memory_pv = []
            memory_num_coins = []
            memory_exp_idx = []
            memory_learning_idx = []

            self.environment.reset()
            self.agent.reset()
            self.policy_network.reset()
            self.reset()
            #            self.visualizer.clear([0, len(self.coin_chart)])

            if learning:
                epsilon = start_epsilon * (1. - float(epoch) /
                                           (num_epoches - 1))
            else:
                epsilon = 0

            while True:
                next_sample = self._build_sample()

                if next_sample is None:
                    break

                action, confidence, exploration = self.agent.decide_action(
                    self.policy_network, self.sample, epsilon)

                immediate_reward, delayed_reward = self.agent.act(
                    action, confidence)

                memory_sample.append(next_sample)
                memory_action.append(action)
                memory_reward.append(immediate_reward)
                memory_pv.append(self.agent.portfolio_value)
                memory_num_coins.append(self.agent.num_coins)

                memory = [
                    (memory_sample[i], memory_action[i], memory_reward[i])
                    for i in list(range(len(memory_action)))[-max_memory:]
                ]

                if exploration:
                    memory_exp_idx.append(itr_cnt)
                    memory_prob.append([np.nan] * Agent.NUM_ACTIONS)
                else:
                    memory_prob.append(self.policy_network.prob)

                batch_size += 1
                itr_cnt += 1
                exploration_cnt += 1 if exploration else 0
                win_cnt += 1 if delayed_reward > 0 else 0

                if delayed_reward == 0 and batch_size >= max_memory:
                    delayed_reward = immediate_reward
                    self.agent.base_portfolio_value = self.agent.portfolio_value

                if learning and delayed_reward != 0:
                    batch_size = min(batch_size, max_memory)
                    x, y = self._get_batch(memory, batch_size, discount_factor,
                                           delayed_reward)

                    if len(x) > 0:
                        accuracy += self.policy_network.train_on_batch(x, y)
                        memory_learning_idx.append([itr_cnt, delayed_reward])
                    batch_size = 0

            num_epoches_digit = len(str(num_epoches))
            epoch_str = str(epoch + 1).rjust(num_epoches_digit, '0')

            logger.info("[Epoch %s/%s]\tEpsilon:%.4f\t#Expl.:%d/%d\t"
                        "#Buy:%d\t#Sell:%d\t#Hold:%d\t"
                        "#Coins:%d\tPV:%s\t"
                        "#Accuracy:%10.6f" %
                        (epoch_str, num_epoches, epsilon, exploration_cnt,
                         itr_cnt, self.agent.num_buy, self.agent.num_sell,
                         self.agent.num_hold, self.agent.num_coins,
                         locale.currency(self.agent.portfolio_value,
                                         grouping=True), accuracy))

            max_portfolio_value = max(max_portfolio_value,
                                      self.agent.portfolio_value)
            if self.agent.portfolio_value > self.agent.initial_balance:
                epoch_win_cnt += 1

        logger.info("Max PV: %s, \t # Win: %d" % (locale.currency(
            max_portfolio_value, grouping=True), epoch_win_cnt))

    def _get_batch(self, memory, batch_size, discount_factor, delayed_reward):
        x = np.zeros((batch_size, 1, self.num_features))
        y = np.full((batch_size, self.agent.NUM_ACTIONS), 0.5)

        for i, (sample, action,
                reward) in enumerate(reversed(memory[-batch_size:])):
            x[i] = np.array(sample).reshape((-1, 1, self.num_features))
            y[i, action] = (delayed_reward + 1) / 2

            if discount_factor > 0:
                y[i] = tl.rein.discount_episode_rewards(y[i], discount_factor)
#                y[i, action] *= discount_factor ** i
        return x, y

    def _build_sample(self):
        self.environment.observe()
        if len(self.training_data) > self.training_data_idx + 1:
            self.training_data_idx += 1
            self.sample = self.training_data.iloc[
                self.training_data_idx].tolist()
            self.sample.extend(self.agent.get_states())
            return self.sample
        return None

    def trade(self, model_path=None, balance=2000000):
        if model_path is None:
            return
        self.policy_network.load_model(model_path=model_path)
        self.fit(balance=balance, num_epoches=1, learning=False)
Beispiel #23
0
ACTIONS = {0: "UP", 1: "DOWN", 2: "RIGHT", 3: "LEFT"}
NUM_ACTIONS = len(ACTIONS)

NUM_GAMES = 30000
OBSERVE = 1000
MAX_TILE = 2048

epsilon = 0.1
min_epsilon = 1e-2
gamma_epsilon = 0.999
gamma_reward = 0.99

replay = ExperienceReplay(capacity=1e6)
logger = Logger()

online = PolicyNetwork(batch_size=32)
target = PolicyNetwork(batch_size=32)


def preprocess(a: np.array) -> np.array:
    a = np.where(a <= 0, 1, a)
    a = np.log2(a) / np.log2(MAX_TILE)
    return a


if __name__ == "__main__":

    best_score = 0
    best_board = None
    best_iteration = 0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--save_dir',
                        type=str,
                        default='./models',
                        help='directory to store checkpointed models')
    parser.add_argument(
        '--val_frac',
        type=float,
        default=0.1,
        help='fraction of data to be witheld in validation set')
    parser.add_argument(
        '--ckpt_name',
        type=str,
        default='',
        help='name of checkpoint file to load (blank means none)')
    parser.add_argument('--data_file',
                        type=str,
                        default='0750am-0805am',
                        help='time slot for data file')
    parser.add_argument('--data_dir',
                        type=str,
                        default='./2d_drive_data/',
                        help='directory containing data')

    parser.add_argument('--batch_size',
                        type=int,
                        default=64,
                        help='minibatch size')
    parser.add_argument('--seq_length',
                        type=int,
                        default=100,
                        help='training sequence length')
    parser.add_argument('--state_dim',
                        type=int,
                        default=51,
                        help='number of state variables')
    parser.add_argument('--extract_temporal',
                        type=bool,
                        default=False,
                        help='Whether to extract temporal features')
    parser.add_argument('--action_dim',
                        type=int,
                        default=2,
                        help='number of action variables')

    parser.add_argument('--num_epochs',
                        type=int,
                        default=50,
                        help='number of epochs')
    parser.add_argument('--learning_rate',
                        type=float,
                        default=0.004,
                        help='learning rate')
    parser.add_argument('--decay_rate',
                        type=float,
                        default=0.5,
                        help='decay rate for learning rate')
    parser.add_argument('--grad_clip',
                        type=float,
                        default=5.0,
                        help='clip gradients at this value')
    parser.add_argument('--save_h5',
                        type=bool,
                        default=False,
                        help='Whether to save network params to h5 file')
    parser.add_argument('--h5_name',
                        type=str,
                        default='',
                        help='Name for saved h5 file')

    ############################
    #       Policy Network     #
    ############################
    parser.add_argument('--mlp_activation',
                        default=tf.nn.elu,
                        help='activation function in policy network')
    parser.add_argument('--mlp_size',
                        type=int,
                        nargs='+',
                        default=[],
                        help='number of neurons in each feedforward layer')
    parser.add_argument('--gru_input_dim',
                        type=int,
                        default=64,
                        help='size of input to gru layer')
    parser.add_argument('--gru_size',
                        type=int,
                        default=64,
                        help='size of gru layer')
    parser.add_argument('--policy_varscope',
                        type=str,
                        default='policy',
                        help='variable scope for policy network')

    args = parser.parse_args()
    if config.TF_NN_SETTRACE:
        ipdb.set_trace()

    # Construct model
    net = PolicyNetwork(args)

    # store config to disk
    with open(os.path.join(args.save_dir, 'config.pkl'), 'w') as f:
        cPickle.dump(args, f)

    # Export model parameters or perform training
    if args.save_h5:
        save_h5(args, net)
    else:
        train(args, net)
Beispiel #25
0
class Train():
    def __init__(self,
                 init_model=None,
                 row=8,
                 column=8,
                 batch_size=200,
                 buffer_size=10000,
                 epochs=5,
                 game_batch_num=100,
                 n_games=1,
                 check_freq=10,
                 lr_multiplier=1.0,
                 use_gpu=True):
        self.row = row
        self.column = column
        self.init_model = init_model
        self.policy_network = PolicyNetwork(model_file=init_model,
                                            width=column,
                                            height=row)

        self.batch_size = batch_size
        self.buffer_size = buffer_size
        self.buffer = deque(maxlen=self.buffer_size)
        self.epochs = epochs
        self.game_batch_num = game_batch_num
        self.n_games = n_games

        self.kl_targ = 0.02  # the target value of KL Divergence
        self.lr_multiplier = lr_multiplier  # adjust the learning rate of the optimization algorithm
        self.check_freq = check_freq  # check every few game rounds to see if the algorithm is improving

        self.use_gpu = use_gpu

    def _collect_training_data(self):
        '''Realize training data collection through self-play.'''
        for i in range(self.n_games):
            # generate self-play training data
            self.board = Board(self.row, self.column)
            self.board.set_state()
            AI = Alpha(model_file=self.init_model, use_gpu=self.use_gpu)
            board_states, mcts_probs, current_players = [], [], []
            while (True):
                move, move_probs = AI.self_play(self.row, self.column,
                                                self.board.board_state)
                board_states.append(self.board.current_state())
                mcts_probs.append(move_probs)
                self.board.move(move)
                current_players.append(self.board.get_cur_player())

                end, winner = self.board.who_win()
                if end:
                    winners = np.zeros(len(current_players))
                    if winner != 0:
                        winners[np.array(current_players) == winner] = 1.0
                        winners[np.array(current_players) != winner] = -1.0
                    print(winners)
                    play_data = zip(board_states, mcts_probs, winners)
                    break

            play_data = list(play_data)[:]
            self.episode_len = len(play_data)
            # print(play_data)
            # add data to buffer
            self.buffer.extend(play_data)
            print(len(self.buffer))

    def _policy_update(self):
        mini_batch = random.sample(self.buffer, self.batch_size)
        board_state_batch = [x[0] for x in mini_batch]
        mcts_probs_batch = [x[1] for x in mini_batch]
        winner_batch = [x[2] for x in mini_batch]

        old_probs, old_v = self.policy_network.batch_policy_fn(
            board_state_batch)

        for i in range(self.epochs):
            loss, entropy = self.policy_network.train_step(
                board_state_batch,
                mcts_probs_batch,
                winner_batch,
                lr=self.lr_multiplier)

            new_probs, new_v = self.policy_network.batch_policy_fn(
                board_state_batch)

            kl = np.mean(
                np.sum(old_probs *
                       (np.log(old_probs + 1e-10) - np.log(new_probs + 1e-10)),
                       axis=1))
            if kl > self.kl_targ * 4:
                break

        if kl > self.kl_targ * 2 and self.lr_multiplier > 0.1:
            self.lr_multiplier /= 1.5
        else:
            self.lr_multiplier *= 1.5

        # explained_var_old = (1 - np.var(np.array(winner_batch) - old_v.flatten()) / np.var(np.array(winner_batch)))

        # explained_var_new = (1 - np.var(np.array(winner_batch) - new_v.flatten()) / np.var(np.array(winner_batch)))

        return loss, entropy

    def _eval_and_save_model(self, game_batch_num):
        '''Save model to the model directory.'''
        self.policy_network.save_model('./model/model{}_{}x{}.model'.format(
            game_batch_num + 1, self.row, self.column))

    def run(self):
        '''play the number of self.game_batch_num games.

        If the amount of data in the buffer is greater than batch_size, 
        perform one policy update including several epochs of training steps.
        '''
        try:
            for i in range(self.game_batch_num):
                self._collect_training_data()
                print("Game batch i: {}, episode_len:{}".format(
                    i + 1, self.episode_len))
                if len(self.buffer) > self.batch_size:
                    loss, entropy = self._policy_update()
                    print("Game batch i: {}. loss: {}. entropy: {}".format(
                        i + 1, loss, entropy))
                if (i + 1) % self.check_freq == 0:
                    print("current self-play game batch i: {}".format(i + 1))
                    self._eval_and_save_model(i)

        except KeyboardInterrupt:
            print('\n\rquit!')
class TRPO(object):
    def __init__(self, alpha, input_size, output_size):

        self.buffer = Buffer()

        self.value_network = ValueNetwork(alpha,
                                          input_size=input_size,
                                          output_size=1)

        self.policy_network = PolicyNetwork(0.0001,
                                            input_size=input_size,
                                            output_size=output_size)

        self.old_policy_network = PolicyNetwork(0.0001,
                                                input_size=input_size,
                                                output_size=output_size)

        # store policy state
        self.buffer.store_parameters(self.policy_network.state_dict())

        self.avg_rewards = []

    def update(self, iter=80):

        observations = self.buffer.get_observations()

        #actions = self.buffer.get_actions()
        rewards = self.buffer.get_rewards()
        advantages = self.buffer.get_advantages()
        log_probs = self.buffer.get_log_probs()

        self.old_policy_network.load_state_dict(self.buffer.old_parameters)

        old_pred = self.old_policy_network.forward(observations)
        old_action_probabilities = torch.distributions.Categorical(old_pred)
        old_action = old_action_probabilities.sample()
        old_probs = old_action_probabilities.log_prob(old_action).reshape(
            -1, 1)
        self.buffer.store_parameters(self.policy_network.state_dict())

        self.policy_network.optimize(log_probs, old_probs, advantages)

        self.value_network.optimize(observations, rewards, iter=iter)

    def calculate_advantage(self):

        prev_observation = self.buffer.observation_buffer[-2]
        observation = self.buffer.observation_buffer[-1]

        v1 = self.value_network(prev_observation)
        v2 = self.value_network(observation)

        return self.buffer.reward_buffer[-1] + v2 - v1

    def act(self, observation):
        prediction = self.policy_network.forward(observation)
        action_probabilities = torch.distributions.Categorical(prediction)
        action = action_probabilities.sample()
        log_prob = action_probabilities.log_prob(action)
        self.buffer.store_log_prob(log_prob)
        return action.item(), log_prob

    def discount_rewards(self, step):
        for s in reversed(range(1, step + 1)):
            update = 0
            for k in reversed(range(1, s + 1)):
                update += self.buffer.reward_buffer[-k] * (0.99**k)
            self.buffer.reward_buffer[-s] += update

    def train(self, env, epochs=1000, steps=4000):

        plt.ion()

        for epoch in range(epochs):

            observation = env.reset()
            self.buffer.store_observation(observation)

            step = 0

            for step in range(steps):

                step += 1

                action, log_prob = self.act(observation)
                self.buffer.store_action(log_prob)

                observation, reward, done, info = env.step(action)

                self.buffer.store_reward(reward / 200 + observation[0] / 2 +
                                         (1 * observation[1])**2)

                #env.render()
                self.buffer.store_observation(observation)
                advantage = self.calculate_advantage()
                self.buffer.store_advantage(advantage)

                if done or step == steps - 1:
                    observation = env.reset()
                    self.discount_rewards(step)
                    step = 0

            self.update(iter=5)
            rwrd = self.buffer.get_rewards()
            self.avg_rewards.append((torch.sum(rwrd) / rwrd.shape[0]).numpy())
            self.buffer.clear_buffer()
            print("Average Reward: {}".format(self.avg_rewards[-1]))

            plt.title("Reward per Epoch")
            plt.xlabel("Epoch")
            plt.ylabel("Reward")
            plt.plot(self.avg_rewards, label="average reward")
            plt.legend(loc="upper left")
            plt.draw()
            plt.pause(0.0001)
            plt.clf()
Beispiel #27
0
class PolicyLearner:
    def __init__(self,
                 stock_code,
                 chart_data,
                 training_data=None,
                 min_trading_unit=1,
                 max_trading_unit=2,
                 delayed_reward_threshold=.05,
                 lr=0.01):
        self.stock_code = stock_code  # 종목코드
        # 차트 데이터
        self.chart_data = chart_data
        # 환경
        self.environment = Environment(stock_code, chart_data)  # 환경 객체
        # 에이전트 객체
        self.agent = Agent(self.environment,
                           min_trading_unit=min_trading_unit,
                           max_trading_unit=max_trading_unit,
                           delayed_reward_threshold=delayed_reward_threshold)
        # 학습 데이터 매칭
        self.training_data = training_data  # 학습 데이터
        # 샘플 초기 상태
        self.sample = None
        # 현재 학습 데이터 인덱스
        self.training_data_idx = -1
        # 입력은 환경에서 발생하는 모든 요소를 반영한다.
        # 정책 신경망; 입력 크기 = 학습 데이터의 크기 + 에이전트 상태 크기
        self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM
        # 정첵 신경멍 객체 생성 및 매칭, 입력 계층 갯수, 출력 갯수, 학습률을 넣어 준다.
        self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                            output_dim=self.agent.NUM_ACTIONS,
                                            lr=lr)
        self.visualizer = Visualizer()  # 가시화 모듈

    # 학습 초기화 - 다시 시작할 때 초기화 한다.
    def reset(self):
        self.sample = None
        self.training_data_idx = -1

    # 학습을 수행하는 함수
    def fit(self,
            num_epoches=1000,
            max_memory=60,
            balance=10000000,
            discount_factor=0,
            start_epsilon=.5,
            learning=True):
        logger.info(
            "LR: {lr}, DF: {discount_factor}, "
            "TU: [{min_trading_unit}, {max_trading_unit}], "
            "DRT: {delayed_reward_threshold}".format(
                lr=self.policy_network.lr,
                discount_factor=discount_factor,
                min_trading_unit=self.agent.min_trading_unit,
                max_trading_unit=self.agent.max_trading_unit,
                delayed_reward_threshold=self.agent.delayed_reward_threshold))

        # 가시화 준비
        # 차트 데이터는 변하지 않으므로 미리 가시화
        self.visualizer.prepare(self.environment.chart_data)

        # 가시화 결과 저장할 폴더 준비
        epoch_summary_dir = os.path.join(
            settings.BASE_DIR, 'epoch_summary/%s/epoch_summary_%s' %
            (self.stock_code, settings.timestr))
        # 에폭 요약 디렉토리를 만든다.
        if not os.path.isdir(epoch_summary_dir):
            os.makedirs(epoch_summary_dir)

        # 에이전트 초기 자본금 설정
        self.agent.set_balance(balance)

        # 학습에 대한 정보 초기화
        max_portfolio_value = 0
        # 에포크에서 성공한  숫자
        epoch_win_cnt = 0

        # 학습 반복
        for epoch in range(num_epoches):
            # 에포크 관련 정보 초기화
            loss = 0.
            # 반복 카운트
            itr_cnt = 0
            # 수익이 발생한 횟수 카운트
            win_cnt = 0
            # 탐험 횟수 - 심층 신경망이 아닌 탐색에 의한 회수
            exploration_cnt = 0
            # 배치 크기
            batch_size = 0
            # 긍정적인 학습 숫자
            pos_learning_cnt = 0
            # 부정적인 학습 숫자
            neg_learning_cnt = 0

            # 메모리 초기화
            memory_sample = []
            # 액션 리스트
            memory_action = []
            # 보상 리스트
            memory_reward = []
            # 확률 리스트
            memory_prob = []
            # 프로파일 가치
            memory_pv = []
            # 보유 주식수
            memory_num_stocks = []
            # 탐험 인덱스 기억
            memory_exp_idx = []
            # 학습 인덱스 기억
            memory_learning_idx = []

            # 환경, 에이전트, 정책 신경망 초기화
            self.environment.reset()
            self.agent.reset()
            self.policy_network.reset()
            self.reset()

            # 가시화 초기화
            self.visualizer.clear([0, len(self.chart_data)])

            # 학습을 진행할 수록 탐험 비율 감소
            if learning:
                epsilon = start_epsilon * (1. - float(epoch) /
                                           (num_epoches - 1))
            else:
                epsilon = 0

            while True:
                # 샘플 생성
                next_sample = self._build_sample()
                if next_sample is None:
                    break

                # 정책 신경망 또는 탐험에 의한 행동 결정
                action, confidence, exploration = self.agent.decide_action(
                    self.policy_network, self.sample, epsilon)

                # 결정한 행동을 수행하고 즉시 보상과 지연 보상 획득
                immediate_reward, delayed_reward = self.agent.act(
                    action, confidence)

                # 행동 및 행동에 대한 결과를 기억
                memory_sample.append(next_sample)
                # 현재의 행동을 저장
                memory_action.append(action)
                # 직접 보상 저장
                memory_reward.append(immediate_reward)
                # 포트폴리오 가치 저장
                memory_pv.append(self.agent.portfolio_value)
                # 주식 갯수 저장
                memory_num_stocks.append(self.agent.num_remain)
                # 샘플값(입력값), 액션값, 보상값을 튜플로 만들어 저장
                memory = [
                    (memory_sample[i], memory_action[i], memory_reward[i])
                    for i in list(range(len(memory_action)))[-max_memory:]
                ]
                if exploration:
                    # 탐색 인덱스를 저장한다.
                    memory_exp_idx.append(itr_cnt)
                    # 액션수만큼 갯수를 가진 리스트를 만들어 붙인다.
                    # 여기에는 출력계층(매수, 매도)에 대한 확률이 들어간다.
                    # 그러나 탐색일 때는 그 확률이 없으므로 이용할 수 없음 값으로 채운다.
                    memory_prob.append([np.nan] * Agent.NUM_ACTIONS)
                else:
                    memory_prob.append(self.policy_network.prob)

                # 반복에 대한 정보 갱신
                batch_size += 1
                itr_cnt += 1
                # 탐험에 의한 것이면 탐험 갯수 추가
                exploration_cnt += 1 if exploration else 0
                # 지연보상이 발생했으면 승리한 회수 추가
                win_cnt += 1 if delayed_reward > 0 else 0

                # 지연보상이 없고 배치크기가 최대 메모리보다 크거나 같으면
                if delayed_reward == 0 and batch_size >= max_memory:
                    # 즉시 보상으로 지연보상 값을 대치하고
                    delayed_reward = immediate_reward
                    # 기준 포트폴리오 값도 바꾸어준다.
                    self.agent.base_portfolio_value = self.agent.portfolio_value
                # 학습 모드이고 지연 보상이 존재할 경우 정책 신경망 갱신
                if learning and delayed_reward != 0:
                    # 배치 학습 데이터 크기
                    batch_size = min(batch_size, max_memory)
                    # 배치 학습 데이터 생성
                    x, y = self._get_batch(memory, batch_size, discount_factor,
                                           delayed_reward)
                    if len(x) > 0:
                        if delayed_reward > 0:
                            pos_learning_cnt += 1
                        else:
                            neg_learning_cnt += 1
                        # 정책 신경망 학습 시킴 - 지연 보상이 발생했을 때만 진행시킨다.
                        loss += self.policy_network.train_on_batch(x, y)
                        memory_learning_idx.append([itr_cnt, delayed_reward])
                    batch_size = 0

            # 에포크 관련 정보 가시화
            num_epoches_digit = len(str(num_epoches))
            epoch_str = str(epoch + 1).rjust(num_epoches_digit, '0')

            self.visualizer.plot(epoch_str=epoch_str,
                                 num_epoches=num_epoches,
                                 epsilon=epsilon,
                                 action_list=Agent.ACTIONS,
                                 actions=memory_action,
                                 num_stocks=memory_num_stocks,
                                 outvals=memory_prob,
                                 exps=memory_exp_idx,
                                 learning=memory_learning_idx,
                                 initial_balance=self.agent.initial_balance,
                                 pvs=memory_pv)
            self.visualizer.save(
                os.path.join(
                    epoch_summary_dir,
                    'epoch_summary_%s_%s.png' % (settings.timestr, epoch_str)))

            # 에포크 관련 정보 로그 기록
            if pos_learning_cnt + neg_learning_cnt > 0:
                loss /= pos_learning_cnt + neg_learning_cnt
            logger.info(
                "[Epoch %s/%s]\tEpsilon:%.4f\t#Expl.:%d/%d\t"
                "#Buy:%d\t#Sell:%d\t#Hold:%d\t"
                "#Stocks:%d\tPV:%s\t"
                "POS:%s\tNEG:%s\tLoss:%10.6f" %
                (epoch_str, num_epoches, epsilon, exploration_cnt, itr_cnt,
                 self.agent.num_buy, self.agent.num_sell, self.agent.num_hold,
                 self.agent.num_remain,
                 locale.currency(self.agent.portfolio_value, grouping=True),
                 pos_learning_cnt, neg_learning_cnt, loss))

            # 학습 관련 정보 갱신
            max_portfolio_value = max(max_portfolio_value,
                                      self.agent.portfolio_value)
            if self.agent.portfolio_value > self.agent.initial_balance:
                epoch_win_cnt += 1

        # 학습 관련 정보 로그 기록
        logger.info("Max PV: %s, \t # Win: %d" % (locale.currency(
            max_portfolio_value, grouping=True), epoch_win_cnt))

    # 배치 학습 데이터를 가져옴
    def _get_batch(self, memory, batch_size, discount_factor, delayed_reward):
        # create an ndarray with all zeros
        x = np.zeros((batch_size, 1, self.num_features))
        y = np.full((batch_size, self.agent.NUM_ACTIONS), 0.5)

        # 배열을 역순으로 도는 것은 가장 최근의 것에 가장 많은 점수를 주기 위해서이다.
        # 과거로 갈 수록 지연보상을 적용할 근거가 떨어지기 때문에 먼 과거의 일일 수록 할인 요인을 적용한다.
        for i, (sample, action,
                reward) in enumerate(reversed(memory[-batch_size:])):
            # x[i] 에는 특징값 수만큼 값들이 3차원으로 구성되어 들어갑니다.
            # 일단 2차원은 반드시 구성하고 데이터가 남을 경우 3차원을 구성하게 된다.
            x[i] = np.array(sample).reshape((-1, 1, self.num_features))
            # y[i, action]에는 액션을 취하면 1.0, 취하지 않았으면 0.5로 들어갑니다.
            # action 0이면 매수이므로 [1.0, 0.5]라고 들어가게 됩니다.
            # action 1이면 매도이므로 [0.5, 1.0]라고 들어가게 됩니다.
            y[i, action] = (delayed_reward + 1) / 2
            # 할인요소를 i승하여 곱해줌.
            if discount_factor > 0:
                y[i, action] *= discount_factor**i
        return x, y

    # 샘플 생성함수
    def _build_sample(self):
        # 차트 데이터를 가져온다.
        self.environment.observe()
        # 학습데이터 크기 끝에 도달하지 않았다면
        if len(self.training_data) > self.training_data_idx + 1:
            # 학습 인덱스 증가
            self.training_data_idx += 1
            temp2 = self.training_data.iloc[self.training_data_idx]
            # 입력값 한세트를 가져옴
            self.sample = self.training_data.iloc[
                self.training_data_idx].tolist()
            # 입력값 세트에 상태들을 더함 - 이것이 최종 입력 계층 값이 됨.
            self.sample.extend(self.agent.get_states())
            # 입력 계층 값을 반환한다.
            return self.sample
        return None

    # 모델을 로드해 거래를 한다.
    def trade(self, model_path=None, balance=2000000):
        if model_path is None:
            return
        # 모델을 로드한다.
        self.policy_network.load_model(model_path=model_path)
        self.fit(balance=balance, num_epoches=1, learning=False)
class PolicyLearner:
    def __init__(self,
                 stock_code,
                 chart_data,
                 training_data=None,
                 min_trading_unit=1,
                 max_trading_unit=2,
                 delayed_reward_threshold=0.05,
                 l_rate=0.01):

        self.stock_code = stock_code
        self.chart_data = chart_data

        self.environment = Environment(chart_data)

        self.agent = Agent(self.environment,
                           min_trading_unit=min_trading_unit,
                           max_trading_unit=max_trading_unit,
                           delayed_reward_threshold=delayed_reward_threshold)

        self.training_data = training_data
        self.sample = None
        self.training_data_idx = -1

        self.num_features = self.training_data.shape[1] + self.agent.STATE_DIM

        self.policy_network = PolicyNetwork(input_dim=self.num_features,
                                            output_dim=self.agent.NUM_ACTIONS,
                                            l_rate=l_rate)

        self.visualizer = Visualizer()

    def reset(self):
        self.sample = None
        self.training_data_idx = -1

    def fit(self,
            num_epoches=1000,
            max_memory=60,
            balance=1000000,
            discount_factor=0,
            start_epsilon=0.5,
            learning=True):
        logger.info(
            "LR: {l_rate}, DF: {discount_factor}, "
            "TU: [{min_trading_unit, {max_trading_unit}], "
            "DRT: {delayed_reward_threshold}".format(
                l_rate=self.policy_network.l_rate,
                discount_factor=discount_factor,
                min_trading_unit=self.agent.min_trading_unit,
                max_trading_unit=self.agent.max_trading_unit,
                delayed_reward_threshold=self.agent.delayed_reward_threshold))

        self.visualizer.prepare(self.environment.chart_data)

        # epoch_summary_dir = os.path.join(settings.BASE_DIR, 'epoch_summary/%s/epoch_summary_%s' % (
        #     self.stock_code, settings.timestr
        # ))
        epoch_summary_dir = os.path.join(settings.BASE_DIR, 'epoch_summary',
                                         '%s' % self.stock_code,
                                         'epoch_summary_%s' % settings.timestr)

        if not os.path.isdir(epoch_summary_dir):
            os.makedirs(epoch_summary_dir)

        self.agent.set_balance(balance)

        max_portfolio_value = 0
        epoch_win_cnt = 0

        for epoch in range(num_epoches):
            loss = 0.0
            itr_cnt = 0
            win_cnt = 0
            exploration_cnt = 0
            batch_size = 0
            pos_learning_cnt = 0
            neg_learning_cnt = 0

            memory_sample = []
            memory_action = []
            memory_reward = []
            memory_prob = []
            memory_pv = []
            memory_num_stocks = []
            memory_exp_idx = []
            memory_learning_idx = []

            self.environment.reset()
            self.agent.reset()
            self.policy_network.reset()
            self.reset()

            self.visualizer.clear([0, len(self.chart_data)])

            if learning:
                epsilon = start_epsilon * (1. - (float(epoch) /
                                                 (num_epoches - 1)))
            else:
                epsilon = 0

            while True:
                next_sample = self._build_sample()
                if next_sample in None:
                    break

                action, confidence, exploration = self.agent.decide_action(
                    self.policy_network, self.sample, epsilon)
                immediate_reward, delayed_reward = self.agent.act(
                    action, confidence)
Beispiel #29
0
    def __init__(self, env, obs_space, action_space, ignoreLTL, gnn_type,
                 dumb_ac, freeze_ltl):
        super().__init__()

        # Decide which components are enabled
        self.use_progression_info = "progress_info" in obs_space
        self.use_text = not ignoreLTL and (gnn_type == "GRU" or gnn_type
                                           == "LSTM") and "text" in obs_space
        self.use_ast = not ignoreLTL and ("GCN"
                                          in gnn_type) and "text" in obs_space
        self.gnn_type = gnn_type
        self.device = torch.device(
            "cuda" if torch.cuda.is_available() else "cpu")
        self.action_space = action_space
        self.dumb_ac = dumb_ac

        self.freeze_pretrained_params = freeze_ltl
        if self.freeze_pretrained_params:
            print("Freezing the LTL module.")

        self.env_model = getEnvModel(env, obs_space)

        # Define text embedding
        if self.use_progression_info:
            self.text_embedding_size = 32
            self.simple_encoder = nn.Sequential(
                nn.Linear(obs_space["progress_info"], 64), nn.Tanh(),
                nn.Linear(64, self.text_embedding_size),
                nn.Tanh()).to(self.device)
            print(
                "Linear encoder Number of parameters:",
                sum(p.numel() for p in self.simple_encoder.parameters()
                    if p.requires_grad))

        elif self.use_text:
            self.word_embedding_size = 32
            self.text_embedding_size = 32
            if self.gnn_type == "GRU":
                self.text_rnn = GRUModel(
                    obs_space["text"], self.word_embedding_size, 16,
                    self.text_embedding_size).to(self.device)
            else:
                assert (self.gnn_type == "LSTM")
                self.text_rnn = LSTMModel(
                    obs_space["text"], self.word_embedding_size, 16,
                    self.text_embedding_size).to(self.device)
            print(
                "RNN Number of parameters:",
                sum(p.numel() for p in self.text_rnn.parameters()
                    if p.requires_grad))

        elif self.use_ast:
            hidden_dim = 32
            self.text_embedding_size = 32
            self.gnn = GNNMaker(self.gnn_type, obs_space["text"],
                                self.text_embedding_size).to(self.device)
            print(
                "GNN Number of parameters:",
                sum(p.numel() for p in self.gnn.parameters()
                    if p.requires_grad))

        # Memory specific code.
        self.image_embedding_size = self.env_model.size()
        self.memory_rnn = nn.LSTMCell(self.image_embedding_size,
                                      self.semi_memory_size)
        self.embedding_size = self.semi_memory_size

        print("embedding size:", self.embedding_size)
        if self.use_text or self.use_ast or self.use_progression_info:
            self.embedding_size += self.text_embedding_size

        if self.dumb_ac:
            # Define actor's model
            self.actor = PolicyNetwork(self.embedding_size, self.action_space)

            # Define critic's model
            self.critic = nn.Sequential(nn.Linear(self.embedding_size, 1))
        else:
            # Define actor's model
            self.actor = PolicyNetwork(self.embedding_size,
                                       self.action_space,
                                       hiddens=[64, 64, 64],
                                       activation=nn.ReLU())

            # Define critic's model
            self.critic = nn.Sequential(nn.Linear(self.embedding_size, 64),
                                        nn.Tanh(), nn.Linear(64, 64),
                                        nn.Tanh(), nn.Linear(64, 1))

        # Initialize parameters correctly
        self.apply(init_params)
Beispiel #30
0
'''
# Trains the state transition model (has to be done before training the policy network)
normalized_state_action_pairs = energy_system.stm_train_s_a_pairs_normalized 
normalized_subsequent_states = energy_system.stm_train_subsequent_states_normalized

state_transition_model = StateTransitionModel([normalized_state_action_pairs.shape[1], 16, 32, 64, normalized_subsequent_states.shape[1]])
state_transition_model.train(normalized_state_action_pairs, normalized_subsequent_states, num_epochs=1000,
                             pricing_model=pricing_model, plot_errors=True, load_weights=False)
'''
# Trains the policy network with the trained state transition model
state_transition_model = StateTransitionModel([
    energy_system.num_state_variables + 1, 16, 32, 64,
    energy_system.num_state_variables
])

policy_network = PolicyNetwork([energy_system.num_state_variables, 16, 32, 1],
                               energy_system)
print("\nStarting training...")
policy_network.train(num_epochs=1000,
                     state_transition_model=state_transition_model,
                     load_weights=False,
                     load_weights_path='./stored_data/weights/policy_network')
'''
# Compares the policy network trained under a chosen pricing model with other policies
policy_network = PolicyNetwork([energy_system.num_state_variables, 16, 32, 1], energy_system)

print("\nWith pricing model " + pricing_model + ":")
energy_system.policy_type = 'rule_based'
energy_system.run_test_simulation()
energy_system.policy_type = 'random'
energy_system.run_test_simulation()
energy_system.policy_type = 'neural_network'