日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

08 线性回归 + 基础优化算法【动手学深度学习v2】

發布時間:2024/4/13 pytorch 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 08 线性回归 + 基础优化算法【动手学深度学习v2】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

線性回歸



輸出層不當成一層 輸入層和權重層放一起



x和y是列向量

因為loss=1/2(y-y_hat)^2
又因為y_hat的平均值=1/n(xi*w+b)=1/n(Xw+b)

唯一一個有顯示解的模型

基礎優化方法

不但更新w
負梯度:下降最快的方向 即圖中負梯度的方向
n:學習率 表示我沿著這個方向每次走多遠
類似下山的時候每次沿著最陡的地方走一大步 這樣很快就可以到山低

學習率太小需要走很多步 計算很多次梯度
學習率太大會震蕩 錯過 并不是真正的在下降


從零開始實現整個方法,包括數據流水線、模型。損失函數和小批量隨機梯度下降優化器。

import random import torch import matplotlib.pyplot as plt # from d2l import torch as d2ldef sy_data(w,b,num_examples):# 生成y=Xw+b+噪音 X中n行有w列X = torch.normal(0, 1, (num_examples, len(w)))y = torch.matmul(X, w)+b# Xw的內積+by += torch.normal(0, 0.01, y.shape)# 再加一個均值為0 方差為0.01的噪音print(X,y,y.reshape((-1, 1)))# 一個形狀尺寸可以為-1。在這種情況下,該值是根據數組的長度和其余維來推斷的。 1表示1列,是列向量return X, y.reshape((-1, 1))true_w = torch.tensor([2, -3.4]) true_b = 4.2 features, labels = sy_data(true_w, true_b, 1000) print('features:', features[0], '\nlabel:', labels[0])# a=plt.scatter(features[:, 1].detach().numpy(), # labels.detach().numpy(), 1); # print(a) ''' features: tensor([1.1566, 0.7321]) label: tensor([4.0169]) '''# 接受批量大小 特征矩陣和標簽向量作為輸入 生成batch_size的小批量 def data_iter(batch_size, features, labels):num_examples = len(features)indices = list(range(num_examples))# 生成數字0-999# 這些樣本隨機讀取 沒有特定順序random.shuffle(indices)print(random.shuffle(indices))for i in range(0, num_examples, batch_size):batch_indices = torch.tensor(indices[i:min(i + batch_size,num_examples)])# 間隔batch_size取數 賦予batch_indicse'''例如[248, 62, 699, 776, 517, 85, 90, 352, 545, 841]tensor([248, 62, 699, 776, 517, 85, 90, 352, 545, 841])'''print(indices[i:min(i + batch_size,num_examples)])print(batch_indices)yield features[batch_indices],labels[batch_indices]batch_size = 10for X, y in data_iter(batch_size, features, labels):print(X, y)break''' 選取樣本 X 10*2 因為batchsize=10 w=2 y 10*1 tensor([[-0.6701, 1.0900],[ 0.9038, -0.1050],[ 0.0928, 1.0312],[ 0.2287, -1.0536],[-0.5450, -0.8574],[-1.0709, -0.6346],[-0.4716, -0.9125],[ 1.1762, 1.4156],[-0.3838, 0.2382],[-1.1287, -0.0346]]) tensor([[-0.8472],[ 6.3714],[ 0.8639],[ 8.2421],[ 6.0209],[ 4.2200],[ 6.3587],[ 1.7371],[ 2.6191],[ 2.0615]])'''# 定義 初始化模型參數 w = torch.normal(0, 0.01, size=(2, 1), requires_grad=True) b = torch.zeros(1, requires_grad=True) print(w, b)# 定義模型 def line(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):# 更新時不要梯度 params是參數列表 [w,b]with torch.no_grad():for p in params:p -= lr*p.grad/batch_size# 因為在損失函數中沒有求均值 所以這里求均值# 手動設置梯度為0 這樣下一次就不會累積上一次的梯度p.grad.zero_()# 訓練過程 lr = 0.03 num_epochs = 3 #整個數據掃三遍 net = line loss = squared_lossfor epoch in range(num_epochs):# 每次處理批量大小的X和yfor X,y in data_iter(batch_size, features, labels):l = loss(net(X, w, b),y) #將X,w,b放進net中做預測,然后預測y與真實y做損失# 損失就是長為一個批量大小的向量(‘batch_size’,1)l.sum().backward() # 求和之后算梯度sgd([w, b], lr, batch_size) # 對w,b進行更新# 評價進度,不需要計算梯度with torch.no_grad():train_l = loss(net(features, w, b), 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}')''' 可以通過增大lr和epoch 使得loss變小 lr=0.03 epoch=3 epoch3, loss 14.084221 w的估計誤差:tensor([ 1.7688, -3.2452], grad_fn=<SubBackward0>) b的估計誤差:tensor([3.7988], grad_fn=<RsubBackward1>)lr=0.5 epoch=10 epoch10, loss 0.000207 w的估計誤差:tensor([-0.0082, -0.0007], grad_fn=<SubBackward0>) b的估計誤差:tensor([0.0150], grad_fn=<RsubBackward1>) '''

