目录
3.2.4 随即环境(random stochastic environment)
3.3.5 算法改进:E-贪婪策略(Epsilon-greedy策略)
第三课 第一周1.1 欢迎来到第三课_哔哩哔哩_bilibili
(1)Unsupervised Learning:无监督学习
a)Clustering:聚类
b)Anomaly detection:异常检测
了解聚类算法,这是一种将数据分组到聚类的方法;再了解异常检测,懂得他们是如何工作的以及能够让他们与自己一起工作
(2)Recommender Systems:推荐系统
如当你浏览在线购物网站或视频媒体网站时,向你推荐产品或电影,我们会了解工作原理,并能够自己实现一个
(3)Reinforcement Learning:强化学习
学习后,我们可以自己实施强化学习,并用它来登录一个模拟的月球着陆器
一、无监督学习
1.1 聚类
聚类算法着眼于许多数据点和自动查找彼此相关或相似的数据点
如下图,在监督学习中,可以根据数据集的输入,输出目标y的分类结果
而在无监督学习中,给出这样一个数据集,只有x,但不是标签或目标标签y,如下图,所以绘制时没有用 ×和⚪表示两个类,而是全用来黑点,因为该数据集没有目标标签y,所以无法分辨该算法想要我们预测的正确答案y是什么;相反,我们将要求算法找到有关数据的有趣内容,那就是找到关于这些数据的一些有趣的结构
而现在学习的无监督算法为聚类算法
1.1.1 K-means的直观理解
这里有30个未标记训练示例的数据集,如下图
K-means算法最喜欢做的第一件事都是随机猜测在哪里可能是你要求它找到的两个集群的中心,此示例中,我们来要求它尝试查找两个集群
第一步是随机选择两个点,用红叉和蓝叉表示,在哪里可能是两种不同成本的中心,这只是一个随机的初始猜测,可能不是特别好。
而K-means将反复做两件不同的事,第一个是将点分配给集群质心,第二个是移动集群质心;簇的中心称为簇质心
这两个步骤中的第一步是它会遍历这些点中的每一个,并查看它是否更接近红十字或蓝十字。在对集群质心的位置进行初步猜测后,它及那个遍历所有这些示例,即30个数据点,检查是否更接近红色的簇质心或者是否更接近蓝色的簇质心,它会将每一个数据点分配给给它最接近的集群质心
第二步是它会查看所有红点并取它们的平均值,然后会将红叉移动到红点的平均位置
然后再次执行第一步,会发现有的点会改变颜色
再次执行第二步
重复执行地一、二步,直到将每个簇质心移动到所有具有i相同颜色的点的平均值,此时再继续执行的化,点的颜色和簇质心不会再发生变化了
1.1.2 K-means算法实现
如果初始化有簇质心没有分配到点,则消除一个簇, K = K - 1,
k-means也常用于集群没有很好分离的数据集
1.1.3 优化目标
很多的监督学习算法将训练集作为成本函数,然后使用分级下降或其他一些算法来优化该成本函数
该代价函数也称失真函数,或 失真成本函数,要求其代价函数J最小
k-means在优化成本函数 J 时,失真成本函数应该下降或保持不变,一旦有一段时间保持不变,则说明k-means已经收敛,可以停止运行
还有另外一种方法可以利用成本函数,就是使用多个不同的簇质心随机初始化,这样做通常可以找到更好的集群
1.1.4 初始化K-means
(1)选择训练集示例作为簇质心
但是这样容易陷入局部最优解,所以要多次运行它,然后尝试找到最佳的局部最优解
多次循行后,最终选择一个成本最低的集群及集,失真更低
多次初始化往往比选择一个好的更好
1.1.5 选择聚类数量
选择k的方法:
(1)肘部法
绘制K 关于成本函数的曲线,找出肘部的点,如左图,个人几乎不使用,因为认为对于很多应用程序,正确数量的集群是模棱两可的,会发现很多成本函数看起来像右边的图像,只是平滑地减少并且它没有一个明确的肘部希望你可以用来选择K的值
一种行不通的方法是选择K作为最小化成本函数J,因为这样做导致你几乎总是选择K的最大可能值,因为更多的集群几乎总是降低成本函数,选择K来最小化成本函数J并不是一个好的技术
(2)手动决定
K的值可以手动决定根据你所要的结果的来看
1.2 异常检测
第二个无监督学习算法
异常检测算法查看未标记的正常事件数据集,从而学会检测或发出危险信号,如果发生异常或异常事件
1.2.1 发现异常事件
如一个检测飞机发动机异常的例子,假设x1测量发动机产生的热量,x2测量振动强度等以获取其他特征,绝大部分的发动机都是正常的好的,所以就有的数据集,这个新的发动机是 x_test
此外,也可以检测一个用户的操作是否存在异常,如通过它的打字速度、浏览速度,登陆地址等,甚至是cpu负载、网络流量,但不会直接关闭它的用户,通常会发送信息提醒他们进行安全检查,通过电话、邮件等方式进行验证
1.2.2 高斯正态分布
假设x是个随机值,随机变量,如果x的概率由高斯或正态分布给出,均值参数Mu,方差Sigma平方,其概率如下列左图,曲线的中心或中间由平均Mu给出,曲线的标准偏差或宽度由该方差参数Sigma给出,形状是一个钟形曲线,x的概率如下图中间所示。
技术上讲Sigma被称为 标准差和平方,Sigma平方称为分布的方差
从这个分布中提取10个数字的直方图,会得到如下右图的图像
Sigma编程0.5后,图像变细了,又概率和为1,所有变得又细又高
Mu和Sigma平方的这些公式在技术上称为最大似然Mu和Sigma的估计值
此时的高斯分布更适合特征x只有一个特征的示例
1.2.3 异常检测算法
所以特征要么非常大,要么相对于他在训练集中看到的非常小,只要有一个非常小的,整体相乘后也会变得非常小
1.2.4 开发与评估异常检测系统
因为有缺陷的引擎很少,所以通常会选择没有测试集,全放入交叉验证集中
缺点就是没有公平方法来评判
1.2.5 异常检测与监督学习的对比
当正例数量非常少时,异常检测更合适,以及相对大量的负样本,因此正例仅用于交叉验证集和测试集,用于参数调整和评估
若有大量的正面和负面的例子,监督学习更适用,
现在即使只有20个正例训练示例,也可以用监督学习,但事实证明,异常检测查看数据集的方式与监督学习查看数据集的方式完全不同,主要区别在于,如果你认为有许多不同类型的明显或许多不同类型的正面例子,然后当飞机发动机有许多不同的方式出错时,异常检测可能更合适,如果明天可能有新的方式让飞机发动机出现问题,那么你的20个正面例子可能无法涵盖飞机发动机可能出现故障的所有方式,这使得任何算法都很难从一小部分正例中学习异常情况,正例是什么样的,未来的异常与迄今看到的任何异常示例都不一样,这会让我们更倾向于使用异常检测算法,因为异常检测所作的是查看正常示例,即y=0负示例,并尝试对他们的外观进行建模,任何与正常情况有很大差异的东西都会标记为异常,包括是否有一种全新的方式导致飞机引擎出现故障
相比之下,监督学习有不同的看待问题的方式,当理想地应用监督学习时,希望有足够的正面例子平均来了解正面例子是什么样的,对于监督学习,我们倾向于假设未来的正例可能与训练集中的正例相似。
举个栗子,比如有人试图用不同更多的方式进行财务欺诈,且每隔几个月或几年都会有新类型的金融欺诈,这意味这他会不断的出现新的欺诈方式,而独特形式的金融欺诈异常检测通常用于寻找任何不同的事物,然后是我们过去看到的交易,相比之下,如果您查看垃圾邮件检测问题,那么垃圾邮件有许多不同类型,但甚至有很多年垃圾邮件不断尝试销售类似的东西,让你访问类似的网站等,你在接下来的几天收到的垃圾邮件可能与你过去看到的垃圾右键相似,这就是为什么监督学习对垃圾邮件检测很好的原因
1.2.6 选择使用什么特征
在构建异常检测算法时,选择一个好的功能选择非常重要
在监督学习中,如果你没有完全正确的特征,或者如果有一些与问题无关的额外特征,事实证明这通常是可以的,因为算法必须监督有足够标签的信号,为什么算法要弄清楚哪些特征忽略了,或者如何重新缩放特征和充分利用你提供的功能;但是对于运行或仅从未标记数据中学习的异常检测,异常更难找出要忽略的特征,所以仔细选择特征比监督学习方法更重要
可以帮助异常检测算法的一个步骤是尝试确保为其提供的特征或多或少是高斯的,如果特征不是高斯的,可以更改它以使其更加高斯,
修改参数
发现有点高斯的样了,但并不完美继续修改
太过了,再改
这看起来已经很像了,所以用x的0.4次幂替换x
也可以直接用 np.log函数,结果得到一个错误,因为结果非常好,这个例子有一些等于0的值,记录零是未定义的负无穷大,所以常见的技巧是调价一个非常小的数字
+0.001变成非负数
若想让他看起来更像高斯,则调整这个值
要记住:无论对训练集做了什么转换,对交叉验证集和测试集数据也要进行相同的转换
除了确保数据近似高斯之外,在训练了异常检测算法后,如果他在测试集上表现不佳,还可以执行错误分析过程进行异常检测。换句话说,可以在出错时尝试查看算法在哪些方面做的不好,然后用它来尝试提出改进。
我们想要的是X的P很大,对于正常示例X
如果找出了一个P相对还算有点的大的异常,通常我们会找出是什么让我们认为是一个异常,即使它与其他训练示例有相似的值,如果能识别处一些新特性,比如x_2,这有助于这个示例与普通示例区分开来,然后添加该功能,可以帮助提高算法的性能
另一个例子,正常计算机可能具有高CPU负载和高网络流量,或地CPU负载和没有网络流量,但这台机器的不寻常之处是CPU负载非常高,而流量却非常低,此时可能会创建一个新的功能x_5,即CPU负载与网络流量的比率,或者考虑其他特征如x_6
二、推荐系统
对于推荐系统这个框架,解决问题的一种可能方法是查看用户未评分的电影并尝试预测用户如何评价这些电影,因为这样我们就可以尝试向用户推荐他们更有可能评价为五颗星的东西
2.1 算法构建
2.1.1 使用每个特征
上例推荐电影的例子中,增加两个特征,是否是爱情电影或动作电影
2.1.2 协同过滤算法
但是如果没有上例中的特征 x_1 和 x_2 怎么办
(1)根据参数w、b自己猜测
(2)根据同一项目的多个用户使用同一部电影进行猜测,学习给定的特征
根据其他看过该电影的用户的评分和与当前用户的相似度进行评分,若打分较高,则推荐
根据学习出来的w、b的参数,可以推断出特征x_1和x_2,若直到其他电影的打分情况,也可以推断出其他电影的相关特征
2.1.3 二进制标签
改变为逻辑回归的形式,变换成本函数
2.2 算法初步实现
2.2.1 均值归一化
添加了一个用户 Eve ,添加均值归一化将有助于算法对用户 Eve 做出更好的预测,
此时Eve的参数w和b可能都为0,为了减小成本函数,如果新用户还未给任何电影评分,我们会认为他会给所有电影评分为零星,这样它的参数就都是0,成本函数也是最小的
从原评级中减去平均评级,这里是把求行的均值,也可求列的均值,但这里规划行比规范列对于给出新用户合理的评级更重要,对于没有人评级的电影,可以对列进行规范化
但要根据参数w、b、x计算时要把 Mu加回来,而此时新用户Eve也加的话,那么它的评分就是这个均值,要比全0预测上更好
2.2.2 协同过滤的TensorFlow实现
TensorFlow是构建神经网络的绝佳工具,但也很有希望用于构建其他类型的学习算法,比如协同过滤算法
用TensorFlow的还有一个原因是需要找到成本函数的导数,而TensorFlow可以自动找出成本函数的导数,要做的就是实现成本函数,无需自己导数
采取梯度步骤并更新w,并再次计算导数并一遍又一遍地更新w直到最终达到w的最优值,即w=1;因此,此过程允许你实现梯度下降,而无需自己弄清楚如何计算这个导数项。这是TensorFlow的一个非常强大的功能,称为 Auto Diff(或 Auto Grad)。
Grad其实就是自动微分,自动取导数的专用软件包的名称
其他机器学习包,如Pytorch,也支持 Auto Diff
w = tf.variable (3.0) # 获取参数w并将其初始化为3.0的值
# 告诉tensorflow,w是一个变量,就是我们告诉他,w是我们想要优化的参数的方式
# 设置 x=1.0,y=1.0,学习率 alpha=0.01
x = 1.0
y = 1.0 # target value
alpha = 0.01
# 运行梯度下降,进行30次迭代
iterations = 30
for iter in range (iterations) :
# Use TensorFlow's Gradient tape to record the steps
# 使用TensorFlow的Gradient tape(梯度种类)的功能
# 定义 梯度下降的内容公式
# used to compute the cost J, to enable auto differentiation.
with tf.GradientTape ( ) as tape:
fwb = w*x
costJ =( fwb - y)**2
# Use the gradient tape to calculate the gradients
# of the cost with respect to the parameter w.
[ aJdw] = tape.gradient ( costJ, [w]) # 用该语法,自动计算导数,求J对w的导数
# Run one step of gradient descent by updating
# the value of w to reduce the cost.
w.assign_add (-alpha * dJdw ) # 用 alpha 更新w
Auto Diff 实现协同过滤算法:
一旦可以自动计算导数,就不仅限于梯度下降,还可以使用更强大的优化算法,例如亚当优化算法
指定代价函数,用函数cofiCostFuncV,ynorm是评级均值归一化
如果使用梯度下降进行附带过滤,记住,成本函数J 将是w、b和x的函数;如果正应用梯度下降,可以对w、b、x取偏导数,正如之前提到的TensorFlow和Auto Diff不仅限于梯度下降,还可以用更强大的优化算法,例如亚当优化
# Instantiate an optimizer.
optimizer = keras.optimizers. Adam (learning_rate=1e-1) # 指定优化器,作为亚当优化器
iterations = 20o
for iter in range (iterations) :
# Use TensorFlow' s GradientTape
# to record the operations used to compute the cost
with tf.GradientTape () as tape :
#Compute the cost (forwardpasssincluded in cost)
cost_value = coficostFuncv,6,)xnorm,R,num_users, num_movies, lambda)
# Use the gradient tapeto automatically retrieve
# the gradients of the trainable variables with respect to the loss
grads = tape.gradient( cost_value,[X,w,b] )
# Run one step of gradient descent by updating
# the value of the variables to minimize the loss.
# 将优化器与刚刚计算的梯度一起使用
# 将一个数字重新排列为应用梯度函数的适当顺序的函数
optimizer.apply_gradients( zip(grads,[x,w,b]))
2.2.3 寻找相关特征
x^k是新特征,与x^i类似
协同过滤的一些限制:
(1)不擅长冷启动问题
如,刚上线了一部电影,但没有人评价,或很少有人评价;同样,对于只评价过几个项目的新用户,如何确保向他们展示一些合理的东西
(2)它不给你使用有关项目或用户的附加信息或附加信息的自然方式
例如,对于目录中的给定电影,可能知道电影的类型,电影明星,工作室,预算等;对于单用户,可能对他们的人口统计有所了解,比如年龄、位置、性别
2.3 基于内容过滤
2.3.1 协同过滤与基于内容过滤
第二种推荐系统:基于内容的过滤算法
对于协同过滤,一般的方法是我们会向你基于与你给出相似评分的用户的评分,有一些用户对某些项目进行评分,该算法会计算出如何使用它,向你推荐新商品;
相比之下,基于内容的过滤是决定向你推荐什么的不同方法;基于内容的过滤会根据用户的特点和项目的特点向你推荐商品,找到一个很好的匹配;换句话说,它需要每个用户都有一些特征以及每个项目的一些特征,它使用这些特征来尝试决定哪些项目和用户可能是彼此很好的匹配。
使用基于内容的过滤,仍然需要用户对某些项目进行评分的数据
对于电影推荐,以下是一些功能示例(用户和电影)
注意:用户和电影特征的大小可能非常不同,,用户可能1500个数字,电影可能50个数字
为了开发基于内容的过滤,要拜托b^(j),事实证明这不会伤害基于内容的过滤的性能
构建新的向量 v,u是用户表现,m是电影特征,如 V_u这个列向量中,第一个表示对爱情电影的喜爱程度,第二个表示对动作电影的喜爱程度等等
点积相乘,但要保证他们两个向量内的数字数量相同,且如何从x计算出v
2.3.2 基于内容过滤的深度学习方法
使用神经网络从x计算出v
还可以用Sidmoid函数对输出进行修改,表示用户j对电影i的的预测,是否为1
实际上也可以把他们拉在一起形成一个单一的图表,就好像它是一个单一的神经网络
构建一个新的成本函数,训练神经网络的参数,使用梯度下降或其他一些优化算法来调整神经网络的参数来使得成本函数J尽可能小;如果进行正则化,还可以添加通常的神经网络正则化项以鼓励神经网络保持他们的参数值很小。
事实证明,在训练了这个模型之后,也可以用它来寻找相似的物品,类似于协同过滤,帮助找到类似的项目
如给定一个电影,想找到类似的电影,向量v^i_m描述了电影i,如果你想找到其他类似的电影,可以再寻找其他电影k,这样可以描述电影k和i之间的平方距离很小,该作用类似于协同过滤,协同过滤是找到特征k和特征i相似的电影,因此通过该方法,还可以找到与给定项目相似的项目
最后,这可以提前预先计算。即可以在一夜之间运行一个计算服务器来浏览所有电影和每部电影的列表,找到与之相似的电影,以便明天如果用户访问该网站并他们正在浏览特定的电影,你已经可以预先计算到当时向用户展示10或20部相似的电影。你可以提前预先计算的事实事件与给定电影相似的东西会变得很重要
2.3.3 从大型目录中推荐
存在很多网站:电影、广告、歌曲、购物等等
每次用户出现在网站上时,都要运行数百万次神经网络推理,计算上都会变得不可行
许多损失尺度推荐系统被实现为两个步骤:检索 、 排名步骤
1、检索
在检索步骤期间将生成大量似是而非的候选项目列表,这些候选项目试图涵盖很多你可能会向用户推荐的内容。在检索步骤中,如果包含了很多用户不太可能喜欢的项目,然后再排名步骤中进行微调并选择最好的项目推荐给用户
有一个例子:
(1)在检索步骤中,我们可能会为用户观看的最后10部电影中给定每一步电影做类似的事情,找出10部最相似的电影,因此,这意味着,如果用户观看了带有向量v^i_m的电影i。你可以找到它与向量v^k_m类似的电影。因此预先计算出最相似的电影以提供电影,可以使用查找表来提取结果,这将为你提供一组可能有些可信的初始电影,以向刚刚出现在你网站上的用户推荐
(2)此外,可能决定将用户最常查看的三种类型添加到其中,假设用户看了很多爱情片和很多喜剧和历史剧,然后我们会将这三种类型的前10部电影添加到可能的候选项目列表中
(3)然后也许我们也会在这个列表中添加用户所在国家/地区的顶部的20部电影
因此,这个检索步骤可以非常快速的完成,最终可能会得到一个包含100或数百个相似的电影的列表推荐给用户,并且希望这份列表会推荐一些不错的选择;但是如果它包含一些用户根本不喜欢的选项也是可以的。
检索步骤的目标是确保广泛的覆盖范围,拥有足够多的电影,至少其中有很多好电影
最后我们将获得在检索步骤中检索到的所有项目,并将他们组合成一个列表,删除重复项和删除用户已经完全清洗或用户已经购买并可能不想你再推荐给他们的物品
2、排名步骤
在排名步骤中,将获得在检索步骤中检索到的列表,因此,这可能只是数百部可能的电影,并使用学习模型对它们进行排名。意味着你将用户特征向量和电影特征向量输入到神经网络中,对每个用户电影计算预测评分。至此,可能得到100多部或数百部用户最有可能给予高评价的电影。
然后,你可以根据你认为用户将给予最高评价的内容向用户显示项目的排名列表
一项额外的优化是:如果你提前为所有电影计算了V_m,那么你需要做的就是进行推理,在上半部分神经网络上单次计算V_u,再去点积,该计算可以相对快速的完成
在检索步骤中,检索更多项目往往会导致更好的性能,但该算法最终会在分析或优化检索多少项目之间的权衡时变得更慢,检索100或500或1000个项目,建议进行离线实验,看看检索附加项目有多少会产生更相关的建议。特别是,根据神经网络模型,如果yij的估计概率等于1,或者根据你的模型的预测,对检索项目高的估计评分最终要高得多,如果只检索500件,而不是100件,那么这将支持即使它会减慢算法速度,也可能会检索更多项目
检索步骤试图修剪掉很多不值得对其进行更详细的影响和内积的项目;然后排民步骤对用户实际可能喜欢的项目进行更仔细的预测
2.3.4 推荐系统中的伦理
2.3.5 基于内容过滤的TensorFlow实现
user_NN = tf.keras.models.sequential ( [
tf.keras.layers.Dense (256,activation='relu'),
tf.keras.layers.Dense (128,activation='relu'),
tf.keras.layers.Dense (32)
] )
item_NN = tf.keras.models.Sequential ( [
tf.keras.layers.Dense(256,activation='relu'),
tf.keras.layers.Dense(128,activation='relu'),
tf.keras.layers.Dense (32)
] )
# create the user input and point to the base network
input_user = tf.keras.layers.Input (shape=(num_user_features) ) # 为用户提取输入特征
vu = user_NN ( input_user) # 将其提供给用户
vu = tf.linalg.l2_normalize (vu, axis=1) # 将向量vu标准化为长度为1,l2归一化函数
# create the item input and point to the base network
input_item = tf.keras.layers.Input (shape=(num_item_features) )
vm = item_NN (input_item)
vm = tf.linalg.l2_normalize (vm,axis=1)
# measure the similarity of the two vector outputs
output = tf.keras.layers.Dot (axes=1) ( [vu, vm] ) # 计算点积
# specify the inputs and output of the model
model = Model ( [input_user,input_item],output) # 告诉keras模型是一个有输入输出的模型
# 都是上面定义的输入和输出
# Specify the cost function
cost_fn = tf.keras.iosses.MeansquaredError() # 均方误差成本函数
三、强化学习
3.1 强化学习介绍
3.1.1 什么是强化学习
一个无线控制直升飞机的例子
通过强化学习算法进行控制,直升机甚至可以倒飞
强化学习中,我们将直升机的位置、方向和速度等称为状态s,所以任务是找到一个函数,将直升机的状态映射到动作a,这意味着按顺序推动两个控制杆的距离,保持直升机在控中的平衡和飞行而不会坠毁。也可以使用监督学习,但对于正在飞的直升机而言不是一个好方法
但可以有一个专业的飞行员告诉我们什么是最好的行动,然后可以使用监督学习来训练神经网络,直接从状态s中学习映射,我们在这里称为x,动作a这里称为标签y
飞行好时,给一个每秒+1的奖励;飞行不佳时,每一个非常大的负奖励
我们不知道最佳的动作是什么,一切都是它自动计算出来的,我们只需给她奖励来激励它,自动找出好的动作
一个狗的过障碍的视频:
应用:
3.1.2 示例:火星探测器
如下,状态1的奖励是100,状态6的奖励是40
假设探测器从状态4开始,前往状态1或6的终端状态后即停止运行,此刻向左或向右到达终端状态是唯一的选择
步骤一直接向左
步骤二直接向右
步骤三是探测器先向右在到终端状态前改变方向向左,但花费了更多的时间
总而言之,在每个时间步,机器人都处于某种状态,称为s,它可以选择一个动作a,并且还享有一些奖励,他从那个状态的太s的R,即R(s),然后到了新的状态 s'
每次行动时都会发生这种情况(状态,行动,奖励,下一个状态),成为强化学习的核心要素,为了清楚起见,这里的奖励R(s)是与此状态相关的奖励,而不是与下一个状态相关。该例子中,这种零奖励与状态4相关,而不是与状态3相关
3.1.3 强化学习的回报(奖励)
要如何知道一组特定的奖励比另一组奖励更好或更差
还是上面火星探测的例子
回报(奖励)被定义为这些奖励的总和,但由一个附加因素加权,称为折扣因子(Gamma)
折扣因子(系数)是一个略小于1的数字,例如假设折扣因子 Gamma 为 0.9,这样可以导致越早而总回报的价值越高
在许多强化学习算法中,常见的选择:折扣因子是一个非常接近1的数字,例如0.9、0.99甚至0.999
为方便说明选择折扣因子Gamma为0.5,这个折扣因子is heavy
对于负奖励,可能导致算法尝试推送尽可能将奖励放在未来
3.1.4 决策:强化学习中的策略(控制器)
还是上述的例子,可能为了时间而走,可能为了更大的奖励而走,也可能是为了某个方向而走;这些都算出发的策略,要构建一个函数Pi,将状态带入,找出下一步的动作
强化学习的目标就是找到一个函数Pi 或 S 的 Pi来告诉你要采取什么行动来获取什么状态,以最大化回报
也可能将函数Pi称为控制器而不是函数
3.1.5 审查关键概念
这种强化学习应用程序的形式实际上有一个名字,被称为马尔可夫决策过程(MDP)
马尔可夫决策过程是指未来只取决于当前状态而不取决于任何事物,这可能发生在进入当前状态之前;换句话说,马尔可夫决策过程中,未来只取决于你现在在哪里,不是关于你是怎么到这里的;
考虑马尔可夫决策过程形式主义的另一种方法是我们有一个机器人或其他一些代理,我们要做的是选择动作a并基于这些动作,世界或环境中会发生某些事情,例如在世界上的位置发生变化或我们去取样一块岩石并执行科学任务。我们选择动作a的方式是使用策略Pi并基于世界上发生的事情,然后观察我们所处的状态以及我们得到什么奖励
我们要定义并最终学会计算状态动作价值函数
3.2 状态-动作价值函数
3.2.1 函数定义
状态动作函数通常用 Q(s, a) 表示
如下图中的第一个函数Q(2,→)表示从状态2开始首先向右出发,但向右后,又重新向左到终端状态1,因为这是向右开始的情况下,表现最佳的情况
因为状态动作价值函数几乎总是用字母Q表示,所以通常称为Q函数,被写作 Q* ,有时也被称为最优Q函数,Q函数和状态动作价值函数可以互换使用
3.2.2 函数示例
import numpy as np
from utils import *
# Do not modify
num_states = 6
num_actions =2
terminal_left _reward = 100
terminal_right_reward = 40
each_step reward = 0 # 中间状态的奖励
# Discount factor
gamma = 0.5
# Probability of going in the wrong direction
# 忽略失步概率
misstep_prob = 0
generate_visualization(terminal_left_reward, terminal_right_reward,
each_step_reward, gamma, misstep_prob)
terminal_left _reward = 100
terminal_right_reward = 10
each_step reward = 0 # 中间状态的奖励
# Discount factor
gamma = 0.5
terminal_left _reward = 100
terminal_right_reward = 40
each_step reward = 0 # 中间状态的奖励
# Discount factor
gamma = 0.9
terminal_left _reward = 100
terminal_right_reward = 40
each_step reward = 0 # 中间状态的奖励
# Discount factor
gamma = 0.3
3.2.3 贝尔曼方程
强化学习中,有个贝尔曼方程将帮助我们计算状态动作价值函数
本例中设置 Gamma = 0.5
总回报 = 当前回报 + Gamma * 下一状态的回报
3.2.4 随即环境(random stochastic environment)
比如上述例子,在状态4时要求向左走,但由10%的可能出现意外如翻车等实际向右走了,90%的可能正确的向左走
中间的过程是因为向左的过程中有一次失败的实际上向右了,又重新向左
所以我们要做的实际上是要最大化平均值,即 期望
总而言之,当遇到随机强化学习问题 或 一个随机马尔可夫决策过程,目标是选择一个策略,告诉我们在状态s中采取什么行动以最大化预期收益
最后一种改变的方式就是要修改一下 贝尔曼方程,因为下一步的动作是随机的
回到刚才的代码,就要修改失步概率为 0.1,即要求向左时,但实际有0.1的可能向右
# Probability of going in the wrong direction
# 失步概率 = 0.1
misstep_prob = 0.1
此时对机器人的控制程度是 90%,奖励值变低了
若修改 失步概率 = 0.4,则对机器人的控制程度是 60%,奖励值会更低
3.3 连续状态空间
3.3.1 示例:连续状态空间应用
例如,火星探测器可以在一条线上的任何地方,所以它的位置由一个数字表示,范围从0-6公里之间的任何数字都有效,这就是一个连续状态空间的例子
对于卡车或汽车,状态可能不仅包括一个数字,就像这条线上有多少公里,但它们可能包括六个数字,依次是x位置、y位置、Theta:方向、x方向上的速度、y方向上的速度、角度变化的速度,这些状态值都是连续的
另一个例子,若要构建强化学习算法控制一架自主直升机,要如何描述直升机的位置?
需要知道直升机x、y、z位置,上下左右旋转,机身左右前后上下的偏转,x、y、z方向上的速度、转动速率(角速度),行变化速度,俯仰变化的速度,偏航的变化速度等,这些都是可以用来控制自主直升机的状态
3.3.2 登月器
在这个应用程序中,我们要指挥正在快速接近月球表面的月球着陆器,在适当的时间使用火力推进器将其安全降落在着陆台上
着陆的成功与失败
我们在这个过程中有四个可以做的 ,打开不同的推进器
对登月器的奖励函数
3.3.3 学习状态值函数
如何使用强化学习来控制月球着陆器或其他强化学习问题,关键思想是我们要训练一个神经网络计算或逼近s,a的状态动作值函数Q,而这反过来又会让我们选择好的行动
学习算法的核心是我们要训练一个神经网络,输入当前状态和当前动作,并计算或逼近Q(s,a),特别是对于月球着陆器,我们将采用状态s和任何动作a并将它们放在一起,具体来说,状态是我们之前看到的8个数字的列表:x、y、x·、y·、Theta、Theta·、左右腿接地的位置,最后有四个可能的动作:nothing、left、main(a main engine)、right,我们可以对这四个动作中的任何一个进行编码,使用 one-hot 特征向量,如果动作是第一个动作,我们可以使用1、0、0、0对其进行编码,所以这12个数字就是我们对神经网络的输入,称为 X,输出Q(s,a)称为目标值 Y
所以,现在问题变成了如何训练一个神经网络来输出Q(s,a) ,事实证明,方法将是使用贝尔曼方程用于创建包含大量示例的训练集 x和y,然后我们将使用监督学习进行学习,从x到y的映射,即从状态动作对到Q(s,a)的映射
那么该如何获得具有x和y的训练集
自己构建状态和动作,每一个都可当做是训练示例
重复月球着陆器的行动,获得数据结果,存储10000个最近的元组到重放缓冲区,并创建这个训练集
要如何得到 Q(s', a'),最初是我们随机初始化的这个神经网络,这可能不是一个很好的猜测,构建新的神经网络Q_new,一直迭代更新Q,因此当将平均值运行足够长的时间,这实际上将称为一个很好的估计,以便可以使用它来选择希望好的行动或MTP
该算法有时被称为 DQN算法,即 Deep Q-Network,因为你正在使用深度学习和神经网络来训练模型学习 Q 函数,因此使用神经网络的 DQN 或 DQ
3.3.4 算法改进:改进的神经网络架构
此时我们的神经网络要分别四次计算这四个值,从而选择最大的Q(s,a),这是低效的,因为我们必须从每个状态进行四次推理
所以,事实证明,训练单个神经网络更有效,同时输出这四个值,选择最大值
3.3.5 算法改进:E-贪婪策略(Epsilon-greedy策略)
如选项2:为什么要偶尔随机选择一个动作,假设Q(s,a) 被随机初始化有一些奇怪的原因,因此学习算法认为启动主推进器绝不是一个好主意,也许神经网络参数被初始化,使得Q(s,main) 总是很低,这样的话,神经网络尝试选择Q的最大值就永远不会尝试启动主推进器,所以也就永远不会发现启动主推进器有时是个好主意
这种随机选择动作的想法有时被称为探索步骤,而采取最大化的行动有时被称为贪婪行动
最后,有时在强化学习中使用的技巧之一是从高 Epsilon 开始,最初,你在一段时间里采取随机的行动,然后逐渐减少,这样随着时间的推移,你不太可能随机采取行动,更有可能使用你改进的估计的Q函数来选择好的动作
3.3.6 算法改进:小批量和软更新
小批量:既可以加速你的学习算法,也适用于监督学习,还可以帮助加快监督学习算法,比如训练一个神经网络,或者训练一个线性回归或逻辑回归模型
软更新:帮助强化学习算法可以更好的收敛到一个好的解决方案
不适用1亿个数据,只是用1000个
每次迭代都是数据集的一个子集
虽然小批量每次迭代可能想着错误的方向前进,不可靠且有些嘈杂,但平均下来确是在趋向于全局最小值,但每次迭代的计算成本要低得多,所以当有一个非常大的训练集时,他是一个更快的算法
事实证明,使用软更新会使强化学习算法更可靠的收敛,学习算法不太可能振荡或转向或具有其他不良特性