PyTorch实战1——预测未来某地区租赁单车的使用情况
傳送門:藍橋云課實驗
目錄
- 1. 實驗環境
- 2. 實驗目的
- 3. 相關原理
- 4. 實驗步驟
- 4.1 數據預處理
- 4.1.1 對于類型變量的處理
- 4.1.2 對于數值類型變量進行標準化
- 4.1.3 數據集分割
- 4.2 創建模型
- 手寫用Tensor運算的人工神經網絡
- 4.3 訓練模型
- 4.3.1 數據的分批次處理
- 4.4 測試模型
1. 實驗環境
Jupyter Notebook
Python 3.7
PyTorch 1.4.0
2. 實驗目的
構建人工神經網絡,并用它來預測未來某地區租賃單車的使用情況。
3. 相關原理
數據歸一化、類型變量的轉換。
搭建基本神經網絡的方法。
數據分批次訓練原則。
測試及簡單分析神經網絡的方法
4. 實驗步驟
#數據的下載與解壓: !wget http://labfile.oss.aliyuncs.com/courses/1073/bike-sharing-dataset.zip !unzip bike-sharing-dataset.zip數據都在文件“hour.csv”中,該文件大小為 1.2M,完全可以直接讀取到內存中
數據文件記錄了每小時(hr)共享單車的使用數量(cnt),除了這兩個數據項外,還包括當天的日期(dteday),季節(season),星期幾(weekday),是否是假期(holiday),當天的溫度、濕度、風速、用戶是否注冊等等,我們就是要使用這些數據訓練神經網絡模型。
4.1 數據預處理
import numpy as np import pandas as pd #讀取csv文件的庫 import matplotlib.pyplot as plt import torch from torch.autograd import Variable import torch.optim as optim# 讓輸出的圖形直接在Notebook中顯示 %matplotlib inline#首先,讓我們再來看看數據長什么樣子 #讀取數據到內存中,rides為一個dataframe對象 data_path = 'bike-sharing-dataset/hour.csv' rides = pd.read_csv(data_path) rides.head() #運用 pandas 模塊的 head 方法,將數據的數據表頭和部分數據項打印出來。4.1.1 對于類型變量的處理
類型變量是指這個變量的不同值僅僅表達不同的類型,值的大小不同但沒有高低之分。
有很多變量都屬于類型變量,例如 season=1,2,3,4 代表四季。
我們不能將 season 變量直接輸入到神經網絡,這是因為 season 數值越高并不表示相應的信號強度越大。
解決方案是將類型變量用一個“一位熱碼“(one-hot)來編碼,也就是:
𝑠𝑒𝑎𝑠𝑜𝑛=1→(1,0,0,0)
𝑠𝑒𝑎𝑠𝑜𝑛=2→(0,1,0,0)
𝑠𝑒𝑎𝑠𝑜𝑛=3→(0,0,1,0)
𝑠𝑒𝑎𝑠𝑜𝑛=4→(0,0,0,1)
因此,如果一個類型變量有 n 個不同取值,那么我 one-hot 所對應的向量長度就為 n。
例如:
從顯示出的數據中可以看到一年四季、12 個月份、24 個小時數、一周 7 天、天氣情況都已經被轉化成了 one-hot 變量。
4.1.2 對于數值類型變量進行標準化
由于每個數值型變量都是相互獨立的,所以它們的數值絕對大小與問題本身沒有關系。(更看重變化趨勢而非數值大小)
為了消除數值大小的差異,我們對每一個數值型變量進行標準化處理,也就是讓其數值都圍繞著0左右波動。
比如,對于溫度 temp 這個變量來說,它在整個數據庫取值的平均值為 mean(temp),方差為 std(temp),所以,歸一化的溫度計算為:
這樣做的好處就是可以將不同的取值范圍的變量設置為讓它們處于一個平等的地位。
4.1.3 數據集分割
首先,在變量集合上,我們分為了特征和目標兩個集合。
其中,特征變量集合包括:年份(yr),是否節假日( holiday),溫度(temp),濕度(hum),風速(windspeed),季節1~4(season),天氣1~4(weathersit,不同天氣種類),月份1~12(mnth),小時0~23(hr),星期0~6(weekday),它們是輸入給神經網絡的變量;
目標變量包括:用戶數(cnt),臨時用戶數(casual),以及注冊用戶數(registered),其中我們僅僅將 cnt 作為我們的目標變量,另外兩個暫時不做任何處理。
這樣我們就將利用 56 個特征變量作為神經網絡的輸入,來預測 1 個變量作為神經網絡的輸出。
接下來,我們再將 17379 條紀錄劃分為兩個集合,分別為前 16875 條記錄作為訓練集訓練我們的神經網絡;后 21 天的數據,也就是 21x24=504 條記錄作為測試集來檢驗我們的模型的預測效果。這一部分數據是不參與神經網絡訓練的。
4.2 創建模型
# 定義神經網絡架構,features.shape[1]個輸入層單元,10個隱含層,1個輸出層 input_size = features.shape[1] hidden_size = 10 output_size = 1 batch_size = 128 neu = torch.nn.Sequential( #調用 torch.nn.Sequential 來構造的神經網絡torch.nn.Linear(input_size, hidden_size), #從輸入到隱含層的線性映射torch.nn.Sigmoid(),torch.nn.Linear(hidden_size, output_size), #從隱含到輸出的線性映射 ) cost = torch.nn.MSELoss() # PyTorch 自帶的損失函數 #neu.parameters():neu包含的所有權重和偏置 lr=0.01:執行梯度下降算法的學習率 optimizer = torch.optim.SGD(neu.parameters(), lr = 0.01) #PyTorch自帶了優化器來自動實現優化算法注:torch.nn.Sequential :作用是將一系列的運算模塊按順序搭建成一個多層的神經網絡。
torch.nn.Sigmoid():隱含層的非線性 Sigmoid 函數
torch.nn.MSELoss :是 PyTorch 自帶的一個封裝好的計算均方誤差的損失函數,它是一個函數指針,賦予了變量 cost
cost(x,y) :計算時調用這個函數,就可以計算預測向量 x 和目標向量 y 之間的均方誤差。
torch.optim.SGD :調用了 PyTorch 自帶的隨機梯度下降算法(Stochastic Gradient Descent,SGD)作為優化器。
手寫用Tensor運算的人工神經網絡
# 定義神經網絡架構,features.shape[1]個輸入層單元,10個隱含層,1個輸出層 input_size = features.shape[1] #輸入層單元個數 hidden_size = 10 #隱含層單元個數 output_size = 1 #輸出層單元個數 batch_size = 128 #每隔batch的記錄數 weights1 = Variable(torch.randn([input_size, hidden_size]), requires_grad = True) #第一到二層權重 biases1 = Variable(torch.randn([hidden_size]), requires_grad = True) #隱含層偏置 weights2 = Variable(torch.randn([hidden_size, output_size]), requires_grad = True) #隱含層到輸出層權重 def neu(x):#計算隱含層輸出#x為batch_size * input_size的矩陣,weights1為input_size*hidden_size矩陣,#biases為hidden_size向量,輸出為batch_size * hidden_size矩陣 hidden = x.mm(weights1) + biases1.expand(x.size()[0], hidden_size)hidden = torch.sigmoid(hidden)#輸入batch_size * hidden_size矩陣,mm上weights2, hidden_size*output_size矩陣,#輸出batch_size*output_size矩陣output = hidden.mm(weights2)return output def cost(x, y):# 計算損失函數error = torch.mean((x - y)**2)return error def zero_grad():# 清空每個參數的梯度信息if weights1.grad is not None and biases1.grad is not None and weights2.grad is not None:weights1.grad.data.zero_()weights2.grad.data.zero_()biases1.grad.data.zero_() def optimizer_step(learning_rate):# 梯度下降算法weights1.data.add_(- learning_rate * weights1.grad.data)weights2.data.add_(- learning_rate * weights2.grad.data)biases1.data.add_(- learning_rate * biases1.grad.data)4.3 訓練模型
4.3.1 數據的分批次處理
設置每批處理的數據大小 batch_size = 128
# 神經網絡訓練循環 losses = [] for i in range(1000):# 每128個樣本點被劃分為一個撮,在循環的時候一批一批地讀取batch_loss = []# start和end分別是提取一個batch數據的起始和終止下標for start in range(0, len(X), batch_size):end = start + batch_size if start + batch_size < len(X) else len(X)xx = Variable(torch.FloatTensor(X[start:end]))yy = Variable(torch.FloatTensor(Y[start:end]))predict = neu(xx)loss = cost(predict, yy)optimizer.zero_grad()loss.backward()optimizer.step()batch_loss.append(loss.data.numpy())# 每隔100步輸出一下損失值(loss)if i % 100==0:losses.append(np.mean(batch_loss))print(i, np.mean(batch_loss))# 打印輸出損失值 fig = plt.figure(figsize=(10, 7)) plt.plot(np.arange(len(losses))*100,losses, 'o-') plt.xlabel('epoch') plt.ylabel('MSE') 輸出: 0 0.90184915 100 0.26658106 200 0.21872732 300 0.12553026 400 0.085256845 500 0.07389378 ......橫坐標表示訓練周期,縱坐標表示平均誤差。可以看到,平均誤差快速地隨訓練周期而下降
4.4 測試模型
# 用訓練好的神經網絡在測試集上進行預測 targets = test_targets['cnt'] #讀取測試集的cnt數值 targets = targets.values.reshape([len(targets),1]) #將數據轉換成合適的tensor形式 targets = targets.astype(float) #保證數據為實數# 將屬性和預測變量包裹在Variable型變量中 x = Variable(torch.FloatTensor(test_features.values)) y = Variable(torch.FloatTensor(targets))# 用神經網絡進行預測 predict = neu(x) predict = predict.data.numpy()# 將后21天的預測數據與真實數據畫在一起并比較 # 橫坐標軸是不同的日期,縱坐標軸是預測或者真實數據的值 fig, ax = plt.subplots(figsize = (10, 7))mean, std = scaled_features['cnt'] ax.plot(predict * std + mean, label='Prediction', linestyle = '--') ax.plot(targets * std + mean, label='Data', linestyle = '-') ax.legend() ax.set_xlabel('Date-time') ax.set_ylabel('Counts') # 對橫坐標軸進行標注 dates = pd.to_datetime(rides.loc[test_data.index]['dteday']) dates = dates.apply(lambda d: d.strftime('%b %d')) ax.set_xticks(np.arange(len(dates))[12::24]) _ = ax.set_xticklabels(dates[12::24], rotation=45)
最后就是預測結果分析實驗就結束了
通過數據的可視化,兩條曲線基本吻合,但在12.25前后實際與預測偏差較大。
考慮現實12.25是圣誕節,并且之后1.1是元旦節,人們的出行習慣會有很大不同,又因為訓練樣本只有兩年長度,圣誕節前后的樣本只有1次,所以沒有辦法對這個特殊假期的模式進行更準確的預測。
總結
以上是生活随笔為你收集整理的PyTorch实战1——预测未来某地区租赁单车的使用情况的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Aria2 Centos7部署
- 下一篇: ecstore session使用