pytorch实现多项式回归,供大家参考,具体内容如下
一元线性回归模型虽然能拟合出一条直线,但精度依然欠佳,拟合的直线并不能穿过每个点,对于复杂的拟合任务需要多项式回归拟合,提高精度。多项式回归拟合就是将特征的次数提高,线性回归的次数使一次的,实际我们可以使用二次、三次、四次甚至更高的次数进行拟合。由于模型的复杂度增加会带来过拟合的风险,因此需要采取正则化损失的方式减少过拟合,提高模型泛化能力。希望大家可以自己动手,通过一些小的训练掌握pytorch(案例中有些观察数据格式的代码,大家可以自己注释掉)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
# 相较于一元线性回归模型,多项式回归可以很好的提高拟合精度,但要注意过拟合风险
# 多项式回归方程 f(x) = -1.13x-2.14x^2+3.12x^3-0.01x^4+0.512
import torch
import matplotlib.pyplot as plt
import numpy as np
# 数据准备(测试数据)
x = torch.linspace( - 2 , 2 , 50 )
print (x.shape)
y = - 1.13 * x - 2.14 * torch. pow (x, 2 ) + 3.15 * torch. pow (x, 3 ) - 0.01 * torch. pow (x, 4 ) + 0.512
plt.scatter(x.data.numpy(),y.data.numpy())
plt.show()
# 此时输入维度为4维
# 为了拼接输入数据,需要编写辅助数据,输入标量x,使其变为矩阵,使用torch.cat拼接
def features(x): # 生成矩阵
# [x,x^2,x^3,x^4]
x = x.unsqueeze( 1 )
print (x.shape)
return torch.cat([x * * i for i in range ( 1 , 5 )], 1 )
result = features(x)
print (result.shape)
# 目标公式用于计算输入特征对应的标准输出
# 目标公式的权重如下
x_weight = torch.tensor([ - 1.13 , - 2.14 , 3.15 , - 0.01 ]).unsqueeze( 1 )
b = torch.tensor([ 0.512 ])
# 得到x数据对应的标准输出
def target(x):
return x.mm(x_weight) + b.item()
# 新建一个随机生成输入数据和输出数据的函数,用于生成训练数据
def get_batch_data(batch_size):
# 生成batch_size个随机的x
batch_x = torch.randn(batch_size)
# 对于每个x要生成一个矩阵
features_x = features(batch_x)
target_y = target(features_x)
return features_x,target_y
# 创建模型
class polynomialregression(torch.nn.module):
def __init__( self ):
super (polynomialregression, self ).__init__()
# 输入四维度 输出一维度
self .poly = torch.nn.linear( 4 , 1 )
def forward( self , x):
return self .poly(x)
# 开始训练模型
epochs = 10000
batch_size = 32
model = polynomialregression()
criterion = torch.nn.mseloss()
optimizer = torch.optim.sgd(model.parameters(), 0.001 )
for epoch in range (epochs):
print ( "{}/{}" . format (epoch + 1 ,epochs))
batch_x,batch_y = get_batch_data(batch_size)
out = model(batch_x)
loss = criterion(out,batch_y)
optimizer.zero_grad()
loss.backward()
# 更新梯度
optimizer.step()
if (epoch % 100 = = 0 ):
print ( "epoch:[{}/{}],loss:{:.6f}" . format (epoch,epochs,loss.item()))
if (epoch % 1000 = = 0 ):
predict = model(features(x))
print (x.shape)
print (predict.shape)
print (predict.squeeze( 1 ).shape)
plt.plot(x.data.numpy(),predict.squeeze( 1 ).data.numpy(), "r" )
loss = criterion(predict,y)
plt.title( "loss:{:.4f}" . format (loss.item()))
plt.xlabel( "x" )
plt.ylabel( "y" )
plt.scatter(x,y)
plt.show()
|
拟合结果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/weixin_49710179/article/details/115457637