基于python和pytorch的多项式回归(待附详细解析)

源代码

代码如下

import torch
import numpy as np
from torch.autograd import Variable
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt

# """ builds features i.e. a matrix with columns [x, x^2, x^3]."""
def make_features(x):
    x = x.unsqueeze(1)
    return torch.cat([ x ** i for i in range(1, 4)], 1)     # 按列合并

# 设定target参数
w_target = torch.FloatTensor([0.5, 3, 2.4]).unsqueeze(1)    # unsqueeze 变“数组”为“矩阵”(增加维度)
b_target = torch.FloatTensor([0.9])

# 计算y的真实值
def f(x):
    """近似 function."""
    return x.mm(w_target) + b_target[0]

# 返回x y
def get_batch(batch_size=256):
    """build a batch i.e (x, f(x)) pair."""
    random = torch.randn(batch_size)    # 生成batch_size个随机数
    random = random.numpy()
    random.sort()                       # 升序排列random,涉及类型转换,tensor 2 array
    random = torch.from_numpy(random)   # random 类型转换 array 2 tensor
    # print(random)
    x = make_features(random)           # 生成x, x^2, x^3 的列矩阵
    y = f(x)                            # 生成真实y
    # 检查cuda加速 转Variable
    if torch.cuda.is_available():
        return Variable(x).cuda(), Variable(y).cuda()
    else:
        return Variable(x), Variable(y)

# -------------------------定义模型---------------------------
class poly_model(nn.Module):
    def __init__(self):
        super(poly_model, self).__init__()
        self.poly = nn.Linear(3, 1)         # 输入三维,输出一维
    def forward(self, x):
        out = self.poly(x)
        return out

if torch.cuda.is_available():
    model = poly_model().cuda()
else:
    model = poly_model()

#  ------------定义损失函数和优化函数--------------
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=1e-3)

# 循环直到误差小于1e-3
epoch = 0
while True:
    # get data
    batch_x, batch_y = get_batch()      # 得到真实值
    # forward pass
    output = model(batch_x)     # 用模型计算output (预测值)
    loss = criterion(output, batch_y)       #计算损失函数,前者为预测值,后者为真实值
    print_loss = loss.data
    # 重置参数
    optimizer.zero_grad()   # 优化器梯度归零
    # backward pass
    loss.backward()
    # 更新参数
    optimizer.step()
    epoch+=1

    if (epoch-1)%500 == 0:
        # print('batch_x:', type(batch_x))
        # print('batch_y:', type(batch_y))
        # print('output:',type(output))
        batch_x = batch_x.cpu()
        batch_y = batch_y.cpu()
        output = output.cpu()
        # print('batch_x:', type(batch_x))
        # print('batch_y:', type(batch_y))
        # print('output:', type(output))
        output = output.detach().numpy()
        plt.plot(batch_x.numpy()[:, 0], batch_y.data.numpy(), color='b', label='real curve')
        # plt.plot(batch_x.numpy()[:, 0], output, 'r', label='fitting curve')
        plt.legend()
        plt.show()

        output = torch.from_numpy(output)
        batch_x = batch_x.cuda()
        batch_y = batch_y.cuda()
        output = output.cuda()


    # --------------------------------------------------------------------------
    if print_loss < 1e-3:
        print('epoch:{}'.format(epoch))
        break

model.eval()    # 将模型转变为测试模式(有一些层操作在训练和测试的时候不一样,所以要转换
# 去cuda化
batch_x = batch_x.cpu()
batch_y = batch_y.cpu()
output = output.cpu()

output = output.detach().numpy()
plt.plot(batch_x.numpy()[:,0], batch_y.data.numpy(), color='b', label='real curve')
# plt.plot(batch_x.numpy()[:,0], output, 'r', label='fitting curve')
# plt.legend()
plt.show()

for param in model.named_parameters():
    print(param[0])
    print(param[1])

疑惑

可视化

猜你喜欢

转载自blog.csdn.net/qq_41683065/article/details/91393924