矩阵分解与梯度下降 1月九日学习笔记

2023-10-20 02:20

本文主要是介绍矩阵分解与梯度下降 1月九日学习笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.矩阵的乘法与分解

矩阵乘法的原理示意图:

矩阵乘法的公式:

矩阵乘法的具体例子:

同样的利用矩阵的乘法的原理我们同样可以一个矩阵分解为两个矩阵。

 例如一个4*5的矩阵可以分解为一个4*K与K*5的矩阵。

2.损失函数:

损失函数用来评价模型的预测值和真实值不一样的程度,损失函数越小,通常模型的性能越好。不同的模型用的损失函数一般也不一样

通俗来讲就是,用数据的真实值去减去采用函数模型得到的预测值,计算的是一个样本的误差。它是用来估量你模型的预测值 f(x)与真实值 Y的不一致程度。 

公式为 LOSS=真实值-预测值

我们当前主要常用的是:均方差损失函数

采用矩阵形式的损失函数:

我们构造好了损失函数,自然希望能够得到一个是误差尽可能小的 函数模型,也就是找到这个损失函数取最小值时的参数,而方法就用到梯度下降的方法来得到目标函数。 

3.梯度下降与偏导:

 梯度下降(gradient descent)在机器学习中应用十分的广泛,不论是在线性回归还是Logistic回归中,它的主要目的是通过迭代找到目标函数的最小值,或者收敛到最小值。

   3.1偏导:

在一元函数中,导数就是函数的变化率。对于二元函数的“变化率”,由于自变量多了一个,情况就要复杂的多。

在 xOy 平面内,当动点由 P(x0,y0) 沿不同方向变化时,函数 f(x,y) 的变化快慢一般来说是不同的,因此就需要研究 f(x,y) 在 (x0,y0) 点处沿不同方向的变化率。

在这里我们只学习函数 f(x,y) 沿着平行于 x 轴平行于 y 轴两个特殊方位变动时, f(x,y) 的变化率。

偏导数的表示符号为:∂。偏导数反映的是函数沿各个坐标轴正方向的变化率。梯度的最大方向就是方向导数方向也就是数值变化最快的方向。

3.2梯度下降;

我们可以用下山作为例子:(这里引用别人所举出的例子)

假设这样一个场景:一个人被困在山上,需要从山上下来(找到山的最低点,也就是山谷)。但此时山上的浓雾很大,导致可视度很低;因此,下山的路径就无法确定,必须利用自己周围的信息一步一步地找到下山的路。这个时候,便可利用梯度下降算法来帮助自己下山。怎么做呢,首先以他当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着下降方向走一步,然后又继续以当前位置为基准,再找最陡峭的地方,再走直到最后到达最低处;

总之:通俗来讲就是利用当前位置的信息,一步一步迭代,找到最小值所在位置。

通过我们所学的高数知识知道,沿导数方向就是数值变化的最大方向。所以求导是必不可少的,就如同下山一样,我们有了下山方向就要考虑自己的下山所迈出的步伐,步长也是梯度下降中的一个重要参数,有了下山的方向也有了自己下山的步长,我们就可以一步一步进行一直到山底,也就是我们想要求出的函数中最小值点的参数

下面是一维以及多维的示意图:。

通俗易懂讲解梯度下降法


参数更新的主要步骤:

1.随机初始化一组参数θ

