大挪耗

pytorch解决温度计转换问题

%matplotlib inline
import numpy as np
import torch
torch.set_printoptions(edgeitems=2, threshold=75)

In [2]:

t_c=[0.5,14.0,15.0,28.0,11.0,8.0,3.0,-4.0,6.0,13.0,21.0]
t_u=[35.7,55.9,58.2,81.9,56.3,48.9,33.9,21.8,48.4,60.4,68.4]

In [3]:

t_c=torch.tensor(t_c)
t_u=torch.tensor(t_u)

In [4]:

t_u

Out[4]:

tensor([35.7000, 55.9000, 58.2000, 81.9000, 56.3000, 48.9000, 33.9000, 21.8000,
        48.4000, 60.4000, 68.4000])

In [5]:

import matplotlib.pyplot as plt
fig=plt.figure()
plt.scatter(t_c,t_u,c='b',edgecolors="r")

Out[5]:

<matplotlib.collections.PathCollection at 0x226b216e090>

In [6]:

def model(t_u,w,b):
    return t_u*w+b

In [7]:

def loss_fn(t_p,t_c):
    squared_diffs=(t_p-t_c)**2
    return squared_diffs.mean()

In [8]:

w=torch.ones(())
b=torch.zeros(())
t_p=model(t_u,w,b)
t_p

Out[8]:

tensor([35.7000, 55.9000, 58.2000, 81.9000, 56.3000, 48.9000, 33.9000, 21.8000,
        48.4000, 60.4000, 68.4000])

In [9]:

w

Out[9]:

tensor(1.)

In [10]:

loss=loss_fn(t_p,t_c)
loss

Out[10]:

tensor(1763.8848)

In [11]:

w=torch.zeros(())
b=torch.zeros(())
t_p=model(t_u,w,b)
t_p

Out[11]:

tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

In [12]:

loss=loss_fn(t_p,t_c)
loss # 通过损失函数来调整参数 

Out[12]:

tensor(187.3864)

广播机制

In [14]:

x=torch.ones(())
y=torch.ones(3,1)
z=torch.ones(1,3)
a=torch.ones(2,1,1)

In [15]:

print("x*y",(x*y).shape)
x*y torch.Size([3, 1])

In [16]:

print("y*z",(y*z).shape)
y*z torch.Size([3, 3])

In [17]:

print("y*z*a",(y*z*a).shape)
y*z*a torch.Size([2, 3, 3])

In [18]:

x=torch.ones(5,2,4,1)
y=torch.ones(3,1,1)
#有数维度太高无法理解广播机制就起不了作用 

梯度

编写梯度代码

In [20]:

def dloss_fn(t_p,t_c):
    dsq_diffs=2*(t_p-t_c)/t_p.size(0)
    return dsq_diffs
def dmodel_dw(t_u,w,b):
    return t_u
def dmodel_db(t_u,w,b):
    return 1.0

In [21]:

def grad_fn(t_u,t_c,t_p,w,b):
    dloss_dtp=dloss_fn(t_p,t_c)
    dloss_dw=dloss_dtp*dmodel_dw(t_u,w,b)
    dloss_db=dloss_dtp*dmodel_db(t_u,w,b)
    return torch.stack([dloss_dw.sum(),dloss_db.sum()])

In [22]:

delta=0.1
loss_rate_of_change_w=(loss_fn(model(t_u,w+delta,b),t_c))-(loss_fn(model(t_u,w-delta,b),t_c))/(2.0*delta)
learning_rate=1e-2
w=w-learning_rate*loss_rate_of_change_w

loss_rate_of_change_b=(loss_fn(model(t_u, w,b+delta),t_c)-loss_fn(model(t_u, w, b-delta),t_c))/(2.0*delta)
b=b-learning_rate*loss_rate_of_change_b

In [23]:

def training_loop(n_epochs,learning_rate,params,t_u,t_c):
    for epoch in range(1,n_epochs+1):
        w,b=params
        t_p=model(t_u,w,b)
        loss=loss_fn(t_p,t_c)
        grad=grad_fn(t_u,t_c,t_p,w,b)
        params=params-learning_rate*grad
        print("Epoch %d,loss %f" % (epoch,float(loss)))
    return params

