自己造轮子--线性回归实现遇到的坑

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()))

 

posted @ 2019-04-28 16:46  broccoli_life  阅读(300)  评论(0编辑  收藏  举报