推荐系统中常常面临冷启动和用户交互数据稀疏的问题。解决这个问题的一个手段就是对用户在多个领域(domain)的日志数据联合起来进行建模,这里的多个领域的数据可以指用户在诸如新闻App、音乐App、视频App等多个软件的日志数据(比如点击的浏览新闻标题和描述等)。这种联合建模基于一个假设:用户在不同领域也倾向于拥有相似的偏好,比如喜欢爱情电影的用户也很可能喜欢言情小说。
而多视角(multi view)或跨域(cross domain)推荐模型[1]就是一种常见的跨域数据联合建模方式,它会将多个视角/多个领域对应的特征映射到一个共享的隐空间(latent space)。
上图展示了对跨域数据建模的多视角DNN,它基于深度结构化语义模型(Deep Structured Sematic Models, DSSM)的计算最大化用户视角和多个物品视角对应隐向量的相似度,并按照相似度排序来推荐物品。图中的User View对应的特征为用户使用搜索引擎的查询信息,而其他的Item View对应的特征为用户在其它App所点击过的物品特征数据。该模型假定所有领域都对应着共同的用户。它使用了DNN将多个视角对应的高维稀疏特征映射\(x_U, x_1, \cdots, x_D\)到共享隐空间中的低维稠密特征\(y_U, y_1, \cdots, y_D\)。
之后可以计算用户隐向量\(y_U\)和物品隐向量\(y_j(j=1,\cdots, D)\)的语义相似度:
这里假设用户隐向量\(y_U\)和物品隐向量\(y_j(j=1,\cdots, D)\)相关,然后接下来的目标就是为每个视角都找到一个非线性的映射,以使\(y_U\)视角和其它物品视角\(y_1,\cdots,y_D\)在隐空间的相似度之和最大化:
其中\(W_{U}, W_{1}, \ldots W_{D}\)为各个视角对应的权重参数,一共有个\(N\)用户-物品对样本和\(D\)个物品视角,其中每个物品视角\(x_j\)都有其单独的输入特征维度\(d_{j}\)。
第\(i\)个用户-物品对样本拥有一个用户视角的输入特征\(x_{i, u}\)和其对应的物品视角特征\(x_{i, a}\),这里\(a\)是样本\(i\)对应物品视角的索引,样本\(i\)对应的其它物品视角的输入\(x_{i,j \neq a}\)则设为\(0\)向量。\(\gamma\)为温度系数。
如上文所述,跨域推荐本质上是个迁移学习问题,它需要在多个领域异构数据的基础上通过某种“桥梁”(bridge)来提高一个或多个目标域的推荐效果。这里的“桥梁”指不同领域之间的关联项目,比如共同的用户,共同的物品,共同的特征等。上面的多视角DNN模型就假定所有领域都对应着共同的用户。
跨域推荐在实际应用中常常面临隐私性的挑战,其一是不同用户的数据难以合法地进行集中化收集;其二是其使用的迁移学习模型跨不同的域和数据集进行映射,这常常会关联到不同的组织机构,同样会面临隐私问题[2]。此时上面提到的需要将数据集中起来的跨域推荐方法就不再行得通了,需要考虑在联邦场景下的跨域推荐模型。
而联邦场景下的跨域推荐模型根据其隐私保护的出发点不同,可大致分为以下三类:
我个人觉得在保证隐私的条件下进行跨领域之间的信息共享(纵向/横向+纵向)是最有意思的,其核心是联邦迁移学习相关的理论:即在隐私保护的前提下,根据不同领域之间的关联来生成共享表征。根据我阅读过的大部分论文来看,如不同领域对应不同的组织机构,则它们的embeddings不能直接进行迁移,需要采取间接的迁移方法。这些方法具体来说就五花八门了,有用GAN来生成带差分隐私保护的共享embeddings的(参见我上一篇博客《联邦学习:联邦场景下的多源知识图谱嵌入》),有用另一个中间视角的数据来训练共享子模型的[4],有用VAE来生成一个独立于所有领域的共享embeddings的[5],有先对数据加以差分隐私保护再用自编码器生成共享embeddings的[6]。可以预见这在未来仍将是个热点。
以下我们分别看下这三类所对应的相关论文,了解一下该领域的大致情况。
这篇论文提出了联邦多视角矩阵分解分解算法,因为其使用的多视角数据不涉及跨组织机构,故只需要保证用户数据不共享即可,属于前面所说的横向类型。具体而言,在传统的矩阵分解算法中,常常只考虑用户-物品矩阵,即所谓共现矩阵\(R\),通过分解该矩阵得到用户的隐向量矩阵\(P\)和物品隐向量矩阵\(Q\):
之后再基于用户矩阵\(P\)和物品矩阵\(Q\)得到用户\(u\)对物品\(i\)的预估评分:
其中\(p_i\)是用户\(i\)在用户矩阵\(P\)中的对应行向量,\(q_j\)是物品\(j\)在物品矩阵\(Q\)中的对应行向量。
而所谓多视角矩阵分解,即包括以下三个视角:用户-物品,用户-特征,物品-特征。这三个视角分别对应用户-物品矩阵\(R\in\mathbb{R}^{N_u\times N_v}\),用户特征矩阵\(X\in \mathbb{R}^{N_u\times D_u}\),物品特征矩阵\(Y\in \mathbb{R}^{N_v\times D_v}\)。这里\(N_v\)为用户个数,\(N_v\)为物品个数,\(D_u\)和\(D_v\)分别为用户和物品的特征维度。则多视角矩阵分解可表示为如下形式:
如下图所示:

