午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

用Pytorch構建第一個神經網絡模型(附案例實戰(zhàn))

 山峰云繞 2023-04-01 發(fā)布于貴州

https://m.toutiao.com/is/AfE658m/ 


目錄

一、Pytorch簡介

二、實驗過程

2.1數據集介紹

2.2加載數據

2.3數據預處理

2.3.1特征轉換

2.3.2缺失值處理

2.3.3樣本不平衡處理

2.4特征工程

2.4.1劃分訓練集和測試集

2.4.2數據類型轉換

2.5構建模型

2.5.1可視化神經元

2.5.2激活函

2.5.3訓練神經網絡

2.6保存模型

2.7模型評估

2.8模型預測

三、總結


一、Pytorch簡介

PyTorch是一個基于python的科學計算包,主要針對兩類人群:

作為NumPy的替代品,可以利用GPU的性能進行計算

作為一個高靈活性、速度快的深度學習平臺

在PyTorch中搭建神經網絡并使用真實的天氣信息預測明天是否會下雨。

預處理 CSV 文件并將數據轉換為張量

PyTorch是一個基于python的科學計算包,主要針對兩類人群:

作為NumPy的替代品,可以利用GPU的性能進行計算

作為一個高靈活性、速度快的深度學習平臺

在PyTorch中搭建神經網絡并使用真實的天氣信息預測明天是否會下雨。

預處理 CSV 文件并將數據轉換為張量

使用 PyTorch 構建神經網絡模型

使用 PyTorch 構建神經網絡模型

使用損失函數和優(yōu)化器來訓練模型

評估模型并了解分類不平衡的危害

在開始構建神經網絡之前,首先了解一下幾個重要概念。

torch.Tensor

一個多維數組,支持諸如backward()等的自動求導操作,同時也保存了張量的梯度。

nn.Module

神經網絡模塊。是一種方便封裝參數的方式,具有將參數移動到GPU、導出、加載等功能。

nn.Parameter

張量的一種,當它作為一個屬性分配給一個Module時,它會被自動注冊為一個參數。

autograd.Function

實現了自動求導前向和反向傳播的定義,每個Tensor至少創(chuàng)建一個Function節(jié)點,該節(jié)點連接到創(chuàng)建Tensor的函數并對其歷史進行編碼。

二、實驗過程

2.1數據集介紹

數據集包含來自多個澳大利亞氣象站的每日天氣信息。本次目標是要回答一個簡單的問題:明天會下雨嗎?

2.2加載數據

首先導入本次實驗用到的第三方庫

import torch import osimport numpy as npimport pandas as pdfrom tqdm import tqdmimport seaborn as snsfrom pylab import rcParamsimport matplotlib.pyplot as pltfrom matplotlib import rcfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import confusion_matrix, classification_reportfrom torch import nn, optimimport torch.nn.functional as F %matplotlib inline%config InlineBackend.figure_format='retina' sns.set(style='whitegrid', palette='muted', font_scale=1.2)HAPPY_COLORS_PALETTE = ['#01BEFE', '#FFDD00', '#FF7D00', '#FF006D', '#93D30C', '#8F00FF']sns.set_palette(sns.color_palette(HAPPY_COLORS_PALETTE))rcParams['figure.figsize'] = 12, 6RANDOM_SEED = 42np.random.seed(RANDOM_SEED)torch.manual_seed(RANDOM_SEED)

接下來先通過Pandas讀取導入數據集

df = pd.read_csv('./data/weatherAUS.csv')df.head()

這里有很多特征列。也有很多NaN。下面來看看整體數據集大小。

df.shape

(145460, 23)

從數據集形狀看,這里數據還不少,超過14.5w條數據。

2.3數據預處理

在數據預處理這,我們并不希望數據集和目標問題有多復雜,嘗試將通過刪除大部分數據來簡化這個問題。這里只使用4個特征來預測明天是否會下雨。在你實際案例中,根據實際問題,特征數量可以比這多,也可以比這少,只要注意下面輸入數據維度即可。

cols = ['Rainfall', 'Humidity3pm', 'Pressure9am', 'RainToday', 'RainTomorrow']df = df[cols]

2.3.1特征轉換

因為神經網絡只能處理數字。所以我們將把文字的 yes 和 no 分別轉換為數字1 和 0。

df['RainToday'].replace({'No': 0, 'Yes': 1}, inplace = True)df['RainTomorrow'].replace({'No': 0, 'Yes': 1}, inplace = True)

2.3.2缺失值處理

刪除缺少值的行。也許會有更好的方法來處理這些缺失的行,但我們這里將簡單地處理,直接刪除含有缺失值的行。

df = df.dropna(how='any')df.head()

2.3.3樣本不平衡處理

到目前為止,我們有了一個可以使用的數據集。這里我們需要回答的一個重要問題是 -- 我們的數據集是否平衡? 或者 明天到底會下多少次雨?

因此通過sns.countplot函數直接定性分析整個樣本集中是否下雨分別多少次,以此判斷正負樣本(是否有雨)是否平衡。

sns.countplot(df.RainTomorrow);

從結果看,下雨次數明顯比不下雨次數要少很多。再通過具體定量計算正負樣本數。

df.RainTomorrow.value_counts() / df.shape[0]

0.0 0.778762

1.0 0.221238

Name: RainTomorrow, dtype: float64

事情看起來不妙。約78%的數據點表示明天不會下雨。這意味著一個預測明天是否下雨的模型在78%的時間里是正確的。

如果想要解決此次樣本不平衡可以采用欠采樣或過采樣處理,以緩解其帶來的影響,我們暫不做任何處理,但愿他對結果影響不大。

2.4特征工程

2.4.1劃分訓練集和測試集

數據預處理的最后一步是將數據分割為訓練集和測試集。這一步大家應該并不陌生,可以直接使用train_test_split()。

X = df[['Rainfall', 'Humidity3pm', 'RainToday', 'Pressure9am']]y = df[['RainTomorrow']]X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=RANDOM_SEED)

2.4.2數據類型轉換

為了符合 PyTorch 所需求的數據類型。使用 python標準庫將數據加載到numpy數組里。然后將這個數組轉化成將全部數據轉換為張量(torch.Tensor)。

注意:Torch張量和NumPy數組將共享它們的底層內存位置,因此當一個改變時,另外也會改變。

X_train.head()

PyTorch中也是非常方便,直接通過from_numpy直接轉換。

X_train = torch.from_numpy(X_train.to_numpy()).float()y_train = torch.squeeze(torch.from_numpy(y_train.to_numpy()).float())X_test = torch.from_numpy(X_test.to_numpy()).float()y_test = torch.squeeze(torch.from_numpy(y_test.to_numpy()).float())print(X_train.shape, y_train.shape)print(X_test.shape, y_test.shape)

torch.Size([99751, 4]) torch.Size([99751])
torch.Size([24938, 4]) torch.Size([24938])

到目前為止,所有數據準備工作已經結束。

2.5構建模型

接下來我們將使用PyTorch建立一個簡單的神經網絡(NN),嘗試預測明天是否會下雨。本次構建的神經網絡結構分為三個層,輸入層、輸出層和隱藏層。

輸入層: 我們的輸入包含四列數據:'Rainfall, Humidity3pm, RainToday, Pressure9am'(降雨量,濕度下午3點,今天下雨,壓力上午9點)。將為此創(chuàng)建一個適當的輸入層。

輸出層: 輸出將是一個介于 0 和 1 之間的數字,代表模型認為明天下雨的可能性。預測將由網絡的輸出層提供給我們。

隱藏層: 將在輸入層和輸出層之間添加兩個隱藏層。這些層的參數(神經元)將決定最終輸出。所有層都將是全連接的,即全連接層。

一個神經網絡的典型訓練過程如下

定義包含一些可學習參數(或者叫權重)的神經網絡

在輸入數據集上迭代

通過網絡處理輸入

計算loss(輸出和正確答案的距離)

將梯度反向傳播給網絡的參數

更新網絡的權重,一般使用一個簡單的規(guī)則:weight = weight - learning_rate * gradient

可以使用torch.nn包來構建神經網絡。即使用 PyTorch 構建神經網絡的一種簡單方法是創(chuàng)建一個繼承自 torch.nn.Module 的類。

這里將nn.Module子類化(它本身是一個類并且能夠跟蹤狀態(tài))。在這種情況下,我們要創(chuàng)建一個類,該類包含前進步驟的權重,偏差和方法。nn.Module具有許多我們將要使用的屬性和方法(例如.parameters()和.zero_grad())。

class Net(nn.Module):     def __init__(self, n_features):        super(Net, self).__init__()        self.fc1 = nn.Linear(n_features, 5)        self.fc2 = nn.Linear(5, 3)        self.fc3 = nn.Linear(3, 1)     def forward(self, x):        x = F.relu(self.fc1(x))        x = F.relu(self.fc2(x))        return torch.sigmoid(self.fc3(x))

我們只需要定義 forward 函數,backward函數會在使用autograd時自動定義,backward函數用來計算導數。我們可以在 forward 函數中使用任何針對張量的操作和計算。

2.5.1可視化神經元

這里的可視化神經元主要基于
https://github.com/Prodicode/ann-visualizer

net = Net(X_train.shape[1])# pip install graphviz# mac上安裝graphviz 需要用 brew install graphviz ann_viz(net, view=True)

我們首先在構造函數中創(chuàng)建模型的層。forward()方法是奇跡發(fā)生的地方。它接受輸入 并允許它流過每一層。有一個相應的由PyTorch定義到向后傳遞backward()方法,它允許模型從當前發(fā)生的誤差中學習,并修正模型參數。

2.5.2激活函數

細心的小伙伴可能會注意到構建的神經網絡中調用 F.relu 和 torch.sigmoid 。這些是激活函數,那我們?yōu)槭裁葱枰@些?

神經網絡的一個很酷的特性是它們可以近似非線性函數。事實上,已經證明它們可以逼近任何函數。不過,如果想通過堆疊線性層來逼近非線性函數,此時就需要激活函數。激活函數可以讓神經網絡擺脫線性世界并學習更多。通常將其應用于某個層的輸出。

ReLU

從最廣泛使用的激活函數之一的 ReLU 定義開始:

該激活函數簡單易行,其結果就是輸入值與零比較,得到的最大值。

從可視化結果看

ax = plt.gca()plt.plot(  np.linspace(-1, 1, 5),   F.relu(torch.linspace(-1, 1, steps=5)).numpy())ax.set_ylim([-1.5, 1.5]);

Sigmoid

它被定義為:

當需要進行二元決策 / 分類(回答yes或no)時,sigmoid 函數是很有用的。sigmoid 以一種超級的方式將輸入值壓縮在 0 和 1 之間。

從可視化結果看

ax = plt.gca() plt.plot( np.linspace(-10, 10, 100), torch.sigmoid(torch.linspace(-10, 10, steps=100)).numpy())ax.set_ylim([-0.5, 1.5]);

2.5.3訓練神經網絡

目前為止,我們已經看到了如何定義網絡,接下來需要找到預測明天是否會下雨的參數。即需要找到該模型應用于此次問題的最佳參數。而要想做到這點,首先需要一些評價指標來告訴我們,該模型目前做得有多好。接下來需要計算損失,并更新網絡的權重。

損失函數

一個損失函數接受一對(output, target)作為輸入,計算一個值來估計網絡的輸出和目標值相差多少。BCELoss是一個損失函數,其度量兩個向量之間的差。

criterion = nn.BCELoss()

而在我們的例子中,這兩個向量即是我們的模型的預測和實際值。該損失函數的期望值由 sigmoid 函數輸出。該值越接近 0,模型效果越好。

但是我們如何找到最小化損失函數的參數呢?

優(yōu)化器

假設我們的神經網絡的每個參數都是一個旋鈕。優(yōu)化器的工作是為每個旋鈕找到完美的位置,使損失接近0。實戰(zhàn)中,模型可能包含數百萬甚至數十億個參數。有這么多旋鈕要轉,如果有一個高效的優(yōu)化器可以快速找到解決方案,那就完美了。而理想很豐滿,現實很骨感。深度學習中的優(yōu)化效果只能達到令人滿意的結果。在實踐中,可以提供可接受的準確性的足夠好的參數,就應該心滿意足了。在使用神經網絡時,PyTorch中提供了許多經過良好調試過的優(yōu)化器,可能希望使用各種不同的更新規(guī)則,如SGD、Nesterov-SGD、Adam、RMSProp等。雖然你可以從這些優(yōu)化器中選擇,一般情況下,首選的還是Adam。

optimizer = optim.Adam(net.parameters(), lr=0.001)

一個模型的可學習參數可以通過net.parameters()。

自然地,優(yōu)化器需要輸入參數。第二個參數lr 是 learning rate (學習率),這是要找到的最優(yōu)參數和到達最優(yōu)解的速度之間的權衡。而為此找到最優(yōu)解的方法或過程可能是黑魔法和大量的暴力“實驗”。

在 GPU 上計算

在 GPU 上進行大規(guī)模并行計算是現代深度學習的推動因素之一。為此,您將需要配置 NVIDIA GPU。如果你的設備上裝有GPU,PyTorch 中可以非常輕松地將所有計算傳輸到 GPU。

我們首先檢查 CUDA 設備是否可用。然后,我們將所有訓練和測試數據傳輸到該設備。最后移動模型和損失函數。張量可以使用.to方法移動到任何設備(device)上。

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') X_train = X_train.to(device)y_train = y_train.to(device) X_test = X_test.to(device)y_test = y_test.to(device) net = net.to(device)criterion = criterion.to(device)

尋找最優(yōu)參數

擁有損失函數固然很好,追蹤模型的準確性是一件更容易理解的事情,而一般通過定義準確性來做模型評價。

def calculate_accuracy(y_true, y_pred):predicted = y_pred.ge(.5).view(-1)return (y_true == predicted).sum().float() / len(y_true)

我們定義一個預值,將連續(xù)概率值轉換為二分類值。即將每個低于 0.5 的值轉換為 0,高于0.5的值設置為 1。最后計算正確值的百分比。所有的模塊都準備好了,我們可以開始訓練我們的模型了。

def round_tensor(t, decimal_places=3):    return round(t.item(), decimal_places) for epoch in range(1000):        y_pred = net(X_train)    y_pred = torch.squeeze(y_pred)    train_loss = criterion(y_pred, y_train)        if epoch % 100 == 0:        train_acc = calculate_accuracy(y_train, y_pred)         y_test_pred = net(X_test)        y_test_pred = torch.squeeze(y_test_pred)         test_loss = criterion(y_test_pred, y_test)        test_acc = calculate_accuracy(y_test, y_test_pred)        print(f'''epoch {epoch}              Train set - loss: {round_tensor(train_loss)}, accuracy: {round_tensor(train_acc)}              Test  set - loss: {round_tensor(test_loss)}, accuracy: {round_tensor(test_acc)}              ''')        optimizer.zero_grad()  # 清零梯度緩存    train_loss.backward() # 反向傳播誤差    optimizer.step()  # 更新參數

在訓練期間,我們向模型傳輸數據共計10,000次。每次測量損失時,將誤差傳播到模型中,并要求優(yōu)化器找到更好的參數。用 zero_grad() 方法清零所有參數的梯度緩存,然后進行隨機梯度的反向傳播。如果忽略了這一步,梯度將會累積,導致模型不可用。測試集上的準確率為 83.4% 聽起來挺合理,但可能要讓你失望了,這樣的結果并不是很理想,接下來看看是如何不合理。但首先我們需要學習如何保存和加載訓練好的模型。

2.6保存模型

訓練一個好的模型可能需要很多時間??赡苁菐字堋讉€月甚至幾年。如果在訓練過程了忘記保存,或不知道需要保存模型,這將會是非常痛苦的事情。因此這里需要確保我們知道如何保存寶貴的工作。其實保存很容易,但你不能忘記這件事。

MODEL_PATH = 'model.pth' # 后綴名為 .pthtorch.save(net, MODEL_PATH) # 直接使用torch.save()函數即可

當然恢復模型也很容易,直接使用 torch.load() 函數即可。

net = torch.load(MODEL_PATH)

2.7模型評估

如果知道你的模型會犯什么樣的錯誤不是很好嗎?當然,這一點是非常難做到的。但是你可以通過一定的方法得到一個估計值。而僅使用準確性來評估并不是一個好方法,尤其在樣本不平衡的二分類數據集上。仔細回想一下,我們的數據是一個很不平衡的數據集,其幾乎不包含明天會降雨樣本。深入研究模型性能的一種方法是評估每個類的精確度和召回率。在我們的例子中,將是結果標簽分別是 no rain 和 rain 。

classes = ['No rain', 'Raining']y_pred = net(X_test)y_pred = y_pred.ge(.5).view(-1).cpu()y_test = y_test.cpu()print(classification_report(y_test, y_pred, target_names=classes))

精確度最大值為1,表明該模型只適用于識別相關的樣本。召回率最大值為1,表示模型可以在這個類的數據集中找到所有相關的示例??梢钥吹侥P驮跓o雨類方面表現良好,因為樣本中無雨類樣本數量較大。不幸的是,我們不能完全相信有雨類的預測,因為樣本不平衡導致模型傾向于無雨類。可以通過查看一個簡單的混淆矩陣來評估二分類效果。

cm = confusion_matrix(y_test, y_pred)df_cm = pd.DataFrame(cm, index=classes, columns=classes)hmap = sns.heatmap(df_cm, annot=True, fmt='d')hmap.yaxis.set_ticklabels(hmap.yaxis.get_ticklabels(), rotation=0, ha='right')hmap.xaxis.set_ticklabels(hmap.xaxis.get_ticklabels(), rotation=30, ha='right')plt.ylabel('True label')plt.xlabel('Predicted label');

你可以清楚地看到,當我們的模型預測要下雨時,我們應該抱有懷疑的態(tài)度。

2.8模型預測

使用一些假設的例子上測試下模型。

def will_it_rain(rainfall, humidity, rain_today, pressure):t = torch.as_tensor([rainfall, humidity, rain_today, pressure]) \.float() \.to(device)output = net(t)return output.ge(0.5).item()

這個函數將根據模型預測返回一個布爾值。讓我們試試看:

will_it_rain(rainfall=10, humidity=10,rain_today=True, pressure=2)>>> True
will_it_rain(rainfall=0, humidity=1,rain_today=False, pressure=100)>>> False

根據一些參數得到了兩種不同的返回值。到這里為止,模型已準備好部署來,但實際情況下,請不要匆忙部署,因為該模型并不是一個最佳的狀態(tài),只是用來掩飾如何使用PyTorch搭建模型!

三、總結

如果你看到這里,將給你點個贊!因為你現在成功搭建了一個可以預測天氣的神經網絡深度學習模型。雖然此次用PyTorch搭建的深度學習模型是一個入門級別的模型,但其他更加復雜的神經網絡模型的核心步驟與此類似。

說實話,構建性能良好的模型真的很難,但在多次搭建模型過程中,你會不斷學到一些技巧,并能夠不斷進步,這將會幫助你以后做的更好。

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多