使用深度學習框架來簡潔地實現線性回歸模型生成數據集

import numpy as np import torch from torch.utils import data from d2l import torch as d2ltrue_w = torch.tensor([2, -3.4]) true_b = 4.2 features, labels = d2l.synthetic_data(true_w, true_b, 1000)# 調用框架中現有的API來讀取數據 def load_array(data_arrays, batch_size, is_train=True):"""構造一個pytorch數據迭代器"""dataset = data.TensorDataset(*data_arrays) # 將X和 y傳進去# 得到數據集之后調用DataLoader# shuffle:是不是需要隨機打亂順序return data.DataLoader(dataset, batch_size, shuffle=is_train)batch_size = 10 data_iter = load_array((features, labels), batch_size)print(next(iter(data_iter))) # 得到x和y# 使用框架的預定義好的層 from torch import nnnet = nn.Sequential(nn.Linear(2, 1)) # 輸入和輸出的維度# 初始化模型參數 # net[0]訪問linear,.weight訪問w,.data真實值,normal_使用正態分布替換掉data值 print(net[0].weight.data.normal_(0, 0.01)) # bias偏差設置為0 print(net[0].bias.data.fill_(0))# 計算均方誤差使用的是MSELoss類(L2范數) loss = nn.MSELoss()# 實例化SGD實例 # net.parameters():所有的參數 trainer = torch.optim.SGD(net.parameters(), lr=0.03)# 訓練過程 num_epochs = 3 # 三次 for epoch in range(num_epochs):for X, y in data_iter:l = loss(net(X), y) # net本身帶有模型參數trainer.zero_grad() # 梯度清零l.backward()trainer.step() # 模型更新l = loss(net(features), labels)print(f'epoch{epoch + 1}, loss {l:f}')

問題答疑:

  • 關于神經網絡 我們是通過誤差反饋修改參數

  • batchsize越小收斂越小 一定的噪音使得網絡不會偏 泛化性更好

  • 針對batchsize大小的數據集進行網絡訓練的時候,網絡中每個參數更新時的減去的梯度是batchsize中每個樣本對應參數梯度求和后取得的平均值

  • 隨機梯度下降的‘隨機’指的是在樣本中隨機采集batchsize大小個的元素

  • 統計模型和優化模型 我關心的是收斂到哪 不是收斂快不快

  • 使用yield而不是return 是因為每次生成一個batchsize接著生成就好,還有就是因為習慣

  • 如果樣本大小不是批量數的整數倍,那需要隨機剔除多余的樣本
    嗎?答:如果是1000=個樣本 batchsize=60 (1)就取剩下的40個(2)丟掉剩下的40個(3)從下一個epoch再補20個

  • 判斷收斂?1用驗證數據集看其梯度有沒有增加 2看兩個epoch直接目標函數已經變化不大了就表示收斂了

  • 本質上我們為什么要用SGD(隨機梯度下降),是因為大部分的實際loss太復雜,推導不出導數為0的解么?只能逐個batch去逼近? 答:是的

總結

以上是生活随笔為你收集整理的08 线性回归 + 基础优化算法【动手学深度学习v2】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。