[推薦アルゴリズムエンジニアシリーズ]機械学習技術スタックの深学習 - 強化学習

学習の基本的な要素を強化

  • エージェント(代理人):環境、アクションの実装を担当体と対話します。
  • 環境(環境):観察環境を完全に分割することができる(完全観測環境)と部分観測環境(部分観測環境)。
    1)完全に観測可能な環境では、エージェントが全体の環境は明らかに理想的な状況であることを理解です。
    2)部分観測環境では、エージェントが()E&Eの一部を使用して、環境の状況を把握し、残りは探検するために、エージェントに依存する必要があります。

  • アクションスペース(アクションスペース、Aは):すべての法的措置とることができるインテリジェントエージェントの集合を意味し;
  • 状態空間(状態空間、S):環境から取得したエージェントの情報。
  • 報酬(報酬/リターン、R):受け付けたアクションを実行する瞬間報酬\(1 + R_ {T} \。) ;報酬の将来の動作で行われる将来の割引インセンティブ(割引後の将来の報酬)をもたらす可能性があり、
    \ [R_T = \和^ T_ {I =
    T} \ガンマ^ {(IT)} R(S_I、a_iを)\] インセンティブ報酬すなわち、現在時刻が現在時刻プラスγを乗じた次の時刻景品割引率に等しいです。
    γは、単に現在のインセンティブを見て意味、0に等しい場合、
    γが1に等しい場合、環境が決定されることを意味し、同じアクションが常に同じ報酬(すなわち巡回マルコフ過程)を取得します。
    したがって、γは0.9の同様の値を取ることが多い実用的です

  • 状態遷移確率行列(遷移):すべての可能な次の状態の状態遷移確率と対応するボード確率行列は、現在の動作剤に応じて与えられます。

  • ポリシー(ポリシー):ポリシーのアルゴリズムは、私たちの目標であるときに入力状態、それが今回は、アクションや分布のアクションの実装に戻ることができるはず確率、機能として見ることができます。
    \ [\ PI(\ MID S)= P [A_T = A \ S = MID S_T] \]
    1.1)決定論的戦略(確定ポリシー):$ \ PI、すなわち、特定の状態の特定のアクションを実行する意味(S)= A $
    1.2)ランダム戦略(確率的政策):$ \パイ(S、a_iを)その確率に基づいて何らかのアクションを実行するために = P_I $; また、政策貪欲として知られている
    2.1)の行動戦略(行動方針) :データを生成するために使用される戦略は、それはトレーニングプロセスで意思決定を行う、ある、環境と相互作用
    トレーニング後の戦略を学ぶことが完了しているアプリケーションが取る:2.2)政策目標(ターゲット・ポリシー)
    オフポリシー(2.3)オフライン戦略を):ターゲット・ポリシーとアクション別のポリシー、基本的な考え方を使用することです重点サンプリングを、行動戦略戦略目標の使用と推定
    戦略と目的行動戦略は、直接学習戦略をターゲットと同じ戦略である:2.4)オンライン戦略(オンラインポリシー)。

  • バリュー(価値関数)は次の場合に入力状態、アクションは(予想される)値の割引将来の報酬を得ることができることを示します。
    値関数は2つの種類があります。
    。1)の状態値の関数:\(V _ {\ PI}(S)= E _ {\ PI} [R_T \ MID S_T = S] \)
    2)行動価値関数:\(Q _ {\ PI}(S。 A)= E _ {\ PI } [R_T \中間S_t = S; A_tと= A] \)

  • ベルマン式:現在の値と次の状態の値と関連する電流フィードバック報酬、ベルマン方程式を明らかにするの値演算機能は、反復方法によって達成することができることを意味します。
    \ [E [R_ mathbb V(S)= \ + \(S_ {T + 1}の)ガンマV {Tの+ 1} | S_T = S] \]
    E mathbb \ [Q(S、A)= \ [R_ {T + 1} + \ガンマ V(S_ {T + 1}、A_ {T + 1})| S_t = S、= A_tとA] \]

  • 強化学習分類
    値ベースRL、値法。明示的にQ機能に対応した最適な戦略を見つけるために、関数Qの値を表現するモデルを構築し、自然に最適な戦略を発見しました。
    ポリシーベースのRL、戦略的なアプローチ。明示的ポリシー関数を表現するモデルを構築して、割引将来の報酬を最大化するための戦略を見つけること。
    環境モデル・アプローチに基づいて、RLをモデルベース。環境遷移モデルに取得するには、その後、このモデルに基づいて最善の戦略を模索します。

マルコフ決定過程

マルコフ決定過程(マルコフ決定過程、MDP)は、環境中のモデリングエージェントの強化学習環境(環境)、またはその正式な記述です。強化学習では、ほとんどすべての問題は、正式にMDPのように表すことができます。

MDPの要素 シンボル 説明
ステータス/状態空間 S 環境の状態の説明は、動きを作るために、エージェントの後、状況が変化し、進化していているマルコフプロパティをMDPは、状態空間のすべての状態の集合です。状態空間が離散または連続することができます。
アクション/行動空間 A アクションは、エージェントの動作の説明は、インテリジェントな意思決定機関の結果です。すべての可能なアクションのMDPセットは、行動空間です。アクション空間は、離散または連続的であってもよいです。
戦術 $ \パイ(| s)は$ MDP戦略は状態によって与えられ、アクションの条件付き確率分布は、コンテキストを強化学習におけるランダム戦略に属します。
瞬時報酬 R エージェントは、アクション後の環境因子に関するフィードバックを与えます。これは、現在時刻の状態、及び時間状態のスカラー関数の動作です。
累積リターン G 戻り値は、トラックの概念が導入された後、戻り値は、トラック上のすべての報酬の合計です、時間ステップの上に蓄積された報酬です。

確立離散時MDP「は、離散時間マルコフ決定過程(descrete時間MDP)」と呼ばれ、その逆は、「連続時間マルコフ決定過程(連続時間MDP)」と呼ばれている[1]。また、部分観測マルコフ決定過程、マルコフ決定過程、およびファジーマルコフ決定過程の制約を含む、いくつかの亜種のMDPがあります。

戦略学習(ポリシーの学習)

戦略学習(ポリシーの学習)は、行動の各ステップで行うには、エージェントに指示命令の非常に詳細なセットとして理解しました。我々はまた、それは、エージェントの現在の状態であり、それだけで1つの入力を持って、関数としてこの戦略を使用することができます。
検索戦略は、パラメータ化されたポリシーです\(\ pi_ \シータ(S)\) ポリシーに(例えば、ニューラルネットワークなど)、線形または非線形を使用して、ターゲットが強化学習の最適なパラメータを見つけるために、と言った:累積リターン所望\(E [\和^ H_ {T = 0} R(s_t)| \ pi_ \シータ] \) 最高。検索戦略のアプローチは、我々は反復計算を反復的に予想される最大累積戻るまで、パラメータ値更新されたポリシー、最適な政策戦略に対応し、この時間パラメータを指示します。

時間差法(TD法)

時間差法は、モンテカルロサンプリング方法(即ち、テスト)及び(後続状態の関数の関数値の推定電流値を使用して)動的プログラミングのブートストラップ法を組み合わせ、次のように数学的に表現します。

$のV(S_T)を取得V(S_T)+ \アルファ\ delta_Tの$ \
$ \ delta_Tの= S_ {T + 1}のR_ {Tの+ 1} + \ガンマV( - V(S_T)] $
$ここで
\ delta_Tの\テキスト{呼ばTD偏差} \
- \アルファ\テキスト\ {学習学習ステップステップサイズ}
{ -割引将来は、割引率の報酬と呼ばれる}報酬の\ \ガンマ\テキスト
$を

Q-学習アルゴリズム

