自己造轮子--线性回归实现遇到的坑
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()))
浙公网安备 33010602011771号