# 矢量相加的两种方法比较
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.])
# import packages
%matplotlib inline
import torch
from IPython import display
from matplotlib import pyplot as plt
import numpy as np
import random
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)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fIQGtnfO-1581680924814)(output_10_1.svg)]
# 返回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)
# 权重、偏差
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)
# y = w * x + b
def linreg(X, w, b):
return torch.mm(X, w.double()) + b
# 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
# 小批量随机梯度下降
def sgd(params, lr, batch_size):
for param in params:
param.data -= lr * param.grad / batch_size
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)