1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | import torch import matplotlib.pyplot as plt torch.manual_seed(10) lr = 0.05 # 学习率 # 创建训练数据 x = torch.rand(20, 1) * 10 # x data (tensor), shape=(20, 1) # torch.randn(20, 1) 用于添加噪声 y = 2*x + (5 + torch.randn(20, 1)) # y data (tensor), shape=(20, 1) # 构建线性回归参数 w = torch.randn((1), requires_grad=True) # 设置梯度求解为 true b = torch.zeros((1), requires_grad=True) # 设置requires_grad梯度求解为 true #此Tensor的梯度将累积到.grad属性中。 # 迭代训练 1000 次 for iteration in range(1000): # 前向传播,计算预测值 wx = torch.mul(w, x) y_pred = torch.add(wx, b) # 计算 MSE loss loss = (0.5 * (y - y_pred) ** 2).mean() # 反向传播 loss.backward() # 更新参数 #b.data.sub_(lr * b.grad) b -= lr * b.grad #w.data.sub_(lr * w.grad) w -= lr * w.grad # 每次更新参数之后,都要清零张量的梯度 w.grad.zero_() #此Tensor的梯度将累积到.grad属性中。 b.grad.zero_() # 绘图,每隔 20 次重新绘制直线 if iteration % 20 == 0: plt.scatter(x.data.numpy(), y.data.numpy()) plt.plot(x.data.numpy(), y_pred.data.numpy(), 'r-' , lw=5) plt.text(2, 20, 'Loss=%.4f' % loss.data.numpy(), fontdict={ 'size' : 20, 'color' : 'red' }) plt.xlim(1.5, 10) plt.ylim(8, 28) plt.title( "Iteration: {}\nw: {} b: {}" .format(iteration, w.data.numpy(), b.data.numpy())) plt.pause(0.5) # 如果 MSE 小于 1,则停止训练 if loss.data.numpy() < 1: break |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | #%matplotlib inline import random import torch from d2l import torch as d2l import matplotlib.pyplot as plt #1 构造样本数据 def synthetic_data(w, b, num_examples): #@save #num_examples 数据样本数目 "" "生成y=Xw+b+噪声" "" '' ' torch.normal() Mean ( float ) – 所有分布的平均值 std ( float ) – 所有分布的标准差 size ( int ... ) – 定义输出张量形状的整数序列。 '' ' X = torch.normal(0, 1, (num_examples, len(w)))# 生成x数值 w (w1,w2) 和 x(x1,x2)保持一致 y = torch.matmul(X, w) + b #y真值 y += torch.normal(0, 0.01, y.shape) #y添加噪声 return X, y.reshape((-1, 1)) #true_w = torch.tensor([2, -3.4]) #真值 true_w = torch.tensor([2.0,2.0 ]) #真值 true_b = 1.0 # 真值 x_features, y_labels = synthetic_data(true_w, true_b, 100) #print('features[0]:', x_features[0],'\nlabel:', y_labels[0]) # 2 可视化样本数据 ax = plt.figure().add_subplot(projection= '3d' ) x1=x_features.data.numpy()[:,0] x2=x_features.data.numpy()[:,1] y=y_labels.data.numpy()[:,0] print( "x1\n" ,x1, "\nx2\n" ,x2, "\ny\n" ,y) ax.plot(x1, x2, y, label= 'x1 x2 -- y' ) ax.legend() plt.show() plt.pause(3) # 3 加载数据 打乱集中数据的样本并以小批量的方式获取数据 #训练模型的时候要对数据集进行遍历,每次抽取一个批量样本,并用它们来更新我们的模型。 def data_iter(batch_size, features, labels): num_examples = len(features) indices = list(range(num_examples))# 0-len(x_features) # 这些样本是随机读取的,没有特定的顺序 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] batch_size = 10 #接收批量大小 for X, y in data_iter(batch_size, x_features, y_labels): print( "随机每次抽取batch_size组数据 样本 x y" ,X, '\n' , y) break #定义模型 def linreg(X, w, b): #@save "" "线性回归模型" "" return torch.matmul(X, w) + b #定义损失函数 def squared_loss(y_hat, y): #@save "" "均方损失" "" return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2 #定义优化算法 def sgd( params , lr, batch_size): #@save "" "小批量随机梯度下降" "" with torch.no_grad(): for param in params : param -= lr / batch_size * param.grad #朝着减少损失的方向更新我们的参数 param.grad.zero_()## 每次更新参数之后,都要清零张量的梯度 #此Tensor的梯度将累积到.grad属性中。 # 更新参数 #b.data.sub_(lr * b.grad) #w.data.sub_(lr * w.grad) #训练 #相同的训练过程几乎一遍又一遍地出现。 #迭代中,我们读取一个批量训练样本,并通过我们的模型来获得一组预测。 # 计算完成损失后,我们开始反向传播,每个存储参数的增量。 # 最后,我们调用优化算法来更新sgd模型参数。 # 4 初始化模型参数 #我们通过从均值为0、标准差为0.01的正态分布中采样随机数来初始化权重,支付重置为0。 w = torch.normal(0, 0.01, size=(2,1), requires_grad=True) b = torch.zeros(1, requires_grad=True) lr = 0.03 # num_epochs = 3 #迭代周期(epoch) batch_size 10 ci net = linreg loss = squared_loss for epoch in range(num_epochs): for X_i, y_i in data_iter(batch_size, x_features, y_labels): y_predict=net(X_i, w, b) l = loss(y_predict, y_i) # X和y的小批量损失 # 因为l形状是(batch_size,1),而不是一个标量。l中的所有元素被加到一起, # 并以此计算关于[w,b]的梯度 l=l.sum() l.backward() sgd([w, b], lr, batch_size) # 使用参数的梯度更新参数 with torch.no_grad(): train_l = loss(net(x_features, w, b), y_labels) print(f 'epoch {epoch + 1}, loss {float(train_l.mean()):f}' ) print(f 'w的估计误差: {true_w - w.reshape(true_w.shape)}' ) print(f 'b的估计误差: {true_b - b}' ) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | import numpy as np import torch from torch.utils import data from d2l import torch as d2l true_w = torch.tensor([2, -3.4]) true_b = 4.2 features, labels = d2l.synthetic_data(true_w, true_b, 1000) #读取数据集 def load_array(data_arrays, batch_size, is_train=True): #@save "" "构造一个PyTorch数据迭代器" "" 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) #定义模型 # nn是神经网络的缩写 from torch import nn #第一个指定输入特征形状,即2,第二个指定输出特征形状,特征输出形状为单个标量,故为1。 net = nn.Sequential(nn.Linear(2, 1)) #初始化模型参数 #权重参数应该从均值0、标准差为0.01的正态分配中随机采样,偏置参数将初始化为均匀。 net[0].weight.data.normal_(0, 0.01) #w net[0].bias.data.fill_(0) #b #定义损失函数 2 范数 loss = nn.MSELoss() #定义优化算法 trainer = torch.optim.SGD(net.parameters(), lr=0.03) #训练 '' ' 在每个迭代周期里,我们将完整遍历一次数据集(train_data),不停地获取一个小批量的输入和相应的标签 '' ' num_epochs = 3 for epoch in range(num_epochs): for X, y in data_iter: l = loss(net(X) ,y) #通过调用net(X)生成预测并计算损失l(前向传播)。 trainer.zero_grad() #clear l.backward() #通过进行逆向传播来计算最小值。 trainer.step() #通过调用优化器来更新模型参数。 l = loss(net(features), labels) #为了更好的快速训练效果,我们计算每个迭代周期后的损失,并将其打印出来监控训练过程。 print(f 'epoch {epoch + 1}, loss {l:f}' ) #比较获得的模型参数 w = net[0].weight.data print( 'w的估计误差:' , true_w - w.reshape(true_w.shape)) b = net[0].bias.data print( 'b的估计误差:' , true_b - b) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2020-09-21 NVIDIA Jetson Xavier NX 介绍 YOLOv4