zoukankan      html  css  js  c++  java
  • 自己造轮子--线性回归实现遇到的坑

    1, 生成数据集

    2,定义一个数据迭代器,迭代器可以每次遍历一次所有的数据集

    3,模型参数初始化,记得申请模型的梯度 attach_grad()

    4,定义线性回归函数

    5,定义损失函数

    6,定义优化算法,随机梯度下降

    7,进行模型训练,输出迭代之后的loss函数

    遇到的几个问题:

    for epoch in epochs 这是一种错误的写法,一定要记得加range函数,integer直接不可以迭代iter

    为防止广播,两个形状相同的矩阵,y_hat-y.reshape(y_hat) 错误,记得最后括号里面是y_hat.shape

    虽然很简单,但是自己写和看代码的感觉完全不一样

    需要学习几个点,一是迭代函数在python中,还有yield的使用(https://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/) 

    还有 nd函数的使用(https://www.jianshu.com/p/7faf137775c8)

    初始化时候nd.random函数的参数 (https://www.jianshu.com/p/3ea2cf092815)

    自己还需要再打一次。

     还有一个重要的点,如果变量l,即求损失函数的时候不是一个标量,l.backward()会对元素求和得到新的变量,再求改变量有关模型参数的梯度,所以这里的l是小批量的损失,最后需要mean()一下

    记住一个事情就是使用函数时候 l.mean().asnumpy() 函数名字后面的括号不要丢了

    shape一定要加 = 号

    你敢信?

    但是刚开始 因为我初始化参数的时候居然 因为不一样最后loss 破百了你敢信?

    一会把改了的和没改的(注释)一起贴在文档之中

      

    #重新实现一次线形回归,从零开始
    from mxnet import autograd, nd
    import random
    #首先需要生成数据集合
    inputs=2
    num=1000
    true_w=[2,-3.4]
    true_b=6
    features=nd.random.normal(scale=1, shape=(num,inputs))
    labels=features[:,0]*2+features[:,1]*true_w[1]+6
    labels +=nd.random.normal(scale=0.01)
    #定义迭代的数据集函数
    def iterdata(features, labels, batch):
        numbers=len(features)
    #     suoyin=nd.array(range(numbers)) 这样经过测试,应该也可以
        suoyin=list(range(numbers))
        random.shuffle(suoyin)
        for x in range(0,numbers, batch):
    # k=nd.array(suoyin[0:min(x+batch, numbers)]) 这又是自己经常犯的错误,fuck,写在迭代里面了你还不改改?还他妈从0开始写!
            k=nd.array(suoyin[x:min(x+batch, numbers)])
            yield features.take(k),labels.take(k)
    #开始进行参数初始化
    # w=nd.random.normal(scale=1,shape=(inputs,1))
    w=nd.random.normal(scale=0.01,shape=(inputs,1))
    # b=nd.random.normal(scale=0.01,shape=(1,))
    b=nd.zeros(shape=(1,))
    w.attach_grad()
    b.attach_grad()
    #然后进行线性函数的定义
    def net(X, w,b):
        return nd.dot(X,w)+b
    #然后进行线性函数的定义
    def net(X, w,b):
        return nd.dot(X,w)+b
    #然后进行sgd梯度下降函数是针对参数的的定义
    def sgd(params, lr,batch):
        for param in params:
            param[:]=param-lr*param.grad/batch
    #然后进行sgd梯度下降函数是针对参数的的定义
    def sgd(params, lr,batch):
        for param in params:
            param[:]=param-lr*param.grad/batch
    #可以通过ture_w和w来查看最终结果
    epochs=3 
    batch=10
    lr=0.03
    for epoch in range(epochs):
        for X,y in iterdata(features, labels, batch):
            with autograd.record():
                h=net(X, w,b)# 这里合起来写和分开写不影响
                l=loss(h, y)
            l.backward()
            sgd([w,b], lr, batch)
        train=loss(net(features,w,b),labels) 
        print('epoch%d loss %f'%(epoch+1, train.mean().asnumpy()))
    
  • 相关阅读:
    【转】PHP使用共享内存进程间通信
    【转】php进程间通信--有名管道
    【转】代理模式-php白话示例
    [转]设计的核心任务之三:确保正交性
    pc主板支持独显和集显视频输出
    OpenGL核心技术之抗锯齿
    读书:有钱人想的和你不一样
    js 文本相似度
    js实现获得QQ截图或者微信截图后剪切板的内容clipboardData
    【转】chrome浏览器F12 Network中Timing参数含义
  • 原文地址:https://www.cnblogs.com/huayecai/p/10784906.html
Copyright © 2011-2022 走看看