其中\(P\in \mathbb{R}^{N_u\times K}\)是用户隐向量矩阵,\(Q\in \mathbb{R}^{N_v\times K}\)是物品隐向量矩阵,\(U\in\mathbb{R}^{D_u\times K}\)是用户特征隐向量矩阵,\(V\in \mathbb{R}^{D_v\times K}\)是物品特征隐向量矩阵,这里\(K\)是隐向量维度。
此时所要优化的目标函数可以写为:
这里\(c_{ij}=1+\alpha r_{ij}\),\(\alpha\)是一个表示隐式反馈不确定性的置信参数;\(\lambda_2\)是L2正则项;\(\lambda_1\)表示用户-物品视角与其它视角间的信息共享强度,若令\(\lambda_1=0\)则表示用户-物品视角不与其它视角进行信息共享,\(0\leqslant\lambda_1\leqslant 1\)可以根据数据生成过程的先验知识选择,也可以通过超参数优化来决定。
模型参数\(P, Q, U, V\)可以通过交替最小二乘法(Alternating Least Square, ASL)来求解。
下图描述了在联邦场景下用交替最小二乘法求解该问题的算法。
如图所示,用户\(i\)和物品的交互信息\(r(i)\)(用户\(i\)在\(R\)中的对应行向量)及用户\(i\)的特征向量\(x_i\)(用户\(i\)在\(X\)中的对应行向量)只能在client \(i\)本地使用。物品的特征矩阵\(Y\)存储在item server中。fl server会将\(Q, U\)分发给client(用户),并将\(Q\)发往item server。
在每个client \(i\),用户的隐向量\(p_i\)会在本地进行计算,其中会使用到该用户与物品的交互信息\(r(i)\)、该用户的特征向量\(x_i\)与来自server的\(Q, U\)。新的用户隐向量\(p_i^*\)计算公式如下:
之后,client \(i\)按照下式计算\(f(j, i)\)(用于之后在fl server计算\(\partial J / \partial q_{j}\)以更新\(Q\)):
按照下式梯度\(f(i, d_u)\)(用于之后在fl server计算\(\partial J / \partial u_{d_u}\)以更新\(U\)):
上述计算完毕后将\(f(j, i),f(i, d_u)\)发往fl server。
与此同时,在item server,物品特征隐向量矩阵\(V\)也会得到更新(其中会用到物品特征),新的物品隐向量\(v^*_{d_y}\)计算方式如下:
更新完成后,在此基础上计算\(f(j, d_y)\)(用于之在fl server计算\(\partial J / \partial q_{j}\)以更新\(Q\)):
之后再将\(f(j ,d_y)\)发给fl server。
而在fl server接收\(f(j, i), f\left(i, d_{u}\right), f(j, d_y)\)后,按照下列两个式子计算梯度并更新\(Q\)和\(U\):
然后又将\(Q\)和\(U\)发往各client,将\(Q\)发往item server,以此循环往复。
综上,该篇论文按照损失函数\(J\)对多视角数据矩阵\(R, X, Y\)共同进行矩阵分解,以学习隐向量矩阵\(P, Q, U\)和\(V\),具体算法采用了联邦交替最小二乘法。可以注意到联邦场景下对参数矩阵\(Q\)和\(U\)进行的更新并不需要对用户数据进行聚合(虽然\(Q\)和\(U\)的更新依赖于用户数据)。
上面提到的是基于联邦矩阵分解的推荐模型,而下面要介绍的是联邦场景下基于内容的(content-based)推荐模型,它侧重将用户或者物品的特征信息作为输入特征来建模。具体的模型采用我们第1部分中所叙述的多视角DSSM模型。该模型同时满足了多个client数据的隐私性和单个client中多视角数据的隐私性,属于横向+纵向类型。
不过本文与原始多视角模型中共享用户视角的特征不同,本文共享的是物品视角的特征。设共有\(C\)个client,第\(c\)个client中的本地数据集表示为\(\mathcal{D}^c=\{x_I, x_1,\cdots x_D \}\)。这里\(x_1,\cdots x_D(x_j\in\mathbb{R}^{d_{j}})\)为用户在\(D\)个不同App中记录的多视角特征数据,而物品视角数据集\(x_I\in \mathbb{R}^{d_I}\)从server下载,比如移动App的后端。DSSM模型将从各个App视角数据集\(x_I, x_1,\cdots x_D\)和物品数据集\(x_I\)中分别提取隐向量。算法的目标是为每个视角学得一个非线性映射\(f(\cdot)\)以使物品视角隐向量和多个用户视角隐向量相似度的和最大化。第\(c\)个client的目标定义如下:
这里\(N_c\)表示client \(c\)中用户-物品对的数量,第\(i\)个用户-物品对样本拥有一个物品视角的输入特征\(x_{i, I}\)和其对应的用户视角特征\(x_{i, a}\),这里\(a\)是样本\(i\)对应用户视角的索引。\(y\)表示\(f(\cdot)\)的映射结果,\(\gamma\)是温度参数。
联邦多视角DSSM模型(FL-MV-DSSM)求解算法的架构如下所示:
(a)FL-MV-DSSM和(b)SEMI-FL-MV-DSSM 都以传统的FedAvg算法为基础,且它们都需要server提供物品数据供所有client共享。不过在FL-MV-DSSM中每个client \(c\)中用户子模型和物品子模型的梯度会根据本地用户数据和本地物品数据进行计算,然后在server端对用户和物品子模型的梯度进行聚合;而SEMI-FL-MV-DSSM则只会聚合物品子模型的梯度,而不会聚合用户子模型的梯度。
注意,client在将梯度发往server前,会在本地先多个视角所算得的物品子模型梯度聚合(注意,\(D\)个用户视角共享同一个物品特征,会总共算得\(D\)个物品子模型的梯度);而为了保护各视角梯度中蕴含的敏感信息,FL-MV-DSSM使用差分隐私技术向各个视角所算得的物品子模型梯度中加入高斯噪声。在本地聚合完成后,client又会再将前述物品子模型梯度同\(D\)个用户子模型的梯度进行加密,然后发往server。
本论文提出的模型满足了多个client数据的隐私性和单个client中跨领域数据的隐私性,也属于横向+纵向类型。不过与前文采用的方法不同,本文提出的DUE(Decentralized User Encoding)模型并没有利用一个中间视角的数据来训练共享子模型,而是采用变分自编码器(VAE)来生成一个单独的用户编码隐向量,该隐向量可以被所有领域共享。
上面的图 (a) 中展示的为领域-领域两两间的知识迁移,而 (b) 则为本文提出的DUE模型中所采用的基于中间表征的迁移方式。用户的表征\(X_{u}=\left[\mathbf{U}_{u}^{\left(d_{1}\right)}, \ldots, \mathbf{U}_{u}^{\left(d_{D}\right)}\right]\)。事实上,(a) 中的这种方法直接迁移用户表征有违隐私性,而且当领域数量增长时计算量会很大。而 (b) 则更能保证隐私性,而且其计算代价也不会随领域数量快速增长。此外,(b) 这种方法有利于各领域随时加入(plug-in)和退出(plug-out),更具灵活性。
设领域集合为\(\mathcal{D}=\left\{d_{1}, \ldots, d_{D}\right\}\)。对每个领域\(d\in \mathcal{D}\),将起对应的物品集合表示为\(I_d\)(大小为\(N_d\))。设领域之间的物品无重叠,即满足\(\forall d, d^{\prime} \in \mathcal{D}, d \neq d^{\prime}, I_{d} \cap I_{d^{\prime}}=0\)。设每个client对应一个用户,一共有\(C\)个用户。一个领域\(d\)可能只涉及到用户集合的子集\(\mathcal{U}^{(d)} \subseteq \mathcal{U}\),一个用户\(u \in \mathcal{U}\)也可能只涉及到领域集合的子集\(\mathcal{D}^{(u)} \subseteq \mathcal{D}\)。每个领域都有对应的共现矩阵\(R_d\)及其协同过滤模型\(f_d\),\(f_d\)为一个给定用户-物品对\((u, i)\)预测评分结果\(: \hat{r}_{u, i, d}=f_{d}\left(\mathbf{U}_{u}^{(d)}, i\right)\)的函数,这里\(\mathbf{U}_{u}^{(d)} \in \mathbb{R}^{L_{d}}\)表示用户\(u\)在领域\(d\)的表征,\(L_d\)为用户表征的维度。在本文的边缘跨域推荐场景下,\(f_d\)和\(\mathbf{U}^{(d)}\)根据特定领域的协同过滤目标函数\(\mathcal{L}^{CF}_d\)进行预训练,并作为该领域对应的本地预训练模型使用。
加上server端,整体的联邦跨域迁移架构如下图所示(图中仅仅展示了单个用户):
这里设\(\boldsymbol{\mathcal{S}}_d\)为server端的领域服务商存储空间(存有\(f_d\)和\(\mathbf{U}_d\));\(\mathcal{E}_u\)为用户在设备上所拥有的个人
存储空间(任何领域都能对其进行访问),用于存放共享隐向量\(\textbf{z}_u\);\(\mathcal{E}_{d,u}\)为领域服务商在用户设备上的存储空间。它能够与\(S_d\)同步获取预训练模型并与用户的个人存储空间\(\mathcal{E}_u\)通信。正如图中所示,对任意领域\(d\)和\(d^{\prime}\)而言,本文在设定上禁止\(\{\boldsymbol{\mathcal{S}}_d, \mathcal{E}_{d, u}\}\)和\(\{\boldsymbol{\mathcal{S}}_{d^{\prime}}, \mathcal{E}_{d^{\prime}, u}\}\)的信息交互。不过,正如我们前面所说的,本文允许用户个人存储空间\(\mathcal{E}_u\)和client端任意领域存储空间\(\mathcal{E}_{d,u}\)的信息交换,这也就意味着用户个人存储空间充当了中间代理的作用,以协调间接性的知识迁移。
本文的最终目标是在为目标领域\(d_t\in\mathcal{D}\)的冷启动用户提供推荐(使用根据其它领域的用户表示做为辅助信息)。给定多个领域的用户表示做为训练数据,则问题就成为了学习对用户表示进行迁移的模型:\(g: \mathbb{R}^{L_{d_{1}}+L_{d_{2}}+\cdots+L_{d_{D}}} \rightarrow \mathbb{R}^{L_{d_{t}}}\),该模型将来自所有领域的用户信息映射到\(d_t\):
这里假定用户的表征\(X_{u}=\left[\mathbf{U}_{u}^{\left(d_{1}\right)}, \ldots, \mathbf{U}_{u}^{\left(d_{D}\right)}\right]\)在优化和推断的过程中是固定的。若是在中心化环境下,所有领域协作训练一个共享的\(g\)是很容易的。但正如开头所说,直接迁移emebddings会带来隐私性的问题,而这就需要使用用户存储空间中的共享编码隐向量\(\mathbf{z}_u\)这一中介了。
由于需要隐向量与用户emebddings的双向编码与恢复,故采用AE/VAE对用户隐向量进行建模。具体地,本文为每个领域\(d\)都设置了一个VAE \(g_d\)(包含编码器和解码器)。如下图所示,设\(\mathbf{z}_u\in\mathbb{R}^{L_c}\),则\(g_d\)由一个编码器\(\mathrm{ENC}_{d}: \mathbb{R}^{L_{d}} \rightarrow \mathbb{R}^{L_{c}}\)(参数为\(\Phi_d\),负责根据特定领域的用户表征\(\mathbf{U}^{(d)}\)生成\(\mathbf{z}_u\))和一个解码器\(\mathrm{DEC}_{d}: \mathbb{R}^{L_{c}} \rightarrow \mathbb{R}^{L_{d}}\)(参数为\(\Theta_d\),负责根据\(z_u\)生成\(\hat{\mathbf{U}}^{(d)}\))组成。这里\(\mathrm{DEC}_d(\cdot)\)生成的\(\hat{\mathbf{U}}_u^{(d)}\)含有来自所有领域的丰富信息,将会被用于之后的推荐服务。另一方面,每个领域也会不断更新自己的编码器和解码器。
下面我们来看论文VAE部分的模型和损失函数细节。这里论文采用生成模型的视角(关于生成模型的一些前置知识可以参见我的博客《寻找领域不变量:从生成模型到因果表征 》),对隐向量\(\mathbf{z}_u\)进行变分推断。
首先,将用户表征\(\textbf{X}_u\)视为观测数据,它由隐向量\(\mathbf{z}_u\)生成:
注意,这里论文假设各领域的独立性,有:\(\prod_d p_{X \mid Z}\left(\mathbf{U}_u^{(d)} \mid \mathbf{z}_u\right)\)。\(\mathbf{z}_u\)的后验分布\(p_{Z \mid X}\left(\mathbf{z}_u \mid \mathbf{X}_u\right)\)难以推断,故采用其变分近似\(q_{Z \mid X}\left(\mathbf{z}_u \mid \mathbf{X}_u\right)\)。优化目标为最大化与用户表征\(\mathbf{X}_u\)相关联的变分下界:
损失函数由\(\mathcal{L}_{\text{dec}}\)与\(\mathcal{L}_{\text{enc}}\)两部分组成。\(\mathcal{L}_{\text{dec}}\)在最大化解码分布\(p_{X|Z}\)的同时,拉近共享隐向量分布\(q_{X|Z}(\textbf{z}_u|\boldsymbol{\mathcal{E}}_u)\)和其先验\(p(\textbf{z}_u)\)的距离:
\(\mathcal{L}_{\text{enc}}\)则拉近隐向量近似后验\(q_{Z|X}(\textbf{z}_u|\textbf{U}_u^{(d)})\)和共享隐向量分布的距离:
接下来设\(q_{Z \mid X}\left(\textbf{z}_u \mid \boldsymbol{\mathcal{E}}_u\right) \sim \mathcal{N}\left(\boldsymbol{\mu}_u, \boldsymbol{\sigma}_u^2\right)\),\(p\left(\textbf{z}_u\right) \sim \mathcal{N}(\mathbf{0}, \mathbf{I})\),\(\boldsymbol{\mu}_d, \boldsymbol{\sigma}_d=\operatorname{ENC}\left(\mathbf{U}_u^{(d)}\right)\),且通过重参数化来完成\(\mathbf{z}_u\)的采样过程:\(\epsilon \sim \mathcal{N}(\mathbf{0}, \mathbf{I})\), \(\mathbf{z}_u \mid \mathbf{U}_u^{(d)}=\boldsymbol{\mu}_d+\boldsymbol{\sigma}_d \times \epsilon\)。
将编码器的分布函数代入上式,我们就能进一步地将损失函数写为
对于解码器分布\(P_{X|Z}\),虽然前面假定了各领域条件独立,即各领域允许有不同的解码器损失函数,但这里为了简便,我们统一定义为高斯核:
这里\(\widehat{\mathbf{U}}_u^{(d)}=\operatorname{DEC}_d\left(\mathbf{z}_u\right)\),且方差\(σ\)在实验中固定,此时即为最小化均方误差。
最后我们可以得到联邦优化过程如下:

