矩阵

C语言实现协方差矩阵

孤人 提交于 2020-01-25 05:36:48
最近在理解机器学习中的PCA降维算法,其中使用协方差矩阵。什么是些方差矩阵,这里不做多介绍。作为软件工程师,理解算法原理是一回事,没有亲自编码实践总觉得缺了什么。 现将自己C语言实现协方差矩阵代码如下 # include <stdio.h> # include <stdlib.h> # include <string.h> void TransposeMatrix ( int * input , int rows , int cols , int * output ) { for ( int row = 0 ; row < rows ; row ++ ) { for ( int col = 0 ; col < cols ; col ++ ) { int sindex = row * cols + col ; int dindex = col * rows + row ; printf ( "sindex=%d,dindex=%d\n" , sindex , dindex ) ; output [ dindex ] = input [ sindex ] ; } } } void PrintMatrix ( int * array , int rows , int cols ) { int index = 0 ; for ( int row = 0 ; row < rows ; row

深度学习与Keras实践|第三期:全连接层简介

我与影子孤独终老i 提交于 2020-01-25 00:57:31
1. 一个相对具体的模型——如何连接: 在第一期中,我们曾实现过如下的神经网络: 输入层 - Dense 4,relu,100 输出层 - Dense 5,softmax 这两个层都是全连接层,我们采用一种更加直观的表示方式展现这两个层是如何连接在一起的: 如图所示,输入层具有四个单元,输出层具有五个单元,作为全连接层,输入层的 每个单元都与下一层的所有单元相连 ,输出层的 每个单元也都与上一层的所有单元相连 。这就是全连接层直观的特点。 当这个模型用于多分类任务时,输出层的五个单元意味着最终的输出结果可以被划分到五个类别中的一个。 2.一个更具体的模型:全连接时到底做了什么? 在上面的模型中,我们看到了采用全连接层时模型的一个稍微具体的形式。但是,我们现在的模型仅仅展示给我们许多复杂的连接线(即使在我们的简单例子中,连接线也有20条之多),而一组数据信息在经过这些连接线、从一个处理层传递到下一个处理层时到底经历了什么,我们仍然不清楚。 实际上,输入的数据经历的过程可以用下面这个数学表达式来表示: output = activation(input · kernel + bias) 其中,activation是按逐个元素来计算的激活函数;kernel是由网络层创建的权值矩阵,权值矩阵将与输入该层的input矩阵进行点乘;bias是偏置量。下面,我们将具体解析这个数学表达式

java数据结构之稀疏数组

喜你入骨 提交于 2020-01-24 22:18:19
java数据结构之稀疏数组 前言 前段时间在讨论群里面,有个大佬说学这种算法没用,实际的开发并不会用到。但是我还是愿意去学习这种学而无用的知识(当然能用到是最好不过啦),因为学习学的是一种解题思路,思路有了,自然而然问题也就解决了。 ~回归正传,简单的介绍一下稀疏数组。 通俗的来讲,稀疏数组就是一个n*3的矩阵,它能够将一些特殊的矩阵的规模缩小,从而大大的节省了存储空间。 1 稀疏数组的一些约定(硬性要求) (1)第一行(三列): 第一列 第二列 第三列 特殊矩阵有多少行 有多少列 有多少个不为0的元素 (2)从第二行往后开始: 存放特殊矩阵中不为0的元素 第一列 第二列 第三列 元素的行 元素的列 元素的值 2 特殊矩阵 这里的特殊数组指的是 矩阵的元素大部分为0(或者大部分为同一个值)的元素 例如 : 0,0,1,2 0,0,0,1 2,0,0,0 3 特殊矩阵转成稀疏数组 3.1 先看效果图 (1)特殊矩阵: (2)转换成的稀疏数组 3.2 代码演示 ~代码演示之前,说点废话,看到矩阵的话,大家应该能够条件反射出二维数组。 简单的来说,这里就是把一些特殊的二维数组,转化成符合特定要求的二维数组(稀疏数组)。 上代码(这里用五子棋盘进行演示) // 定义一个棋盘 11*11 int [ ] [ ] chessArr = new int [ 11 ] [ 11 ] ;

【模板】线性基

ぐ巨炮叔叔 提交于 2020-01-24 18:45:59
线性基 定义:给定数集 \(S\) ,以异或运算张成的数集与 \(Span{S}\) 相同的极大线性无关集,称为原数集的一个线性基。 线性基具有以下性质: 显然,线性基是原数集的一个子集。 线性基的张成集合中一般不包含有数字0。一般给定的数集中不会有0,否则在线性基中加入0即可。 张成集合中的每个数都可以唯一表示成基的线性组合。这与第一点是统一的。 将线性基中的一个元素通过“倍加变换”(在这里即异或上另一个元素),张成集合不变。 线性基中每一个元素的最高位均不同。 由以上性质不难看出,线性基与线性方程组有一些相似之处。事实上,如果把原数集的每一个元素二进制拆分为多项式,把每一项的系数看作一个向量,将所有系数向量看作一个矩阵的行,那么这个构造出的矩阵就可以看作某个线性方程组的系数矩阵。也就是说,对这个矩阵施以异或意义下的初等行变换,即将某些行消成0行,形成的新矩阵与原矩阵行等价。这给了性质5一个很好的阐释:每个元素的最高位对应的是该系数矩阵化为阶梯形后的主元位置,而主元可以将其他行的该项通过行变换消去,结合异或的性质就不难理解了。 以上基于线性代数的讨论表明,可以使用类似高斯消元的行化简算法求得原数集的一个线性基。把每个行向量压成一个数处理,时间复杂度 \(O(n^2)\) 。 具体来说,对于每一个新加入的数x,我们从高位到低位枚举;如果x的第i位是1(即对应方程左边含有这个元素)

