質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.35%

pythonコードの確認

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 677
退会済みユーザー

退会済みユーザー

ネットワークスパラメーターが同じ状態での報酬のばらつきが大き過ぎます。
ネットパラメータはきちんとリストアできているのに、上記の問題が発生するということはコードに何らかのバグが存在するということになりますが、自分が確認してもどこにバグがあるのかわかりません。

コードは文字制限により一部とはなりますが、よろしくお願いします。

報酬の決定

import numpy as np

def reward2(double trend,list pip,int action,int position,list states,double pip_cost,double spread):
    cdef list r = []
    cdef int sub = 0
    if position != 3:
        if action == 0:
            p = [(trend - s) * pip_cost for s in states]
        else:
            p = [(s - trend) * pip_cost for s in states]
            spread *= -1

        if action == position:
            sub = 0
            for b in range(0, len(p)):
                r = [-40.0, True] if p[b] <= -40 else [p[b], False]
                if r[1]:
                    pip.append(r[0])
                    states.pop(b - sub)
                    sub += 1
            states.append(trend+ spread)
            position = action
        else:
            for b in p:
              b = -40.0 if b <= -40 else b
              pip.append(b)
            states = [trend+ spread]
            position = action

    else:
        states = [trend + spread] if action == 0 else [trend - spread]
        position = action

    return states,pip,position


アクションの決定

def exploration(prediction,output_size,e = 0.2):
  prediction = prediction.astype("float64")

  if np.random.rand() < e:
    tau=2.0
    clip=(-1.0, 1.0)
    exp_values = np.exp(np.clip(prediction / tau, clip[0], clip[1]))
    probs = exp_values / np.sum(exp_values)
    action = np.random.choice(range(output_size), p=probs)
  else:
    action = np.argmax(prediction)

  return action

強化学習のトレーニング

    def train(self, iterations, checkpoint, spread, pip_cost, n=4):
        copy = 0
        for i in range(iterations):
            position = 3
            total_pip = 0.00
            pip = []
            spread = spread / pip_cost
            done = False
            states = []
            p = []
            h_s = []
            h_r = []
            h_i = []
            h_p = []
            self.init_value = np.zeros((1, 128))
            tau = 0
            old_reword = 0.0
            self.history = []
            self.best_pip = 0
            self.MEMORIES = deque()
            self.pip = []
            if (copy + 1) % 2 == 0: 
              self._assign('actor-original', 'actor-target')
              self._assign('critic-original', 'critic-target')
            for t in  range(0, len(self.trend)-1, self.skip):
                state = self.get_state(t)
                h_s.append(state)
                next_state = self.get_state(t + 1)
                h_i.append(self.init_value[0])
                action = self._select_action(state,next_state)
                self.history.append(action)
                h_p.append(self.pred)

                states,pip,position = self.reward(self.trend,t,pip,action,position,states,pip_cost,spread)

                if len(pip) != 0:
                  self.pip = np.asanyarray(pip)
                  total_pip = np.sum(self.pip)
                mean_pip = total_pip / (t + 1)
                reward = total_pip - old_reword + self.ri
                old_reword = total_pip
                h_r.append(reward)

                tau = t - n + 1
                if tau >= 0:
                  reward = self.discount_rewards([r for r in h_r[tau+1:tau+n]])
                  self._memorize(h_s[tau], self.history[tau], reward, next_state,h_p[tau], done, h_i[tau])

イメージ説明
イメージ説明
イメージ説明

