<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          保姆級(jí)教程,用PyTorch搭一個(gè)神經(jīng)網(wǎng)絡(luò)

          共 10537字,需瀏覽 22分鐘

           ·

          2022-05-23 14:29

          PyTorch是一個(gè)基于python的科學(xué)計(jì)算包,主要針對(duì)兩類人群:
          • 作為NumPy的替代品,可以利用GPU的性能進(jìn)行計(jì)算
          • 作為一個(gè)高靈活性、速度快的深度學(xué)習(xí)平臺(tái)

          在PyTorch中搭建神經(jīng)網(wǎng)絡(luò)并使用真實(shí)的天氣信息預(yù)測(cè)明天是否會(huì)下雨。

          • 預(yù)處理 CSV 文件并將數(shù)據(jù)轉(zhuǎn)換為張量
          • 使用 PyTorch 構(gòu)建神經(jīng)網(wǎng)絡(luò)模型
          • 使用損失函數(shù)和優(yōu)化器來訓(xùn)練模型
          • 評(píng)估模型并了解分類不平衡的危害

          寫在前面

          在開始構(gòu)建神經(jīng)網(wǎng)絡(luò)之前,首先了解一下幾個(gè)重要概念。

          • torch.Tensor
            一個(gè)多維數(shù)組,支持諸如backward()等的自動(dòng)求導(dǎo)操作,同時(shí)也保存了張量的梯度。
          • nn.Module
            神經(jīng)網(wǎng)絡(luò)模塊。是一種方便封裝參數(shù)的方式,具有將參數(shù)移動(dòng)到GPU、導(dǎo)出、加載等功能。
          • nn.Parameter
            張量的一種,當(dāng)它作為一個(gè)屬性分配給一個(gè)Module時(shí),它會(huì)被自動(dòng)注冊(cè)為一個(gè)參數(shù)。
          • autograd.Function
            實(shí)現(xiàn)了自動(dòng)求導(dǎo)前向和反向傳播的定義,每個(gè)Tensor至少創(chuàng)建一個(gè)Function節(jié)點(diǎn),該節(jié)點(diǎn)連接到創(chuàng)建Tensor的函數(shù)并對(duì)其歷史進(jìn)行編碼。

          導(dǎo)入相關(guān)模塊

          #?pip?install?torch
          import?torch

          import?os
          import?numpy?as?np
          import?pandas?as?pd
          from?tqdm?import?tqdm
          import?seaborn?as?sns
          from?pylab?import?rcParams
          import?matplotlib.pyplot?as?plt
          from?matplotlib?import?rc
          from?sklearn.model_selection?import?train_test_split
          from?sklearn.metrics?import?confusion_matrix,?classification_report
          from?torch?import?nn,?optim
          import?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,?6
          RANDOM_SEED?=?42
          np.random.seed(RANDOM_SEED)
          torch.manual_seed(RANDOM_SEED)


          數(shù)據(jù)集

          我們的數(shù)據(jù)集包含來自多個(gè)澳大利亞氣象站的每日天氣信息。本次目標(biāo)是要回答一個(gè)簡(jiǎn)單的問題:明天會(huì)下雨嗎?

          數(shù)據(jù)集來自Kaggle[文末參考鏈接2]接下來先通過Pandas讀取導(dǎo)入數(shù)據(jù)集。

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

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

          df.shape
          (145460, 23)

          從數(shù)據(jù)集形狀看,這里數(shù)據(jù)還不少,超過14.5w條數(shù)據(jù)。


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

          本節(jié)中,我們并不希望數(shù)據(jù)集和目標(biāo)問題有多復(fù)雜,嘗試將通過刪除大部分?jǐn)?shù)據(jù)來簡(jiǎn)化這個(gè)問題。這里只使用4個(gè)特征來預(yù)測(cè)明天是否會(huì)下雨。在你實(shí)際案例中,根據(jù)實(shí)際問題,特征數(shù)量可以比這多,也可以比這少,只要注意下面輸入數(shù)據(jù)維度即可。

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

          特征轉(zhuǎn)換

          因?yàn)樯窠?jīng)網(wǎng)絡(luò)只能處理數(shù)字。所以我們將把文字的?yes 和 no?分別轉(zhuǎn)換為數(shù)字1 和 0。

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

          缺失值處理

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

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

          樣本不平衡處理

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

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

          sns.countplot(df.RainTomorrow);

          從結(jié)果看,下雨次數(shù)明顯比不下雨次數(shù)要少很多。再通過具體定量計(jì)算正負(fù)樣本數(shù)。

          df.RainTomorrow.value_counts()?/?df.shape[0]
          0.0    0.778762
          1.0 0.221238
          Name: RainTomorrow, dtype: float64

          事情看起來不妙。約78%的數(shù)據(jù)點(diǎn)表示明天不會(huì)下雨。這意味著一個(gè)預(yù)測(cè)明天是否下雨的模型在78%的時(shí)間里是正確的。

          如果想要解決此次樣本不平衡,以緩解其帶來的影響,可以參考云朵君先前文章機(jī)器學(xué)習(xí)中樣本不平衡,怎么辦?而這里,我們暫不做任何處理,但愿他對(duì)結(jié)果影響不大。

          樣劃分訓(xùn)練集和測(cè)試集

          數(shù)據(jù)預(yù)處理的最后一步是將數(shù)據(jù)分割為訓(xùn)練集和測(cè)試集。這一步大家應(yīng)該并不陌生,可以直接使用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)

          數(shù)據(jù)類型轉(zhuǎn)換

          為了符合 PyTorch 所需求的數(shù)據(jù)類型。使用 python標(biāo)準(zhǔn)庫(kù)將數(shù)據(jù)加載到numpy數(shù)組里。然后將這個(gè)數(shù)組轉(zhuǎn)化成將全部數(shù)據(jù)轉(zhuǎn)換為張量(torch.Tensor)

          注意:Torch張量和NumPy數(shù)組將共享它們的底層內(nèi)存位置,因此當(dāng)一個(gè)改變時(shí),另外也會(huì)改變。

          X_train.head()

          PyTorch中也是非常方便,直接通過from_numpy直接轉(zhuǎn)換。

          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])

          到目前為止,所有數(shù)據(jù)準(zhǔn)備工作已經(jīng)結(jié)束。


          構(gòu)建神經(jīng)網(wǎng)絡(luò)

          接下來我們將使用PyTorch建立一個(gè)簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)(NN),嘗試預(yù)測(cè)明天是否會(huì)下雨。本次構(gòu)建的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)分為三個(gè)層,輸入層、輸出層和隱藏層

          輸入層:?我們的輸入包含四列數(shù)據(jù):"Rainfall, Humidity3pm, RainToday, Pressure9am"(降雨量,濕度下午3點(diǎn),今天下雨,壓力上午9點(diǎn))。將為此創(chuàng)建一個(gè)適當(dāng)?shù)妮斎雽印?/p>

          輸出層:?輸出將是一個(gè)介于 0 和 1 之間的數(shù)字,代表模型認(rèn)為明天下雨的可能性。預(yù)測(cè)將由網(wǎng)絡(luò)的輸出層提供給我們。

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

          一個(gè)神經(jīng)網(wǎng)絡(luò)的典型訓(xùn)練過程如下:

          • 定義包含一些可學(xué)習(xí)參數(shù)(或者叫權(quán)重)的神經(jīng)網(wǎng)絡(luò)
          • 在輸入數(shù)據(jù)集上迭代
          • 通過網(wǎng)絡(luò)處理輸入
          • 計(jì)算loss(輸出和正確答案的距離)
          • 將梯度反向傳播給網(wǎng)絡(luò)的參數(shù)
          • 更新網(wǎng)絡(luò)的權(quán)重,一般使用一個(gè)簡(jiǎn)單的規(guī)則:weight = weight - learning_rate * gradient

          可以使用torch.nn包來構(gòu)建神經(jīng)網(wǎng)絡(luò)。即使用 PyTorch 構(gòu)建神經(jīng)網(wǎng)絡(luò)的一種簡(jiǎn)單方法是創(chuàng)建一個(gè)繼承自?torch.nn.Module?的類。

          這里將nn.Module子類化(它本身是一個(gè)類并且能夠跟蹤狀態(tài))。在這種情況下,我們要?jiǎng)?chuàng)建一個(gè)類,該類包含前進(jìn)步驟的權(quán)重,偏差和方法。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 函數(shù),backward函數(shù)會(huì)在使用autograd時(shí)自動(dòng)定義,backward函數(shù)用來計(jì)算導(dǎo)數(shù)。我們可以在 forward 函數(shù)中使用任何針對(duì)張量的操作和計(jì)算。

          可視化神經(jīng)元

          這里的可視化神經(jīng)元主要基于https://github.com/Prodicode/ann-visualizer,完整神經(jīng)網(wǎng)絡(luò)可視化獲取方式:公眾號(hào)「機(jī)器學(xué)習(xí)研習(xí)院」消息框回復(fù) 【神經(jīng)網(wǎng)絡(luò)可視化】獲取

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

          我們首先在構(gòu)造函數(shù)中創(chuàng)建模型的層。forward()方法是奇跡發(fā)生的地方。它接受輸入??并允許它流過每一層。

          有一個(gè)相應(yīng)的由PyTorch定義到向后傳遞backward()方法,它允許模型從當(dāng)前發(fā)生的誤差中學(xué)習(xí),并修正模型參數(shù)。

          激活函數(shù)

          細(xì)心的讀者可能會(huì)注意到構(gòu)建的神經(jīng)網(wǎng)絡(luò)中調(diào)用?F.relu?和?torch.sigmoid?。這些是激活函數(shù),那我們?yōu)槭裁葱枰@些?

          神經(jīng)網(wǎng)絡(luò)的一個(gè)很酷的特性是它們可以近似非線性函數(shù)。事實(shí)上,已經(jīng)證明它們可以逼近任何函數(shù)[3]

          不過,如果想通過堆疊線性層來逼近非線性函數(shù),此時(shí)就需要激活函數(shù)。激活函數(shù)可以讓神經(jīng)網(wǎng)絡(luò)擺脫線性世界并學(xué)習(xí)更多。通常將其應(yīng)用于某個(gè)層的輸出。

          ReLU

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

          該激活函數(shù)簡(jiǎn)單易行,其結(jié)果就是輸入值與零比較,得到的最大值。

          從可視化結(jié)果看

          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

          它被定義為

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

          從可視化結(jié)果看

          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]);


          訓(xùn)練神經(jīng)網(wǎng)絡(luò)


          目前為止,我們已經(jīng)看到了如何定義網(wǎng)絡(luò),接下來需要找到預(yù)測(cè)明天是否會(huì)下雨的參數(shù)。即需要找到該模型應(yīng)用于此次問題的最佳參數(shù)。而要想做到這點(diǎn),首先需要一些評(píng)價(jià)指標(biāo)來告訴我們,該模型目前做得有多好。

          接下來需要計(jì)算損失,并更新網(wǎng)絡(luò)的權(quán)重。

          損失函數(shù)

          一個(gè)損失函數(shù)接受一對(duì)(output, target)作為輸入,計(jì)算一個(gè)值來估計(jì)網(wǎng)絡(luò)的輸出和目標(biāo)值相差多少。BCELoss[4]是一個(gè)損失函數(shù),其度量?jī)蓚€(gè)向量之間的差。

          criterion?=?nn.BCELoss()

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

          但是我們?nèi)绾握业阶钚』瘬p失函數(shù)的參數(shù)呢?

          優(yōu)化器

          假設(shè)我們的神經(jīng)網(wǎng)絡(luò)的每個(gè)參數(shù)都是一個(gè)旋鈕。優(yōu)化器的工作是為每個(gè)旋鈕找到完美的位置,使損失接近0。

          實(shí)戰(zhàn)中,模型可能包含數(shù)百萬甚至數(shù)十億個(gè)參數(shù)。有這么多旋鈕要轉(zhuǎn),如果有一個(gè)高效的優(yōu)化器可以快速找到解決方案,那就完美了。

          而理想很豐滿,現(xiàn)實(shí)很骨感。深度學(xué)習(xí)中的優(yōu)化效果只能達(dá)到令人滿意的結(jié)果。在實(shí)踐中,可以提供可接受的準(zhǔn)確性的足夠好的參數(shù),就應(yīng)該心滿意足了。

          在使用神經(jīng)網(wǎng)絡(luò)時(shí),PyTorch中提供了許多經(jīng)過良好調(diào)試過的優(yōu)化器,可能希望使用各種不同的更新規(guī)則,如SGD、Nesterov-SGD、Adam、RMSProp等。雖然你可以從這些優(yōu)化器中選擇,一般情況下,首選的還是Adam[5]

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

          一個(gè)模型的可學(xué)習(xí)參數(shù)可以通過net.parameters()

          自然地,優(yōu)化器需要輸入?yún)?shù)。第二個(gè)參數(shù)lr?是?learning rate?(學(xué)習(xí)率),這是要找到的最優(yōu)參數(shù)和到達(dá)最優(yōu)解的速度之間的權(quán)衡。而為此找到最優(yōu)解的方法或過程可能是黑魔法和大量的暴力“實(shí)驗(yàn)”。

          在 GPU 上計(jì)算

          在 GPU 上進(jìn)行大規(guī)模并行計(jì)算是現(xiàn)代深度學(xué)習(xí)的推動(dòng)因素之一。為此,您將需要配置 NVIDIA GPU。

          如果你的設(shè)備上裝有GPU,PyTorch 中可以非常輕松地將所有計(jì)算傳輸?shù)?GPU。

          我們首先檢查 CUDA 設(shè)備是否可用。然后,我們將所有訓(xùn)練和測(cè)試數(shù)據(jù)傳輸?shù)皆撛O(shè)備。最后移動(dòng)模型和損失函數(shù)。

          張量可以使用.to方法移動(dòng)到任何設(shè)備(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)參數(shù)

          擁有損失函數(shù)固然很好,追蹤模型的準(zhǔn)確性是一件更容易理解的事情,而一般通過定義準(zhǔn)確性來做模型評(píng)價(jià)。

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

          我們定義一個(gè)預(yù)值,將連續(xù)概率值轉(zhuǎn)換為二分類值。即將每個(gè)低于 0.5 的值轉(zhuǎn)換為 0,高于0.5的值設(shè)置為 1。最后計(jì)算正確值的百分比。

          所有的模塊都準(zhǔn)備好了,我們可以開始訓(xùn)練我們的模型了。

          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()??#?更新參數(shù)
          epoch 0
          Train set - loss: 0.94, accuracy: 0.779
          Test set - loss: 0.94, accuracy: 0.778

          epoch 100
          Train set - loss: 0.466, accuracy: 0.78
          Test set - loss: 0.466, accuracy: 0.779
          ...
          epoch 900
          Train set - loss: 0.41, accuracy: 0.833
          Test set - loss: 0.408, accuracy: 0.834

          在訓(xùn)練期間,我們向模型傳輸數(shù)據(jù)共計(jì)10,000次。每次測(cè)量損失時(shí),將誤差傳播到模型中,并要求優(yōu)化器找到更好的參數(shù)。

          用?zero_grad()?方法清零所有參數(shù)的梯度緩存,然后進(jìn)行隨機(jī)梯度的反向傳播。如果忽略了這一步,梯度將會(huì)累積,導(dǎo)致模型不可用。

          測(cè)試集上的準(zhǔn)確率為 83.4% 聽起來挺合理,但可能要讓你失望了,這樣的結(jié)果并不是很理想,接下來看看是如何不合理。

          但首先我們需要學(xué)習(xí)如何保存和加載訓(xùn)練好的模型。


          保存模型

          訓(xùn)練一個(gè)好的模型可能需要很多時(shí)間。可能是幾周、幾個(gè)月甚至幾年。如果在訓(xùn)練過程了忘記保存,或不知道需要保存模型,這將會(huì)是非常痛苦的事情。因此這里需要確保我們知道如何保存寶貴的工作。其實(shí)保存很容易,但你不能忘記這件事。

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

          當(dāng)然恢復(fù)模型也很容易,直接使用?torch.load()?函數(shù)即可。

          net?=?torch.load(MODEL_PATH)


          評(píng)估


          如果知道你的模型會(huì)犯什么樣的錯(cuò)誤不是很好嗎?當(dāng)然,這一點(diǎn)是非常難做到的。但是你可以通過一定的方法得到一個(gè)估計(jì)值。而僅使用準(zhǔn)確性來評(píng)估并不是一個(gè)好方法,尤其在樣本不平衡的二分類數(shù)據(jù)集上。仔細(xì)回想一下,我們的數(shù)據(jù)是一個(gè)很不平衡的數(shù)據(jù)集,其幾乎不包含明天會(huì)降雨樣本。

          深入研究模型性能的一種方法是評(píng)估每個(gè)類的精確度和召回率。在我們的例子中,將是結(jié)果標(biāo)簽分別是?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))
                       precision  recall f1-score support

          No rain 0.84 0.97 0.90 19413
          Raining 0.76 0.37 0.50 5525

          accuracy 0.83 24938
          macro avg 0.80 0.67 0.70 24938
          weighted avg 0.82 0.83 0.81 24938

          精確度最大值為1,表明該模型只適用于識(shí)別相關(guān)的樣本。召回率最大值為1,表示模型可以在這個(gè)類的數(shù)據(jù)集中找到所有相關(guān)的示例。

          可以看到模型在無雨類方面表現(xiàn)良好,因?yàn)闃颖局袩o雨類樣本數(shù)量較大。不幸的是,我們不能完全相信有雨類的預(yù)測(cè),因?yàn)闃颖静黄胶鈱?dǎo)致模型傾向于無雨類。

          可以通過查看一個(gè)簡(jiǎn)單的混淆矩陣來評(píng)估二分類效果。

          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');

          你可以清楚地看到,當(dāng)我們的模型預(yù)測(cè)要下雨時(shí),我們應(yīng)該抱有懷疑的態(tài)度。


          模型預(yù)測(cè)

          使用一些假設(shè)的例子上測(cè)試下模型。

          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()

          這個(gè)函數(shù)將根據(jù)模型預(yù)測(cè)返回一個(gè)布爾值。讓我們?cè)囋嚳矗?/p>

          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

          根據(jù)一些參數(shù)得到了兩種不同的返回值。到這里為止,模型已準(zhǔn)備好部署來,但實(shí)際情況下,請(qǐng)不要匆忙部署,因?yàn)樵撃P筒⒉皇且粋€(gè)最佳的狀態(tài),只是用來掩飾如何使用PyTorch搭建模型!

          寫在最后


          如果你看到這里,將給你點(diǎn)個(gè)贊!因?yàn)槟悻F(xiàn)在成功搭建了一個(gè)可以預(yù)測(cè)天氣的神經(jīng)網(wǎng)絡(luò)深度學(xué)習(xí)模型。雖然此次用PyTorch搭建的深度學(xué)習(xí)模型是一個(gè)入門級(jí)別的模型,但其他更加復(fù)雜的神經(jīng)網(wǎng)絡(luò)模型的核心步驟與此類似。

          說實(shí)話,構(gòu)建性能良好的模型真的很難,但在多次搭建模型過程中,你會(huì)不斷學(xué)到一些技巧,并能夠不斷進(jìn)步,這將會(huì)幫助你以后做的更好。

          參考資料

          [1]?

          參考原文:?https://curiousily.com/posts/build-your-first-neural-network-with-pytorch/

          [2]?

          Kaggle:?https://www.kaggle.com/jsphyg/weather-dataset-rattle-package

          [3]?

          已經(jīng)證明它們可以逼近任何函數(shù):?https://en.wikipedia.org/wiki/Universal_approximation_theorem

          [4]?

          BCELoss:?https://pytorch.org/docs/stable/nn.html#bceloss

          [5]?

          Adam:?https://pytorch.org/docs/stable/optim.html#torch.optim.Adam

          瀏覽 76
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久人人爽人人爽人人片 | 伊人网伊人网 | www.黄色大片 | 国产1区2区3区 | 国产成人麻豆精品午夜在线 |