# 值函数近似器
class Estimator():
def __init__(self):
state_examples = np.array([env.observation_space.sample() for x in range(10000)]) # 对环境进行10000次采样,便于后续对状态state抽取特征
# 特征处理1:归一化数据状态为零均值和单位方差
self.scaler = Scaler()
self.scaler.fit(state_examples) # 训练参数
# 特征处理2:状态state的特征状态抽取表示
self.featurizer = FeatureUnion([ # 类似容器,并行执行,然后拼接合成
('rbf1', RBF(gamma=5.0, n_components=100)),
('rbf2', RBF(gamma=1.0, n_components=100))
])
self.featurizer.fit(self.scaler.transform(state_examples)) # 训练参数
self.action_models = [] # 动作空间模型,对于每个状态,都会把经过特征处理的状态值分配对各自对应的动作模型中
self.nA = env.action_space.n # 动作空间数量
for na in range(self.nA):
# 动作模型使用随机梯度下降法
model = SGD(learning_rate='constant')
model.partial_fit([self.__featurize_state(env.reset())], [0])
self.action_models.append(model) # 将每个动作的模型存入列表
# 返回状态信号的特征化表示形式
def __featurize_state(self, state):
scaled = self.scaler.transform([state]) # 对输入状态归一化
featurized = self.featurizer.transform(scaled)[0] # 对归一化的状态提取特征
return featurized
# 对状态值函数进行预测
def predict(self, s):
features = self.__featurize_state(s) # 对输入的状态信号提取特征
predicter = np.array([model.predict([features])[0] for model in self.action_models]) # 预测该状态信号对应所有动作的概率
return predicter
# 更新值函数近似器
def update(self, s, a, y):
cur_features = self.__featurize_state(s) # 对当前的状态信号提取特征
self.action_models[a].partial_fit([cur_features], [y]) # 根据目标y和当前的状态信号特征更新对应的近似模型
class VF_QLearning():
def __init__(self, env, estimator, num_episodes, epsilon=0.1, discount_factor=1.0, epsilon_decay=1.0):
self.nA = env.action_space.n # 动作空间数量
self.nS = env.observation_space.shape[0] # 状态空间数量
self.env = env # 环境
self.num_episodes = num_episodes # 经验轨迹迭代次数
self.epsilon = epsilon # 贪婪算法参数
self.discount_factor = discount_factor # 折扣因子参数
self.epsilon_decay = epsilon_decay # 贪婪算法策略衰减系数
self.estimator = estimator # 函数近似器
def __epislon_greedy_policy(self, nA, epislon=0.5): # 贪婪策略
def policy(state):
A = np.ones(nA, dtype=float) * epsilon / nA
Q = self.estimator.predict(state) # 动作概率(列表)
best_action = np.argmax(Q)
A[best_action] += (1 - epsilon)
return A
return policy
def __random_action(self, action_prob): # 选取随机动作
return np.random.choice(np.arange(len(action_prob)), p=action_prob)
def q_learning(self):
for i_episode in range(self.num_episodes):
policy_epislon = self.epsilon * (self.epsilon_decay ** i_episode) # 策略参数,贪婪参数*衰减因子^代数
policy = self.__epislon_greedy_policy(self.nA, policy_epislon) # 声明策略
state = self.env.reset() # 重置环境
next_action = None # 下一个动作信号的初始化
for t in itertools.count(): # 生成无限的迭代器
# 根据策略获得当前状态信号的动作值
action_probs = policy(state)
action = self.__random_action(action_probs)
next_state, reward, done, _ = self.env.step(action) # 向前执行一步
q_values_next = self.estimator.predict(next_state)
td_target = reward + self.discount_factor * np.max(q_values_next) # 使用时间差分目标作为预测觉果更新函数近期器
self.estimator.update(state, action, td_target) # 更新函数近似器
state = next_state
2021-10-23 6.9
最新推荐文章于 2023-02-21 20:22:10 发布