258 KiB
258 KiB
In [1]:
import torch
import numpy
import pandas
from sympy.physics.control.control_plots import matplotlib
from torch.distributed.algorithms.ddp_comm_hooks.powerSGD_hook import batched_powerSGD_hook
In [2]:
torch.randn(3,4,2)Out [2]:
tensor([[[ 1.1696, -0.5395],
[-1.2794, -1.0168],
[ 3.2351, 0.6066],
[ 1.5116, -0.1253]],
[[-0.1823, 0.1887],
[ 0.0186, -1.5205],
[-0.3032, 0.1184],
[-0.1708, 1.2866]],
[[ 0.1142, 0.0435],
[-0.4102, -0.4663],
[ 0.2203, 0.3123],
[ 1.9645, 1.8992]]])In [3]:
X = torch.arange(12, dtype=torch.float32).reshape((3,4))
Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)Out [3]:
(tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[ 2., 1., 4., 3.],
[ 1., 2., 3., 4.],
[ 4., 3., 2., 1.]]),
tensor([[ 0., 1., 2., 3., 2., 1., 4., 3.],
[ 4., 5., 6., 7., 1., 2., 3., 4.],
[ 8., 9., 10., 11., 4., 3., 2., 1.]]))In [4]:
a = torch.arange(3).reshape((3, 1))
b = torch.arange(2).reshape((1, 2))
a, b
a+bOut [4]:
tensor([[0, 1],
[1, 2],
[2, 3]])In [5]:
X[-1], X[1:3]
Out [5]:
(tensor([ 8., 9., 10., 11.]),
tensor([[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]]))In [6]:
A = X.numpy()
B = torch.tensor(A)
type(A), type(B)Out [6]:
(numpy.ndarray, torch.Tensor)
In [7]:
import os
os.makedirs(os.path.join("..","data"),exist_ok=True)
data_file = os.path.join(os.path.join("..","data","data.csv"))
with open(data_file, "w") as f:
f.write('NumRooms,Alley,Price\n') # 列名
f.write('NA,Pave,127500\n') # 每行表示一个数据样本
f.write('2,NA,106000\n')
f.write('4,NA,178100\n')
f.write('NA,NA,140000\n')
In [8]:
import pandas as pd
data = pd.read_csv(data_file)
print(data)
NumRooms Alley Price 0 NaN Pave 127500 1 2.0 NaN 106000 2 4.0 NaN 178100 3 NaN NaN 140000
In [9]:
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs = pd.get_dummies(inputs, dummy_na=True)
print(inputs)
inputs = inputs.fillna(inputs.mean())
print(inputs)
NumRooms Alley_Pave Alley_nan 0 NaN True False 1 2.0 False True 2 4.0 False True 3 NaN False True NumRooms Alley_Pave Alley_nan 0 3.0 True False 1 2.0 False True 2 4.0 False True 3 3.0 False True
In [10]:
X = torch.tensor(inputs.to_numpy(dtype=float))
y = torch.tensor(outputs.to_numpy(dtype=float))
X, y
Out [10]:
(tensor([[3., 1., 0.],
[2., 0., 1.],
[4., 0., 1.],
[3., 0., 1.]], dtype=torch.float64),
tensor([127500., 106000., 178100., 140000.], dtype=torch.float64))In [11]:
B=torch.tensor([[1,2,3],[2,0,4],[3,4,5]])
BOut [11]:
tensor([[1, 2, 3],
[2, 0, 4],
[3, 4, 5]])In [12]:
B==B.TOut [12]:
tensor([[True, True, True],
[True, True, True],
[True, True, True]])In [13]:
X=torch.arange(24).reshape(2,3,4)
XOut [13]:
tensor([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])In [14]:
A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
B = A.clone() # 通过分配新内存,将A的一个副本分配给B
A, A + B
#A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
#B = A # 通过分配新内存,将A的一个副本分配给B
id(A),id(B)Out [14]:
(140539332541136, 140539333492432)
In [15]:
A*BOut [15]:
tensor([[ 0., 1., 4., 9.],
[ 16., 25., 36., 49.],
[ 64., 81., 100., 121.],
[144., 169., 196., 225.],
[256., 289., 324., 361.]])In [16]:
a=2
X=torch.arange(24).reshape(2,3,4)
a+X,(a*X).shapeOut [16]:
(tensor([[[ 2, 3, 4, 5],
[ 6, 7, 8, 9],
[10, 11, 12, 13]],
[[14, 15, 16, 17],
[18, 19, 20, 21],
[22, 23, 24, 25]]]),
torch.Size([2, 3, 4]))In [17]:
print(A)
A_sum_axis0=A.sum(axis=0)
A_sum_axis1=A.sum(axis=1)
A_sum_axis0,A_sum_axis1Out [17]:
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]])
(tensor([40., 45., 50., 55.]), tensor([ 6., 22., 38., 54., 70.]))
In [18]:
x=torch.arange(4,dtype=torch.float32)
torch.mv(A,x)Out [18]:
tensor([ 14., 38., 62., 86., 110.])
In [19]:
import time
def showtime(func):
def wrapper():
start = time.time()
result = func() # 执行原始函数
end = time.time()
print(f"执行时间: {end - start:.6f}秒")
return result
return wrapper # 返回包装函数
@showtime
def fun():
print("I am silly")
fun()
I am silly 执行时间: 0.000630秒
In [20]:
torch.norm(torch.ones((4, 9)))Out [20]:
tensor(6.)
In [21]:
x =torch.arange(4.0,requires_grad=True)
x.gradIn [22]:
y=2*torch.dot(x,x)
yOut [22]:
tensor(28., grad_fn=<MulBackward0>)
In [23]:
y.backward()
x.gradOut [23]:
tensor([ 0., 4., 8., 12.])
In [24]:
x.grad.zero_()
y = x.sum()
y.backward()
x.grad
Out [24]:
tensor([1., 1., 1., 1.])
In [25]:
# 对非标量调用backward需要传入一个gradient参数,该参数指定微分函数关于self的梯度。
# 本例只想求偏导数的和,所以传递一个1的梯度是合适的
x.grad.zero_()
y = x * x
# 等价于y.backward(torch.ones(len(x)))
print(y)
y.sum().backward()
x.gradOut [25]:
tensor([0., 1., 4., 9.], grad_fn=<MulBackward0>)
tensor([0., 2., 4., 6.])
In [26]:
torch.ones(len(x))Out [26]:
tensor([1., 1., 1., 1.])
In [27]:
x.grad.zero_()
y=x*x
u=y.detach()
z=u*x
z.sum().backward()
x.grad==uOut [27]:
tensor([True, True, True, True])
In [28]:
x.grad.zero_()
y.sum().backward()
x.grad==2*xOut [28]:
tensor([True, True, True, True])
In [29]:
from torch.distributions import multinomial
fair_probs=torch.ones([6])
fair_probsOut [29]:
tensor([1., 1., 1., 1., 1., 1.])
In [30]:
multinomial.Multinomial(1, fair_probs).sample()Out [30]:
tensor([0., 0., 1., 0., 0., 0.])
In [31]:
counts = multinomial.Multinomial(10, fair_probs).sample((500,))
cum_counts = counts.cumsum(dim=0)
cum_counts.size()Out [31]:
torch.Size([500, 6])
In [32]:
import matplotlib.pyplot as plt
# 假设 estimates 是你的数据张量
estimates = cum_counts / cum_counts.sum(dim=1, keepdims=True)
# 设置图形大小 (等效于 d2l.set_figsize)
plt.figure(figsize=(6, 4.5))
# 绘制每条概率曲线
for i in range(6):
plt.plot(estimates[:, i].numpy(),
label=f"P(die={i + 1})") # 使用 f-string 更简洁
# 添加理论概率水平线
plt.axhline(y=0.167, color='black', linestyle='dashed', label='Theoretical probability')
# 设置坐标轴标签
plt.xlabel('Groups of experiments')
plt.ylabel('Estimated probability')
# 添加图例
plt.legend()
# 显示图形
plt.show()
#plt.savefig('dice_probability.png', bbox_inches='tight')In [33]:
import numpy as np
class Timer:
"""记录多次运行时间"""
def __init__(self):
self.times = []
self.start()
def start(self):
"""启动计时器"""
self.tik = time.time()
def stop(self):
"""停止计时器并将时间记录在列表中"""
self.times.append(time.time() - self.tik)
return self.times[-1]
def avg(self):
"""返回平均时间"""
return sum(self.times) / len(self.times)
def sum(self):
"""返回时间总和"""
return sum(self.times)
def cumsum(self):
"""返回累计时间"""
return np.array(self.times).cumsum().tolist()In [34]:
n = 10000
a = torch.ones([n])
b = torch.ones([n])
c=torch.zeros(n)
timer = Timer()
for i in range(n):
c[i]=a[i]+b[i]
f'{timer.stop():.5f} sec'Out [34]:
'0.05042 sec'
In [35]:
timer.start()
d=a+b
f'{timer.stop():.5f} sec'Out [35]:
'0.00046 sec'
In [36]:
import math
def normal(x, mu, sigma):
p = 1 / math.sqrt(2 * math.pi * sigma**2)
return p * np.exp(-0.5 / sigma**2 * (x - mu)**2)In [37]:
from matplotlib_inline import backend_inline
def use_svg_display(): #@save
"""使用svg格式在Jupyter中显示绘图"""
backend_inline.set_matplotlib_formats('svg')
def set_figsize(figsize=(3.5, 2.5)): #@save
"""设置matplotlib的图表大小"""
use_svg_display()
plt.rcParams['figure.figsize'] = figsize
def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
"""设置matplotlib的轴"""
axes.set_xlabel(xlabel)
axes.set_ylabel(ylabel)
axes.set_xscale(xscale)
axes.set_yscale(yscale)
axes.set_xlim(xlim)
axes.set_ylim(ylim)
if legend:
axes.legend(legend)
axes.grid()
def plot(X, Y=None, xlabel=None, ylabel=None, legend=None, xlim=None,
ylim=None, xscale='linear', yscale='linear',
fmts=('-', 'm--', 'g-.', 'r:'), figsize=(3.5, 2.5), axes=None):
"""绘制数据点"""
if legend is None:
legend = []
set_figsize(figsize)
axes = axes if axes else plt.gca()
# 如果X有一个轴,输出True
def has_one_axis(X):
return (hasattr(X, "ndim") and X.ndim == 1 or isinstance(X, list)
and not hasattr(X[0], "__len__"))
if has_one_axis(X):
X = [X]
if Y is None:
X, Y = [[]] * len(X), X
elif has_one_axis(Y):
Y = [Y]
if len(X) != len(Y):
X = X * len(Y)
axes.cla()
for x, y, fmt in zip(X, Y, fmts):
if len(x):
axes.plot(x, y, fmt)
else:
axes.plot(y, fmt)
set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend)In [38]:
# 再次使用numpy进行可视化
x = np.arange(-7, 7, 0.01)
# 均值和标准差对
params = [(0, 1), (0, 2), (3, 1)]
plot(x, [normal(x, mu, sigma) for mu, sigma in params], xlabel='x',
ylabel='p(x)', figsize=(4.5, 2.5),
legend=[f'mean {mu}, std {sigma}' for mu, sigma in params])In [39]:
#注意一下matmul做向量乘上矩阵的时候不用考虑转置的情况
def synthetic_data(w, b, num_examples): #@save
"""生成y=Xw+b+噪声"""
X = torch.normal(0, 1, (num_examples, len(w)))
y = torch.matmul(X, w) + b
y += torch.normal(0, 0.01, y.shape)
return X, y.reshape((-1, 1))
In [40]:
true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)In [41]:
set_figsize()
plt.scatter(features[:, (1)].detach().numpy(), labels.detach().numpy(), 1)Out [41]:
<matplotlib.collections.PathCollection at 0x7fd1dc5d8050>
In [42]:
w=torch.normal(0,0.01,size=(2,1),requires_grad=True)
b=torch.zeros(1,requires_grad=True)
def linreg(X, w, b):
return torch.matmul(X,w)+b
def squared_loss(y_hat,y):
return (y_hat-y.reshape(y_hat.shape))**2/2
def sgd(params,lr,batch_size):
with torch.no_grad():
for param in params:
param-=lr*param.grad/batch_size
param.grad.zero_()
lr = 0.03
num_epochs =20
net = linreg
loss = squared_lossIn [43]:
import random
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):
batch_indices = torch.tensor(
indices[i: min(i + batch_size, num_examples)])
yield features[batch_indices], labels[batch_indices]In [44]:
batch_size =10
for X,y in data_iter(batch_size, features, labels):
print(X,'\n',y)
breaktensor([[-0.3577, 0.6754],
[-0.1904, -0.6314],
[-1.5305, -0.2903],
[ 2.0532, -0.3528],
[ 0.4056, -0.7645],
[-0.7985, 1.3492],
[-0.4550, 0.1608],
[ 1.1672, -0.5057],
[ 0.3912, -2.4489],
[ 1.9930, 1.6857]])
tensor([[ 1.1766],
[ 5.9634],
[ 2.1265],
[ 9.5015],
[ 7.6220],
[-1.9910],
[ 2.7378],
[ 8.2718],
[13.2983],
[ 2.4553]])
In [45]:
for epoch in range(num_epochs):
for X, y in data_iter(batch_size, features, labels):
l=loss(net(X, w, b), y)
l.sum().backward()
sgd([w,b],lr,batch_size)
with torch.no_grad():
train_l =loss(net(features, w, b), labels)
print(f'epoch {epoch+1}, train loss: {float(train_l.mean()):3f}')epoch 1, train loss: 0.052015 epoch 2, train loss: 0.000228 epoch 3, train loss: 0.000049 epoch 4, train loss: 0.000048 epoch 5, train loss: 0.000048 epoch 6, train loss: 0.000048 epoch 7, train loss: 0.000048 epoch 8, train loss: 0.000048 epoch 9, train loss: 0.000048 epoch 10, train loss: 0.000048 epoch 11, train loss: 0.000048 epoch 12, train loss: 0.000048 epoch 13, train loss: 0.000048 epoch 14, train loss: 0.000048 epoch 15, train loss: 0.000048 epoch 16, train loss: 0.000048 epoch 17, train loss: 0.000048 epoch 18, train loss: 0.000048 epoch 19, train loss: 0.000048 epoch 20, train loss: 0.000048
In [46]:
print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')
print(f'b的估计误差: {true_b - b}')w的估计误差: tensor([-0.0004, 0.0002], grad_fn=<SubBackward0>) b的估计误差: tensor([-0.0005], grad_fn=<RsubBackward1>)
In [51]:
from torch.utils import data
true_w = torch.tensor([2,-3.4])
true_b = 4.2
features,labels=synthetic_data(true_w, true_b, 1000)
def load_array(data_arrays,batch_size,is_train=True):
dataset = data.TensorDataset(*data_arrays)
return data.DataLoader(dataset,batch_size,shuffle=is_train)
batch_size = 10
data_iter = load_array((features,labels),batch_size)In [52]:
from torch import nn
net = nn.Sequential(nn.Linear(2, 1))
net[0].weight.data.normal_(0,0.001)
net[0].bias.data.fill_(0)Out [52]:
tensor([0.])
In [63]:
loss = nn.MSELoss()
trainer = torch.optim.SGD(net.parameters(), lr=0.01)
num_epochs = 3
for epoch in range(num_epochs):
for X, y in data_iter:
l = loss(net(X) ,y)
trainer.zero_grad()
l.backward()
trainer.step()
l = loss(net(features), labels)
print(f'epoch {epoch + 1}, loss {l:f}')
epoch 1, loss 0.000091 epoch 2, loss 0.000091 epoch 3, loss 0.000091
In [49]: