动手学深度学习学习笔记(6)

定义模型
下面是线性回归的矢量计算表达式的实现,使用mm函数做矩阵乘法。

def linreg(X,w,b):
	return torch.mm(X,w) + b

定义损失函数

使用平方损失来定义线型回归的损失函数。
需要把真实值y变成预测值y_hat的形状。
函数返回结果也和y_hat的形状相同。

def squared_loss(y_hat,y):
	#返回值仍是向量,此外,pytorch中的MSELoss并没有除以2
	return (y_hat-y.view(y_hat.size()))**2/2

定义优化算法
sgd函数实现了小批量随机梯度下降算法,通过不断迭代模型参数来优化损失函数。这里自动求梯度模块计算得来的梯度是一个批量样本的梯度和。
除以样本的大小来得到平均值。

def sgd(params,lr,batch_size):
	for param in params:
		param.data -= lr * param.grad/ batch_size

训练模型
训练时,迭代模型参数。每次得带,根据当前的小批量数据样本,通过调用反向函数backward计算小批量随机梯度,并用sgd算法迭代优化模型参数。
由于batch_size设为10,每个小批量的loss形状为(10,1)。
由于l不是一个标量,所以可以提前调用.sum()将其求和得到一个标量。在运行l.backward()得到该变量有关模型参数的梯度。
重点,每次更新完参数要将梯度清零。
在一个迭代周期(epoch)中,将完整遍历一遍data_iter函数,并且数据集中的所有样本都使用一次。
迭代周期个数num_epochs和虚席率lr都是超参数,分别设3和0.03.
在实践中,大多数超参数都需要通过反复是错来不断调节。
虽然迭代周期数设的越大模型可能越有效,但是训练时间可能过长。

lr = 0.03
num_epochs = 3
net = linreg
loss = squared_loss

for epoch in range(num_epochs):
	#一个训练epoch个周期
	#每个迭代周期会使用一次所有数据集样本
	#X和y分别是小批量样本的特征和标签
	for X,y in data_iter(batch_size,features,labels):
		l = loss(net(X,w,b),y).sum()
		l.backward()
		sgd([w,b], lr, batch_size)

		#重点:梯度清零
		w.grad.data.zero_()
		b.grad.data.zero_()
	train_l = loss(net(features,w,b),labels)
	print('epoch %d, loss %f'% (epoch + 1, train_l.mean().item()))

输出:

epoch 1, loss 0.032553
epoch 2, loss 0.000111
epoch 3, loss 0.000047

训练之后可以比较学到的参数和真实的参数,应该很接近。

print(true_w, '\n', w)
print(true_b, '\n', b)

输出:

[2, -3.4] 
 tensor([[ 2.0005],
        [-3.4000]], requires_grad=True)
4.2 
 tensor([4.1989], requires_grad=True)

线性回归的简洁实现

使用PyTorch更方便的实现线性回归

生成数据集

num_inputs = 2
num_examples = 1000
true_w = [2,-3.4]
true_b = 4.2
features = torch.tensor(np.random.narmal(0,1,(num_examples,num_inputs)),dtype = torch.float)
labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b
labels += torch.tensor(np.random.normal(0,0.01, size = labels.size()),dtype = torch.float)

读取数据
PyTorch提供了data包用来读取数据
由于data常用于变量名,所以将导入的data模块用Data代替。在每一次迭代中,随机读取batch_size为10的样本

import torch.utils.data as Data

batch_size = 10
#将训练数据的样本和标签结合
data = Data.TensorDataset(features,labels)
#随机读取
data_iter = Data.DataLoader(dataset, batch_size, shuffle = True)

读取并打印第一组样本

for X,y in data_iter:
	print(X,y)
	break

输出

tensor([[ 1.1560,  0.5133],
        [-1.3982,  0.0846],
        [ 0.4936,  0.7641],
        [ 1.5037, -1.1534],
        [ 0.5931, -0.9144],
        [-0.4403,  0.8581],
        [-0.3884,  1.0050],
        [-1.4649, -1.4879],
        [-1.1145, -0.1628],
        [-0.2325,  0.1286]]) tensor([ 4.7585,  1.1172,  2.6008, 11.1254,  8.5001,  0.4031,  0.0118,  6.3202,
         2.5142,  3.3013])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值