纯纯python实现梯度下降、随机梯度下降

最近面试有要求手撕SGD,这里顺便就把梯度下降、随机梯度下降、批次梯度下降给写出来了

有几个注意点:

1.求梯度时注意label[i]和pred[i]不要搞反,否则会导致模型发散

2.如果跑了几千个epoch,还是没有收敛,可能是学习率太小了

python 复制代码
# X:n*k
# Y: n*1

import random
import numpy

class GD:
    def __init__(self,w_dim,r):
        # 随机初始化
        self.w = [random.random() for _ in range(w_dim)]
        self.bias = random.random()
        self.learningRate = r
        print(f"original w is {self.w}, original bias is {self.bias}")
        

    def forward(self,x):
        # 前馈网络
        ans = []
        for i in range(len(x)):
            y=0
            for j in range(len(x[0])):
                y+=self.w[j]*x[i][j]
            ans.append(y+self.bias)
        return ans

    def bp(self,X,pred,label,op="GD"):
        # 计算均方差
        loss = 0
        for i in range(len(pred)):
            loss+=(label[i]-pred[i])**2
        loss = loss/len(X)
            
        
        # 计算梯度
        # 梯度下降
        if op=="GD":
            grad_w = [0 for _ in range(len(self.w))]
            grad_bias=0
            for i in range(len(X)):
                grad_bias+=-2*(label[i]-pred[i])
                for j in range(len(self.w)):
                    grad_w[j]+=-2*(label[i]-pred[i])*X[i][j]  
            # 反向传播,更新梯度
            self.bias=self.bias-self.learningRate*grad_bias/len(X)
            for i in range(len(self.w)):
                self.w[i]-=self.learningRate*grad_w[i]/len(X)
        
        # 随机梯度下降
        if op=="SGD":
            grad_w = [0 for _ in range(len(self.w))]
            grad_bias=0
            randInd = random.randint(0,len(X)-1)
            grad_bias+=-2*(label[randInd]-pred[randInd])
            for j in range(len(self.w)):
                grad_w[j]+=-2*(label[randInd]-pred[randInd])*X[randInd][j]  
            # 反向传播,更新梯度
            self.bias=self.bias-self.learningRate*grad_bias
            for i in range(len(self.w)):
                self.w[i]-=self.learningRate*grad_w[i]
        
        # 批次梯度下降
        if op=="BGD":        
            grad_w = [0 for _ in range(len(self.w))]
            grad_bias=0
            BS=8
            randInd = random.randint(0,len(X)/BS-1)
            X = X[BS*randInd:BS*(randInd+1)]
            label = label[BS*randInd:BS*(randInd+1)]
            pred = pred[BS*randInd:BS*(randInd+1)]
            
            for i in range(len(X)):
                grad_bias+=-2*(label[i]-pred[i])
                for j in range(len(self.w)):
                    grad_w[j]+=-2*(label[i]-pred[i])*X[i][j]  
            # 反向传播,更新梯度
            self.bias=self.bias-self.learningRate*grad_bias/len(X)
            for i in range(len(self.w)):
                self.w[i]-=self.learningRate*grad_w[i]/len(X)

        return loss




def testY(X,w):

    Y = []
    for x in X:
        y=0
        for i in range(len(x)):
            y+=w[i]*x[i]
        Y.append(y)
    return Y

# 构建数据
n = 1000
X=[[random.random() for _ in range(2)] for _ in range(n)]
w=[0.2,0.3]
B=0.4
Y = testY(X,w)

# 设置样本维度为2
k = 2
lr = GD(k,0.01)
Loss=0
epochs=2000

for e in range(epochs):
    Loss = 0
    pred = lr.forward(X)
    loss=lr.bp(X,pred,Y,"BGD")
    Loss+=loss 
       
    if (e%100)==0:       
        print(f"step:{e},Loss:{Loss}") 
    
    
X_test=[[random.random() for _ in range(2)] for _ in range(2)]
Y_test=testY(X_test,w)

print("X_test=",X_test)
print("Y_test=",Y_test)
print("Y_pred=",lr.forward(X_test))

测试效果如下:

也还行

相关推荐
幽络源小助理2 分钟前
Python使用requests_html库爬取掌阅书籍(附完整源码及使用说明)
python·html·python爬虫·爬虫教程·requests_html·爬取书籍·掌阅
取个名字真难呐4 分钟前
LossMaskMatrix损失函数掩码矩阵
python·深度学习·矩阵
南宫理的日知录5 分钟前
「Python数据科学」标量、向量、矩阵、张量与多维数组的辨析
python·numpy·数据科学
xlsw_6 分钟前
java全栈day21--Web后端实战之利用Mybaits查询数据
java·开发语言
Murphy202321 分钟前
.net4.0 调用API(form-data)上传文件及传参
开发语言·c#·api·httpwebrequest·form-data·uploadfile·multipart/form-
GZ同学22 分钟前
Arcgis中python工具箱制造要点及统计要素图层字段信息工具分享
python·arcgis
我曾经是个程序员32 分钟前
C#Directory类文件夹基本操作大全
服务器·开发语言·c#
白云~️33 分钟前
uniappX 移动端单行/多行文字隐藏显示省略号
开发语言·前端·javascript
编码浪子39 分钟前
构建一个rust生产应用读书笔记7-确认邮件2
开发语言·后端·rust
Kenneth風车42 分钟前
【机器学习(九)】分类和回归任务-多层感知机(Multilayer Perceptron,MLP)算法-Sentosa_DSML社区版 (1)111
算法·机器学习·分类