コードを追加します。

    def __init__(self, path, window_size, skip, save=False, saver_path=None, restore=False,sess=None, noise=True,norm=True):
        self.path = path
        self.window_size = window_size
        self._preproc()
        self.state_size = (None, self.window_size, self.df.shape[-1])
        self.skip = skip
        self.reward = reward
        self.memory = Memory(self.MEMORY_SIZE)
        self.mem = Memory
        #
        self.ent_coef = ent_coef
        self.target_entropy = target_entropy
        self.sess = sess
        self.actor = Actor('actor-original', self.state_size, self.OUTPUT_SIZE,noise,norm)
        self.critic = Critic('critic-original', self.state_size, self.OUTPUT_SIZE, self.LEARNING_RATE,noise,norm)
        self.critic_target = Critic('critic-target', self.state_size, self.OUTPUT_SIZE, self.LEARNING_RATE,noise,norm)
        self.icm = ICM(self.state_size, self.OUTPUT_SIZE, self.LEARNING_RATE)

        with tf.variable_scope("loss"):
          if self.target_entropy == 'auto':
            self.target_entropy = -np.prod(self.OUTPUT_SIZE).astype(np.float32)
          self.target_entropy = float(self.target_entropy)

          entropy = tf.reduce_mean(self.actor.entropy)

          if isinstance(self.ent_coef, str) and self.ent_coef.startswith('auto'):
            init_value = 1.0
            if '_' in self.ent_coef:
              init_value = float(self.ent_coef.split('_')[1])
              assert init_value > 0., "The initial value of ent_coef must be greater than 0"

            self.log_ent_coef = tf.get_variable('log_ent_coef', dtype=tf.float32,initializer=np.log(init_value).astype(np.float32))
            self.ent_coef = tf.exp(self.log_ent_coef)
          else:
            self.ent_coef = float(self.ent_coef)

          min_qf = tf.minimum(self.critic.qf1, self.critic.qf2)
          ent_coef_loss, entropy_optimizer = None, None
          if not isinstance(self.ent_coef, float):
            ent_coef_loss = -tf.reduce_mean(
                self.log_ent_coef * tf.stop_gradient(self.actor.log_pi + self.target_entropy))

          policy_kl_loss = tf.reduce_mean(self.ent_coef * self.actor.log_pi - self.critic.qf1)
          policy_loss = policy_kl_loss
          v_backup = tf.stop_gradient(min_qf - self.ent_coef * self.actor.log_pi)
          value_loss = 0.5 * tf.reduce_mean((self.critic.value_fn - v_backup) ** 2)
          value_loss += self.critic.td_loss
          self.policy_loss = policy_loss
          self.actor_optimizer = tf.train.AdamOptimizer(self.LEARNING_RATE,name="actor_optimizer").minimize(policy_loss,var_list=get_vars("actor-original"))
          self.vf_optimizer = tf.train.AdamOptimizer(self.LEARNING_RATE,name="actor_optimizer").minimize(value_loss,var_list=get_vars("critic-original"))
          self.entropy_optimizer = tf.train.AdamOptimizer(learning_rate=self.LEARNING_RATE,name="entropy_optimizer").minimize(ent_coef_loss,var_list=self.log_ent_coef)

        self.save = save
        self.saver = tf.train.Saver(tf.global_variables())
        self.actor_saver = tf.train.Saver(tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, "actor-original"))
        self.saver_path = saver_path

        if restore==True:
          self.saver.restore(self.sess,self.saver_path)
          self.actor_saver.restore(self.sess,"actor_sac")
        else:
          self.sess.run(tf.global_variables_initializer())

環境の準備

    def _preproc(self):
        df = pd.read_csv(self.path)
        X = df[["Close"]]
        X = MinMaxScaler().fit_transform(X)
#         X = np.asanyarray(X)

        gen = tf.keras.preprocessing.sequence.TimeseriesGenerator(X, np.asanyarray(df[["Open"]])[-len(X)::], self.window_size)
        x = []
        y = []
        for i in gen:
            x.extend(i[0].tolist())
        x = np.asanyarray(x)

        self.df = x[-self.STEP_SIZE::]
        self.trend = np.asanyarray(df[["Open"]])[-len(self.df)::]

探査

    def _select_action(self, state,next_state=None):
        prediction, self.init_value = self.sess.run([self.actor.logits,self.actor.last_state],
                                                     feed_dict={self.actor.X:[state],self.actor.initial_state:self.init_value})
        self.pred = prediction
        action = exploration(prediction[0], self.OUTPUT_SIZE,self.EPSILON)
        if next_state is not None:
          self.ri = self.sess.run(self.icm.ri,
                                  feed_dict={self.icm.state:[state],self.icm.next_state:[next_state],self.icm.action:action.reshape((-1,1))})
        return action


エージェントの評価

    def buy(self, spread, pip_cost, sl):
        position = 3
        pip = []
        states = []
        spread = spread / pip_cost
        loscut = False
        self.init_value = np.zeros((1, 512))
        for t in  range(0, len(self.trend), self.skip):
                state = self.get_state(t)
                action = self._select_action(state)

                states,pip,position = self.reward(self.trend,t,pip,action,position,states,pip_cost,spread)

                if len(pip) != 0:
                  self.pip = np.asanyarray(pip)
                  total_pip = np.sum(self.pip)
              # st ate = next_state
        return total_pip, self.pip
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

お疲れ様です。
コードの流れを追いきれていませんが、気になった点を回答します。

exploration()にてnp.random.rand()を使用されていますが、使用の前にnp.random.seed()でnumpyの乱数のseedを指定していますか?
指定していない場合には、ネットワークパラメータが同じでも、同じ結果が得られる保証はありませんので、ご確認ください。

参考 : 【python】numpyで乱数のseedを設定する方法
https://www.haya-programming.com/entry/2018/05/25/041924

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/17 21:41 編集

    確かにある程度の変化はしかないとしても画像(追加します)のような大幅は差異は確立による影響ではないのではないでしょうか。

    また、seed()はリセットしない限り同じ乱数を生成するので、探査での利用は向かないのでないでしょうか?

    参考 : https://stackoverflow.com/questions/21494489/what-does-numpy-random-seed0-do

    ご回答ありがとうございます。

    キャンセル

  • 2019/08/18 13:56

    お疲れ様です。

    >確かにある程度の変化はしかないとしても画像(追加します)のような大幅は差異は確立による影響ではないのではないでしょうか。

    タスクの特性やモデルの構造によっては、影響が大きく出る可能性となるかと思います。問題の切り分けの参考になさってください。

    >また、seed()はリセットしない限り同じ乱数を生成するので、探査での利用は向かないのでないでしょうか?

    強化学習での扱いに慣れていませんので、他の方の回答に期待したいと思います。

    キャンセル

  • 2019/08/18 14:57

    すいません、ですが今の問題では、最初の報酬がモデルのリストアしなくともしても似たような値を生成します。こういったことを考えるとランダムの問題ではないと考えます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る