线性回归从零实现

#import packages and modules
%matplotlib inline
import torch
from IPython import display
import matplotlib.pyplot as plt
import numpy as np
import random

生成数据集

#set input feature number
number_inputs = 2
#set example number
number_examples = 1000
#set true weight and bias in order to gengerate corresponded label
true_w = [2,-3.4]
true_b = 4.2
features = torch.randn(number_examples,number_inputs,
                      dtype = torch.float32)
labels = true_w[0]*features[:,0]+true_w[1]*features[:,1]+true_b

图像显示

plt.scatter(features[:,1].numpy(),labels.numpy(),1);

读取数据集

def data_iter(batch_size,features,labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    random.shuffle(indices)#random read 10 samples
    for i in range(0,num_examples,batch_size):
        j = torch.LongTensor(indices[i:min(i+batch_size,num_examples)])
        yield features.index_select(0,j),labels.index_select(0,j)
batch_size = 10
for X,y in data_iter(batch_size,features,labels):
    print(X,'\n',y)
    break

初始化模型参数

w = torch.tensor(np.random.normal(0,0.01,(number_inputs,1)),dtype = torch.float32)
b = torch.zeros(1,dtype=torch.float32)

w.requires_grad_(requires_grad = True)
b.requires_grad_(requires_grad = True)

定义模型

def linreg(X,w,b):
    return torch.mm(X,w)+b

定义损失函数

def square_loss(y_hat,y):
    return (y_hat-y.view(y_hat.size()))**2/2

定义优化函数

def sgd(params,lr,batch_size):
    for param in params:
        param.data -= lr*param.grad/batch_size

训练

lr = 0.03
num_epoches = 5

net = linreg
loss = square_loss

# training
for epoch in range(num_epoches):
    
    for X,y in data_iter(batch_size,features,labels):
        l = loss(net(X,w,b),y).sum()
        l.backward()
        sgd([w,b],lr,batch_size)
        
        w.grad.data.zero_()
        b.grad.data.zero_()
        
    train_1 = loss(net(features,w,b),labels)
    print('epoch %d,loss%f' %(epoch+1,train_1.mean().item()))

pytorch的简洁实现

import torch
from torch import nn
import numpy as np
torch.manual_seed(1)
torch.set_default_tensor_type('torch.FloatTensor')

生成数据集

num_inputs = 2
num_examples = 1000

true_w = [2, -3.4]
true_b = 4.2

features = torch.tensor(np.random.normal(0, 1, (num_examples, num_inputs)), dtype=torch.float)
labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b
labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)

读取数据集

import torch.utils.data as Data

batch_size = 10

# combine featues and labels of dataset
dataset = Data.TensorDataset(features, labels)

# put dataset into DataLoader
data_iter = Data.DataLoader(
    dataset=dataset,            # torch TensorDataset format
    batch_size=batch_size,      # mini batch size
    shuffle=True,               # whether shuffle the data or not
    #num_workers=2              # read data in multithreading
)

定义模型

class LinearNet(nn.Module):
    def __init__(self,n_feature):
        super(LinearNet,self).__init__()
        self.linear = nn.Linear(n_feature,1)#unction prototype: `torch.nn.Linear(in_features, out_features, bias=True)
        
    def forward(self,x):
        y = self.linear(x)
        return y
    
net = LinearNet(num_inputs)
print(net)

实现网络的三种形式

# ways to init a multilayer network
# method one
net = nn.Sequential(
    nn.Linear(num_inputs,1)
                   )
#method two
net = nn.Sequential()
net.add_module('linear',nn.Linear(num_inputs,1))

#method three
from collections import OrderedDict
net = nn.Sequential(OrderedDict([
    ('linear',nn.Linear(num_inputs,1))
]))
### 初始化模型参数
```python
from torch.nn import init

init.normal_(net[0].weight,mean=0.0,std=0.01)
init.constant_(net[0].bias,val = 0.0)

损失函数与优化函数

loss = nn.MSELoss()
### 优化函数
import torch.optim as optim

optimizer = optim.SGD(net.parameters(),lr=0.03)
print(optimizer)

训练

### training
num_epoches = 3
for epoch in range(1,num_epoches + 1):
    for X,y in data_iter:
        output = net(X)
        l = loss(output,y.view(-1,1))
        optimizer.zero_grad()
        l.backward()
        optimizer.step()
    print('epoch %d, loss: %f' % (epoch, l.item()))
dense = net[0]
print(true_w, dense.weight.data)
print(true_b, dense.bias.data)
posted on 2020-04-10 10:41  吕店老板  阅读(212)  评论(0编辑  收藏  举报