In [24]:

t_un=0.1*t_u
params=training_loop(n_epochs=20000,learning_rate=1e-2,params=torch.tensor([10,0.0]),t_u=t_un,t_c=t_c)
print(params)
Epoch 19994,loss 2.927645
Epoch 19995,loss 2.927645
Epoch 19996,loss 2.927645
Epoch 19997,loss 2.927645
Epoch 19998,loss 2.927645
Epoch 19999,loss 2.927645
Epoch 20000,loss 2.927645
tensor([  5.3676, -17.3042])

In [25]:

%matplotlib inline
from matplotlib import pyplot as plt
t_p=model(t_un,*params)
fig=plt.figure(dpi=600)
plt.xlabel("Temperature Fahrenheit")
plt.ylabel("Temperature Celsius")
plt.plot(t_u.numpy(),t_p.detach().numpy())
plt.plot(t_u.numpy(),t_c.numpy(),"o")
plt.savefig("temp_unknow_plot.png")

PyTorch自动梯度计算

自动求导

In [28]:

t_c=torch.tensor([0.5,14.0,15.0,28.0,11.0,8.0,3.0,-4.0,6.0,13.0,21.0])
t_u=torch.tensor([35.7,55.9,58.2,81.9,56.3,48.9,33.9,21.8,48.4,60.4,68.4])
# 定义函数
def model(t_u,w,b):
    return t_u*w+b
# 算方差
def loss_fn(t_p,t_c):
    squared_diffs=(t_p-t_c)**2
    return squared_diffs.mean()

# 唯一改变
params=torch.tensor([1.0,0.0],requires_grad=True)
# 反向传播
loss=loss_fn(model(t_u,*params),t_c)
loss.backward()

# 输出params的梯度看看
params.grad

    

Out[28]:

tensor([4517.2969,   82.6000])

In [29]:

def training_loop(n_epochs,learning_rate,params,t_u,t_c):
    for epoch in range(1,n_epochs+1):
        if params[0].grad is None:
            params.grad.zero_()
        t_p=model(t_u,*params) 
        loss=loss_fn(t_p,t_c)
        loss.backward()
        with torch.no_grad():
            params-=learning_rate*params.grad
        if epoch%500==0:
            print("Epoch %d,loss %f" % (epoch,float(loss)))
    return params
        

In [30]:

t_un=0.1*t_u
params=training_loop(n_epochs=3000,learning_rate=1e-2,params=params,t_u=t_un,t_c=t_c)
print(params)
C:\Users\tanhaowen\AppData\Local\Temp\ipykernel_13452\3767616033.py:3: UserWarning: The .grad attribute of a Tensor that is not a leaf Tensor is being accessed. Its .grad attribute won't be populated during autograd.backward(). If you indeed want the .grad field to be populated for a non-leaf Tensor, use .retain_grad() on the non-leaf Tensor. If you access the non-leaf Tensor by mistake, make sure you access the leaf Tensor instead. See github.com/pytorch/pytorch/pull/30531 for more informations. (Triggered internally at C:\cb\pytorch_1000000000000\work\build\aten\src\ATen/core/TensorBody.h:494.)
  if params[0].grad is None:
Epoch 500,loss 7.860115
Epoch 1000,loss 3.828538
Epoch 1500,loss 3.092191
Epoch 2000,loss 2.957698
Epoch 2500,loss 2.933134
Epoch 3000,loss 2.928648
tensor([  5.3489, -17.1980], requires_grad=True)

PyTorch的优化器

In [32]:

import torch.optim as optim
params=torch.tensor([1.0,0.0],requires_grad=True)
learning_rate=1e-5
optimizer=optim.SGD([params],lr=learning_rate)

t_p=model(t_u,*params)
loss=loss_fn(t_p,t_c)
loss.backward()

optimizer.step()
params

Out[32]:

tensor([ 9.5483e-01, -8.2600e-04], requires_grad=True)

In [33]:

def training_loop(n_epochs,optimizer,params,t_u,t_c):
    for epoch in range(1,n_epochs+1):
        t_p=model(t_u,*params) 
        loss=loss_fn(t_p,t_c)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        if epoch%500==0:
            print("Epoch %d,loss %f" % (epoch,float(loss)))
    return params

