首頁 > 軟體

PyTorch 之 強大的 hub 模組和搭建神經網路進行氣溫預測

2023-03-21 06:01:13

本文參加新星計劃人工智慧(Pytorch)賽道:https://bbs.csdn.net/topics/613989052

一、強大的 hub 模組

1. hub 模組的使用

首先,我們進入網址。會出現如下的介面(這其中就是別人訓練好的模型,我們通過一行程式碼就可以實現呼叫)。

然後,我們隨便點開一個模型,會出現如下介面。

其中,第一個按鈕是對應的 GITHUB 程式碼,第二個是使用谷歌設定好的實驗環境,第三個進行模型演示。

2. hub 模組的程式碼演示

首先,我們進行基本的匯入。

import torch
model = torch.hub.load('pytorch/vision:v0.4.2', 'deeplabv3_resnet101', pretrained=True)
model.eval()

我們可以使用 hub.list() 檢視對應 pytorch 版本的模型資訊。

torch.hub.list('pytorch/vision:v0.4.2')
#Using cache found in C:UsersAdministrator/.cachetorchhubpytorch_vision_v0.4.2
#['alexnet',
# 'deeplabv3_resnet101',
# 'densenet121',
# 'densenet161',
# 'densenet169',
# 'densenet201',
# 'fcn_resnet101',
# 'googlenet',
# 'inception_v3',
# 'mobilenet_v2',
# 'resnet101',
# 'resnet152',
# 'resnet18',
# 'resnet34',
# 'resnet50',
# 'resnext101_32x8d',
# 'resnext50_32x4d',
# 'shufflenet_v2_x0_5',
# 'shufflenet_v2_x1_0',
# 'squeezenet1_0',
# 'squeezenet1_1',
# 'vgg11',
# 'vgg11_bn',
# 'vgg13',
# 'vgg13_bn',
# 'vgg16',
# 'vgg16_bn',
# 'vgg19',
# 'vgg19_bn',
# 'wide_resnet101_2',
# 'wide_resnet50_2']

我們可以從 pytorch 的網站上下載一個範例。

# Download an example image from the pytorch website
import urllib
url, filename = ("https://github.com/pytorch/hub/raw/master/dog.jpg", "dog.jpg")
try: urllib.URLopener().retrieve(url, filename)
except: urllib.request.urlretrieve(url, filename)

我們執行樣本,這裡需要注意的是 torchvision。

# sample execution (requires torchvision)
from PIL import Image
from torchvision import transforms
input_image = Image.open(filename)
preprocess = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
​
input_tensor = preprocess(input_image)
input_batch = input_tensor.unsqueeze(0) # create a mini-batch as expected by the model

我們需要將輸入和模型移動到GPU以獲得速度(如果可用)。

# move the input and model to GPU for speed if available
if torch.cuda.is_available():
    input_batch = input_batch.to('cuda')
    model.to('cuda')
​
with torch.no_grad():
    output = model(input_batch)['out'][0]
output_predictions = output.argmax(0)

我們可以建立一個調色盤,為每個類選擇一種顏色。

# create a color pallette, selecting a color for each class
palette = torch.tensor([2 ** 25 - 1, 2 ** 15 - 1, 2 ** 21 - 1])
colors = torch.as_tensor([i for i in range(21)])[:, None] * palette
colors = (colors % 255).numpy().astype("uint8")

我們可以使用 hub 模組中的模型繪製每種顏色 21 個類別的語意分割預測。​

# plot the semantic segmentation predictions of 21 classes in each color
r = Image.fromarray(output_predictions.byte().cpu().numpy()).resize(input_image.size)
r.putpalette(colors)
​
import matplotlib.pyplot as plt
plt.imshow(r)
plt.show()

二、搭建神經網路進行氣溫預測

1. 資料資訊處理 在最開始,我們需要匯入必備的庫。

import numpy as np
import pandas as pd 
import matplotlib.pyplot as plt
import torch
import torch.optim as optim
import warnings
warnings.filterwarnings("ignore")
%matplotlib inline

我們需要觀察一下自己的資料都有哪些資訊,在此之前,我們需要進行資料的讀入,並列印資料的前五行進行觀察。

features = pd.read_csv('temps.csv')
features.head()
#year	month	day	week	temp_2	temp_1	average	actual	friend
#0	2016	1	1	Fri	45	45	45.6	45	29
#1	2016	1	2	Sat	44	45	45.7	44	61
#2	2016	1	3	Sun	45	44	45.8	41	56
#3	2016	1	4	Mon	44	41	45.9	40	53
#4	2016	1	5	Tues	41	40	46.0	44	41
  • 在我們的資料表中,包含如下資料資訊:
  • (1) year 表示年數時間資訊。
  • (2) month 表示月數時間資訊。
  • (3) day 表示天數時間資訊。
  • (4) week 表示週數時間資訊。
  • (5) temp_2 表示前天的最高溫度值。
  • (6) temp_1 表示昨天的最高溫度值。
  • (7) average 表示在歷史中,每年這一天的平均最高溫度值。
  • (8) actual 表示這就是我們的標籤值了,當天的真實最高溫度。
  • (9) friend 表示這一列可能是湊熱鬧的,你的朋友猜測的可能值,咱們不管它就好了。
  • 在獲悉每一個資料的資訊之後,我們需要知道一共有多少個資料。

print('資料維度:', features.shape)
#資料維度: (348, 9)
  • (348, 9) 表示一共有 348 天,每一天有 9 個資料特徵。
  • 對於這麼多的資料,直接進行行和列的操作可能會不太容易,因此,我們可以匯入時間資料模組,將其轉換為標準的時間資訊。
# 處理時間資料
import datetime
​
# 分別得到年,月,日
years = features['year']
months = features['month']
days = features['day']
​
# datetime格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]

我們可以讀取新列 dates 中的部分資料。

dates[:5]
#[datetime.datetime(2016, 1, 1, 0, 0),
# datetime.datetime(2016, 1, 2, 0, 0),
# datetime.datetime(2016, 1, 3, 0, 0),
# datetime.datetime(2016, 1, 4, 0, 0),
# datetime.datetime(2016, 1, 5, 0, 0)]

2. 資料圖畫繪製

在基本資料處理完成後,我們就開始圖畫的繪製,在最開始,需要指定為預設的風格。

plt.style.use('fivethirtyeight')

設定佈局資訊。

# 設定佈局
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, figsize = (10,10))
fig.autofmt_xdate(rotation = 45)

設定標籤值資訊。

#標籤值
ax1.plot(dates, features['actual'])
ax1.set_xlabel(''); ax1.set_ylabel('Temperature'); ax1.set_title('Max Temp')

繪製昨天也就是 temp_1 的資料圖畫。​

# 昨天
ax2.plot(dates, features['temp_1'])
ax2.set_xlabel(''); ax2.set_ylabel('Temperature'); ax2.set_title('Previous Max Temp')

繪製前天也就是 temp_2 的資料圖畫。​

# 前天
ax3.plot(dates, features['temp_2'])
ax3.set_xlabel('Date'); ax3.set_ylabel('Temperature'); ax3.set_title('Two Days Prior Max Temp')

繪製朋友也就是 friend 的資料圖畫。

# 我的逗逼朋友
ax4.plot(dates, features['friend'])
ax4.set_xlabel('Date'); ax4.set_ylabel('Temperature'); ax4.set_title('Friend Estimate')

在上述資訊設定完成後,開始圖畫的繪製。

plt.tight_layout(pad=2)

對原始資料中的資訊進行編碼,這裡主要是指週數資訊。

# 獨熱編碼
features = pd.get_dummies(features)
features.head(5)
#year	month	day	temp_2	temp_1	average	actual	friend	week_Fri	week_Mon	week_Sat	week_Sun	week_Thurs	week_Tues	week_Wed
#0	2016	1	1	45	45	45.6	45	29	1	0	0	0	0	0	0
#1	2016	1	2	44	45	45.7	44	61	0	0	1	0	0	0	0
#2	2016	1	3	45	44	45.8	41	56	0	0	0	1	0	0	0
#3	2016	1	4	44	41	45.9	40	53	0	1	0	0	0	0	0
#4	2016	1	5	41	40	46.0	44	41	0	0	0	0	0	1	0

在週數資訊編碼完成後,我們將準確值進行標籤操作,在特徵資料中去掉標籤資料,並將此時資料特徵中的標籤資訊儲存一下,並將其轉換成合適的格式。

# 標籤
labels = np.array(features['actual'])
​
# 在特徵中去掉標籤
features= features.drop('actual', axis = 1)
​
# 名字單獨儲存一下,以備後患
feature_list = list(features.columns)
​
# 轉換成合適的格式
features = np.array(features)

我們可以檢視此時特徵資料的具體數量。

features.shape
#(348, 14)
  • (348, 14) 表示我們的特徵資料當中一共有 348 個,每一個有 14 個特徵。
  • 我們可以檢視第一個的具體資料。
from sklearn import preprocessing
input_features = preprocessing.StandardScaler().fit_transform(features)
input_features[0]
#array([ 0.        , -1.5678393 , -1.65682171, -1.48452388, -1.49443549,
#       -1.3470703 , -1.98891668,  2.44131112, -0.40482045, -0.40961596,
#       -0.40482045, -0.40482045, -0.41913682, -0.40482045])

3. 構建網路模型