もう一つの方法は、明示的に各状態でアクションを実行するためにそれを伝えるのではなく、現在の環境に応じて薬を作るために単独で行動しましょう与えられたフレームの後に代理店を導くことです。異なる戦略を学ぶ、Q学習アルゴリズムは、2つのそれぞれの入力と、動作状態を有し、動作状態のそれぞれに対応する値を返します。あなたが選択に直面している場合、アルゴリズムは、さまざまなアクションの期待を取るために、エージェントに対応する時間を算出します。
イノベーションのQ学習は、それが短期的な値の現在の状態の行動を推定するだけでなく、持って来ることが指定されたアクションを取った後、潜在的な将来の値を取得していないだけということです。未来は現在のインセンティブ報酬よりも少なくなりますので、Q学習アルゴリズムは、このプロセスをシミュレートするための割引率を使用しますので。
Q-学習アルゴリズムのフローチャート
Q-Learningの擬似コード

俳優-Critic法

俳優-Critic法は、コスト関数とポリシーベースの方法の機能の組み合わせに基づいてタイミング差分法(TD法)であり、非常に重要な強化学習アルゴリズムです。前記ポリシー関数の役者(俳優)、アクションを与え、価値関数評価(評論家)、俳優が良いか悪いかのアクションを与え、ガイダンス値の機能とポリシー機能を更新するために、差動信号のタイミングを生成するために評価します。

Acror、評論家の構造を以下に示すとおり
Acror-評論家アーキテクチャ

DQN

DQNは、Q学習、ニューラルネットワークとの嵌合の深さの中にQ値法に基づいています。DQNは、ニューラルネットワークの嵌合深さ、高次元データ入力のネットワークプレイの深さの処理能力とエンドツーエンドで行われます。次の二つの質問を解決:

  • 1.深学習は、データサンプルのラベルの多くを必要とし、強化学習は、サンプル、サンプルサイズとまばらな遅延を得るために、活性剤です。
  • 2.各サンプル互いの間に必要な学習の深さは独立しており、同一分布、取得したサンプル各学習隣接関連強化、独立していません。

2015年版DQN構造.JPG

:これは、2つの重要な技術有する
キュベット(経験返信/再生バッファ):最初のサンプルセルに採取した試料、及びネットワークを訓練するために使用されるサンプルプールからランダムに選択されたサンプル。このプロセスは、サンプル間の互いに独立したサンプル間の相関を破ります。
図2に示すように、固定されたターゲット・ネットワーク(固定Q-ターゲット):Q値の既存のネットワークに必要な目標値を算出し、このQ値に専用の低速ネットワークで更新されます。これは、訓練の安定性と収束性を向上させます。

NPG

DDPG方法可以应对高维的输入,实现端对端的控制,且可以输出连续动作,使得深度强化学习方法可以应用于较为复杂的有大的动作空间和连续动作空间的情境。DDPG是基于Actor-Critic方法,在动作输出方面采用一个网络来拟合策略函数,直接输出动作,可以应对连续动作的输出及大的动作空间。

DDPG_ALGO

该结构包含两个网络,一个策略网络(Actor),一个价值网络(Critic)。策略网络输出动作,价值网络评判动作。两者都有自己的更新信息。策略网络通过梯度计算公式进行更新,而价值网络根据目标值进行更新。
DDPG采用了DQN的成功经验。即采用了样本池和固定目标值网络这两项技术。也就是说这两个网络分别有一个变化较慢的副本,该变化较慢的网络提供给更新信息中需要的一些值。DDPG的整体结构如下:
DDPG全体構造

TF实现DDPG

import numpy as np
from collections import deque
import random
import tensorflow as tf
from math import sqrt


