2.线性回归与非线性回归

2.1 线性回归

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

# 示例:随机生成一些点,符合线性分布,然后构造一个模型来拟合这些数据
x_data =np.random.rand(100)
noise=np.random.normal(0,0.01,x_data.shape)
y_data=x_data*0.1+0.2+noise
plt.scatter(x_data,y_data)
plt.show()

# 把x_data和y_data都变成一个二维的数据,(-1,1)对应100行1列,-1表示自适应
x_data=x_data.reshape(-1,1)
y_data=y_data.reshape(-1,1)

# 把numpy数据变成tensor
x_data=torch.FloatTensor(x_data)
y_data=torch.FloatTensor(y_data)
inputs=Variable(x_data)
target=Variable(y_data)

# 构造神经网络模型
# 一般把网络中具有可学习参数的层放在__init__()中,注意是双下划线
class LinearRegression(nn.Module):
    #定义网络结构
    def __init__(self):
        #初始化nn.Module
        super(LinearRegression,self).__init__()
        #  fc表示全连接层    nn.Linear(in_features: int, out_features: int, bias: bool = True) -> None
        self.fc=nn.Linear(1,1)
    #定义网络计算  这里x是输入值
    def forward(self,x):
        # 将x交给全连接层,然后将输出out返回
        out=self.fc(x)
        return out

# 定义模型
model=LinearRegression()
# 定义损失函数
mse_loss=nn.MSELoss()
# 定义优化器,即改变参数使用的算法,这里使用梯度下降算法,lr表示学习率
optimizer=optim.SGD(model.parameters(),lr=0.1)

# 看一下模型的参数(可选)
for name,parameters in model.named_parameters():
    print('name:{},param:{}'.format(name,parameters))
    ## name:fc.weight,param:Parameter containing:
    ## tensor([[-0.0850]], requires_grad=True)
    ## name:fc.bias,param:Parameter containing:
    ## tensor([-0.0769], requires_grad=True)

# 开始训练
for i in range(1001):
    out=model(inputs)
    # 计算loss
    loss=mse_loss(out,target)
    # 梯度清0
    optimizer.zero_grad()
    # 计算梯度
    loss.backward()
    # 修改权值
    optimizer.step()
    if i%200==0:
        print(i,loss.item())
        ## 0 0.14513587951660156
        ## 200 9.770684118848294e-05
        ## 400 9.749281889526173e-05
        ## 600 9.749160381034017e-05
        ## 800 9.74916183622554e-05
        ## 1000 9.749161108629778e-05

y_pred=model(inputs)
# 原始数据的散点图
plt.scatter(x_data,y_data)
# 训练的模型得到的回归线,第三个参数是颜色,第四个参数是线的宽度
plt.plot(x_data,y_pred.data.numpy(),'r-',lw=3)
plt.show()

2.2 非线性回归

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

# 随机出非线性的一些点
x_data =np.linspace(-2,2,200)[:,np.newaxis]
noise=np.random.normal(0,0.2,x_data.shape)
y_data=np.square(x_data)+noise
plt.scatter(x_data,y_data)
plt.show()

# 把x_data和y_data都变成一个二维的数据,(-1,1)对应100
x_data=x_data.reshape(-1,1)
y_data=y_data.reshape(-1,1)

# 把numpy数据变成tensor
x_data=torch.FloatTensor(x_data)
y_data=torch.FloatTensor(y_data)
inputs=Variable(x_data)
target=Variable(y_data)

# 构造神经网络模型
# 一般把网络中具有可学习参数的层放在__init__()中,注意是双下划线
class LinearRegression(nn.Module):
    #定义网络结构
    def __init__(self):
        #初始化nn.Module
        super(LinearRegression,self).__init__()
        #  fc表示全连接层    nn.Linear(in_features: int, out_features: int, bias: bool = True) -> None
        # 非线性要增加隐藏层 网络结构1-10-1
        self.fc1=nn.Linear(1,10)
        # 设置激活函数 
        self.tanh=nn.Tanh()
        # 输出层
        self.fc2=nn.Linear(10,1)
    #定义网络计算  这里x是输入值
    def forward(self,x):
        # 一层一层计算
        x=self.fc1(x)
        x=self.tanh(x)
        x=self.fc2(x)
        return x

# 定义模型
model=LinearRegression()
# 定义损失函数
mse_loss=nn.MSELoss()
# 定义优化器,即改变参数使用的算法,这里使用梯度下降算法,lr表示学习率
optimizer=optim.SGD(model.parameters(),lr=0.3)

# 看一下模型的参数(可选)
for name,parameters in model.named_parameters():
    print('name:{},param:{}'.format(name,parameters))
    ## 略

# 开始训练
for i in range(2001):
    out=model(inputs)
    # 计算loss
    loss=mse_loss(out,target)
    # 梯度清0
    optimizer.zero_grad()
    # 计算梯度
    loss.backward()
    # 修改权值
    optimizer.step()
    if i%200==0:
        print(i,loss.item())
        ## 0 2.554469347000122
        ## 200 0.1598265916109085
        ## 400 0.09634878486394882
        ## 600 0.07832301408052444
        ## 800 0.07250834256410599
        ## 1000 0.06939169019460678
        ## 1200 0.06747214496135712
        ## 1400 0.06636324524879456
        ## 1600 0.06561310589313507
        ## 1800 0.0650334283709526
        ## 2000 0.06455783545970917

y_pred=model(inputs)
# 原始数据的散点图
plt.scatter(x_data,y_data)
# 训练的模型得到的回归线,第三个参数是颜色,第四个参数是线的宽度
plt.plot(x_data,y_pred.data.numpy(),'r-',lw=3)
plt.show()