首页
学习
活动
专区
工具
TVP
发布

非线性回归

寒假撸了几把深度学习,感觉颇有意思。

在数据科学中,回归是最基础的计算。通俗来讲,回归就是找出一堆数据之间的函数关系。线性回归是最简单的回归,很容易利用最小二乘法解决。非线性回归也可以使用最小二乘法去处理,然而如果数据之间看不到明显的函数关系,最小二乘法利用起来就比较麻烦,比如下面的数据点就很难找到一个合适的数学函数进行拟合。

利用神经网络可以对上面的数据点进行拟合,下面是一个最简单的利用Pytorch进行非线性回归的代码。

import torch

from torch import nn,optim

import matplotlib.pyplot as plt

import pandas as pd

data = pd.read_csv('temp.csv')

x = torch.from_numpy(data['time'].values.reshape(-1,1)).type(torch.float32)

y = torch.from_numpy(data['deltaT'].values.reshape(-1,1)).type(torch.float32)

class NonLinearNet(nn.Module):

def __init__(self):

super(NonLinearNet,self).__init__()

self.linear = nn.Sequential(

nn.Linear(1,20),

nn.ReLU(),

nn.Linear(20,12),

nn.ReLU(),

nn.Linear(12,1)

)

def forward(self,x):

out = self.linear(x)

return out

model = NonLinearNet()

loss_fn = nn.MSELoss()

optimizer = optim.Adam(model.parameters(),lr = 0.005)

for epoch in range(10000):

output = model(x)

loss = loss_fn(output,y)

optimizer.zero_grad()

loss.backward()

optimizer.step()

if epoch % 500 == 499:

print('epoch:%d,loss=%.3f'%(epoch+1,loss.item()))

plt.cla()

plt.scatter(x, y, s=3, color='blue')

y_pred = model(x)

plt.plot(x, y_pred.detach().numpy(), lw=2, color='red')

plt.grid()

plt.title('epoch:%d,loss=%.3f'%(epoch+1,loss.item()))

plt.pause(0.05)

plt.show()

这里数据规模很小,没有使用GPU计算。拟合过程如下图所示。

训练完毕后可以将模型保存下来,可以利用下面的代码:

torch.save(model.state_dict(),'NonLinearNet.pkl')

后面就可以直接加载模型对输入的X数据进行Y值预测了,如下面的示例代码计算x=700时的Y值。

model = NonLinearNet()

state_dict = torch.load('NonLinearNet.pkl')

model.load_state_dict(state_dict)

test_x = torch.tensor([[700.0]],dtype=torch.float32)

print(model(test_x))

程序输出结果为:

tensor([[52.3139]], grad_fn=)

预测Y=52.3139。

当然这里只是随便举了个例子。神经网络也有一大堆莫名其妙的麻烦问题有待解决,比如复现性很差,比如过拟合等等,一不留神就变成了神经病网络,这个有兴趣的道友可以自己尝试。

利用神经网络处理拟合问题一个最大的好处是,每次只需要提供不同的数据而无需修改代码。下面看看拟合100个点的正弦数据。代码很简单,如下所示。

import torch

from torch import nn,optim

import matplotlib.pyplot as plt

import pandas as pd

import numpy as np

# 准备数据

x = np.linspace(0,2*np.pi,num=100).reshape(-1,1)

ysin = np.sin(x).reshape(-1,1)

class NonLinearNet(nn.Module):

def __init__(self):

super(NonLinearNet,self).__init__()

self.linear = nn.Sequential(

nn.Linear(1,20),

nn.ReLU(),

nn.Linear(20,12),

nn.ReLU(),

nn.Linear(12,4),

nn.ReLU(),

nn.Linear(4,1)

)

def forward(self,x):

out = self.linear(x)

return out

model = NonLinearNet()

loss_fn = nn.MSELoss()

optimizer = optim.Adam(model.parameters(),lr = 0.002)

for epoch in range(10000):

x = torch.Tensor(x)

y = torch.Tensor(ysin)

output = model(x)

loss = loss_fn(output,y)

optimizer.zero_grad()

loss.backward()

optimizer.step()

if epoch % 1000 == 999:

print('epoch:%d,loss=%.3f'%(epoch+1,loss.item()))

plt.cla()

plt.scatter(x, y, s=3, color='blue')

y_pred = model(x)

plt.plot(x, y_pred.detach().numpy(), lw=2, color='red')

plt.grid()

plt.title('epoch:%d,loss=%.5f'%(epoch+1,loss.item()))

plt.pause(0.05)

plt.show()

训练过程如下图所示。

来预测一个sin(3*pi)的值。

下一次要训练余弦数据,此时只需要替换源数据即可。代码如下所示。

import torch

from torch import nn,optim

import matplotlib.pyplot as plt

import pandas as pd

import numpy as np

# 准备数据

x = np.linspace(0,2*np.pi,num=100).reshape(-1,1)

# ysin = np.sin(x).reshape(-1,1)

ycos = np.cos(x).reshape(-1,1)

class NonLinearNet(nn.Module):

def __init__(self):

super(NonLinearNet,self).__init__()

self.linear = nn.Sequential(

nn.Linear(1,20),

nn.ReLU(),

nn.Linear(20,12),

nn.ReLU(),

nn.Linear(12,4),

nn.ReLU(),

nn.Linear(4,1)

)

def forward(self,x):

out = self.linear(x)

return out

model = NonLinearNet()

loss_fn = nn.MSELoss()

optimizer = optim.Adam(model.parameters(),lr = 0.002)

for epoch in range(10000):

x = torch.Tensor(x)

y = torch.Tensor(ycos)

output = model(x)

loss = loss_fn(output,y)

optimizer.zero_grad()

loss.backward()

optimizer.step()

if epoch % 1000 == 999:

print('epoch:%d,loss=%.3f'%(epoch+1,loss.item()))

plt.cla()

plt.scatter(x, y, s=3, color='blue')

y_pred = model(x)

plt.plot(x, y_pred.detach().numpy(), lw=2, color='red')

plt.grid()

plt.title('epoch:%d,loss=%.5f'%(epoch+1,loss.item()))

plt.pause(0.05)

plt.show()

余弦数据训练过程如下图所示。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20210223A07EG100?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券