本文不考虑用户间数据的隔离性,只考虑在两个相互隔离的领域间进行知识迁移,属于纵向类型。本文假定两个领域(源域和目标域)之间有着相同的用户,但是有着不同的用户-物品共现矩阵,目标在于在保证数据隐私的情况下,利用原域的数据以提高目标域的推荐表现。本文基于Johnson-Lindenstrauss变换(JLT)将共现矩阵加以差分隐保护,然后使用深度自编码器和深度学习网络来分别对源域和目标域中的共现矩阵进行建模,
本文采用的技术解决方案具体描述如下两个阶段:
在第一阶段,先基于JLT变换将共现矩阵由高维空间映射到低维空间空间,能够在够保护数据隐私(即无法辨识出某个用户的评分情况)的同时保持用户间的几何相似度(即相似评分的用户有相似品味)。此外本文还给出了考虑到稀疏情形的JLT(SJLT),能够进一步减少JLT的计算复杂度并解决源域的数据稀疏性问题,其中使用了sub-Gaussian随机矩阵和Hadamard变换。
在第二阶段,本文提出了一个异构的跨域推荐模型(HeteroCDR),该模型使用深度自编码器和DNN来分别对差分隐私保护的源域共现矩阵和目标域共现矩阵进行建模。此外,论文对这两个网络学得的用户embeddings进行对齐,从而使知识能够进行迁移。
论文采用JLT随机变换以得到差分隐私保护的共现矩阵\(R^{\prime}\)。JLT将一个来自\(\mathbb{R}^d\)的向量变换到\(\mathbb{R}^{d^{\prime}}\):\(\phi: x \rightarrow Mx\)。这里\(M\sim \mathcal{N}(0, O_{d^{\prime}\times d})\),\(O_{d^{\prime}\times d}\)为所有元素为1的稠密矩阵。
而稀疏架构下的JLT和JLT的作用原理相似,也是定义一个从从高维到低维空间的映射,同时大概率保持变换后向量的\(l_2\)范数不变。将稀疏向量从\(\mathbb{R}^d\)转换到\(\mathbb{R}^{d^{\prime}}\)的SJLT定义为:\(\psi: x \rightarrow Mx\),这里\(M=PHD\),\(P \in \mathbb{R}^{d^{\prime}\times d}\), \(H\in \mathbb{R}^{d\times d}\),\(D\in\mathbb{R}^{d\times d}\)
\(h_{i j}=d^{-1 / 2}(-1)^{(i-1, j-1)}\)是标准化后的Hadamard矩阵(每个元素都是 +1或−1且每行互相正交),这里\((i, j)=\sum_{k} i_{k} j_{k} \text{ mod } 2\)是一个按位运算并模2的内积,\(D\)是个随机对角矩阵并满足
整个隐私保护下的跨域推荐架构如下:
如图所示,将\(R^A\in \mathbb{R}^{m\times n_1}\)变换到\(R^{\prime}\in \mathbb{R}^{m\times n^{\prime}_1}\)后,会通过自编码器来学习用户的embeddings(用于源域和目标域的知识迁移)。先通过编码器获取用户embeddings:\(u_{i}^{A}=\text{ENC}\left(r_{(i)}^{\prime A}\right) \in \mathbb{R}^{h}\),这里\(h\)是用户embeddings的维度;然后解码器对共现矩阵进行重构:\(\hat{r}_{(i)}^{\prime A}=\text{DEC}\left(u_{i}^{A}\right) \in \mathbb{R}^{n_{1}^{\prime}}\)。重构的loss为:
这里\(\mathcal{F}\)为均方误差。
此外,论文对源域和目标域用户embeddings进行对齐以完成知识迁移。在对齐模型中,论文将用户embeddings的loss表示如下:
在目标域\(B\)方面,采用深度矩阵分解模型来拟合用户评分,其核心思想为最小化真实评分\(r^B_{ij}\)和预测评分\(\hat{r}^B_{ij}\)之间的交叉熵,这里预测评分由多层全连接网络输出。该网络会先计算计算用户和物品的隐向量\(u_{i}^{B} \in \mathbb{R}^{h}\)和\(v_{j}^{B} \in \mathbb{R}^{h}\)(\(h\)表示隐向量维度),然后计算用户和物品的隐向量的余弦相似度做为评分预测值,即\(\hat{r}_{i j}^{B}=\left(u_{i}^{B}\right)^{T} v_{j}^{B}\)。损失函数描述如下:
最终的完整损失函数为以上三个损失函数之和:
我想为我的Rails网络应用程序提供推荐功能。特别是,我想向新注册的用户推荐他可能想要关注的其他用户。Rails中是否有用于此目的的引擎/gem?如果没有,我应该从哪里开始构建它?谢谢。 最佳答案 有Coletivogemhttps://github.com/diogenes/coletivo我试了一下。在MySQL上运行。Neo4jhttp://neo4j.org真的很容易实现一个“跟随谁”。事实上,大多数展示其能力的样本都涉及“跟随谁”。快速提示-只有在JRuby上运行时,Neo4j.rb才会很酷。如果不是-使用Neograph
本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
如何学习ruby的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/
您能为RubyonRails推荐好的数据网格类/gem吗?喜欢http://code.google.com/p/zend-framework-datagrid/采埃孚 最佳答案 你也可以试试datagridgem。这不仅关注带有列的网格,还关注过滤器。classSimpleReportincludeDatagridscopedoUser.includes(:group)endfilter(:category,:enum,:select=>["first","second"])filter(:disabled,:eboolean)fi
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG