【PyTorch Deep Learning】一次元畳み込みニューラルネットワーク時系列を使って北京地下鉄西直門の旅客流動を予測(ソースコードあり)

ソースコードとデータセットが必要な場合は、コレクションを気に入ってフォローし、コメント領域にプライベートメッセージを残してください~~~

実際の予測を行う前に、畳み込みニューラル ネットワークを紹介しましょう。

完全に接続されたニューラル ネットワークを使用して画像の問題を処理する場合、多くの場合、次の 3 つの欠点があります。

パラメータが多すぎる

 隠れ層のニューロンの数が増えると、パラメーターのサイズが急激に増加し、ニューラル ネットワーク全体のコストが高くなり、トレーニング効率が非常に低くなり、オーバーフィッティングが発生しやすくなります。

局所的な特徴をとらえるのが難しい

 完全に接続されたフィードフォワード ネットワークは、局所的な不変の特徴 (スケール スケーリング、平行移動、回転、およびその他の操作がセマンティック情報に影響しないなど) を抽出することが困難であり、通常、パフォーマンスを向上させるためにデータの拡張が必要です。

情報不足につながる

全結合ニューラルネットワークは、画像情報を処理する際にまず画像をベクトルに展開する必要があるため、空間情報の一部が失われやすく、画像認識の精度が低くなります。

画像処理における完全に接続されたフィードフォワード ニューラル ネットワークの欠陥を目指して、学者は生物学的受容野メカニズムに触発され、上記の 3 つの欠陥をより適切に解決する畳み込みニューラル ネットワーク (CNN) を提案しました。

その中心的なアイデアは、畳み込み層、プーリング層、および完全に接続された層を確立することにより、画像の正確な処理を実現することです。畳み込み層は、画像内の局所的な特徴を抽出する役割を担い、次にプーリング層を使用してパラメーターの数を大幅に減らし (次元削減)、トレーニング効率を向上させ、最後に全結合層を介して線形変換を実行して結果を出力します。

1.畳み込み層

 特徴抽出

画像 (異なるデータ ウィンドウ データ) とフィルター マトリックス (固定された重みのセット) に対するマトリックスの内積 (対応する要素の乗算と合計) の操作は、「畳み込み」と呼ばれ、畳み込みニューラル ネットワークのソースでもあります。

特定のアプリケーションでは、複数の畳み込みカーネルが存在することが多く、各畳み込みカーネルは色深度、輪郭などの画像の特徴を表します。画像ブロックと畳み込みカーネルの内積によって得られる値が大きい場合、画像の特徴に非常に近いと見なされます。画像の局所的な特徴は、畳み込みカーネルのフィルタリングを通じて抽出できます

 

 

2. プーリング層

 プーリング レイヤー (ダウンサンプリング) - オーバーフィッティングを回避するためのデータの次元削減

プーリング層は単にダウンサンプリングであり、データとパラメータの量を圧縮し、桁数を減らし、オーバーフィッティングの現象を減らすために使用されます. 一般的に言えば、最大面積または平均面積を取ります.

特徴の不変性: プーリング操作により、画像の重要な特徴を維持できます。

データの次元の削減: プーリングによってこれらの冗長な情報を排除し、データの次元を大幅に削減し、過剰適合を防ぎます。

3. 全結合層

 全結合層 - 出力結果

この部分は畳み込みニューラル ネットワーク全体の最後のステップです. 畳み込みとプーリングの後, データは完全に接続された層に入力されます. 回帰または分類の問題の必要に応じて, 異なる活性化関数が選択されて最終的な目的の結果が得られます. つまり、従来のニューラル ネットワーク ニューロンの結合方法と同じ、つまり、すべてのニューロンが重み結合を持っているということです。

近年、コンピュータ ビジョンの急速な発展により、畳み込みニューラル ネットワークが広く使用されています。現在、2 次元畳み込みニューラル ネットワークが最も広く使用されており、多くのコンピューター愛好家によって求められ、研究されています。そのため、畳み込みニューラル ネットワーク (CNN) と言うときは、通常、画像分類の 2 次元畳み込みを指します. 上記の畳み込みニューラル ネットワークの紹介は、2 次元畳み込みに基づいています. 実は、2 次元の畳み込みニューラル ネットワークに加えて、時系列を予測するための 1 次元の畳み込みニューラル ネットワークや、ビデオ処理 (アクションやキャラクターの動作の検出) のための 3 次元の畳み込みニューラル ネットワークもあります。

それで、2つの違いは何ですか?1 次元畳み込み処理は 1 次元データ、2 次元畳み込み処理は 2 次元データです。

これは間違っています

1D か 2D かに関係なく、CNN は同じ機能を持ち、同じアプローチを採用します。主な違いは、入力データの次元と、特徴検出器 (畳み込みカーネル) がデータをどのようにスライドするかです。

1D 畳み込みニューラル ネットワーク 

1 次元畳み込みニューラル ネットワークの場合、その畳み込みカーネルはデータ上で 1 次元 (水平) 方向にのみスライドできます。通常、入力はベクトルで、出力もベクトルです。1 次元畳み込みニューラル ネットワークは、データ セット全体の短いセグメントから重要な特徴を取得したい場合に非常に効果的であり、その特徴は空間的な位置に関連していません (すべての特徴が同じ場所で生成されるなど)。具体的な計算は以下の通り

2D 畳み込みニューラル ネットワーク 

1D 畳み込みと比較して、2D 畳み込みニューラル ネットワークの畳み込みカーネルは、データ上で 2 つの次元 (水平および垂直方向) にスライドします。2 次元畳み込みニューラル ネットワークは、その畳み込みカーネルを使用して、画像のエッジ、色分布などの検出など、データから空間的特徴を抽出できるため、2 次元畳み込みニューラル ネットワークは画像分類に使用できます。空間属性を含む他の同様のデータ処理機能は非常に強力で、現在最も広く使用されている畳み込みニューラル ネットワークでもあります。

4. PyTorch は 1 次元畳み込みニューラル ネットワークの時系列予測を実装します

 例として、2016 年に北京地下鉄の西直門駅の 15 分ごとのインバウンド データを取り上げます。PyTorch を使用して 1 次元畳み込みニューラル ネットワークを構築し、インバウンド旅客フロー データの予測を実現します。

データをインポートして、次のように視覚化します

西直門地下鉄駅のインバウンド旅客流動データを入力した後、トレーニング セットとテスト セットを分割する必要があります。旅客流動データは 1799 の期間があり、データ セットの最後の 300 がテスト セットとして使用されます。より良いトレーニング効果を得るために、乗客の流れのデータは正規化され、[-1,1] 間隔に正規化されます

1次元畳み込みニューラルネットワークは、予測の精度を向上させるために、最大プーリング層1層と全結合層2層を重ねた2層の畳み込み層を採用し、活性化関数としてReLUを使用し、プーリング後に、また、ドロップアウト関数を使用して、トレーニングでのオーバーフィッティングを回避します。

次のステップは、損失関数とオプティマイザーを定義することです。この実験では、MSELoss がトレーニング損失関数として選択され、Adam がトレーニング オプティマイザーとして選択され、学習率 lr=0.0005 が選択されます。

以上が畳み込みニューラル ネットワークの構築プロセスであり、ネットワークをトレーニングする必要があります。最初に反復回数 epoch = 20 を定義し、同時にネットワークをトレーニング モードに調整します。Then use the for loop to traverse the sample data used for training. パラメータを更新する前に、勾配をゼロにして初期化する必要があることに注意してください。入力データの形状はネットワーク入力の形式に準拠していないため、サンプル データの形状を conv1: (batch_size, in_channels, series_legth) の input_size に調整する必要があります。

トレーニング結果は次のように繰り返されます

モデルのトレーニングが完了したら、シーケンスの最後の 72 データを選択して予測を開始します。まず、ネットワーク モードを eval モードに設定します。データ セットの最後の 300 データを予測する必要があるため、300 回トラバースする必要があります。ループの各ステップは、タイム ウィンドウが時系列に 1 グリッド戻ることを意味します。 , so that the real value of each latest moment Data sets will added as input to predict and output newばくしゃの流れデータ. 時間ウィンドウに追加された最新の値は、予測値ではなく実際の値であり、これにより、ある程度の誤差。同時に、トレーニング済みのモデルが予測に使用されるため、モデルの重みとバイアスを逆伝播して最適化する必要はありません。また、予測終了後、予測の効果を反映させるため、予測値を非正規化して実際の旅客流動値に復元するため、実際の旅客流動との比較に便利です。

予想結果は以下の通り 

 

 一部の最大値と頻繁に変動する期間がわずかに異なることを除いて、フィッティングは一般的に非常に良好であることがわかります。これは、モデルの改善の目標方向でもあります。

コードの最後の部分は次のとおりです。

import torch
import torch.nn as nn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler

# 导入北京地铁站点15min进站客流
df = pd.read_csv('./15min_in.csv', index_col = 0, encoding = "gbk", parse_dates = True)
len(df)
df.head()  # 观察数据集,这是一个单变量时间序列
试集和训练集,最后300个作为测试集
test_size = 300
train_iter = y[
# 创建时间序列训练集
train_set = torch.FloatTensor(train_norm).view(-1)
# 定义时间窗口
Time_window_size = 72

# 从原时间序列中抽取出训练样本,用第1个值到第72个值作为X输入,预测第73个值作为y输出,这是一个用于训练的数据点,时间窗口向后滑动以此类推
def input_data(seq, ws):  
    out = []
    L = len(seq)
    for i in range(L-ws):
        window = seq[i:i + ws]
        label = seq[i + ws:i + ws + 1]
        out.append((window, label))
    return out


train_data = input_data(train_set, Time_window_size)
len(train_data)  # 等于1799(原始数据集长度)-300(测试集长度)-72(时间窗口)
from numpy.lib.stride_tricks import sliding_window_view
output = slidCNNnetwork, self).__init__()
        self.conv1 = nn.Conv1d(in_channels=1, out_channels=64, kernel_size=2)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = nn.Conv1d(in_channels=64, out_channels=32, kernel_size=2)
        self.pool = nn.MaxPool1d(kernel_size=2,stride=2)
        self.fc1 = nn.Linear(32*35, 640)
        self.fc2 = nn.Linear(640, 1)
        # self.fc1 = nn.Linear(32*70, 640)
        self.drop = nn.Dropout(0.5)
        
        
    def forward(self,x):
        x = self.conv1(x)
        x = self.relu(x)
        x = self.conv2(x)
        x = self.relu(x)
        x = self.pool(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x
device = torch.device("cuda")    
net = CNNnetwork().to(device)
# 开始训练模型
epochs = 20
net.train()

for epoch in range(epochs):

    for seq, y_train in train_data:
        # 每次更新参数前都梯度归零和初始化
        optimizer.zero_grad()
        y_train = y_train.to(device)
        # 对mizer.step()

    print(f'Epoch: {epoch + 1:2} Loss:{loss.item():10.8f}')
future = 300

# 选取序列最后12个值开始预测
preds = train_set[-Time_window_size:].tolist()

# 设置成eval模式
net.eval()

for i in range(future):
    seq = torch.FloatTensor(preds[-Time_window_size:])
    with torch.no_grad():
        seq = seq.reshape(1,1,-1).to(device)
        preds.append(net(seq).item())
# 逆归re(figsize=(12, 4))
plt.grid(True)
plt.plot(y)
x = np.arange(1500, 1800)
plt.plot(x, true_predictions)
plt.show()

作るのは簡単ではありませんが、参考にしてください。いいね、フォロー、収集してください~~~

おすすめ

転載: blog.csdn.net/jiebaoshayebuhui/article/details/130446904