首先是模块的导入:
%matplotlib inline
from IPython import display
from matplotlib import pyplot as plt
from mxnet import autograd, nd
import random #引入随机相关函数
```
其中:
%matplotlib inline
是一个魔法函数,可以将matplotlib的图表直接嵌入到Notebook之中,或者使用指定的界面库显示图表
from IPython import display
引入IPython,用于jupyter notebook中的显示,在Pycharm中不生效。
```
# 生成数据集
num_input = 2 # 特征的数量
num_examples = 1000 #样本个数,每个样本都包含两个特征
ture_w = [2,-3.4]
true_b = 4.2
features = nd.random.normal(scale=1, shape=(num_examples,num_input))
lables = ture_w[0] * features[:,0] + ture_w[1] * features[:,1] + true_b #生成标签
lables += nd.random.normal(scale=0.01,shape=lables.shape) #引入噪声
# 读取数据集
def data_iter(batch_size, features, labels):
"""读取小批量数据样本,返回 batch_size个大小的随机样本特征和标签"""
num_examples = len(features)
indices = list(range(num_examples))
random.shuffle(indices)
for i in range(0, num_examples, batch_size): #从0开始,num_examples结束,步长为batch_size
j = nd.array(indices[i: min(i + batch_size, num_examples)])
yield features.take(j), labels.take(j) #在for循环内将两个矩阵传递出去
其中indices = list(range(num_examples))
建立了一个包含全部examples序号的列表,然后random.shuffle(indices)
将其打乱;
j同样是一个矩阵形式的列表,包含的是每个步长(batch_size)下的从i开始的数个序号;
```yield``语句较为特殊**接着上一步停止的地方开始,然后遇到yield后,return出要生成的数,此步就结束。**因此yield语句可以在for循环中多次传递出一组features & label。
batch_size = 10
for X, y in data_iter(batch_size, features, labels):
print(X, y)
break
继续上文,打印输出X, y的内容结果如下:
[[-0.39118123 1.643744 ]
[-0.5122933 -0.64786017]
[ 0.647578 0.57934767]
[-2.479361 -2.0917244 ]
[-1.4493372 -0.4517469 ]
[-0.642467 0.56937444]
[ 1.5835577 1.2613702 ]
[-0.20462556 0.2593268 ]
[ 1.054078 -2.725135 ]
[-1.1439118 0.9233982 ]]
<NDArray 10x2 @cpu(0)>
[-2.1710699 5.3783774 3.5251415 6.3483696 2.8295393 1.0028826
3.0916178 2.9046066 15.578272 -1.218089 ]
<NDArray 10 @cpu(0)>
就是在for X, y in data_iter(batch_size, features, labels):
循环中,一次循环完成,yield暂停,执行对X, y的打印,本该继续执行下一次的打印,但是被break
终止,for循环和函数迭代器都无法继续进行。
batch_size = 10 # 设定 batch_size
w = nd.random.normal(scale=0.01, shape=(num_input,1))
b = nd.zeros(shape=(1,))
w.attach_grad()
b.attach_grad() # 创建参数的梯度
设置batch_size,清除w&b
def linereg(X, w, b):
""" 定义模型"""
return nd.dot(X, w) + b
def squared_loss(y_hat, y):
"""定义损失函数"""
return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2
def sgd(params, lr, batch_size):
"""定义优化算法"""
for param in params:
param[:] = param - lr * param.grad / batch_size
定义模型和定义损失函数都是依照线性回归原理返回公式,定义优化过程涉及了一些难点如下:
https://blog.csdn.net/spylinda/article/details/123376869
# 训练模型
lr = 1
num_epochs = 5
net = linereg
loss = squared_loss
# 训练模型一共需要num_epochs个迭代周期
# 在每一个迭代周期中,会使用训练数据集中所有样本一次(假设样本数能够被批量大小整除)。
# X和y分别是小批量样本的特征和标签
for epoch in range(num_epochs):
for X, y in data_iter(batch_size, features, lables): ##见第三部分
with autograd.record(): ##见第二章自动求导数
l = loss(net(X, w, b), y)
l.backward()
sgd([w,b], lr, batch_size)
train_l = loss(net(features, w, b), lables)
print('epoch %d, loss %f' %(epoch + 1, train_l.mean().asnumpy()))
print(ture_w, w)
print(true_b, b)
其实在定义的以上函数核心在d2lzh包中都已经成型的情况下,这一部分就是核心了,但在充分理解线性回归原理和函数的前提下这一部分的理解也不困难:
整体运行框图如下图所示:
本着万事开头难的原则,在学习前期希望可以好好的记录自己遇到的疑惑和存在的不足,感觉详细理解了线性回归算法之后对于后续的学习会提供比较好的帮助,其中理解和内容有什么问题恳请各位指正。
如下图所示:
[外链图片转存中…(img-oBHjNBqR-1646807256040)]
本着万事开头难的原则,在学习前期希望可以好好的记录自己遇到的疑惑和存在的不足,感觉详细理解了线性回归算法之后对于后续的学习会提供比较好的帮助,其中理解和内容有什么问题恳请各位指正。
另,mabplotlib 和 numpy相关知识以前看的太囫囵吞枣了,CSDN救我命