矩阵分解推荐算法(LMF)

自古美人都是妖i 提交于 2020-01-24 16:43:14
首先我们现在有一个矩阵 \(R_{mn}\) ,其中 \(R_{ij}\) 代表第 \(i\) 个用户对第 \(j\) 个商品的喜爱程度。 \(LMF\) 算法认为每个商品上面都有一些隐因子,而顾客的喜爱程度是由这些隐因子来决定的。因此便可以将 \(R_{mn}\) 分解成 \(P_{mF} \times Q_{Fn}\) 的形式。 矩阵 \(P_{mF}\) 代表了这 \(m\) 个用户对 \(F\) 个隐因子的喜爱程度, \(Q_{Fn}\) 代表这 \(F\) 个隐因子在这 \(n\) 个商品上的分布概率。 \[R'_{ij}=\sum_{f=1}^F {P_{if}Q_{fj}}\] 我们最终的目的是使得 \(R_{ij}\) 和 \(R'_ {ij}\) 尽可能的相近。因此,损失函数为: \[f(P,Q)=\sum{(R_{ij}-R'_{ij})^2}\] 为了防止过拟合,需要加上一个正则项来防止 \(P_{if},Q_{fj}\) 过小或过大。 \[f(P,Q)=\sum{(R_{ij}-R'_{ij})^2}+\lambda(\sum{(P_{if}^2}+\sum{Q_{fj}^2})\] 接下来就是对这个函数用梯度下降进行拟合,递推式为: \[P_{k+1}=P_{k}-\alpha\frac{\partial f(P,Q)}{\partial P_k}\] \

我的reshape观

旧街凉风 提交于 2020-01-24 14:06:55
reshape(1,2)把结果分成1块,每一块2个元素 reshape(2,1)把结果分成2块,每一块1个元素 reshape(-1,1)把结果分成任意块,每一块1个元素 reshape(1,-1)把结果分成1块,这一块里面放所有的元素 reshape(4,3,2)把结果分成4块,每一块3个元素,做出一个2维的 reshape(a,3,2)在a中取数据,分成3块,每一块2个元素 reshape(A,[2,3]) 将 A 重构为一个 2×3 矩阵 reshape(A,2,3,4)将 A 重构为一个 2×3x4矩阵,与reshape(A,[2,3,4])相同 reshape(A,2,[ ])将 A 重构为一个 2×?矩阵 在这里面占位符[ ] 只能使用一次。 关于如何查看数据大小,请直接使用A.shape()的方法即可 all in all 如果你把我说的x块理解为x行,把y个元素理解为y列,那就是其他教程的说法了,只是这样有时难以构想 最基本的就是reshape(x,y)把结果分成x块,这一块里面放y元素 如有任何错误或者不理解的地方,烦请在下发留言处回复,感谢🙏 举一个例子 行向量: a = [1 2 3 4 5 6] 执行下面语句把它变成3行2列: b = reshape(a,3,2) 执行结果: b = 1 4 2 5 3 6 来源: https://www.cnblogs

矩阵快速幂

假装没事ソ 提交于 2020-01-24 02:19:02
1.快速幂 快速幂 也叫 二进制取幂 ,想要快速求出 a n a^n a n 的结果就用它来求。 a n a^n a n 表示将n个a乘在一起, 时间复杂度是O(n) 级别,如果n太大的话这种方法就不适用了。 如果使用快速幂, 时间复杂度能达到O( l o g 2 log_2 l o g 2 ​ n) ,因为n有⌊ l o g 2 log_2 l o g 2 ​ n⌋ + 1 个二进制位,所以当知道了每一位的值后,只需要通过 l o g 2 log_2 l o g 2 ​ n次乘法就可计算出 a n a^n a n 。 用快速幂进行计算 例如计算 a 9 a^9 a 9 ,9的二进制是1001, 9 = 1 × 2 0 2^0 2 0 + 0 × 2 1 2^1 2 1 + 0 × 2 2 2^2 2 2 +1 × 2 3 2^3 2 3 = 2 1 2^1 2 1 + 2 3 2^3 2 3 ; 因此 a 9 a^9 a 9 = a (2^1 + 2^3) = a 2^1 * a 2^3 , 也就是a 1 * a 8 。现在这样就快多了吧,原来9个a连乘要计算8次乘法,现在使用快速幂只要乘两次。 但是像a 8 这种式子好像不是很好求的样子。。。 long long pow ( int a , int b ) { long long int ans = 1 ; while ( b