LinearRegression

3.1.2.2 矢量计算
# 矢量相加的两种方法比较
import torch
from time import time

a = torch.ones(1000)
b = torch.ones(1000)
# method 1
start = time()
c = torch.zeros(1000)
for i in range(1000):
    c[i] = a[i] + b[i]
print("%f sec" % (time() - start))
0.030923 sec
# method 2
start = time()
d = a + b
print("%f sec" % (time() - start))
0.000000 sec
# broadcast mechanism
a = torch.ones(3)
b = 10
print(a + b)
tensor([11., 11., 11.])

3.2 线性回归从零实现

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

3.2.1 生成数据集

num_inputs = 2  # 特征数
num_examples = 1000  # 样本数
true_w = [2, -3.4]  # weight
true_b = 4.2  # bias
features= torch.from_numpy(np.random.normal(0, 1, (num_examples, num_inputs)))
labels = true_w[0] * features[:, 0] + true_w[1] + features[:, 1] + b
labels += torch.from_numpy(np.random.normal(0, 0.01, size=labels.size()))
print(features[0], labels[0])
tensor([ 0.9043, -0.7762], dtype=torch.float64) tensor(7.6342, dtype=torch.float64)
# 生成第二个特征和标签的散点图
def use_svg_display():
    # 设置用矢量图显示
    display.set_matplotlib_formats('svg')

def set_figsize(figsize=(3.5, 2.5)):
    use_svg_display()
    # 设置图的尺寸
    plt.rcParams['figure.figsize'] = figsize
    
set_figsize()
plt.scatter(features[:, 1].numpy(), labels.numpy(), 1)
<matplotlib.collections.PathCollection at 0x28e9c4baa08>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fIQGtnfO-1581680924814)(output_10_1.svg)]

3.2.2 读取数据

# 返回batch_size个随机样本的特征和标签
def data_iter(batch_size, features, labels):
    num_examples = len(features) # 样本数

    indices = list(range(num_examples))
    random.shuffle(indices)
    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)
# 默认的Tensor为FloatTensor,LongTensor为数据类型为long的Tensor
# torch.index(input, dim, index, out=None) 沿指定维度对input进行切片
# input(Tensor) - 输入的张量
# dim(int) - 索引的轴,0为列轴,一行一行的选取
# index(LongTensor) - 包含索引下标的一位Tensor
batch_size = 10

for X, y in data_iter(batch_size, features, labels):
    print(X, y)
    break
tensor([[-0.8234,  2.4055],
        [ 2.1394, -1.4180],
        [ 0.8803,  0.9584],
        [ 0.2310, -1.4648],
        [-1.6114, -0.2770],
        [-0.1147, -0.3696],
        [ 0.3489,  1.0079],
        [-0.5462,  1.3363],
        [-1.5867,  0.6097],
        [-0.1388, -1.1018]], dtype=torch.float64) tensor([7.3576, 9.4671, 9.3204, 5.5955, 3.1126, 5.9952, 8.3144, 6.8455, 4.0234,
        5.2047], dtype=torch.float64)

3.2.3 初始化模型参数

# 权重、偏差
w = torch.tensor(np.random.normal(0, 0.01, (num_inputs, 1)), dtype= torch.float32)
b = torch.zeros(1, dtype=torch.float32)
w.requires_grad_(requires_grad=True)
b.requires_grad_(requires_grad=True)
tensor([0.], requires_grad=True)

3.2.4 定义模型

# y = w * x + b
def linreg(X, w, b):
    return torch.mm(X, w.double()) + b

3.2.5 定义损失函数

# loss function
def squared_loss(y_hat, y):
    print(y_hat.size())
    print(y.size())
    return (y_hat - y.view(y_hat.size())) ** 2 / 2

3.2.6 定义优化算法

# 小批量随机梯度下降
def sgd(params, lr, batch_size):
    for param in params:
        param.data -= lr * param.grad / batch_size

3.2.7 训练模型

lr = 0.03 # learning rate
num_epochs = 3 # 迭代周期
net = linreg 
loss = squared_loss
for epoch in range(num_epochs):
    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_l = loss(net(features, w, b), labels)
    print('epoch %d, loss %f' % (epoch + 1, train_l.mean().item()))
    # tensor.item() 如果tensor只有一个元素,将tensor转换为scalar;否则报错
print(true_w, '\n', w)
print(true_b, '\n', b)
[2, -3.4] 
 tensor([[1.9989],
        [0.9996]], requires_grad=True)
4.2 
 tensor([6.5995], requires_grad=True)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值