In [34]:

params=torch.tensor([1.0,0.0],requires_grad=True)
learning_rate=1e-2
optimizer=optim.SGD([params],lr=learning_rate)

training_loop(n_epochs=1000,optimizer=optimizer,params=params,t_u=t_un,t_c=t_c)
Epoch 500,loss 7.860115
Epoch 1000,loss 3.828538

Out[34]:

tensor([  4.8021, -14.1031], requires_grad=True)

In [35]:

# 激活函数

%matplotlib inline
import numpy
import torch
import torch.optim as optim
torch.set_printoptions(edgeitems=2,linewidth=75)
t_c=[0.5,14.0,15.0,28.0,11.0,8.0,3.0,-4.0,6.0,13.0,21.0]
t_u=[35.7,55.9,58.2,81.9,56.3,48.9,33.9,21.8,48.4,60.4,68.4]
t_c=torch.tensor(t_c).unsqueeze(1)
t_u=torch.tensor(t_u).unsqueeze(1)

In [36]:

t_u.shape

Out[36]:

torch.Size([11, 1])

In [37]:

n_samples=t_u.shape[0]
n_val=int(0.2*n_samples)

shuffled_indices=torch.randperm(n_samples)

train_indices=shuffled_indices[:-n_val]
val_indices=shuffled_indices[-n_val:]

t_u_train=t_u[train_indices]
t_c_train=t_c[train_indices]

t_u_val=t_u[val_indices]
t_c_val=t_c[val_indices]

t_un_train=0.1*t_u_train
t_un_val=0.1*t_u_val

In [38]:

import torch.nn as nn
linear_model=nn.Linear(1,1)
linear_model(t_un_val)

Out[38]:

tensor([[2.3831],
        [2.0567]], grad_fn=<AddmmBackward0>)

In [39]:

linear_model.weight

Out[39]:

Parameter containing:
tensor([[0.3331]], requires_grad=True)

In [40]:

linear_model.bias

Out[40]:

Parameter containing:
tensor([0.4445], requires_grad=True)

In [41]:

x=torch.ones(10,1)
linear_model(x)

Out[41]:

tensor([[0.7776],
        [0.7776],
        [0.7776],
        [0.7776],
        [0.7776],
        [0.7776],
        [0.7776],
        [0.7776],
        [0.7776],
        [0.7776]], grad_fn=<AddmmBackward0>)

In [42]:

optimizer=optim.SGD(
    linear_model.parameters(),
    lr=1e-2
)
list(linear_model.parameters())

Out[42]:

[Parameter containing:
 tensor([[0.3331]], requires_grad=True),
 Parameter containing:
 tensor([0.4445], requires_grad=True)]

In [43]:

def train_loop(n_epochs,optimizer,model,loss_fn,t_u_train,t_u_val,t_c_train,t_c_val):
    for epoch in range(1,n_epochs+1):
        t_p_train=model(t_u_train)
        loss_train=loss_fn(t_p_train,t_c_train)
        
        t_p_val=model(t_u_val)
        loss_val=loss_fn(t_p_train,t_c_train)
        
        optimizer.zero_grad()
        loss_train.backward()
        optimizer.step()
        
        if epoch==1 or epoch %1000==0:
            print(f"Epoch {epoch},Training loss loss {loss_train.item():.4f},"f"Validation loss {loss_val.item():.4f}")
            
            

In [44]:

def loss_fn(t_p,t_c):
    squard_diffs=(t_p-t_c)**2
    return squard_diffs.mean()

linear_model=nn.Linear(1,1)
optimizer=optim.SGD(linear_model.parameters(),lr=1e-2)

train_loop(
    n_epochs=3000,
    optimizer=optimizer,
    model=linear_model,
    loss_fn=loss_fn,
    t_u_train=t_u_train,
    t_u_val=t_u_val,
    t_c_train=t_c_train,
    t_c_val=t_c_val,
)

已发布

分类

可以收藏大挪耗一下。下载麻烦点城通网盘,站长保证下载速度,不会限速的,放心点就是了;分卷,安卓下载为txt:程序下载为url,不会下载参考不会下载。如果你想让本站活的久一点,请直接捐助

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注