(1)回顾了从神经元学到了神经网络,再到训练神经网络的方法,以及神经网络和深度学习的关系(如下),初步学习工具Spark、TensorFlow 和 Redis的基础操作。
(2)画图神器:https://app.diagrams.net/
- 学习心得
- 往期回顾
- 一、深度学习基础
- (1)神经元和点击率
- (2)神经网络如何学习
- 1)前向传播
- 2)损失函数
- 3)梯度下降
- 二、神经网络和深度学习的关系
- 三、深度学习在推荐系统的应用
- 四、资料推荐和工具
- 4.1 书籍
- 4.2 工具Spark、TensorFlow 和 Redis
- (1)Spark。
- (2)TensorFlow。
- (3)Redis
- 五、作业
- Reference
【王喆-深度学习推荐系统实战】开篇词
【王喆-深度学习推荐系统实战】基础架构篇-(task1)DL推荐系统架构
【王喆-深度学习推荐系统实战】基础架构篇-(task2)Sparrow麻雀推荐系统
神经元工作的生物学过程,那如果要用一个神经元来解决推荐问题,具体又该怎么做呢?
举个例子,我们可以假设其他神经元通过树突传递过来的信号就是推荐系统用到的特征,有的信号可能是“用户性别是男是女”,有的信号可能是“用户之前有没有点击过这个物品”等等。细胞体在接收到这些信号的时候,会做一个简单的判断,然后通过轴突输出一个信号,这个输出信号大小代表了用户对这个物品的感兴趣程度。这样一来,我们就可以用这个输出信号给用户做推荐。
上图中的激活函数是 sigmoid 激活函数,它的数学定义是: f ( z ) = 1 1 + e − z f(z)=frac{1}{1+mathrm{e}^{-z}} f(z)=1+e−z1它的函数图像就是上图中的 S 型曲线,它的作用:
- 把输入信号从(-∞,+∞)的定义域映射到(0,1)的值域(因为在点击率预测,推荐问题中,往往是要预测一个从 0 到 1 的概率)。
- sigmoid 函数有处处可导的优良数学形式,方便之后的梯度下降学习过程,所以它成为了经常使用的激活函数。比较流行的还有 tanh、ReLU 等,在训练神经元或者神经网络的时候,我们可以尝试多种激活函数,根据效果来做最终的决定。
多神经元构成的网络具有更强的拟合数据能力,如下图的一个由输入层、两神经元隐层和单神经元输出层组成的简单神经网络:
每个蓝色神经元的构造都和刚才的单神经元构造相同,h1和 h2神经元的输入是由 x1和 x2组成的特征向量,而神经元 o1的输入则是由 h1和 h2输出组成的输入向量。
神经网络的重要训练方法,前向传播(Forward Propagation)和反向传播(Back Propagation)。
1)前向传播前向传播的目的是在当前网络参数的基础上得到模型对输入的预估值,也就是我们常说的模型推断过程。比如说,我们要通过一位同学的体重、身高预测 TA 的性别,前向传播的过程就是给定体重值 71,身高值 178,经过神经元 h1、h2和 o1的计算,得到一个性别概率值,比如说 0.87,这就是 TA 可能为男性的概率。
2)损失函数如果这位同学的真实性别是男,那真实的概率值就是 1,根据公式 2 的绝对值误差定义,这次预测的损失就是|1-0.87| = 0.13。
l
1
(
y
i
,
y
^
i
)
=
∣
y
i
−
y
^
i
∣
l_{1}left(y_{i}, hat{y}_{i}right)=left|y_{i}-hat{y}_{i}right|
l1(yi,y^i)=∣yi−y^i∣
发现了预测值和真实值之间的误差(Loss),我们就要用这个误差来指导权重的更新,让整个神经网络在下次预测时变得更准确。最常见的权重更新方式就是梯度下降法,它是通过求取偏导的形式来更新权重的。比如,我们要更新权重 w5,就要先求取损失函数到 w5 的偏导 ∂ L o 1 ∂ w 5 frac{partial L_{o 1}}{partial w_{5}} ∂w5∂Lo1从数学角度来看,梯度的方向是函数增长速度最快的方向,那么梯度的反方向就是函数下降最快的方向,所以让损失函数减小最快的方向就是我们希望梯度 w5 更新的方向。这里我们再引入一个超参数α,它代表了梯度更新的力度,也称为学习率。现在可以写出梯度更新的公式了: w 5 t + 1 = w 5 t − α ∗ ∂ L o 1 ∂ w 5 w_{5}^{t+1}=w_{5}^{t}-alpha * frac{partial L_{o 1}}{partial w_{5}} w5t+1=w5t−α∗∂w5∂Lo1公式中的 w5当然可以换成其他要更新的参数,公式中的 t 代表着更新的次数。
对输出层神经元来说(图中的 o1),我们可以直接利用梯度下降法计算神经元相关权重(即图 5 中的权重 w5和 w6)的梯度,从而进行权重更新,但对隐层神经元的相关参数(比如 w1),我们又该如何利用输出层的损失进行梯度下降呢?
——“利用求导过程中的链式法则(Chain Rule)”。通过链式法则我们可以解决梯度逐层反向传播的问题。最终的损失函数到权重 w1的梯度是由损失函数到神经元 h1输出的偏导,以及神经元 h1输出到权重 w1的偏导相乘而来的。也就是说,最终的梯度逐层传导回来,“指导”权重 w1的更新。
∂
L
o
1
∂
w
1
=
∂
L
o
1
∂
h
1
⋅
∂
h
1
∂
w
1
frac{partial L_{o 1}}{partial w_{1}}=frac{partial L_{o 1}}{partial h_{1}} cdot frac{partial h_{1}}{partial w_{1}}
∂w1∂Lo1=∂h1∂Lo1⋅∂w1∂h1
2012年深度学习大突破的原因:
(1)算力提高
(2)数据极大丰富
(3)深度学习理论的发展,如pooling 层的加入和成功应用,各类更适合深度学习的梯度下降方法的提出等等
无论是单个神经元,还是结构非常复杂的深度学习网络,它们在推荐系统场景下要解决的问题都是一样的,就是预测用户对某个物品的感兴趣程度,这个感兴趣程度往往是一个概率,最典型的就是点击率、播放率、购买概率等。
深度学习的革命要求我们对算力、数据都作出大幅度的调整,而这些调整因为涉及到分布式计算平台、深度学习平台,以及线上的模型服务部分,所以我们需要在推荐系统的整体架构上都作出不小的改造。
四、资料推荐和工具 4.1 书籍西瓜书《机器学习》
复旦邱锡鹏的nndl《神经网络与深度学习》
葫芦书《百面机器学习》
项亮的《推荐系统实践》:介绍了经典的协同过滤、矩阵分解方法,还有推荐系统可以利用的数据,以及基本的评测方法等等。
王喆的《深度学习与推荐系统》,书和极客时间课程相互补充。
王喆推荐的其他闲书:《数学之美》、《程序员修炼之道》书里面介绍了很多重构、架构、系统设计、程序员哲学相关的经验知识。
它是业界最流行的分布式计算平台,学习三部曲:
(1)可以通过这篇文章(如何用形象的比喻描述大数据的技术生态?Hadoop、Hive、Spark 之间是什么关系?)来了解一下大数据的生态。
(2)可以通过 Spark 的官方教程尝试写一个 Spark Hello World 程序(在我们的 SparrowRecSys 里面新建一个 Scala 文件就可以)。
(3)因为这门课大量使用了 Spark 的机器学习库 Spark MLlib,所以最后可以通过这个官方教程来做一些初步的了解。
Tensorflow是这门课要使用的训练深度学习模型的平台。
Keras 是一套 TensorFlow 支持的 API,因为它的易用性,我们主要利用 Keras API 来实现我们的推荐模型。
(1)先看一篇介绍 TensorFlow 和 Keras 的基本概念的文章,对它们有一个初步的认识
(2)通过给 TensorFlow 的 Keras 接口写一个 Hello World项目做一个基本的上手实践。
(3)通过TensorFlow 官方教程进一步熟悉 TensorFlow 的其他功能。
Redis 是我们这门课要频繁使用的内存数据库,用来存储模型所需线上特征。
(1)先在官网熟悉一下Redis的基本介绍;
(2)然后下载安装redis;
(3)最后尝试使用 Redis 内置客户端 redis-cli,来执行几条基本的Redis命令。
作业需要熟悉 movielens 数据、推荐服务器代码。
(1)第一题:通过阅读 SparrowRecSys 的代码,能找到首页中每行内部的电影都是按照什么排序的吗?
答:根据影片历史平均评分,降序排列。详细调用过程:
a.index.html里面的js代码,调用在头部加载的recsys.js 的addGenreRow, 传入参数(页面ID,影片类别名称,rowId, 每行放置影片个数,baseUrl)
b.在addGenreRow调用已注册的 getrecommendation 服务,传参的排序依据为rating.
c.服务getrecommendation绑定类RecommendationService, GET请求数据
d.RecommendationService.doGet 中 调用 online.datamanager.DataManager#getMoviesByGenre,根据每个影片的历史平均rating,降序排列.
(2)第二道题:如果你已经发现了排序的规则,能在推荐服务器的代码里添加一个叫“热度”(popularity)的排序规则,然后让首页按照“热度”排序吗(补充:热度的定义是“这个电影被评价的次数”)?
1、RecSysServer.java的68行找到RecommendationService(),进入后找到35行getMoviesByGenre,再进入后,在switch里新增 case “popularity”: movies.sort((m1,m2) -> Integer.compare(m2.getRatingNumber(),m1.getRatingNumber()));break;
2、回到RecommendationService.java中找到
//ranking algorithm
String sortby = request.getParameter(“sortby”);
选中sortby,右键find in files,
找到
$.getJSON(baseUrl + “getrecommendation?genre=”+rowName+"&size="+size+"&sortby=rating", function(result)
将其中的sortby=rating,改成sortby=popularity
3、为看显示效果,参考了Kelper的“ 修改index.html的,原加载js文件为recsys.js?v=1.19”,然后重新run RecSysServer.java就可以了
Reference《深度学习推荐系统实战》——王喆