class Agent(object):
    def __init__(self, model, replay_buffer, exploration_noise, discout_factor, verbose=False):
        self.model = model
        self.replay_buffer = replay_buffer
        self.exploration_noise = exploration_noise
        self.discout_factor = discout_factor
        self.verbose = verbose

    def predict_action(self, observation):
        return self.model.predict_action(observation)

    def select_action(self, observation, p=None):
        pred_action = self.predict_action(observation)
        noise = self.exploration_noise.return_noise()
        if p is not None:
            return pred_action * p + noise * (1 - p)
        else:
            return pred_action + noise

    def store_transition(self, transition):
        self.replay_buffer.store_transition(transition)

    def init_process(self):
        self.exploration_noise.init_process()

    def get_transition_batch(self):
        batch = self.replay_buffer.get_batch()
        transpose_batch = list(zip(*batch))
        s_batch = np.vstack(transpose_batch[0])
        a_batch = np.vstack(transpose_batch[1])
        r_batch = np.vstack(transpose_batch[2])
        next_s_batch = np.vstack(transpose_batch[3])
        done_batch = np.vstack(transpose_batch[4])
        return s_batch, a_batch, r_batch, next_s_batch, done_batch

    def preprocess_batch(self, s_batch, a_batch, r_batch, next_s_batch, done_batch):
        target_actor_net_pred_action = self.model.actor.predict_action_target_net(next_s_batch)
        target_critic_net_pred_q = self.model.critic.predict_q_target_net(next_s_batch, target_actor_net_pred_action)
        y_batch = r_batch + self.discout_factor * target_critic_net_pred_q * (1 - done_batch)
        return s_batch, a_batch, y_batch

    def train_model(self):
        s_batch, a_batch, r_batch, next_s_batch, done_batch = self.get_transition_batch()
        self.model.update(*self.preprocess_batch(s_batch, a_batch, r_batch, next_s_batch, done_batch))


class Replay_Buffer(object):
    def __init__(self, buffer_size=10e6, batch_size=1):
        self.buffer_size = buffer_size
        self.batch_size = batch_size
        self.memory = deque(maxlen=buffer_size)

    def __call__(self):
        return self.memory

    def store_transition(self, transition):
        self.memory.append(transition)

    def store_transitions(self, transitions):
        self.memory.extend(transitions)

    def get_batch(self, batch_size=None):
        b_s = batch_size or self.batch_size
        cur_men_size = len(self.memory)
        if cur_men_size < b_s:
            return random.sample(list(self.memory), cur_men_size)
        else:
            return random.sample(list(self.memory), b_s)

    def memory_state(self):
        return {"buffer_size": self.buffer_size,
                "current_size": len(self.memory),
                "full": len(self.memory) == self.buffer_size}

    def empty_transition(self):
        self.memory.clear()


class DDPG_Actor(object):
    def __init__(self, state_dim, action_dim, optimizer=None, learning_rate=0.001, tau=0.001, scope="", sess=None):
        self.scope = scope
        self.sess = sess
        self.state_dim = state_dim
        self.action_dim = action_dim
        self.learning_rate = learning_rate
        self.l2_reg = 0.01
        self.optimizer = optimizer or tf.train.AdamOptimizer(self.learning_rate)
        self.tau = tau
        self.h1_dim = 400
        self.h2_dim = 300
        # self.h3_dim = 200
        self.activation = tf.nn.relu
        self.kernel_initializer = tf.contrib.layers.variance_scaling_initializer()
        # fan-out uniform initializer which is different from original paper
        self.kernel_initializer_1 = tf.random_uniform_initializer(minval=-1 / sqrt(self.h1_dim),
                                                                  maxval=1 / sqrt(self.h1_dim))
        self.kernel_initializer_2 = tf.random_uniform_initializer(minval=-1 / sqrt(self.h2_dim),
                                                                  maxval=1 / sqrt(self.h2_dim))
        self.kernel_initializer_3 = tf.random_uniform_initializer(minval=-3e-3, maxval=3e-3)
        self.kernel_regularizer = tf.contrib.layers.l2_regularizer(self.l2_reg)

        with tf.name_scope("actor_input"):
            self.input_state = tf.placeholder(tf.float32, shape=[None, self.state_dim], name="states")

        with tf.name_scope("actor_label"):
            self.actions_grad = tf.placeholder(tf.float32, shape=[None, self.action_dim], name="actions_grad")

        self.source_var_scope = "ddpg/" + "actor_net"
        with tf.variable_scope(self.source_var_scope):
            self.action_output = self.__create_actor_network()

        self.target_var_scope = "ddpg/" + "actor_target_net"
        with tf.variable_scope(self.target_var_scope):
            self.target_net_actions_output = self.__create_target_network()

        with tf.name_scope("compute_policy_gradients"):
            self.__create_loss()

        self.train_op_scope = "actor_train_op"
        with tf.variable_scope(self.train_op_scope):
            self.__create_train_op()

        with tf.name_scope("actor_target_update_train_op"):
            self.__create_update_target_net_op()

        self.__create_get_layer_weight_op_source()
        self.__create_get_layer_weight_op_target()

    def __create_actor_network(self):
        h1 = tf.layers.dense(self.input_state,
                             units=self.h1_dim,
                             activation=self.activation,
                             kernel_initializer=self.kernel_initializer_1,
                             # kernel_initializer=self.kernel_initializer,
                             kernel_regularizer=self.kernel_regularizer,
                             name="hidden_1")

        h2 = tf.layers.dense(h1,
                             units=self.h2_dim,
                             activation=self.activation,
                             kernel_initializer=self.kernel_initializer_2,
                             # kernel_initializer=self.kernel_initializer,
                             kernel_regularizer=self.kernel_regularizer,
                             name="hidden_2")

        # h3 = tf.layers.dense(h2,
        # units=self.h3_dim,
        # activation=self.activation,
        # kernel_initializer=self.kernel_initializer,
        # kernel_regularizer=self.kernel_regularizer,
        # name="hidden_3")

        action_output = tf.layers.dense(h2,
                                        units=self.action_dim,
                                        activation=tf.nn.tanh,
                                        # activation=tf.nn.tanh,
                                        kernel_initializer=self.kernel_initializer_3,
                                        # kernel_initializer=self.kernel_initializer,
                                        kernel_regularizer=self.kernel_regularizer,
                                        use_bias=False,
                                        name="action_outputs")

        return action_output

    def __create_target_network(self):
        # get source variales and initialize
        source_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=self.source_var_scope)
        self.sess.run(tf.variables_initializer(source_vars))

        # create target network and initialize it by source network
        action_output = self.__create_actor_network()
        target_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=self.target_var_scope)

        target_init_op_list = [target_vars[i].assign(source_vars[i]) for i in range(len(source_vars))]
        self.sess.run(target_init_op_list)

        return action_output

    def __create_loss(self):
        source_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=self.source_var_scope)
        self.policy_gradient = tf.gradients(self.action_output, source_vars, -self.actions_grad)
        self.grads_and_vars = zip(self.policy_gradient, source_vars)

    def __create_train_op(self):
        self.train_policy_op = self.optimizer.apply_gradients(self.grads_and_vars,
                                                              global_step=tf.contrib.framework.get_global_step())
        train_op_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                                          scope=self.scope + "/" + self.train_op_scope)  # to do: remove prefix
        train_op_vars.extend(tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope=self.train_op_scope))
        self.sess.run(tf.variables_initializer(train_op_vars))

    def __create_update_target_net_op(self):
        source_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=self.source_var_scope)
        target_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=self.target_var_scope)
        update_target_net_op_list = [target_vars[i].assign(self.tau * source_vars[i] + (1 - self.tau) * target_vars[i])
                                     for i in range(len(source_vars))]

        # source_net_dict = {var.name[len(self.source_var_scope):]: var for var in source_vars}
        # target_net_dict = {var.name[len(self.target_var_scope):]: var for var in target_vars}
        # keys = source_net_dict.keys()
        # update_target_net_op_list = [target_net_dict[key].assign((1-self.tau)*target_net_dict[key]+self.tau*source_net_dict[key]) \
        # for key in keys]

        # for s_v, t_v in zip(source_vars, target_vars):
        # update_target_net_op_list.append(t_v.assign(self.tau*s_v - (1-self.tau)*t_v))

        self.update_target_net_op = tf.group(*update_target_net_op_list)

    def predict_action_source_net(self, feed_state, sess=None):
        sess = sess or self.sess
        return sess.run(self.action_output, {self.input_state: feed_state})

    def predict_action_target_net(self, feed_state, sess=None):
        sess = sess or self.sess
        return sess.run(self.target_net_actions_output, {self.input_state: feed_state})

    def update_source_actor_net(self, feed_state, actions_grad, sess=None):
        sess = sess or self.sess
        batch_size = len(actions_grad)
        return sess.run([self.train_policy_op],
                        {self.input_state: feed_state,
                         self.actions_grad: actions_grad / batch_size})

    def update_target_actor_net(self, sess=None):
        sess = sess or self.sess
        return sess.run(self.update_target_net_op)

    def __create_get_layer_weight_op_source(self):
        with tf.variable_scope(self.source_var_scope, reuse=True):
            self.h1_weight_source = tf.get_variable("hidden_1/kernel")
            self.h1_bias_source = tf.get_variable("hidden_1/bias")

    def run_layer_weight_source(self, sess=None):
        sess = sess or self.sess
        return sess.run([self.h1_weight_source, self.h1_bias_source])

    def __create_get_layer_weight_op_target(self):
        with tf.variable_scope(self.target_var_scope, reuse=True):
            self.h1_weight_target = tf.get_variable("hidden_1/kernel")
            self.h1_bias_target = tf.get_variable("hidden_1/bias")

    def run_layer_weight_target(self, sess=None):
        sess = sess or self.sess
        return sess.run([self.h1_weight_target, self.h1_bias_target])


class DDPG_Critic(object):
    def __init__(self, state_dim, action_dim, optimizer=None, learning_rate=0.001, tau=0.001, scope="", sess=None):
        self.scope = scope
        self.sess = sess
        self.state_dim = state_dim
        self.action_dim = action_dim
        self.learning_rate = learning_rate
        self.l2_reg = 0.01
        self.optimizer = optimizer or tf.train.AdamOptimizer(self.learning_rate)
        self.tau = tau
        self.h1_dim = 400
        self.h2_dim = 100
        self.h3_dim = 300
        self.activation = tf.nn.relu
        self.kernel_initializer = tf.contrib.layers.variance_scaling_initializer()
        # fan-out uniform initializer which is different from original paper
        self.kernel_initializer_1 = tf.random_uniform_initializer(minval=-1 / sqrt(self.h1_dim),
                                                                  maxval=1 / sqrt(self.h1_dim))
        self.kernel_initializer_2 = tf.random_uniform_initializer(minval=-1 / sqrt(self.h2_dim),
                                                                  maxval=1 / sqrt(self.h2_dim))
        self.kernel_initializer_3 = tf.random_uniform_initializer(minval=-1 / sqrt(self.h3_dim),
                                                                  maxval=1 / sqrt(self.h3_dim))
        self.kernel_initializer_4 = tf.random_uniform_initializer(minval=-3e-3, maxval=3e-3)
        self.kernel_regularizer = tf.contrib.layers.l2_regularizer(self.l2_reg)

        with tf.name_scope("critic_input"):
            self.input_state = tf.placeholder(tf.float32, shape=[None, self.state_dim], name="states")
            self.input_action = tf.placeholder(tf.float32, shape=[None, self.action_dim], name="actions")

        with tf.name_scope("critic_label"):
            self.y = tf.placeholder(tf.float32, shape=[None, 1], name="y")

        self.source_var_scope = "ddpg/" + "critic_net"
        with tf.variable_scope(self.source_var_scope):
            self.q_output = self.__create_critic_network()

        self.target_var_scope = "ddpg/" + "critic_target_net"
        with tf.variable_scope(self.target_var_scope):
            self.target_net_q_output = self.__create_target_network()

        with tf.name_scope("compute_critic_loss"):
            self.__create_loss()

        self.train_op_scope = "critic_train_op"
        with tf.variable_scope(self.train_op_scope):
            self.__create_train_op()

        with tf.name_scope("critic_target_update_train_op"):
            self.__create_update_target_net_op()

        with tf.name_scope("get_action_grad_op"):
            self.__create_get_action_grad_op()

        self.__create_get_layer_weight_op_source()
        self.__create_get_layer_weight_op_target()

    def __create_critic_network(self):
        h1 = tf.layers.dense(self.input_state,
                             units=self.h1_dim,
                             activation=self.activation,
                             kernel_initializer=self.kernel_initializer_1,
                             # kernel_initializer=self.kernel_initializer,
                             kernel_regularizer=self.kernel_regularizer,
                             name="hidden_1")

        # h1_with_action = tf.concat([h1, self.input_action], 1, name="hidden_1_with_action")

        h2 = tf.layers.dense(self.input_action,
                             units=self.h2_dim,
                             activation=self.activation,
                             kernel_initializer=self.kernel_initializer_2,
                             # kernel_initializer=self.kernel_initializer,
                             kernel_regularizer=self.kernel_regularizer,
                             name="hidden_2")

        h_concat = tf.concat([h1, h2], 1, name="h_concat")

        h3 = tf.layers.dense(h_concat,
                             units=self.h3_dim,
                             activation=self.activation,
                             kernel_initializer=self.kernel_initializer_3,
                             # kernel_initializer=self.kernel_initializer,
                             kernel_regularizer=self.kernel_regularizer,
                             name="hidden_3")

        # h2_with_action = tf.concat([h2, self.input_action], 1, name="hidden_3_with_action")

        q_output = tf.layers.dense(h3,
                                   units=1,
                                   # activation=tf.nn.sigmoid,
                                   activation=None,
                                   kernel_initializer=self.kernel_initializer_4,
                                   # kernel_initializer=self.kernel_initializer,
                                   kernel_regularizer=self.kernel_regularizer,
                                   name="q_output")

        return q_output

    def __create_target_network(self):
        # get source variales and initialize
        source_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=self.source_var_scope)
        self.sess.run(tf.variables_initializer(source_vars))

        # create target network and initialize it by source network
        q_output = self.__create_critic_network()
        target_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=self.target_var_scope)

        target_init_op_list = [target_vars[i].assign(source_vars[i]) for i in range(len(source_vars))]
        self.sess.run(target_init_op_list)

        return q_output

    def __create_loss(self):
        self.loss = tf.losses.mean_squared_error(self.y, self.q_output)

    def __create_train_op(self):
        self.train_q_op = self.optimizer.minimize(self.loss)
        train_op_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                                          scope=self.scope + "/" + self.train_op_scope)  # to do: remove prefix
        train_op_vars.extend(tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope=self.train_op_scope))
        self.sess.run(tf.variables_initializer(train_op_vars))

    def __create_update_target_net_op(self):
        source_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=self.source_var_scope)
        target_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=self.target_var_scope)
        update_target_net_op_list = [target_vars[i].assign(self.tau * source_vars[i] + (1 - self.tau) * target_vars[i])
                                     for i in range(len(source_vars))]
        # source_net_dict = {var.name[len(self.source_var_scope):]: var for var in source_vars}
        # target_net_dict = {var.name[len(self.target_var_scope):]: var for var in target_vars}
        # keys = source_net_dict.keys()
        # update_target_net_op_list = [target_net_dict[key].assign((1-self.tau)*target_net_dict[key]+self.tau*source_net_dict[key]) \
        # for key in keys]

        # for s_v, t_v in zip(source_vars, target_vars):
        # update_target_net_op_list.append(t_v.assign(self.tau*s_v - (1-self.tau)*t_v))

        self.update_target_net_op = tf.group(*update_target_net_op_list)

    def __create_get_action_grad_op(self):
        self.get_action_grad_op = tf.gradients(self.q_output, self.input_action)

    def predict_q_source_net(self, feed_state, feed_action, sess=None):
        sess = sess or self.sess
        return sess.run(self.q_output, {self.input_state: feed_state,
                                        self.input_action: feed_action})

    def predict_q_target_net(self, feed_state, feed_action, sess=None):
        sess = sess or self.sess
        return sess.run(self.target_net_q_output, {self.input_state: feed_state,
                                                   self.input_action: feed_action})

    def update_source_critic_net(self, feed_state, feed_action, feed_y, sess=None):
        sess = sess or self.sess
        return sess.run([self.train_q_op],
                        {self.input_state: feed_state,
                         self.input_action: feed_action,
                         self.y: feed_y})

    def update_target_critic_net(self, sess=None):
        sess = sess or self.sess
        return sess.run(self.update_target_net_op)

    def get_action_grads(self, feed_state, feed_action, sess=None):
        sess = sess or self.sess
        return (sess.run(self.get_action_grad_op, {self.input_state: feed_state,
                                                   self.input_action: feed_action}))[0]

    def __create_get_layer_weight_op_source(self):
        with tf.variable_scope(self.source_var_scope, reuse=True):
            self.h1_weight_source = tf.get_variable("hidden_1/kernel")
            self.h1_bias_source = tf.get_variable("hidden_1/bias")

    def run_layer_weight_source(self, sess=None):
        sess = sess or self.sess
        return sess.run([self.h1_weight_source, self.h1_bias_source])

    def __create_get_layer_weight_op_target(self):
        with tf.variable_scope(self.target_var_scope, reuse=True):
            self.h1_weight_target = tf.get_variable("hidden_1/kernel")
            self.h1_bias_target = tf.get_variable("hidden_1/bias")

    def run_layer_weight_target(self, sess=None):
        sess = sess or self.sess
        return sess.run([self.h1_weight_target, self.h1_bias_target])


class Model(object):
    def __init__(self,
                 state_dim,
                 action_dim,
                 optimizer=None,
                 actor_learning_rate=1e-4,
                 critic_learning_rate=1e-3,
                 tau=0.001,
                 sess=None):
        self.state_dim = state_dim
        self.action_dim = action_dim
        self.actor_learning_rate = actor_learning_rate
        self.critic_learning_rate = critic_learning_rate
        self.tau = tau

        # tf.reset_default_graph()
        self.sess = sess or tf.Session()

        self.global_step = tf.Variable(0, name="global_step", trainable=False)
        global_step_vars = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope="global_step")
        self.sess.run(tf.variables_initializer(global_step_vars))

        self.actor_scope = "actor_net"
        with tf.name_scope(self.actor_scope):
            self.actor = DDPG_Actor(self.state_dim,
                                    self.action_dim,
                                    learning_rate=self.actor_learning_rate,
                                    tau=self.tau,
                                    scope=self.actor_scope,
                                    sess=self.sess)

        self.critic_scope = "critic_net"
        with tf.name_scope(self.critic_scope):
            self.critic = DDPG_Critic(self.state_dim,
                                      self.action_dim,
                                      learning_rate=self.critic_learning_rate,
                                      tau=self.tau,
                                      scope=self.critic_scope,
                                      sess=self.sess)

    def update(self, state_batch, action_batch, y_batch, sess=None):
        sess = sess or self.sess
        self.critic.update_source_critic_net(state_batch, action_batch, y_batch, sess)
        action_batch_for_grad = self.actor.predict_action_source_net(state_batch, sess)
        action_grad_batch = self.critic.get_action_grads(state_batch, action_batch_for_grad, sess)
        self.actor.update_source_actor_net(state_batch, action_grad_batch, sess)

        self.critic.update_target_critic_net(sess)
        self.actor.update_target_actor_net(sess)

    def predict_action(self, observation, sess=None):
        sess = sess or self.sess
        return self.actor.predict_action_source_net(observation, sess)

推荐系统强化学习建模

强化学习(MDP)概念 对应推荐系统中的概念
智能体(Agent) 推荐系统
环境(Environment) 用户
状态(State) 状态来自于Agent对Environment的观察,在推荐场景下即用户的意图和所处场景;具体可以使用Dense和Embedding特征表达用户所处的时间、地点、场景,以及更长时间周期内用户行为习惯的挖掘。
动作(Action) 建议先建模奖励后再建模动作;解决业务问题不同对应的动作也不同,比较常见的是多目标排序时的模型融合比例,或者推荐系统中各个召回的流量分发占比等。
奖励(Reward) 根据用户反馈给予Agent相应的奖励,为业务目标直接负责。比较常见的是点击率,转化率或者停留时长等

实时强化学习框架设计
構造

附录

おすすめ

転載: www.cnblogs.com/arachis/p/DRL.html