线性回归

1.批输入线性回归

  • 1.1 原理

线性回归_第1张图片
  • 1.2 代码

import torch
import matplotlib.pylab as plt

def Produce_X(x):
    x0=torch.ones(x.numpy().size)
    X=torch.stack((x,x0),dim=1)     #拼接
    return X

x=torch.Tensor([1.4,5,11,16,21])
y=torch.Tensor([14.4,29.6,62,85.5,113.4])
X=Produce_X(x)
#print(X)
#tensor([[ 1.4000,  1.0000],
#        [ 5.0000,  1.0000],
#        [11.0000,  1.0000],
#        [16.0000,  1.0000],
#        [21.0000,  1.0000]])
inputs=X
target=y
w=torch.rand(2,requires_grad=True)#随机化初始向量w

#每一轮训练分成两部分,前向传播和反向传播
def train(epochs=1,learning_rate=0.01):#第一个参数代表轮数,第二个参数代表学习率
    for epoch in range(epochs):
        output=inputs.mv(w)
        loss=(output-target).pow(2).sum()
        #反向传播更新w的值
        loss.backward()#w的梯度向量
        w.data-=learning_rate * w.grad#更新w的值
        #清空w的grad的值,否则会出现累加
        w.grad.zero_()
        if epoch%80==0:
            draw(output,loss)
    return w,loss

def draw(output,loss):
    plt.cla()
    plt.scatter(x.numpy(),y.numpy())#样本点
    plt.plot(x.numpy(),output.data.numpy(),'r-',lw=5)#绘制回归曲线
    plt.text(0.5,0,'loss-%s' %(loss.item()),fontdict={'size':20,'color':'red'})
    plt.pause(0.005)

w,loss=train(10000,learning_rate=1e-4)

print(loss.item())#item()的作用是取出单元素张量的元素值并返回该值,保持该元素类型不变。
print(w.data)

#8.234036445617676
#tensor([5.0833, 5.5962])
  • 1.3 实验结果图

线性回归_第2张图片

2.大规模数据的线性回归

  • 2.1 准备数据

现在我们尝试使用自动生成的100000个数据样本,再进行一次线性回归

linspace(a,b,c)函数可以在(a,b)区间内划分出c个点

1.为了使得数据符合线性分布且真实,y值在x值得基础上增加了一些误差。关于误差可以用rand()函数生成一组在[0,1)区间内均匀分布的随机数,随机数的个数为x的元素个数*1.2
2.对于loss的处理,要除掉100000,否则会出现loss返回nan的情况,对于 loss返回nan的情况 ,有可能就是因为 学习率太大了

y=x + 1.2 * torch.rand(x.size())

loss = (output - target).pow(2).sum()/100000#注意此处/100000,否则会出现返回nan的情况
import torch
import matplotlib.pylab as plt

def Produce_X(x):
    x0=torch.ones(x.numpy().size)
    X=torch.stack((x,x0),dim=1)     #拼接
    return X

x=torch.linspace(-3,3,100000)
X=Produce_X(x)
y=x+1.2*torch.rand(x.size())
w=torch.rand(2)

plt.scatter(x.numpy(),y.numpy(),s=0.001)
plt.show()
线性回归_第3张图片
  • 2.2 GPU加速

CUDA=torch.cuda.is_available()
#使用cuda.is_available()函数对运行平台进行CUDA检测,如果支持,就GPU加速
if CUDA:
    inputs=X.cuda()
    target=y.cuda()
    w=w.cuda()
    w.requires_grad=True
else:
    inputs = X
    target = y
    w=w
    w.requires_grad = True

如果采用了CUDA加速,draw()函数的output需要还原成CPU的数据类型才可以绘图

 if CUDA:
    output=output.cpu()  
  • 代码

import torch
import matplotlib.pylab as plt
from time import perf_counter
#训练时,为了记录整个熟练的时间长度,我们引入time包

def Produce_X(x):
    x0=torch.ones(x.numpy().size)
    X=torch.stack((x,x0),dim=1)     #拼接
    return X

x=torch.linspace(-3,3,100000)
X=Produce_X(x)
y=x+1.2*torch.rand(x.size())

w=torch.rand(2)


CUDA=torch.cuda.is_available()
#使用cuda.is_available()函数对运行平台进行CUDA检测,如果支持,就GPU加速
if CUDA:
    inputs=X.cuda()
    target=y.cuda()
    w=w.cuda()
    w.requires_grad=True
else:
    inputs = X
    target = y
    w=w
    w.requires_grad = True


def draw(output, loss):
        if CUDA:
            output = output.cpu()
        plt.cla()
        plt.scatter(x.numpy(), y.numpy())  # 样本点
        plt.plot(x.numpy(), output.data.numpy(), 'r-', lw=5)  # 绘制回归曲线
        plt.text(0.5, 0, 'loss-%s' % (loss.item()), fontdict={'size': 20, 'color': 'red'})
        plt.pause(0.005)

def train(epochs=1, learning_rate=0.01):  # 第一个参数代表轮数,第二个参数代表学习率
    for epoch in range(epochs):
            output = inputs.mv(w)
            loss = (output - target).pow(2).sum()/100000#注意此处/100000,否则会出现返回nan的情况
            # 反向传播更新w的值
            loss.backward()  # w的梯度向量
            w.data -= learning_rate * w.grad  # 更新w的值
            # 清空w的grad的值,否则会出现累加
            w.grad.zero_()
            if epoch % 80 == 0:
                draw(output, loss)
    return w, loss

start=perf_counter()
w,loss=train(10000,learning_rate=1e-4)
finish=perf_counter()
time=finish-start

print("计算时间:%s" % time)
print("finish loss:",loss.item())
print("weights:",w.data)

  • 实验结果

计算时间:49.1337396
finish loss: 0.12007612735033035
weights: tensor([0.9996, 0.6050], device='cuda:0')
线性回归_第4张图片
线性回归_第5张图片

你可能感兴趣的:(线性回归)