2.将目标函数J(θ)J(θ)分别对每个参数θ求偏导,(也可以理解为每个当前位置下山的最快方向

3.用旧的值减去旧的值的导数乘于步长得到新的值。

θnew=θold-a *f'(θold)

a 为学习效率(也可以理解为下山的步伐

b为每次迭代X的变化量  b=θold-θnew。

4.迭代次数一般通过2个参数控制

         初设的循环次数  或者 当b 也就是变化量小于一个特定的值。注意:a可以自己设定不易过大或过小,过大容易造成不准确,过小容易造成迭代次数过多。

 下面看一个具体例子:(利用梯度下降求损失函数最小值点参数

另一个y=(x-2.5)**2+3为例:(求函数最小值点对应的横坐标

 

 

 可以看到所求梯度下降得到最低点已经十分逼近函数真实最低点2.5了

部分代码实现

def dJ(x):return 2*(x-2.5)###定义一个求函数值的函数J
def J(x):try:return (x-2.5)**2+3except:return float('inf')
x=0.0							#随机选取一个起始点
eta=0.1		#学习率
i=0
epsilon=1e-8				    #用来判断是否到达二次函数的最小值点的条件
history_x=[x]                   #用来记录使用梯度下降法走过的点的X坐标
while True:i=i+1d=(x-2.5)**2+3gradient=dJ(x)				#梯度(导数)last_x=xx=x-eta*gradientprint("第%d次迭代 函数值%f x坐标%f 变化率%f"%(i,J(last_x),x,abs(J(last_x)-J(x))))history_x.append(x)if (abs(J(last_x)-J(x)) <epsilon):		#用来判断是否逼近最低点break

 4.正则化:(这个也不太明白)

 我们一般为了防止过拟合,在损失函数中增加正则化项

以矩阵为例:

也即是:

 有了上面的基础知识我们来看看关于矩阵分解的例子

 我们可以看U代表user及也就是用户,D表示数据也就是data(代表评分)。

图中有未评分的项目,我们要利用其他数据来预估这些评分。

 首先我们可以将矩阵拆分为2个矩阵的相乘。

R(m,n)为原始矩阵,Q(m,k)和P(k,n)为分解矩阵。

此时R1=Q*P。R1为预估矩阵。使R近似等于R1

1.我们要构建损失函数:

 2.对其求偏导:

 3.更新参数:

 4.接下来就是不断的迭代了。(一般要加入正则化这里也不要太明白就不加了)

下面是借鉴的别人的代码(自己初学还写不出来),看一下利用python的代码实现

# from pylab import *
import matplotlib.pyplot as plt
from math import pow
import numpydef matrix_factorization(R,P,Q,K,steps=5000,alpha=0.0002,beta=0.02):Q=Q.T  # .T操作表示矩阵的转置result=[]for step in range(steps):for i in range(len(R)):for j in range(len(R[i])):if R[i][j]>0:eij=R[i][j]-numpy.dot(P[i,:],Q[:,j]) # .dot(P,Q) 表示矩阵内积for k in range(K):P[i][k]=P[i][k]+alpha*(2*eij*Q[k][j]-beta*P[i][k])Q[k][j]=Q[k][j]+alpha*(2*eij*P[i][k]-beta*Q[k][j])eR=numpy.dot(P,Q)e=0for i in range(len(R)):for j in range(len(R[i])):if R[i][j]>0:e=e+pow(R[i][j]-numpy.dot(P[i,:],Q[:,j]),2)for k in range(K):e=e+(beta/2)*(pow(P[i][k],2)+pow(Q[k][j],2))result.append(e)if e<0.001:breakreturn P,Q.T,resultif __name__ == '__main__':R=[[5,3,0,1],[4,0,0,1],[1,1,0,5],[1,0,0,4],[0,1,5,4]]R=numpy.array(R)N=len(R)M=len(R[0])K=2P=numpy.random.rand(N,K) #随机生成一个 N行 K列的矩阵Q=numpy.random.rand(M,K) #随机生成一个 M行 K列的矩阵nP,nQ,result=matrix_factorization(R,P,Q,K)print("原始的评分矩阵R为:\n",R)R_MF=numpy.dot(nP,nQ.T)print("经过MF算法填充0处评分值后的评分矩阵R_MF为:\n",R_MF)

 5总结:

主要学习矩阵的乘法与分解,以及什么是损失函数,然后就是利用梯度下降法去求得损失函数的最小值,这里也要清楚高等数学中的偏导概念,最后一般防止过度拟合要加入正则化(这个目前自己还不是特别清楚),其中还加了一些pytohn代码的实现,自己确实有很多地方不太清楚,刚开始写这些,也借鉴了许多别人的文章,那些人文章写的非常好,自己以后也会进步的。

这篇关于矩阵分解与梯度下降 1月九日学习笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/243942

相关文章

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

pytorch自动求梯度autograd的实现

《pytorch自动求梯度autograd的实现》autograd是一个自动微分引擎,它可以自动计算张量的梯度,本文主要介绍了pytorch自动求梯度autograd的实现,具有一定的参考价值,感兴趣... autograd是pytorch构建神经网络的核心。在 PyTorch 中,结合以下代码例子,当你

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操