x = torch.tensor(input_features, dtype = float)
​
y = torch.tensor(labels, dtype = float)
​
# 權重引數初始化
weights = torch.randn((14, 128), dtype = float, requires_grad = True) 
biases = torch.randn(128, dtype = float, requires_grad = True) 
weights2 = torch.randn((128, 1), dtype = float, requires_grad = True) 
biases2 = torch.randn(1, dtype = float, requires_grad = True) 
​
learning_rate = 0.001 
losses = []
​
for i in range(1000):
    # 計算隱層
    hidden = x.mm(weights) + biases
    # 加入啟用函數
    hidden = torch.relu(hidden)
    # 預測結果
    predictions = hidden.mm(weights2) + biases2
    # 通計算損失
    loss = torch.mean((predictions - y) ** 2) 
    losses.append(loss.data.numpy())
    
    # 列印損失值
    if i % 100 == 0:
        print('loss:', loss)
    #返向傳播計算
    loss.backward()
    
    #更新引數
    weights.data.add_(- learning_rate * weights.grad.data)  
    biases.data.add_(- learning_rate * biases.grad.data)
    weights2.data.add_(- learning_rate * weights2.grad.data)
    biases2.data.add_(- learning_rate * biases2.grad.data)
    
    # 每次迭代都得記得清空
    weights.grad.data.zero_()
    biases.grad.data.zero_()
    weights2.grad.data.zero_()
    biases2.grad.data.zero_()
​#loss: tensor(8347.9924, dtype=torch.float64, grad_fn=<MeanBackward0>)
#loss: tensor(152.3170, dtype=torch.float64, grad_fn=<MeanBackward0>)
#loss: tensor(145.9625, dtype=torch.float64, grad_fn=<MeanBackward0>)
#loss: tensor(143.9453, dtype=torch.float64, grad_fn=<MeanBackward0>)
#loss: tensor(142.8161, dtype=torch.float64, grad_fn=<MeanBackward0>)
#loss: tensor(142.0664, dtype=torch.float64, grad_fn=<MeanBackward0>)
#loss: tensor(141.5386, dtype=torch.float64, grad_fn=<MeanBackward0>)
#loss: tensor(141.1528, dtype=torch.float64, grad_fn=<MeanBackward0>)
#loss: tensor(140.8618, dtype=torch.float64, grad_fn=<MeanBackward0>)
#loss: tensor(140.6318, dtype=torch.float64, grad_fn=<MeanBackward0>)

我們檢視預測資料的具體數量,應該是一共有 348 個,每個只有一個值,也就是 (348,1)。

predictions.shape
#torch.Size([348, 1])

4. 更簡單的構建網路模型

input_size = input_features.shape[1]
hidden_size = 128
output_size = 1
batch_size = 16
my_nn = torch.nn.Sequential(
    torch.nn.Linear(input_size, hidden_size),
    torch.nn.Sigmoid(),
    torch.nn.Linear(hidden_size, output_size),
)
cost = torch.nn.MSELoss(reduction='mean')
optimizer = torch.optim.Adam(my_nn.parameters(), lr = 0.001)
# 訓練網路
losses = []
for i in range(1000):
    batch_loss = []
    # MINI-Batch方法來進行訓練
    for start in range(0, len(input_features), batch_size):
        end = start + batch_size if start + batch_size < len(input_features) else len(input_features)
        xx = torch.tensor(input_features[start:end], dtype = torch.float, requires_grad = True)
        yy = torch.tensor(labels[start:end], dtype = torch.float, requires_grad = True)
        prediction = my_nn(xx)
        loss = cost(prediction, yy)
        optimizer.zero_grad()
        loss.backward(retain_graph=True)
        optimizer.step()
        batch_loss.append(loss.data.numpy())
    
    # 列印損失
    if i % 100==0:
        losses.append(np.mean(batch_loss))
        print(i, np.mean(batch_loss))
#0 3950.7627
#100 37.9201
#200 35.654438
#300 35.278366
#400 35.116814
#500 34.986076
#600 34.868954
#700 34.75414
#800 34.637356
#900 34.516705

我們可以得到如下的預測訓練結果,將其用圖畫的形式展現出來。

x = torch.tensor(input_features, dtype = torch.float)
predict = my_nn(x).data.numpy()
# 轉換日期格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]
​
# 建立一個表格來存日期和其對應的標籤數值
true_data = pd.DataFrame(data = {'date': dates, 'actual': labels})
​
# 同理,再建立一個來存日期和其對應的模型預測值
months = features[:, feature_list.index('month')]
days = features[:, feature_list.index('day')]
years = features[:, feature_list.index('year')]
​
test_dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
​
test_dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in test_dates]
​
predictions_data = pd.DataFrame(data = {'date': test_dates, 'prediction': predict.reshape(-1)}) 
# 真實值
plt.plot(true_data['date'], true_data['actual'], 'b-', label = 'actual')
​
# 預測值
plt.plot(predictions_data['date'], predictions_data['prediction'], 'ro', label = 'prediction')
plt.xticks(rotation = '60'); 
plt.legend()
​
# 圖名
plt.xlabel('Date'); plt.ylabel('Maximum Temperature (F)'); plt.title('Actual and Predicted Values');

到此這篇關於PyTorch 之 強大的 hub 模組和搭建神經網路進行氣溫預測的文章就介紹到這了,更多相關PyTorch hub神經網路氣溫預測內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com