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

歡迎訪問 生活随笔!

生活随笔

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

pytorch

梯度消失和梯度爆炸_知识干货-动手学深度学习-05 梯度消失和梯度爆炸以及Kaggle房价预测...

發(fā)布時間:2023/12/4 pytorch 73 豆豆
生活随笔 收集整理的這篇文章主要介紹了 梯度消失和梯度爆炸_知识干货-动手学深度学习-05 梯度消失和梯度爆炸以及Kaggle房价预测... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  • 梯度消失和梯度爆炸
  • 考慮到環(huán)境因素的其他問題
  • Kaggle房價預測
  • 梯度消失和梯度爆炸

    深度模型有關(guān)數(shù)值穩(wěn)定性的典型問題是消失(vanishing)和爆炸(explosion)。

    當神經(jīng)網(wǎng)絡(luò)的層數(shù)較多時,模型的數(shù)值穩(wěn)定性容易變差。

    PyTorch的默認隨機初始化

    隨機初始化模型參數(shù)的方法有很多。在線性回歸的簡潔實現(xiàn)中,我們使用torch.nn.init.normal_()使模型net的權(quán)重參數(shù)采用正態(tài)分布的隨機初始化方式。不過,PyTorch中nn.Module的模塊參數(shù)都采取了較為合理的初始化策略(不同類型的layer具體采樣的哪一種初始化方法的可參考源代碼),因此一般不用我們考慮。

    鏈接:https://github.com/pytorch/pytorch/tree/master/torch/nn/modules

    Xavier隨機初始化

    還有一種比較常用的隨機初始化方法叫作Xavier隨機初始化。 假設(shè)某全連接層的輸入個數(shù)為aa,輸出個數(shù)為bb,Xavier隨機初始化將使該層中權(quán)重參數(shù)的每個元素都隨機采樣于均勻分布

    它的設(shè)計主要考慮到,模型參數(shù)初始化后,每層輸出的方差不該受該層輸入個數(shù)影響,且每層梯度的方差也不該受該層輸出個數(shù)影響。

    考慮環(huán)境因素?

    協(xié)變量偏移

    這里我們假設(shè),雖然輸入的分布可能隨時間而改變,但是標記函數(shù),即條件分布P(y∣x)不會改變。雖然這個問題容易理解,但在實踐中也容易忽視。

    想想?yún)^(qū)分貓和狗的一個例子。我們的訓練數(shù)據(jù)使用的是貓和狗的真實的照片,但是在測試時,我們被要求對貓和狗的卡通圖片進行分類。

    ?

    顯然,這不太可能奏效。訓練集由照片組成,而測試集只包含卡通。在一個看起來與測試集有著本質(zhì)不同的數(shù)據(jù)集上進行訓練,而不考慮如何適應(yīng)新的情況,這是不是一個好主意。不幸的是,這是一個非常常見的陷阱。

    統(tǒng)計學家稱這種協(xié)變量變化是因為問題的根源在于特征分布的變化(即協(xié)變量的變化)。數(shù)學上,我們可以說P(x)改變了,但P(y∣x)保持不變。盡管它的有用性并不局限于此,當我們認為x導致y時,協(xié)變量移位通常是正確的假設(shè)。

    標簽偏移

    當我們認為導致偏移的是標簽P(y)上的邊緣分布的變化,但類條件分布是不變的P(x∣y)時,就會出現(xiàn)相反的問題。當我們認為y導致x時,標簽偏移是一個合理的假設(shè)。例如,通常我們希望根據(jù)其表現(xiàn)來預測診斷結(jié)果。在這種情況下,我們認為診斷引起的表現(xiàn),即疾病引起的癥狀。有時標簽偏移和協(xié)變量移位假設(shè)可以同時成立。例如,當真正的標簽函數(shù)是確定的和不變的,那么協(xié)變量偏移將始終保持,包括如果標簽偏移也保持。有趣的是,當我們期望標簽偏移和協(xié)變量偏移保持時,使用來自標簽偏移假設(shè)的方法通常是有利的。這是因為這些方法傾向于操作看起來像標簽的對象,這(在深度學習中)與處理看起來像輸入的對象(在深度學習中)相比相對容易一些。

    病因(要預測的診斷結(jié)果)導致 癥狀(觀察到的結(jié)果)。

    訓練數(shù)據(jù)集,數(shù)據(jù)很少只包含流感p(y)的樣本。

    而測試數(shù)據(jù)集有流感p(y)和流感q(y),其中不變的是流感癥狀p(x|y)。

    概念偏移

    另一個相關(guān)的問題出現(xiàn)在概念轉(zhuǎn)換中,即標簽本身的定義發(fā)生變化的情況。這聽起來很奇怪,畢竟貓就是貓。的確,貓的定義可能不會改變,但我們能不能對軟飲料也這么說呢?事實證明,如果我們周游美國,按地理位置轉(zhuǎn)移數(shù)據(jù)來源,我們會發(fā)現(xiàn),即使是如圖所示的這個簡單術(shù)語的定義也會發(fā)生相當大的概念轉(zhuǎn)變。

    Kaggle 房價預測實戰(zhàn)?

    作為深度學習基礎(chǔ)篇章的總結(jié),我們將對本章內(nèi)容學以致用。下面,讓我們動手實戰(zhàn)一個Kaggle比賽:房價預測。本節(jié)將提供未經(jīng)調(diào)優(yōu)的數(shù)據(jù)的預處理、模型的設(shè)計和超參數(shù)的選擇。我們希望讀者通過動手操作、仔細觀察實驗現(xiàn)象、認真分析實驗結(jié)果并不斷調(diào)整方法,得到令自己滿意的結(jié)果。

    %matplotlib inline import torch import torch.nn as nn import numpy as np import pandas as pd import sys sys.path.append("/home/kesci/input") import d2lzh1981 as d2l print(torch.__version__) torch.set_default_tensor_type(torch.FloatTensor)#設(shè)置默認值

    獲取和讀取數(shù)據(jù)集

    比賽數(shù)據(jù)分為訓練數(shù)據(jù)集和測試數(shù)據(jù)集。兩個數(shù)據(jù)集都包括每棟房子的特征,如街道類型、建造年份、房頂類型、地下室狀況等特征值。這些特征值有連續(xù)的數(shù)字、離散的標簽甚至是缺失值“na”。只有訓練數(shù)據(jù)集包括了每棟房子的價格,也就是標簽。我們可以訪問比賽網(wǎng)頁,點擊“Data”標簽,并下載這些數(shù)據(jù)集。

    我們將通過pandas庫讀入并處理數(shù)據(jù)。在導入本節(jié)需要的包前請確保已安裝pandas庫。 假設(shè)解壓后的數(shù)據(jù)位于/home/kesci/input/houseprices2807/目錄,它包括兩個csv文件。下面使用pandas讀取這兩個文件

    test_data = pd.read_csv("/home/kesci/input/houseprices2807/house-prices-advanced-regression-techniques/test.csv") train_data = pd.read_csv("/home/kesci/input/houseprices2807/house-prices-advanced-regression-techniques/train.csv")#訓練數(shù)據(jù)集包括1460個樣本、80個特征和1個標簽。 train_data.shape #(1460, 81)#查看前4個樣本的前4個特征、后2個特征和標簽(SalePrice): train_data.iloc[0:4, [0, 1, 2, 3, -3, -2, -1]]

    可以看到第一個特征是Id,它能幫助模型記住每個訓練樣本,但難以推廣到測試樣本,所以我們不使用它來訓練。我們將所有的訓練數(shù)據(jù)和測試數(shù)據(jù)的79個特征按樣本連結(jié)。

    all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:])) #(2919, 79)

    預處理數(shù)據(jù)

    我們對連續(xù)數(shù)值的特征做標準化(standardization):設(shè)該特征在整個數(shù)據(jù)集上的均值為μ,標準差為σ。那么,我們可以將該特征的每個值先減去μ再除以σ得到標準化后的每個特征值。對于缺失的特征值,我們將其替換成該特征的均值。

    numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index #參考鏈接:https://pandas.pydata.org/pandas-#docs/stable/reference/api/pandas.DataFrame.dtypes.html?#highlight=dtypes#pandas.DataFrame.dtypes all_features[numeric_features] = all_features[numeric_features].apply(lambda x: (x - x.mean()) / (x.std())) # 標準化后,每個數(shù)值特征的均值變?yōu)?,所以可以直接用0來替換缺失值 all_features[numeric_features] = all_features[numeric_features].fillna(0) #Fill NA/NaN values using the specified method.

    接下來將離散數(shù)值轉(zhuǎn)成指示特征。舉個例子,假設(shè)特征MSZoning里面有兩個不同的離散值RL和RM,那么這一步轉(zhuǎn)換將去掉MSZoning特征,并新加兩個特征MSZoning_RL和MSZoning_RM,其值為0或1。如果一個樣本原來在MSZoning里的值為RL,那么有MSZoning_RL=1且MSZoning_RM=0。

    # dummy_na=True將缺失值也當作合法的特征值并為其創(chuàng)建指示特征 all_features = pd.get_dummies(all_features, dummy_na=True) #Convert categorical variable into dummy/indicator variables. all_features.shape#(2919, 331) #可以看到這一步轉(zhuǎn)換將特征數(shù)從79增加到了331。 #最后,通過values屬性得到NumPy格式的數(shù)據(jù),并轉(zhuǎn)成Tensor方便后面的訓練。 n_train = train_data.shape[0] train_features = torch.tensor(all_features[:n_train].values, dtype=torch.float) test_features = torch.tensor(all_features[n_train:].values, dtype=torch.float) train_labels = torch.tensor(train_data.SalePrice.values, dtype=torch.float).view(-1, 1)#訓練模型 loss = torch.nn.MSELoss()def get_net(feature_num):net = nn.Linear(feature_num, 1)for param in net.parameters():nn.init.normal_(param, mean=0, std=0.01)return net

    ??def log_rmse(net, features, labels):with torch.no_grad():# 將小于1的值設(shè)成1,使得取對數(shù)時數(shù)值更穩(wěn)定clipped_preds = torch.max(net(features), torch.tensor(1.0))rmse = torch.sqrt(2 * loss(clipped_preds.log(), labels.log()).mean())#感覺寫的有點問題return rmse.item()#下面的訓練函數(shù)跟本章中前幾節(jié)的不同在于使用了Adam優(yōu)化算法。相對之前使用的小批量隨機梯度下降,它對學習率相對不那么敏感。我們將在之后的“優(yōu)化算法”一章里詳細介紹它。def train(net, train_features, train_labels, test_features, test_labels,num_epochs, learning_rate, weight_decay, batch_size):train_ls, test_ls = [], []#定義訓練和測試的loss值dataset = torch.utils.data.TensorDataset(train_features, train_labels)train_iter = torch.utils.data.DataLoader(dataset, batch_size, shuffle=True)# 這里使用了Adam優(yōu)化算法optimizer = torch.optim.Adam(params=net.parameters(), lr=learning_rate, weight_decay=weight_decay) net = net.float()for epoch in range(num_epochs):for X, y in train_iter:l = loss(net(X.float()), y.float())optimizer.zero_grad()l.backward()optimizer.step()train_ls.append(log_rmse(net, train_features, train_labels))if test_labels is not None:test_ls.append(log_rmse(net, test_features, test_labels))return train_ls, test_ls

    K折交叉驗證

    我們在模型選擇、欠擬合和過擬合中介紹了K折交叉驗證。它將被用來選擇模型設(shè)計并調(diào)節(jié)超參數(shù)。下面實現(xiàn)了一個函數(shù),它返回第i折交叉驗證時所需要的訓練和驗證數(shù)據(jù)。

    def get_k_fold_data(k, i, X, y):# 返回第i折交叉驗證時所需要的訓練和驗證數(shù)據(jù)assert k > 1fold_size = X.shape[0] // kX_train, y_train = None, Nonefor j in range(k):#這里面還定義了一個循環(huán),用來取數(shù)據(jù)idx = slice(j * fold_size, (j + 1) * fold_size)X_part, y_part = X[idx, :], y[idx]if j == i:#當相等的時候就是驗證集X_valid, y_valid = X_part, y_partelif X_train is None:#第一次不等的時候就是訓練X_train, y_train = X_part, y_partelse:#第2次以及之后不等的時候,就累加測試集X_train = torch.cat((X_train, X_part), dim=0)y_train = torch.cat((y_train, y_part), dim=0)return X_train, y_train, X_valid, y_valid# 在K折交叉驗證中我們訓練K次并返回訓練和驗證的平均誤差 def k_fold(k, X_train, y_train, num_epochs,learning_rate, weight_decay, batch_size):train_l_sum, valid_l_sum = 0, 0for i in range(k):data = get_k_fold_data(k, i, X_train, y_train)net = get_net(X_train.shape[1])train_ls, valid_ls = train(net, *data, num_epochs, learning_rate,weight_decay, batch_size)train_l_sum += train_ls[-1]valid_l_sum += valid_ls[-1]if i == 0:d2l.semilogy(range(1, num_epochs + 1), train_ls, 'epochs', 'rmse',range(1, num_epochs + 1), valid_ls,['train', 'valid'])print('fold %d, train rmse %f, valid rmse %f' % (i, train_ls[-1], valid_ls[-1]))return train_l_sum / k, valid_l_sum / k#輸出train 和 test的loss

    模型選擇

    我們使用一組未經(jīng)調(diào)優(yōu)的超參數(shù)并計算交叉驗證誤差。可以改動這些超參數(shù)來盡可能減小平均測試誤差。 有時候你會發(fā)現(xiàn)一組參數(shù)的訓練誤差可以達到很低,但是在KK折交叉驗證上的誤差可能反而較高。這種現(xiàn)象很可能是由過擬合造成的。因此,當訓練誤差降低時,我們要觀察KK折交叉驗證上的誤差是否也相應(yīng)降低。

    k, num_epochs, lr, weight_decay, batch_size = 5, 100, 5, 0, 64 train_l, valid_l = k_fold(k, train_features, train_labels, num_epochs, lr, weight_decay, batch_size) print('%d-fold validation: avg train rmse %f, avg valid rmse %f' % (k, train_l, valid_l))

    預測并在Kaggle中提交結(jié)果

    下面定義預測函數(shù)。在預測之前,我們會使用完整的訓練數(shù)據(jù)集來重新訓練模型,并將預測結(jié)果存成提交所需要的格式。

    def train_and_pred(train_features, test_features, train_labels, test_data,num_epochs, lr, weight_decay, batch_size):net = get_net(train_features.shape[1])train_ls, _ = train(net, train_features, train_labels, None, None,num_epochs, lr, weight_decay, batch_size)d2l.semilogy(range(1, num_epochs + 1), train_ls, 'epochs', 'rmse')print('train rmse %f' % train_ls[-1])preds = net(test_features).detach().numpy()test_data['SalePrice'] = pd.Series(preds.reshape(1, -1)[0])submission = pd.concat([test_data['Id'], test_data['SalePrice']], axis=1)submission.to_csv('./submission.csv', index=False)# sample_submission_data = pd.read_csv("../input/house-prices-advanced-regression-techniques/sample_submission.csv")#設(shè)計好模型并調(diào)好超參數(shù)之后,下一步就是對測試數(shù)據(jù)集上的房屋樣本做價格預測。如果我們得到與交叉驗證時差不多的訓練誤差, #那么這個結(jié)果很可能是理想的,可以在Kaggle上提交結(jié)果。 train_and_pred(train_features, test_features, train_labels, test_data, num_epochs, lr, weight_decay, batch_size)

    歡迎大家指正和留言評論

    總結(jié)

    以上是生活随笔為你收集整理的梯度消失和梯度爆炸_知识干货-动手学深度学习-05 梯度消失和梯度爆炸以及Kaggle房价预测...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。