
目錄第一步 準備數據第二步 設計模型第三步 構造損失函數和優化器1、損失函數2、優化器第四步 訓練過程第五步 測試模型代碼作業Adagrad優化器1、介紹2、代碼y_hat w * x b第一步 準備數據采用minibatch風格的梯度下降的算法利用pytorch的廣播機制因此X,Y必須是矩陣3×1的向量w矩陣的維度要根據 X 和 Y 的維度來確定第二步 設計模型重點是構造計算圖想要構造w和b的維度形狀需要知道輸入x和輸出y_hat的維度因為X,Y都以張量的形式計算所以計算出的loss也是張量的形式因此需要對 loss_i 求和再根據需要決定是不是要求均值所有模型類一定要繼承于Module必須要實現__init__構造函數和forward前饋網絡兩個函數繼承于Module類會自動實現 backward() 的過程class torch.nn.Linear(in_features, out_features, biasTure)超參數不可訓練但可配置1in_features --每一個輸入的特征樣本x的維度2out_features --每一個輸出的特征樣本y的維度3bias --指定是否需要偏置值b可訓練的參數1weight --學習權重矩陣形狀是out_features×in_features2bias --偏置向量形狀是out_featuresself.linear torch.nn.Linear(11) 是一個對象其中包含權重w和偏置值b兩個張量因此可以使用linear來自動實現這樣一個計算linear也繼承自Module因此也可以自動進行反向傳播注意in_features 和out_features是指每一個特征樣本x或y的維度例如在一元線性回歸中輸入為x輸出為y所以值為in_features 1out_features1,此時輸入X的形狀為[batchsizein_features][n1]Y的形狀為[n1]W的形狀為1×1b的形狀為1×1在多元線性回歸中輸入為x1,x2,x3輸出為y所以值為in_features 3out_features1此時輸入X的形狀為[batchsizein_features][n3]Y的形狀為[n1]W的形狀為1×3b的形狀為1×1。self.linear(x)是一個可以調用的對象其作用是完成線性函數的計算得到y_predmodel LinearModel()中 model也是一個可以調用的對象第三步 構造損失函數和優化器1、損失函數類classtorch.nn.MSELoss(size_averageTrue, reduceTrue)MSELoss也是繼承于nn.Modulesize_average -- 是不是要對所有樣本的Loss求均值一般設置為Falsereduce -- 最后是不是要把得到的Loss向量降維也就是求和一般不管對象criterion是這個類的一個可調用對象核心方法就是__call__需要的參數是y_hat和y用于求Loss2、優化器類classtorch.optim.SGD(params, lrobject object, momentum0, dampening0, weight_decay0, nesterovFalse)params就是指權重Model里面沒有定義權重只有一個Linear成員這個成員包含兩個權重model.parameters()會檢查model中的所有成員取得Linear的權重是通過調用linear.parameters如果成員里面有相應的權重它就把這些都加入到要訓練的參數集合里面lr是學習率對象optimizer就是一個優化器對象它知道自己要優化哪些參數也知道學習率optimizer對象的核心方法方法作用是否需要參數optimizer.zero_grad()清零所有參數的梯度? 不需要optimizer.step()用梯度更新所有參數? 不需要optimizer.param_groups查看參數組調試用? 不需要注意雖然這里的優化器是SGD但這段代碼算法實際是BGD。這是因為 PyTorch偷懶。torch.optim.SGD這個類名它具體執行的是 SGD、BGD 還是 Mini-batch SGD完全不取決于優化器本身而是取決于傳給它的 數據批次大小Batch Size如果把所有數據一次性喂進去如你的代碼 →就是 BGD。如果把1個樣本喂進去 →就是純 SGD。如果把32個樣本喂進去Mini-batch →就是 Mini-batch SGD工業界最常用大家平時口頭說的“SGD”通常指這個。第四步 訓練過程print(loss)時會自動調用loss.__str__()不會產生計算圖.step()會根據每個參數的梯度和更新每次backward求梯度之前要把之前的梯度清零第五步 測試模型前面的步驟已經將模型訓練好了重新創建一個tensor張量x_test輸入給模型得到輸出y_test model(x_test)—— 執行預測前向傳播model(x_test)實際上會調用model.__call__()方法而__call__()方法內部會自動調用forward()所以model的參數應該與forward()傳入的參數一樣也就是x代碼import torch import matplotlib.pyplot as plt x_data torch.Tensor([[1.0], [2.0], [3.0]]) y_data torch.Tensor([[2.0], [4.0], [6.0]]) class LinearModel(torch.nn.Module): def __init__(self): super(LinearModel, self).__init__() self.linear torch.nn.Linear(1, 1) def forward(self, x): y_pred self.linear(x) return y_pred model LinearModel() criterion torch.nn.MSELoss(size_averageFalse) optimizer torch.optim.SGD(model.parameters(), lr0.01) for epoch in range(100): y_pred model(x_data) loss criterion(y_pred, y_data) print(epoch, loss.item()) optimizer.zero_grad() loss.backward() optimizer.step() print(w , model.linear.weight.item()) print(b ,model.linear.bias.item()) x_test torch.Tensor([[4.0]]) y_test model(x_test) plt.plot(range(1, 101, 1), loss_list) plt.xlabel(epoch) plt.ylabel(Loss) plt.show() print(y_pred , y_test.data)運行結果w 1.7945618629455566 b 0.4670093357563019y_pred tensor([[7.6134]])作業Adagrad優化器1、介紹傳統 SGD優化器所有參數用同一個學習率但是有些參數更新頻繁有些很少用同一個學習率不合理。Adagrad中每個參數有自己的學習率。更新頻繁的參數學習率自動變小更新稀少的參數學習率自動變大數學公式為# 累計梯度平方和歷史信息G G (梯度)2# 參數更新公式w w - (lr / (√G ε)) * 梯度torch.optim.Adagrad(params, # 要優化的參數必需lr0.01, # 學習率默認 0.01lr_decay0, # 學習率衰減默認 0weight_decay0, # L2 正則化默認 0eps1e-10, # 防止除零默認 1e-10initial_accumulator_value0 # G 的初始值默認 0)2、代碼只需將optimizer torch.optim.SGD(model.parameters(), lr0.01)改為optimizer torch.optim.Adagrad( model.parameters(), lr0.01, # 學習率 weight_decay0.001 # 可以加 L2 正則化 )運行結果w 0.6798529624938965 b 1.0155056715011597 y_pred tensor([[3.7349]])