एमएल समुदाय दिवस 9 नवंबर है! TensorFlow, JAX से नई जानकारी के लिए हमसे जुड़ें, और अधिक जानें

समय श्रृंखला पूर्वानुमान

TensorFlow.org पर देखें Google Colab में चलाएं GitHub पर स्रोत देखेंनोटबुक डाउनलोड करें

यह ट्यूटोरियल TensorFlow का उपयोग करके समय श्रृंखला पूर्वानुमान का परिचय है। यह कन्वेन्शनल और आवर्तक तंत्रिका नेटवर्क (सीएनएन और आरएनएन) सहित मॉडलों की कुछ अलग शैलियों का निर्माण करता है।

यह उपखंडों के साथ दो मुख्य भागों में शामिल है:

  • सिंगल टाइम स्टेप के लिए पूर्वानुमान:
    • एक ही विशेषता।
    • सभी सुविधाएं।
  • कई चरणों का पूर्वानुमान:
    • सिंगल-शॉट: भविष्यवाणियां एक ही बार में करें।
    • ऑटोरेग्रेसिव: एक बार में एक भविष्यवाणी करें और आउटपुट को वापस मॉडल में फीड करें।

सेट अप

import os
import datetime

import IPython
import IPython.display
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import tensorflow as tf

mpl.rcParams['figure.figsize'] = (8, 6)
mpl.rcParams['axes.grid'] = False
2021-08-03 01:29:35.290679: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0

मौसम डेटासेट

इस ट्यूटोरियल एक का उपयोग करता है मौसम समय श्रृंखला डाटासेट द्वारा दर्ज की गई biogeochemistry मैक्स प्लैंक इंस्टीट्यूट फॉर

इस डेटासेट में 14 अलग-अलग विशेषताएं हैं जैसे हवा का तापमान, वायुमंडलीय दबाव और आर्द्रता। ये हर 10 मिनट में एकत्र किए गए थे, 2003 में शुरुआत दक्षता के लिए, आप केवल डेटा 2009 और 2016 के बीच एकत्र डाटासेट के इस खंड में अपनी पुस्तक के लिए फ़्राँस्वा Chollet द्वारा तैयार किया गया था का उपयोग करेगा अजगर के साथ दीप लर्निंग

zip_path = tf.keras.utils.get_file(
    origin='https://storage.googleapis.com/tensorflow/tf-keras-datasets/jena_climate_2009_2016.csv.zip',
    fname='jena_climate_2009_2016.csv.zip',
    extract=True)
csv_path, _ = os.path.splitext(zip_path)
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/jena_climate_2009_2016.csv.zip
13574144/13568290 [==============================] - 1s 0us/step

इस ट्यूटोरियल केवल प्रति घंटा की भविष्यवाणियों के साथ सौदा होगा, ताकि द्वारा शुरू उप नमूना एक घंटे के अंतराल को 10 मिनट के अंतराल से डेटा:

df = pd.read_csv(csv_path)
# Slice [start:stop:step], starting from index 5 take every 6th record.
df = df[5::6]

date_time = pd.to_datetime(df.pop('Date Time'), format='%d.%m.%Y %H:%M:%S')

आइए आंकड़ों पर एक नजर डालते हैं। यहाँ पहली कुछ पंक्तियाँ हैं:

df.head()

यहाँ समय के साथ कुछ विशेषताओं का विकास हुआ है:

plot_cols = ['T (degC)', 'p (mbar)', 'rho (g/m**3)']
plot_features = df[plot_cols]
plot_features.index = date_time
_ = plot_features.plot(subplots=True)

plot_features = df[plot_cols][:480]
plot_features.index = date_time[:480]
_ = plot_features.plot(subplots=True)

पीएनजी

पीएनजी

निरीक्षण और सफाई

इसके बाद, डेटासेट के आँकड़ों को देखें:

df.describe().transpose()

पवन वेग

एक बात है कि बाहर खड़े होना चाहिए है min हवा के वेग (का मान wv (m/s) ) और अधिकतम मूल्य ( max. wv (m/s) ) स्तंभों। यह -9999 संभावना गलत है।

एक अलग हवा की दिशा स्तंभ, नहीं है तो वेग शून्य से अधिक (होना चाहिए >=0 )। इसे शून्य से बदलें:

wv = df['wv (m/s)']
bad_wv = wv == -9999.0
wv[bad_wv] = 0.0

max_wv = df['max. wv (m/s)']
bad_max_wv = max_wv == -9999.0
max_wv[bad_max_wv] = 0.0

# The above inplace edits are reflected in the DataFrame.
df['wv (m/s)'].min()
0.0

फ़ीचर इंजीनियरिंग

एक मॉडल बनाने के लिए गोता लगाने से पहले, अपने डेटा को समझना और यह सुनिश्चित करना महत्वपूर्ण है कि आप मॉडल को उचित रूप से स्वरूपित डेटा पास कर रहे हैं।

हवा

डेटा के अंतिम स्तंभ, wd (deg) -gives डिग्री की इकाइयों में हवा की दिशा। कोण अच्छे मॉडल इनपुट नहीं बनाते हैं: 360° और 0° एक-दूसरे के करीब होने चाहिए और आसानी से चारों ओर लपेटे जाने चाहिए। अगर हवा नहीं चल रही है तो दिशा मायने नहीं रखती।

अभी पवन डेटा का वितरण इस तरह दिखता है:

plt.hist2d(df['wd (deg)'], df['wv (m/s)'], bins=(50, 50), vmax=400)
plt.colorbar()
plt.xlabel('Wind Direction [deg]')
plt.ylabel('Wind Velocity [m/s]')
Text(0, 0.5, 'Wind Velocity [m/s]')

पीएनजी

लेकिन इस आसान मॉडल की व्याख्या करने के लिए यदि आप एक हवा वेक्टर के लिए हवा की दिशा और वेग कॉलम परिवर्तित हो जाएगा:

wv = df.pop('wv (m/s)')
max_wv = df.pop('max. wv (m/s)')

# Convert to radians.
wd_rad = df.pop('wd (deg)')*np.pi / 180

# Calculate the wind x and y components.
df['Wx'] = wv*np.cos(wd_rad)
df['Wy'] = wv*np.sin(wd_rad)

# Calculate the max wind x and y components.
df['max Wx'] = max_wv*np.cos(wd_rad)
df['max Wy'] = max_wv*np.sin(wd_rad)

मॉडल के लिए सही ढंग से व्याख्या करने के लिए पवन वैक्टर का वितरण बहुत आसान है:

plt.hist2d(df['Wx'], df['Wy'], bins=(50, 50), vmax=400)
plt.colorbar()
plt.xlabel('Wind X [m/s]')
plt.ylabel('Wind Y [m/s]')
ax = plt.gca()
ax.axis('tight')
(-11.305513973134667, 8.24469928549079, -8.27438540335515, 7.7338312955467785)

पीएनजी

समय

इसी प्रकार, Date Time स्तंभ बहुत उपयोगी है, लेकिन इस स्ट्रिंग के रूप में नहीं। इसे सेकंड में परिवर्तित करके प्रारंभ करें:

timestamp_s = date_time.map(pd.Timestamp.timestamp)

हवा की दिशा के समान, सेकंड में समय एक उपयोगी मॉडल इनपुट नहीं है। मौसम के आंकड़े होने के कारण, इसकी दैनिक और वार्षिक आवधिकता स्पष्ट है। ऐसे कई तरीके हैं जिनसे आप आवधिकता से निपट सकते हैं।

आप "दिन का समय" और "वर्ष का समय" संकेतों को साफ़ करने के लिए साइन और कोसाइन ट्रांसफ़ॉर्म का उपयोग करके प्रयोग करने योग्य सिग्नल प्राप्त कर सकते हैं:

day = 24*60*60
year = (365.2425)*day

df['Day sin'] = np.sin(timestamp_s * (2 * np.pi / day))
df['Day cos'] = np.cos(timestamp_s * (2 * np.pi / day))
df['Year sin'] = np.sin(timestamp_s * (2 * np.pi / year))
df['Year cos'] = np.cos(timestamp_s * (2 * np.pi / year))
plt.plot(np.array(df['Day sin'])[:25])
plt.plot(np.array(df['Day cos'])[:25])
plt.xlabel('Time [h]')
plt.title('Time of day signal')
Text(0.5, 1.0, 'Time of day signal')

पीएनजी

यह मॉडल को सबसे महत्वपूर्ण आवृत्ति सुविधाओं तक पहुंच प्रदान करता है। इस मामले में आप समय से पहले जानते थे कि कौन सी आवृत्तियां महत्वपूर्ण थीं।

आपको लगता है कि जानकारी नहीं है, तो आप तय कर सकें आवृत्तियों के साथ सुविधाओं निकाल कर महत्वपूर्ण हैं फास्ट फूरियर रूपांतरण । मान्यताओं की जाँच करने के लिए, यहाँ है tf.signal.rfft समय के साथ तापमान की। नोट के पास आवृत्तियों पर स्पष्ट चोटियों 1/year और 1/day :

fft = tf.signal.rfft(df['T (degC)'])
f_per_dataset = np.arange(0, len(fft))

n_samples_h = len(df['T (degC)'])
hours_per_year = 24*365.2524
years_per_dataset = n_samples_h/(hours_per_year)

f_per_year = f_per_dataset/years_per_dataset
plt.step(f_per_year, np.abs(fft))
plt.xscale('log')
plt.ylim(0, 400000)
plt.xlim([0.1, max(plt.xlim())])
plt.xticks([1, 365.2524], labels=['1/Year', '1/day'])
_ = plt.xlabel('Frequency (log scale)')
2021-08-03 01:29:41.976610: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcuda.so.1
2021-08-03 01:29:42.626738: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-03 01:29:42.627640: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1733] Found device 0 with properties: 
pciBusID: 0000:00:05.0 name: Tesla V100-SXM2-16GB computeCapability: 7.0
coreClock: 1.53GHz coreCount: 80 deviceMemorySize: 15.78GiB deviceMemoryBandwidth: 836.37GiB/s
2021-08-03 01:29:42.627697: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
2021-08-03 01:29:42.630402: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublas.so.11
2021-08-03 01:29:42.630533: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublasLt.so.11
2021-08-03 01:29:42.631505: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcufft.so.10
2021-08-03 01:29:42.631863: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcurand.so.10
2021-08-03 01:29:42.632610: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcusolver.so.11
2021-08-03 01:29:42.633312: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcusparse.so.11
2021-08-03 01:29:42.633541: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudnn.so.8
2021-08-03 01:29:42.633650: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-03 01:29:42.634551: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-03 01:29:42.635454: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1871] Adding visible gpu devices: 0
2021-08-03 01:29:42.636067: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2021-08-03 01:29:42.636598: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-03 01:29:42.637440: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1733] Found device 0 with properties: 
pciBusID: 0000:00:05.0 name: Tesla V100-SXM2-16GB computeCapability: 7.0
coreClock: 1.53GHz coreCount: 80 deviceMemorySize: 15.78GiB deviceMemoryBandwidth: 836.37GiB/s
2021-08-03 01:29:42.637536: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-03 01:29:42.638404: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-03 01:29:42.639205: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1871] Adding visible gpu devices: 0
2021-08-03 01:29:42.639284: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
2021-08-03 01:29:43.206803: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1258] Device interconnect StreamExecutor with strength 1 edge matrix:
2021-08-03 01:29:43.206840: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1264]      0 
2021-08-03 01:29:43.206848: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1277] 0:   N 
2021-08-03 01:29:43.207063: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-03 01:29:43.208016: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-03 01:29:43.208856: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-08-03 01:29:43.209685: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1418] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 14646 MB memory) -> physical GPU (device: 0, name: Tesla V100-SXM2-16GB, pci bus id: 0000:00:05.0, compute capability: 7.0)
2021-08-03 01:29:43.470908: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcufft.so.10

पीएनजी

डेटा विभाजित करें

आप एक का उपयोग करेंगे (70%, 20%, 10%) प्रशिक्षण, मान्यता, और परीक्षण सेट के लिए विभाजन। डेटा बेतरतीब ढंग से बंटवारे से पहले shuffled नहीं किया जा रहा है पर ध्यान दें। ऐसा दो कारणों से है:

  1. यह सुनिश्चित करता है कि डेटा को लगातार नमूनों की विंडो में काटना अभी भी संभव है।
  2. यह सुनिश्चित करता है कि सत्यापन / परीक्षण के परिणाम अधिक यथार्थवादी हैं, मॉडल के प्रशिक्षण के बाद एकत्र किए गए डेटा पर मूल्यांकन किया जा रहा है।
column_indices = {name: i for i, name in enumerate(df.columns)}

n = len(df)
train_df = df[0:int(n*0.7)]
val_df = df[int(n*0.7):int(n*0.9)]
test_df = df[int(n*0.9):]

num_features = df.shape[1]

डेटा को सामान्य करें

तंत्रिका नेटवर्क को प्रशिक्षित करने से पहले सुविधाओं को स्केल करना महत्वपूर्ण है। सामान्यीकरण इस स्केलिंग को करने का एक सामान्य तरीका है: माध्य घटाएं और प्रत्येक सुविधा के मानक विचलन से विभाजित करें।

माध्य और मानक विचलन की गणना केवल प्रशिक्षण डेटा का उपयोग करके की जानी चाहिए ताकि मॉडल की सत्यापन और परीक्षण सेट में मानों तक कोई पहुंच न हो।

यह भी तर्कपूर्ण है कि प्रशिक्षण के दौरान मॉडल को प्रशिक्षण सेट में भविष्य के मूल्यों तक पहुंच नहीं होनी चाहिए, और यह सामान्यीकरण चलती औसत का उपयोग करके किया जाना चाहिए। यह इस ट्यूटोरियल का फोकस नहीं है, और सत्यापन और परीक्षण सेट यह सुनिश्चित करते हैं कि आपको (कुछ हद तक) ईमानदार मेट्रिक्स मिले। तो, सादगी के हित में यह ट्यूटोरियल एक साधारण औसत का उपयोग करता है।

train_mean = train_df.mean()
train_std = train_df.std()

train_df = (train_df - train_mean) / train_std
val_df = (val_df - train_mean) / train_std
test_df = (test_df - train_mean) / train_std

अब, सुविधाओं के वितरण पर नज़र डालें। कुछ सुविधाओं लंबी पूंछ की क्या ज़रूरत है, लेकिन वहाँ की तरह कोई स्पष्ट त्रुटियाँ हैं -9999 हवा के वेग मूल्य।

df_std = (df - train_mean) / train_std
df_std = df_std.melt(var_name='Column', value_name='Normalized')
plt.figure(figsize=(12, 6))
ax = sns.violinplot(x='Column', y='Normalized', data=df_std)
_ = ax.set_xticklabels(df.keys(), rotation=90)

पीएनजी

डेटा विंडोिंग

इस ट्यूटोरियल के मॉडल डेटा से लगातार नमूनों की एक विंडो के आधार पर भविष्यवाणियों का एक सेट बनाएंगे।

इनपुट विंडो की मुख्य विशेषताएं हैं:

  • इनपुट और लेबल विंडो की चौड़ाई (समय चरणों की संख्या)।
  • उनके बीच समय ऑफसेट।
  • इनपुट, लेबल या दोनों के रूप में किन विशेषताओं का उपयोग किया जाता है।

यह ट्यूटोरियल विभिन्न प्रकार के मॉडल बनाता है (रैखिक, डीएनएन, सीएनएन और आरएनएन मॉडल सहित), और दोनों के लिए उनका उपयोग करता है:

  • एकल आउटपुट, और बहु-उत्पादन के पूर्वानुमान।
  • एकल-समय कदम और बहु समय कदम भविष्यवाणियों।

यह खंड डेटा विंडोिंग को लागू करने पर केंद्रित है ताकि उन सभी मॉडलों के लिए इसका पुन: उपयोग किया जा सके।

कार्य और मॉडल के प्रकार के आधार पर आप विभिन्न प्रकार की डेटा विंडो उत्पन्न करना चाह सकते हैं। यहां कुछ उदाहरण दिए गए हैं:

  1. उदाहरण के लिए, 24 घंटे के इतिहास को देखते हुए, भविष्य में 24 घंटे की एक भविष्यवाणी करने के लिए, आप इस तरह एक विंडो परिभाषित कर सकते हैं:

    भविष्य में 24 घंटे एक भविष्यवाणी।

  2. एक मॉडल जो भविष्य में एक घंटे की भविष्यवाणी करता है, छह घंटे के इतिहास को देखते हुए, उसे इस तरह की एक खिड़की की आवश्यकता होगी:

    भविष्य में एक घंटा एक भविष्यवाणी।

इस भाग के बाकी एक को परिभाषित करता है WindowGenerator वर्ग। यह वर्ग कर सकता है:

  1. इंडेक्स और ऑफ़सेट को हैंडल करें जैसा कि ऊपर दिए गए डायग्राम में दिखाया गया है।
  2. में सुविधाओं के विभाजन खिड़कियों (features, labels) जोड़े।
  3. परिणामी विंडो की सामग्री को प्लॉट करें।
  4. कुशलता प्रशिक्षण, मूल्यांकन, और परीक्षण डाटा से इन खिड़कियों के बैच उत्पन्न करते हैं, का उपयोग कर tf.data.Dataset रों।

1. इंडेक्स और ऑफ़सेट

बनाकर शुरुआत WindowGenerator वर्ग। __init__ विधि इनपुट और लेबल सूचकांक के लिए सभी आवश्यक तर्क भी शामिल है।

यह इनपुट के रूप में प्रशिक्षण, मूल्यांकन और डेटाफ़्रेम का परीक्षण भी करता है। इन में परिवर्तित हो जाएगा tf.data.Dataset रों खिड़कियों के बाद।

class WindowGenerator():
  def __init__(self, input_width, label_width, shift,
               train_df=train_df, val_df=val_df, test_df=test_df,
               label_columns=None):
    # Store the raw data.
    self.train_df = train_df
    self.val_df = val_df
    self.test_df = test_df

    # Work out the label column indices.
    self.label_columns = label_columns
    if label_columns is not None:
      self.label_columns_indices = {name: i for i, name in
                                    enumerate(label_columns)}
    self.column_indices = {name: i for i, name in
                           enumerate(train_df.columns)}

    # Work out the window parameters.
    self.input_width = input_width
    self.label_width = label_width
    self.shift = shift

    self.total_window_size = input_width + shift

    self.input_slice = slice(0, input_width)
    self.input_indices = np.arange(self.total_window_size)[self.input_slice]

    self.label_start = self.total_window_size - self.label_width
    self.labels_slice = slice(self.label_start, None)
    self.label_indices = np.arange(self.total_window_size)[self.labels_slice]

  def __repr__(self):
    return '\n'.join([
        f'Total window size: {self.total_window_size}',
        f'Input indices: {self.input_indices}',
        f'Label indices: {self.label_indices}',
        f'Label column name(s): {self.label_columns}'])

इस खंड की शुरुआत में आरेखों में दिखाए गए 2 विंडो बनाने के लिए कोड यहां दिया गया है:

w1 = WindowGenerator(input_width=24, label_width=1, shift=24,
                     label_columns=['T (degC)'])
w1
Total window size: 48
Input indices: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
Label indices: [47]
Label column name(s): ['T (degC)']
w2 = WindowGenerator(input_width=6, label_width=1, shift=1,
                     label_columns=['T (degC)'])
w2
Total window size: 7
Input indices: [0 1 2 3 4 5]
Label indices: [6]
Label column name(s): ['T (degC)']

2. विभाजित

लगातार आदानों की एक सूची को देखते हुए, split_window विधि आदानों की एक खिड़की और लेबल की एक खिड़की करने के लिए उन्हें परिवर्तित कर देंगे।

उदाहरण w2 आप पहले परिभाषित इस तरह विभाजित हो जाएगा:

प्रारंभिक विंडो सभी लगातार नमूने हैं, यह इसे एक (इनपुट, लेबल) जोड़े में विभाजित करता है

यह चित्र प्रदर्शित नहीं करता है features डेटा की धुरी है, लेकिन इस split_window समारोह भी संभालती label_columns तो यह दोनों ही उत्पादन और बहु उत्पादन उदाहरण के लिए इस्तेमाल किया जा सकता है।

def split_window(self, features):
  inputs = features[:, self.input_slice, :]
  labels = features[:, self.labels_slice, :]
  if self.label_columns is not None:
    labels = tf.stack(
        [labels[:, :, self.column_indices[name]] for name in self.label_columns],
        axis=-1)

  # Slicing doesn't preserve static shape information, so set the shapes
  # manually. This way the `tf.data.Datasets` are easier to inspect.
  inputs.set_shape([None, self.input_width, None])
  labels.set_shape([None, self.label_width, None])

  return inputs, labels

WindowGenerator.split_window = split_window

कोशिश करके देखो:

# Stack three slices, the length of the total window.
example_window = tf.stack([np.array(train_df[:w2.total_window_size]),
                           np.array(train_df[100:100+w2.total_window_size]),
                           np.array(train_df[200:200+w2.total_window_size])])

example_inputs, example_labels = w2.split_window(example_window)

print('All shapes are: (batch, time, features)')
print(f'Window shape: {example_window.shape}')
print(f'Inputs shape: {example_inputs.shape}')
print(f'Labels shape: {example_labels.shape}')
All shapes are: (batch, time, features)
Window shape: (3, 7, 19)
Inputs shape: (3, 6, 19)
Labels shape: (3, 1, 1)

आमतौर पर, TensorFlow में डेटा को सरणियों में पैक किया जाता है, जहां सबसे बाहरी सूचकांक उदाहरणों ("बैच" आयाम) में होता है। मध्य सूचकांक "समय" या "स्थान" (चौड़ाई, ऊंचाई) आयाम हैं। अंतरतम सूचकांक विशेषताएं हैं।

ऊपर दिए गए कोड ने प्रत्येक समय चरण में 19 सुविधाओं के साथ तीन 7-बार चरण वाली विंडो का एक बैच लिया। यह उन्हें 6-बार चरण 19-सुविधा इनपुट और 1-बार चरण 1-फ़ीचर लेबल के एक बैच में विभाजित करता है। क्योंकि लेबल का केवल एक सुविधा है WindowGenerator साथ प्रारंभ किया गया था label_columns=['T (degC)'] । प्रारंभ में, यह ट्यूटोरियल ऐसे मॉडल बनाएगा जो एकल आउटपुट लेबल की भविष्यवाणी करते हैं।

3. प्लॉट

यहाँ एक प्लॉट विधि है जो स्प्लिट विंडो के एक सरल दृश्य की अनुमति देती है:

w2.example = example_inputs, example_labels
def plot(self, model=None, plot_col='T (degC)', max_subplots=3):
  inputs, labels = self.example
  plt.figure(figsize=(12, 8))
  plot_col_index = self.column_indices[plot_col]
  max_n = min(max_subplots, len(inputs))
  for n in range(max_n):
    plt.subplot(max_n, 1, n+1)
    plt.ylabel(f'{plot_col} [normed]')
    plt.plot(self.input_indices, inputs[n, :, plot_col_index],
             label='Inputs', marker='.', zorder=-10)

    if self.label_columns:
      label_col_index = self.label_columns_indices.get(plot_col, None)
    else:
      label_col_index = plot_col_index

    if label_col_index is None:
      continue

    plt.scatter(self.label_indices, labels[n, :, label_col_index],
                edgecolors='k', label='Labels', c='#2ca02c', s=64)
    if model is not None:
      predictions = model(inputs)
      plt.scatter(self.label_indices, predictions[n, :, label_col_index],
                  marker='X', edgecolors='k', label='Predictions',
                  c='#ff7f0e', s=64)

    if n == 0:
      plt.legend()

  plt.xlabel('Time [h]')

WindowGenerator.plot = plot

यह प्लॉट उस समय के आधार पर इनपुट, लेबल, और (बाद में) भविष्यवाणियों को संरेखित करता है जो आइटम को संदर्भित करता है:

w2.plot()

पीएनजी

आप अन्य स्तंभों प्लॉट कर सकते हैं, लेकिन उदाहरण खिड़की w2 विन्यास केवल के लिए लेबल है T (degC) स्तंभ।

w2.plot(plot_col='p (mbar)')

पीएनजी

4. बनाएं tf.data.Dataset रों

अंत में, इस make_dataset विधि एक समय श्रृंखला DataFrame लेने के लिए और एक करने के लिए इसे परिवर्तित कर देंगे tf.data.Dataset की (input_window, label_window) का उपयोग कर जोड़े preprocessing.timeseries_dataset_from_array समारोह:

def make_dataset(self, data):
  data = np.array(data, dtype=np.float32)
  ds = tf.keras.preprocessing.timeseries_dataset_from_array(
      data=data,
      targets=None,
      sequence_length=self.total_window_size,
      sequence_stride=1,
      shuffle=True,
      batch_size=32,)

  ds = ds.map(self.split_window)

  return ds

WindowGenerator.make_dataset = make_dataset

WindowGenerator वस्तु प्रशिक्षण, सत्यापन, और परीक्षण डाटा रखती है।

उन्हें पहुँचने के लिए गुण जोड़े tf.data.Dataset s का उपयोग करके make_dataset विधि आप पहले परिभाषित किया। साथ ही, आसान पहुंच और प्लॉटिंग के लिए एक मानक उदाहरण बैच जोड़ें:

@property
def train(self):
  return self.make_dataset(self.train_df)

@property
def val(self):
  return self.make_dataset(self.val_df)

@property
def test(self):
  return self.make_dataset(self.test_df)

@property
def example(self):
  """Get and cache an example batch of `inputs, labels` for plotting."""
  result = getattr(self, '_example', None)
  if result is None:
    # No example batch was found, so get one from the `.train` dataset
    result = next(iter(self.train))
    # And cache it for next time
    self._example = result
  return result

WindowGenerator.train = train
WindowGenerator.val = val
WindowGenerator.test = test
WindowGenerator.example = example

अब, WindowGenerator वस्तु आप को एक्सेस करने देता tf.data.Dataset , वस्तुओं तो आप आसानी से पुनरावृति डेटा पर।

Dataset.element_spec संपत्ति आप संरचना, डेटा प्रकार, और डाटासेट तत्वों का आकार बताता है।

# Each element is an (inputs, label) pair.
w2.train.element_spec
(TensorSpec(shape=(None, 6, 19), dtype=tf.float32, name=None),
 TensorSpec(shape=(None, 1, 1), dtype=tf.float32, name=None))

एक से अधिक पुनरावृत्ति Dataset पैदावार ठोस बैचों:

for example_inputs, example_labels in w2.train.take(1):
  print(f'Inputs shape (batch, time, features): {example_inputs.shape}')
  print(f'Labels shape (batch, time, features): {example_labels.shape}')
Inputs shape (batch, time, features): (32, 6, 19)
Labels shape (batch, time, features): (32, 1, 1)
2021-08-03 01:29:50.245637: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:176] None of the MLIR Optimization Passes are enabled (registered 2)
2021-08-03 01:29:50.246163: I tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 2000179999 Hz

सिंगल स्टेप मॉडल

इस प्रकार के डेटा पर आप जो सबसे सरल मॉडल बना सकते हैं, वह वह है जो केवल वर्तमान परिस्थितियों के आधार पर किसी एकल विशेषता के मान—1 समय चरण (एक घंटा) को भविष्य में भविष्यवाणी करता है।

तो, भविष्यवाणी करने के लिए मॉडल के निर्माण से शुरू T (degC) भविष्य में मूल्य एक घंटे।

अगली बार चरण की भविष्यवाणी करें

एक कॉन्फ़िगर WindowGenerator वस्तु इन एकल-चरण के उत्पादन के लिए (input, label) जोड़े:

single_step_window = WindowGenerator(
    input_width=1, label_width=1, shift=1,
    label_columns=['T (degC)'])
single_step_window
Total window size: 2
Input indices: [0]
Label indices: [1]
Label column name(s): ['T (degC)']

window वस्तु बनाता है tf.data.Dataset डेटा की आसानी से पुनरावृति से अधिक बैचों के लिए आप की अनुमति के प्रशिक्षण, मान्यता, और परीक्षण सेट से है,।

for example_inputs, example_labels in single_step_window.train.take(1):
  print(f'Inputs shape (batch, time, features): {example_inputs.shape}')
  print(f'Labels shape (batch, time, features): {example_labels.shape}')
Inputs shape (batch, time, features): (32, 1, 19)
Labels shape (batch, time, features): (32, 1, 1)

आधारभूत

एक प्रशिक्षित मॉडल बनाने से पहले बाद के अधिक जटिल मॉडल के साथ तुलना के लिए एक प्रदर्शन आधार रेखा होना अच्छा होगा।

सभी सुविधाओं के वर्तमान मूल्य को देखते हुए, यह पहला कार्य भविष्य में एक घंटे के तापमान की भविष्यवाणी करना है। वर्तमान मूल्यों में वर्तमान तापमान शामिल है।

तो, एक मॉडल के साथ शुरू करें जो "कोई परिवर्तन नहीं" की भविष्यवाणी करते हुए, वर्तमान तापमान को भविष्यवाणी के रूप में लौटाता है। यह एक उचित आधार रेखा है क्योंकि तापमान धीरे-धीरे बदलता है। बेशक, अगर आप भविष्य में और भविष्यवाणी करते हैं तो यह आधार रेखा कम काम करेगी।

आउटपुट को इनपुट भेजें

class Baseline(tf.keras.Model):
  def __init__(self, label_index=None):
    super().__init__()
    self.label_index = label_index

  def call(self, inputs):
    if self.label_index is None:
      return inputs
    result = inputs[:, :, self.label_index]
    return result[:, :, tf.newaxis]

इस मॉडल को तत्काल और मूल्यांकन करें:

baseline = Baseline(label_index=column_indices['T (degC)'])

baseline.compile(loss=tf.losses.MeanSquaredError(),
                 metrics=[tf.metrics.MeanAbsoluteError()])

val_performance = {}
performance = {}
val_performance['Baseline'] = baseline.evaluate(single_step_window.val)
performance['Baseline'] = baseline.evaluate(single_step_window.test, verbose=0)
439/439 [==============================] - 1s 1ms/step - loss: 0.0128 - mean_absolute_error: 0.0785

इसने कुछ प्रदर्शन मेट्रिक्स मुद्रित किए, लेकिन वे आपको यह महसूस नहीं कराते कि मॉडल कितना अच्छा कर रहा है।

WindowGenerator एक साजिश विधि है, लेकिन भूखंडों बहुत केवल एक ही नमूना के साथ रोचक नहीं किया जाएगा।

तो, एक व्यापक बनाने WindowGenerator कि एक समय में खिड़कियों उत्पन्न लगातार आदानों और लेबल के 24 घंटे। नई wide_window चर रास्ता मॉडल संचालित नहीं बदलता है। मॉडल अभी भी एक इनपुट समय चरण के आधार पर भविष्य में एक घंटे की भविष्यवाणी करता है। इधर, time अक्ष में कार्य करता है की तरह batch अक्ष: प्रत्येक भविष्यवाणी समय चरणों के बीच कोई बातचीत के साथ स्वतंत्र रूप से किया जाता है:

wide_window = WindowGenerator(
    input_width=24, label_width=24, shift=1,
    label_columns=['T (degC)'])

wide_window
Total window size: 25
Input indices: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
Label indices: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
Label column name(s): ['T (degC)']

इस विस्तार खिड़की एक ही करने के लिए सीधे पारित किया जा सकता baseline किसी भी कोड में परिवर्तन के बिना मॉडल। यह संभव है क्योंकि इनपुट और लेबल में समान समय के चरण होते हैं, और बेसलाइन इनपुट को आउटपुट में आगे की ओर ले जाती है:

भविष्य में एक भविष्यवाणी 1 घंटे, कभी घंटा।

print('Input shape:', wide_window.example[0].shape)
print('Output shape:', baseline(wide_window.example[0]).shape)
Input shape: (32, 24, 19)
Output shape: (32, 24, 1)

बेसलाइन मॉडल की भविष्यवाणियों की साजिश रचने से, ध्यान दें कि यह केवल एक घंटे से लेबल को स्थानांतरित कर दिया गया है:

wide_window.plot(baseline)

पीएनजी

तीन उदाहरणों के उपरोक्त भूखंडों में 24 घंटे के दौरान सिंगल स्टेप मॉडल चलाया जाता है। यह कुछ स्पष्टीकरण के योग्य है:

  • नीले Inputs शो हर बार कदम पर इनपुट तापमान लाइन। मॉडल सभी सुविधाओं को प्राप्त करता है, यह प्लॉट केवल तापमान दिखाता है।
  • हरी Labels डॉट्स लक्ष्य भविष्यवाणी मूल्य दिखा। इन बिंदुओं को पूर्वानुमान समय पर दिखाया जाता है, इनपुट समय पर नहीं। यही कारण है कि लेबल की श्रेणी को इनपुट के सापेक्ष 1 कदम स्थानांतरित कर दिया जाता है।
  • नारंगी Predictions पार मॉडल की भविष्यवाणी प्रत्येक उत्पादन समय कदम के लिए है रहे हैं। अगर मॉडल पूरी तरह से भविष्यवाणी कर रहे थे भविष्यवाणियों पर सीधे पहुंच जाएगा Labels

रैखिक मॉडल

सबसे सरल trainable मॉडल आप इस कार्य को करने के लिए आवेदन कर सकते हैं इनपुट और आउटपुट के बीच रैखिक परिवर्तन डालने के लिए है। इस मामले में एक समय चरण से आउटपुट केवल उस चरण पर निर्भर करता है:

एक कदम भविष्यवाणी

एक tf.keras.layers.Dense कोई साथ परत activation सेट एक रेखीय मॉडल है। परत केवल से डेटा के अंतिम अक्ष बदल देती है (batch, time, inputs) के लिए (batch, time, units) ; यह भर में हर आइटम के लिए स्वतंत्र रूप से लागू किया जाता है batch और time कुल्हाड़ियों।

linear = tf.keras.Sequential([
    tf.keras.layers.Dense(units=1)
])
print('Input shape:', single_step_window.example[0].shape)
print('Output shape:', linear(single_step_window.example[0]).shape)
Input shape: (32, 1, 19)
2021-08-03 01:29:52.088029: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublas.so.11
Output shape: (32, 1, 1)
2021-08-03 01:29:52.467708: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublasLt.so.11

यह ट्यूटोरियल कई मॉडलों को प्रशिक्षित करता है, इसलिए प्रशिक्षण प्रक्रिया को एक फ़ंक्शन में पैकेज करें:

MAX_EPOCHS = 20

def compile_and_fit(model, window, patience=2):
  early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss',
                                                    patience=patience,
                                                    mode='min')

  model.compile(loss=tf.losses.MeanSquaredError(),
                optimizer=tf.optimizers.Adam(),
                metrics=[tf.metrics.MeanAbsoluteError()])

  history = model.fit(window.train, epochs=MAX_EPOCHS,
                      validation_data=window.val,
                      callbacks=[early_stopping])
  return history

मॉडल को प्रशिक्षित करें और उसके प्रदर्शन का मूल्यांकन करें:

history = compile_and_fit(linear, single_step_window)

val_performance['Linear'] = linear.evaluate(single_step_window.val)
performance['Linear'] = linear.evaluate(single_step_window.test, verbose=0)
Epoch 1/20
1534/1534 [==============================] - 4s 3ms/step - loss: 0.3780 - mean_absolute_error: 0.3770 - val_loss: 0.0286 - val_mean_absolute_error: 0.1310
Epoch 2/20
1534/1534 [==============================] - 4s 3ms/step - loss: 0.0156 - mean_absolute_error: 0.0945 - val_loss: 0.0105 - val_mean_absolute_error: 0.0761
Epoch 3/20
1534/1534 [==============================] - 4s 3ms/step - loss: 0.0102 - mean_absolute_error: 0.0750 - val_loss: 0.0093 - val_mean_absolute_error: 0.0718
Epoch 4/20
1534/1534 [==============================] - 4s 3ms/step - loss: 0.0095 - mean_absolute_error: 0.0717 - val_loss: 0.0089 - val_mean_absolute_error: 0.0700
Epoch 5/20
1534/1534 [==============================] - 4s 2ms/step - loss: 0.0092 - mean_absolute_error: 0.0704 - val_loss: 0.0088 - val_mean_absolute_error: 0.0697
Epoch 6/20
1534/1534 [==============================] - 4s 2ms/step - loss: 0.0091 - mean_absolute_error: 0.0700 - val_loss: 0.0087 - val_mean_absolute_error: 0.0694
Epoch 7/20
1534/1534 [==============================] - 4s 2ms/step - loss: 0.0091 - mean_absolute_error: 0.0697 - val_loss: 0.0087 - val_mean_absolute_error: 0.0697
Epoch 8/20
1534/1534 [==============================] - 4s 3ms/step - loss: 0.0091 - mean_absolute_error: 0.0697 - val_loss: 0.0088 - val_mean_absolute_error: 0.0698
439/439 [==============================] - 1s 2ms/step - loss: 0.0088 - mean_absolute_error: 0.0698

जैसा baseline मॉडल, रेखीय मॉडल व्यापक खिड़कियों के बैच पर कहा जा सकता है। इस तरह इस्तेमाल किया गया मॉडल लगातार समय के चरणों पर स्वतंत्र भविष्यवाणियों का एक सेट बनाता है। time अक्ष एक और की तरह काम करता batch अक्ष। हर समय कदम पर भविष्यवाणियों के बीच कोई बातचीत नहीं होती है।

एक कदम भविष्यवाणी

print('Input shape:', wide_window.example[0].shape)
print('Output shape:', baseline(wide_window.example[0]).shape)
Input shape: (32, 24, 19)
Output shape: (32, 24, 1)

यहाँ पर इसके उदाहरण भविष्यवाणियों की साजिश है wide_window , नोट कितने मामलों में भविष्यवाणी स्पष्ट रूप से सिर्फ इनपुट तापमान लौटने से बेहतर है, लेकिन कुछ मामलों में यह भी बदतर है:

wide_window.plot(linear)

पीएनजी

रैखिक मॉडल का एक फायदा यह है कि वे व्याख्या करने के लिए अपेक्षाकृत सरल हैं। आप परत के भार को बाहर निकाल सकते हैं और प्रत्येक इनपुट को दिए गए भार की कल्पना कर सकते हैं:

plt.bar(x = range(len(train_df.columns)),
        height=linear.layers[0].kernel[:,0].numpy())
axis = plt.gca()
axis.set_xticks(range(len(train_df.columns)))
_ = axis.set_xticklabels(train_df.columns, rotation=90)

पीएनजी

कभी कभी मॉडल भी इनपुट पर सबसे वज़न रखने नहीं है T (degC) । यह यादृच्छिक आरंभीकरण के जोखिमों में से एक है।

सघन

ऐसे मॉडल लागू करने से पहले जो वास्तव में कई समय-चरणों पर काम करते हैं, यह गहन, अधिक शक्तिशाली, एकल इनपुट चरण मॉडल के प्रदर्शन की जांच करने योग्य है।

यहाँ एक मॉडल के समान है linear , मॉडल को छोड़कर यह कई कुछ स्टैक्स Dense इनपुट और आउटपुट के बीच परतों:

dense = tf.keras.Sequential([
    tf.keras.layers.Dense(units=64, activation='relu'),
    tf.keras.layers.Dense(units=64, activation='relu'),
    tf.keras.layers.Dense(units=1)
])

history = compile_and_fit(dense, single_step_window)

val_performance['Dense'] = dense.evaluate(single_step_window.val)
performance['Dense'] = dense.evaluate(single_step_window.test, verbose=0)
Epoch 1/20
1534/1534 [==============================] - 6s 3ms/step - loss: 0.0143 - mean_absolute_error: 0.0809 - val_loss: 0.0078 - val_mean_absolute_error: 0.0638
Epoch 2/20
1534/1534 [==============================] - 5s 3ms/step - loss: 0.0081 - mean_absolute_error: 0.0655 - val_loss: 0.0086 - val_mean_absolute_error: 0.0695
Epoch 3/20
1534/1534 [==============================] - 5s 3ms/step - loss: 0.0075 - mean_absolute_error: 0.0627 - val_loss: 0.0070 - val_mean_absolute_error: 0.0597
Epoch 4/20
1534/1534 [==============================] - 5s 3ms/step - loss: 0.0072 - mean_absolute_error: 0.0607 - val_loss: 0.0067 - val_mean_absolute_error: 0.0583
Epoch 5/20
1534/1534 [==============================] - 5s 3ms/step - loss: 0.0071 - mean_absolute_error: 0.0603 - val_loss: 0.0066 - val_mean_absolute_error: 0.0572
Epoch 6/20
1534/1534 [==============================] - 5s 3ms/step - loss: 0.0069 - mean_absolute_error: 0.0592 - val_loss: 0.0065 - val_mean_absolute_error: 0.0570
Epoch 7/20
1534/1534 [==============================] - 5s 3ms/step - loss: 0.0068 - mean_absolute_error: 0.0585 - val_loss: 0.0072 - val_mean_absolute_error: 0.0608
Epoch 8/20
1534/1534 [==============================] - 5s 3ms/step - loss: 0.0068 - mean_absolute_error: 0.0583 - val_loss: 0.0066 - val_mean_absolute_error: 0.0578
439/439 [==============================] - 1s 2ms/step - loss: 0.0066 - mean_absolute_error: 0.0578

बहु-चरण घना

सिंगल-टाइम-स्टेप मॉडल में इसके इनपुट के वर्तमान मूल्यों के लिए कोई संदर्भ नहीं है। यह नहीं देख सकता कि समय के साथ इनपुट सुविधाएँ कैसे बदल रही हैं। इस समस्या को हल करने के लिए मॉडल को भविष्यवाणी करते समय कई बार चरणों तक पहुंच की आवश्यकता होती है:

प्रत्येक भविष्यवाणी के लिए तीन समय चरणों का उपयोग किया जाता है।

baseline , linear और dense मॉडल स्वतंत्र रूप से हर बार कदम संभाला। यहां मॉडल एकल आउटपुट का उत्पादन करने के लिए इनपुट के रूप में कई बार कदम उठाएगा।

एक बनाएं WindowGenerator कि तीन घंटे की इनपुट और एक घंटे के लेबल के बैच का उत्पादन करेगा:

ध्यान दें कि Window की shift पैरामीटर दो खिड़कियां के अंत के सापेक्ष है।

CONV_WIDTH = 3
conv_window = WindowGenerator(
    input_width=CONV_WIDTH,
    label_width=1,
    shift=1,
    label_columns=['T (degC)'])

conv_window
Total window size: 4
Input indices: [0 1 2]
Label indices: [3]
Label column name(s): ['T (degC)']
conv_window.plot()
plt.title("Given 3 hours of inputs, predict 1 hour into the future.")
Text(0.5, 1.0, 'Given 3 hours of inputs, predict 1 hour into the future.')

पीएनजी

आप एक प्रशिक्षण दे सकते dense एक जोड़कर एक बहु-इनपुट कदम खिड़की पर मॉडल tf.keras.layers.Flatten मॉडल की पहली परत के रूप में:

multi_step_dense = tf.keras.Sequential([
    # Shape: (time, features) => (time*features)
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(units=32, activation='relu'),
    tf.keras.layers.Dense(units=32, activation='relu'),
    tf.keras.layers.Dense(units=1),
    # Add back the time dimension.
    # Shape: (outputs) => (1, outputs)
    tf.keras.layers.Reshape([1, -1]),
])
print('Input shape:', conv_window.example[0].shape)
print('Output shape:', multi_step_dense(conv_window.example[0]).shape)
Input shape: (32, 3, 19)
Output shape: (32, 1, 1)
history = compile_and_fit(multi_step_dense, conv_window)

IPython.display.clear_output()
val_performance['Multi step dense'] = multi_step_dense.evaluate(conv_window.val)
performance['Multi step dense'] = multi_step_dense.evaluate(conv_window.test, verbose=0)
438/438 [==============================] - 1s 2ms/step - loss: 0.0061 - mean_absolute_error: 0.0539
conv_window.plot(multi_step_dense)

पीएनजी

इस दृष्टिकोण का मुख्य नकारात्मक पक्ष यह है कि परिणामी मॉडल को केवल इस आकार की इनपुट विंडो पर ही निष्पादित किया जा सकता है।

print('Input shape:', wide_window.example[0].shape)
try:
  print('Output shape:', multi_step_dense(wide_window.example[0]).shape)
except Exception as e:
  print(f'\n{type(e).__name__}:{e}')
Input shape: (32, 24, 19)

ValueError:Input 0 of layer dense_4 is incompatible with the layer: expected axis -1 of input shape to have value 57 but received input with shape (32, 456)

अगले भाग में संकेंद्रित मॉडल इस समस्या को ठीक करते हैं।

कनवल्शन न्यूरल नेटवर्क

एक घुमाव के परत ( tf.keras.layers.Conv1D ) भी प्रत्येक भविष्यवाणी को इनपुट के रूप में एक से अधिक समय कदम उठाता है।

नीचे के रूप में एक ही मॉडल है multi_step_dense , एक घुमाव के साथ फिर से लिखा।

परिवर्तनों पर ध्यान दें:

conv_model = tf.keras.Sequential([
    tf.keras.layers.Conv1D(filters=32,
                           kernel_size=(CONV_WIDTH,),
                           activation='relu'),
    tf.keras.layers.Dense(units=32, activation='relu'),
    tf.keras.layers.Dense(units=1),
])

यह जांचने के लिए एक उदाहरण बैच पर चलाएँ कि मॉडल अपेक्षित आकार के साथ आउटपुट उत्पन्न करता है:

print("Conv model on `conv_window`")
print('Input shape:', conv_window.example[0].shape)
print('Output shape:', conv_model(conv_window.example[0]).shape)
Conv model on `conv_window`
Input shape: (32, 3, 19)
Output shape: (32, 1, 1)

ट्रेन और पर यह मूल्यांकन conv_window और इसे करने के लिए इसी तरह के प्रदर्शन देना चाहिए multi_step_dense मॉडल।

history = compile_and_fit(conv_model, conv_window)

IPython.display.clear_output()
val_performance['Conv'] = conv_model.evaluate(conv_window.val)
performance['Conv'] = conv_model.evaluate(conv_window.test, verbose=0)
438/438 [==============================] - 1s 2ms/step - loss: 0.0063 - mean_absolute_error: 0.0550

इस बीच का अंतर conv_model और multi_step_dense मॉडल है कि है conv_model किसी भी लम्बाई के इनपुट पर चलाया जा सकता है। इनपुट की स्लाइडिंग विंडो पर कनवल्शनल लेयर लागू होती है:

अनुक्रम पर एक दृढ़ मॉडल निष्पादित करना

यदि आप इसे व्यापक इनपुट पर चलाते हैं, तो यह व्यापक आउटपुट उत्पन्न करता है:

print("Wide window")
print('Input shape:', wide_window.example[0].shape)
print('Labels shape:', wide_window.example[1].shape)
print('Output shape:', conv_model(wide_window.example[0]).shape)
Wide window
Input shape: (32, 24, 19)
Labels shape: (32, 24, 1)
Output shape: (32, 22, 1)

ध्यान दें कि आउटपुट इनपुट से छोटा है। प्रशिक्षण या साजिश रचने का काम करने के लिए, आपको समान लंबाई के लेबल और भविष्यवाणी की आवश्यकता होती है। तो एक का निर्माण WindowGenerator कुछ अतिरिक्त इनपुट समय चरणों के साथ व्यापक खिड़कियों के उत्पादन के लिए तो लेबल और भविष्यवाणी लंबाई से मेल खाते हैं:

LABEL_WIDTH = 24
INPUT_WIDTH = LABEL_WIDTH + (CONV_WIDTH - 1)
wide_conv_window = WindowGenerator(
    input_width=INPUT_WIDTH,
    label_width=LABEL_WIDTH,
    shift=1,
    label_columns=['T (degC)'])

wide_conv_window
Total window size: 27
Input indices: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25]
Label indices: [ 3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26]
Label column name(s): ['T (degC)']
print("Wide conv window")
print('Input shape:', wide_conv_window.example[0].shape)
print('Labels shape:', wide_conv_window.example[1].shape)
print('Output shape:', conv_model(wide_conv_window.example[0]).shape)
Wide conv window
Input shape: (32, 26, 19)
Labels shape: (32, 24, 1)
Output shape: (32, 24, 1)

अब, आप मॉडल की भविष्यवाणियों को एक विस्तृत विंडो पर प्लॉट कर सकते हैं। पहली भविष्यवाणी से पहले 3 इनपुट समय चरणों पर ध्यान दें। यहां हर भविष्यवाणी 3 पूर्ववर्ती समय चरणों पर आधारित है:

wide_conv_window.plot(conv_model)

पीएनजी

आवर्तक तंत्रिका नेटवर्क

एक आवर्तक तंत्रिका नेटवर्क (RNN) एक प्रकार का तंत्रिका नेटवर्क है जो समय श्रृंखला डेटा के लिए उपयुक्त है। आरएनएन एक समय-श्रृंखला को चरण-दर-चरण संसाधित करता है, समय-समय पर आंतरिक स्थिति को बनाए रखता है।

आप में अधिक सीख सकते हैं एक RNN साथ पाठ पीढ़ी ट्यूटोरियल और Keras साथ आवर्तक तंत्रिका नेटवर्क (RNN) गाइड।

इस ट्यूटोरियल में, आप एक RNN परत लांग अल्पकालिक स्मृति (कहा जाता है का उपयोग करेगा tf.keras.layers.LSTM )।

इस तरह के रूप में सभी Keras RNN परतों, के लिए एक महत्वपूर्ण निर्माता तर्क tf.keras.layers.LSTM , है return_sequences तर्क। यह सेटिंग परत को दो में से किसी एक तरीके से कॉन्फ़िगर कर सकती है:

  1. तो False , डिफ़ॉल्ट, परत केवल अंतिम समय कदम के उत्पादन देता है, मॉडल समय एक भी भविष्यवाणी करने से पहले अपनी आंतरिक स्थिति को गर्म करने दे रही है:

एक LSTM वार्म अप और एकल भविष्यवाणी करना

  1. अगर True , परत प्रत्येक इनपुट के लिए एक आउटपुट देता है। यह इसके लिए उपयोगी है:
    • आरएनएन परतों को ढेर करना।
    • एक साथ कई बार चरणों पर एक मॉडल का प्रशिक्षण।

एक LSTM हर कदम के बाद भविष्यवाणी करता है

lstm_model = tf.keras.models.Sequential([
    # Shape [batch, time, features] => [batch, time, lstm_units]
    tf.keras.layers.LSTM(32, return_sequences=True),
    # Shape => [batch, time, features]
    tf.keras.layers.Dense(units=1)
])

साथ return_sequences=True , मॉडल एक समय में डेटा के 24 घंटे पर प्रशिक्षित किया जा सकता है।

print('Input shape:', wide_window.example[0].shape)
print('Output shape:', lstm_model(wide_window.example[0]).shape)
Input shape: (32, 24, 19)
Output shape: (32, 24, 1)
history = compile_and_fit(lstm_model, wide_window)

IPython.display.clear_output()
val_performance['LSTM'] = lstm_model.evaluate(wide_window.val)
performance['LSTM'] = lstm_model.evaluate(wide_window.test, verbose=0)
438/438 [==============================] - 1s 2ms/step - loss: 0.0056 - mean_absolute_error: 0.0514
wide_window.plot(lstm_model)

पीएनजी

प्रदर्शन

इस डेटासेट के साथ आमतौर पर प्रत्येक मॉडल पहले वाले की तुलना में थोड़ा बेहतर करता है:

x = np.arange(len(performance))
width = 0.3
metric_name = 'mean_absolute_error'
metric_index = lstm_model.metrics_names.index('mean_absolute_error')
val_mae = [v[metric_index] for v in val_performance.values()]
test_mae = [v[metric_index] for v in performance.values()]

plt.ylabel('mean_absolute_error [T (degC), normalized]')
plt.bar(x - 0.17, val_mae, width, label='Validation')
plt.bar(x + 0.17, test_mae, width, label='Test')
plt.xticks(ticks=x, labels=performance.keys(),
           rotation=45)
_ = plt.legend()

पीएनजी

for name, value in performance.items():
  print(f'{name:12s}: {value[1]:0.4f}')
Baseline    : 0.0852
Linear      : 0.0682
Dense       : 0.0600
Multi step dense: 0.0549
Conv        : 0.0548
LSTM        : 0.0527

मल्टी-आउटपुट मॉडल

मॉडल अब तक सभी एक ही उत्पादन सुविधा, भविष्यवाणी की T (degC) , एक ही समय के लिए कदम।

इन मॉडलों के सभी बस उत्पादन परत में पुस्तकों की संख्या बदल रहा है और प्रशिक्षण खिड़कियों को एडजस्ट करने में सभी सुविधाओं को शामिल करने के द्वारा एक से अधिक सुविधाओं की भविष्यवाणी करने के लिए परिवर्तित किया जा सकता है labels ( example_labels ):

single_step_window = WindowGenerator(
    # `WindowGenerator` returns all features as labels if you 
    # don't set the `label_columns` argument.
    input_width=1, label_width=1, shift=1)

wide_window = WindowGenerator(
    input_width=24, label_width=24, shift=1)

for example_inputs, example_labels in wide_window.train.take(1):
  print(f'Inputs shape (batch, time, features): {example_inputs.shape}')
  print(f'Labels shape (batch, time, features): {example_labels.shape}')
Inputs shape (batch, time, features): (32, 24, 19)
Labels shape (batch, time, features): (32, 24, 19)

इसके बाद के संस्करण है कि नोट features लेबल की धुरी अब आदानों के रूप में ही गहराई है, के बजाय 1

आधारभूत

एक ही आधारभूत मॉडल ( Baseline ) यहां इस्तेमाल किया जा सकता, लेकिन इस बार सभी सुविधाओं को दोहरा बजाय एक विशिष्ट का चयन label_index :

baseline = Baseline()
baseline.compile(loss=tf.losses.MeanSquaredError(),
                 metrics=[tf.metrics.MeanAbsoluteError()])
val_performance = {}
performance = {}
val_performance['Baseline'] = baseline.evaluate(wide_window.val)
performance['Baseline'] = baseline.evaluate(wide_window.test, verbose=0)
438/438 [==============================] - 1s 1ms/step - loss: 0.0886 - mean_absolute_error: 0.1589

सघन

dense = tf.keras.Sequential([
    tf.keras.layers.Dense(units=64, activation='relu'),
    tf.keras.layers.Dense(units=64, activation='relu'),
    tf.keras.layers.Dense(units=num_features)
])
history = compile_and_fit(dense, single_step_window)

IPython.display.clear_output()
val_performance['Dense'] = dense.evaluate(single_step_window.val)
performance['Dense'] = dense.evaluate(single_step_window.test, verbose=0)
439/439 [==============================] - 1s 2ms/step - loss: 0.0690 - mean_absolute_error: 0.1302

आरएनएन

%%time
wide_window = WindowGenerator(
    input_width=24, label_width=24, shift=1)

lstm_model = tf.keras.models.Sequential([
    # Shape [batch, time, features] => [batch, time, lstm_units]
    tf.keras.layers.LSTM(32, return_sequences=True),
    # Shape => [batch, time, features]
    tf.keras.layers.Dense(units=num_features)
])

history = compile_and_fit(lstm_model, wide_window)

IPython.display.clear_output()
val_performance['LSTM'] = lstm_model.evaluate( wide_window.val)
performance['LSTM'] = lstm_model.evaluate( wide_window.test, verbose=0)

print()
438/438 [==============================] - 1s 2ms/step - loss: 0.0617 - mean_absolute_error: 0.1210

CPU times: user 3min 47s, sys: 51.9 s, total: 4min 38s
Wall time: 1min 29s

उन्नत: अवशिष्ट कनेक्शन

Baseline पहले से मॉडल तथ्य यह है कि अनुक्रम समय कदम के लिए समय कदम से काफी परिवर्तन नहीं करता है का फायदा उठाया। इस ट्यूटोरियल में अब तक प्रशिक्षित प्रत्येक मॉडल को बेतरतीब ढंग से इनिशियलाइज़ किया गया था, और फिर यह सीखना था कि आउटपुट पिछले समय के चरण से एक छोटा बदलाव है।

जबकि आप इस मुद्दे को सावधानीपूर्वक आरंभीकरण के साथ प्राप्त कर सकते हैं, इसे मॉडल संरचना में बनाना आसान है।

मॉडल बनाने के लिए समय श्रृंखला विश्लेषण में यह सामान्य है कि अगले मूल्य की भविष्यवाणी करने के बजाय, भविष्यवाणी करें कि अगली बार चरण में मूल्य कैसे बदलेगा। इसी तरह, अवशिष्ट नेटवर्क -या गहरी सीखने ResNets-इन आर्किटेक्चर का उल्लेख जहां प्रत्येक परत मॉडल की जमा परिणाम के लिए कहते हैं।

इस तरह आप इस ज्ञान का लाभ उठाते हैं कि परिवर्तन छोटा होना चाहिए।

अवशिष्ट कनेक्शन वाला एक मॉडल

अनिवार्य रूप से, इस मॉडल का मिलान करने के लिए आरंभ Baseline । इस कार्य के लिए यह मॉडल को थोड़ा बेहतर प्रदर्शन के साथ तेजी से अभिसरण करने में मदद करता है।

इस ट्यूटोरियल में चर्चा किए गए किसी भी मॉडल के संयोजन के साथ इस दृष्टिकोण का उपयोग किया जा सकता है।

यहाँ, यह LSTM मॉडल पर लागू किया जा रहा है, के उपयोग पर ध्यान दें tf.initializers.zeros सुनिश्चित करना है कि प्रारंभिक भविष्यवाणी परिवर्तन छोटे हैं, और अवशिष्ट कनेक्शन को पराजित नहीं करना है। वहाँ के बाद से, यहाँ ढ़ाल के लिए कोई समरूपता को तोड़ने चिंताएं हैं zeros केवल पिछले परत पर किया जाता है।

class ResidualWrapper(tf.keras.Model):
  def __init__(self, model):
    super().__init__()
    self.model = model

  def call(self, inputs, *args, **kwargs):
    delta = self.model(inputs, *args, **kwargs)

    # The prediction for each time step is the input
    # from the previous time step plus the delta
    # calculated by the model.
    return inputs + delta
%%time
residual_lstm = ResidualWrapper(
    tf.keras.Sequential([
    tf.keras.layers.LSTM(32, return_sequences=True),
    tf.keras.layers.Dense(
        num_features,
        # The predicted deltas should start small.
        # Therefore, initialize the output layer with zeros.
        kernel_initializer=tf.initializers.zeros())
]))

history = compile_and_fit(residual_lstm, wide_window)

IPython.display.clear_output()
val_performance['Residual LSTM'] = residual_lstm.evaluate(wide_window.val)
performance['Residual LSTM'] = residual_lstm.evaluate(wide_window.test, verbose=0)
print()
438/438 [==============================] - 1s 2ms/step - loss: 0.0619 - mean_absolute_error: 0.1180

CPU times: user 1min 49s, sys: 25.1 s, total: 2min 14s
Wall time: 43.4 s

प्रदर्शन

इन बहु-आउटपुट मॉडलों के लिए समग्र प्रदर्शन यहां दिया गया है।

x = np.arange(len(performance))
width = 0.3

metric_name = 'mean_absolute_error'
metric_index = lstm_model.metrics_names.index('mean_absolute_error')
val_mae = [v[metric_index] for v in val_performance.values()]
test_mae = [v[metric_index] for v in performance.values()]

plt.bar(x - 0.17, val_mae, width, label='Validation')
plt.bar(x + 0.17, test_mae, width, label='Test')
plt.xticks(ticks=x, labels=performance.keys(),
           rotation=45)
plt.ylabel('MAE (average over all outputs)')
_ = plt.legend()

पीएनजी

for name, value in performance.items():
  print(f'{name:15s}: {value[1]:0.4f}')
Baseline       : 0.1638
Dense          : 0.1321
LSTM           : 0.1229
Residual LSTM  : 0.1191

उपरोक्त प्रदर्शन सभी मॉडल आउटपुट में औसत हैं।

बहु-चरण मॉडल

दोनों एकल उत्पादन और पिछले अनुभाग में मल्टीपल-आउटपुट मॉडल एक बार कदम भविष्यवाणियों, भविष्य में एक घंटे कर दिया।

इस अनुभाग में बताया इन मॉडलों का विस्तार करने के लिए कई बार का चरण अनुमान लगाने के लिए पर लग रहा है।

बहु-चरणीय भविष्यवाणी में, मॉडल को भविष्य के मूल्यों की एक श्रृंखला की भविष्यवाणी करना सीखना होगा। इस प्रकार, एकल चरण मॉडल के विपरीत, जहां केवल एक भविष्य के बिंदु की भविष्यवाणी की जाती है, एक बहु-चरण मॉडल भविष्य के मूल्यों के अनुक्रम की भविष्यवाणी करता है।

इसके लिए दो मोटे दृष्टिकोण हैं:

  1. सिंगल शॉट भविष्यवाणियां जहां पूरी समय श्रृंखला की भविष्यवाणी एक ही बार में की जाती है।
  2. ऑटोरेग्रेसिव भविष्यवाणियां जहां मॉडल केवल एकल चरण भविष्यवाणियां करता है और इसके आउटपुट को इसके इनपुट के रूप में वापस फीड किया जाता है।

इस खंड में सभी मॉडलों के सभी उत्पादन विभिन्न समयावधियों में सभी सुविधाओं की भविष्यवाणी करेगा।

मल्टी-स्टेप मॉडल के लिए, प्रशिक्षण डेटा में फिर से प्रति घंटा नमूने होते हैं। हालांकि, यहां, मॉडल 24 घंटे अतीत को देखते हुए, भविष्य में 24 घंटे की भविष्यवाणी करना सीखेंगे।

यहाँ एक है Window उद्देश्य यह है कि डाटासेट से इन स्लाइस उत्पन्न करता है:

OUT_STEPS = 24
multi_window = WindowGenerator(input_width=24,
                               label_width=OUT_STEPS,
                               shift=OUT_STEPS)

multi_window.plot()
multi_window
Total window size: 48
Input indices: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
Label indices: [24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47]
Label column name(s): None

पीएनजी

आधार रेखा

इस कार्य के लिए एक सरल आधार रेखा आउटपुट समय चरणों की आवश्यक संख्या के लिए अंतिम इनपुट समय चरण को दोहराना है:

प्रत्येक आउटपुट चरण के लिए अंतिम इनपुट दोहराएं

class MultiStepLastBaseline(tf.keras.Model):
  def call(self, inputs):
    return tf.tile(inputs[:, -1:, :], [1, OUT_STEPS, 1])

last_baseline = MultiStepLastBaseline()
last_baseline.compile(loss=tf.losses.MeanSquaredError(),
                      metrics=[tf.metrics.MeanAbsoluteError()])

multi_val_performance = {}
multi_performance = {}

multi_val_performance['Last'] = last_baseline.evaluate(multi_window.val)
multi_performance['Last'] = last_baseline.evaluate(multi_window.test, verbose=0)
multi_window.plot(last_baseline)
437/437 [==============================] - 1s 1ms/step - loss: 0.6285 - mean_absolute_error: 0.5007

पीएनजी

चूंकि यह कार्य भविष्य में 24 घंटों की भविष्यवाणी करना है, पिछले 24 घंटों को देखते हुए, एक और आसान तरीका पिछले दिन को दोहराना है, यह मानते हुए कि कल समान होगा:

पिछले दिन दोहराएं

class RepeatBaseline(tf.keras.Model):
  def call(self, inputs):
    return inputs

repeat_baseline = RepeatBaseline()
repeat_baseline.compile(loss=tf.losses.MeanSquaredError(),
                        metrics=[tf.metrics.MeanAbsoluteError()])

multi_val_performance['Repeat'] = repeat_baseline.evaluate(multi_window.val)
multi_performance['Repeat'] = repeat_baseline.evaluate(multi_window.test, verbose=0)
multi_window.plot(repeat_baseline)
437/437 [==============================] - 1s 2ms/step - loss: 0.4270 - mean_absolute_error: 0.3959

पीएनजी

सिंगल-शॉट मॉडल

इस समस्या के लिए एक उच्च-स्तरीय दृष्टिकोण "सिंगल-शॉट" मॉडल का उपयोग करना है, जहां मॉडल एक ही चरण में पूरे अनुक्रम की भविष्यवाणी करता है।

यह कुशलता से एक के रूप में लागू किया जा सकता tf.keras.layers.Dense साथ OUT_STEPS*features उत्पादन इकाइयों। मॉडल सिर्फ आवश्यक है कि उत्पादन नयी आकृति प्रदान करने की जरूरत है (OUTPUT_STEPS, features)

रैखिक

अंतिम इनपुट समय चरण के आधार पर एक साधारण रैखिक मॉडल बेसलाइन से बेहतर करता है, लेकिन कम शक्ति वाला होता है। मॉडल भविष्यवाणी करने के लिए की जरूरत है OUTPUT_STEPS एक रेखीय प्रक्षेपण के साथ एक एकल इनपुट बार का चरण-समय कदम,। यह केवल व्यवहार का एक निम्न-आयामी टुकड़ा कैप्चर कर सकता है, संभवतः मुख्य रूप से दिन के समय और वर्ष के समय पर आधारित होता है।

अंतिम समय-चरण से सभी समय-चरणों की भविष्यवाणी करें

multi_linear_model = tf.keras.Sequential([
    # Take the last time-step.
    # Shape [batch, time, features] => [batch, 1, features]
    tf.keras.layers.Lambda(lambda x: x[:, -1:, :]),
    # Shape => [batch, 1, out_steps*features]
    tf.keras.layers.Dense(OUT_STEPS*num_features,
                          kernel_initializer=tf.initializers.zeros()),
    # Shape => [batch, out_steps, features]
    tf.keras.layers.Reshape([OUT_STEPS, num_features])
])

history = compile_and_fit(multi_linear_model, multi_window)

IPython.display.clear_output()
multi_val_performance['Linear'] = multi_linear_model.evaluate(multi_window.val)
multi_performance['Linear'] = multi_linear_model.evaluate(multi_window.test, verbose=0)
multi_window.plot(multi_linear_model)
437/437 [==============================] - 1s 2ms/step - loss: 0.2555 - mean_absolute_error: 0.3052

पीएनजी

सघन

एक जोड़ा जा रहा है tf.keras.layers.Dense इनपुट और आउटपुट के बीच रेखीय मॉडल अधिक शक्ति देता है, लेकिन अभी भी केवल एक ही इनपुट समय कदम पर आधारित है।

multi_dense_model = tf.keras.Sequential([
    # Take the last time step.
    # Shape [batch, time, features] => [batch, 1, features]
    tf.keras.layers.Lambda(lambda x: x[:, -1:, :]),
    # Shape => [batch, 1, dense_units]
    tf.keras.layers.Dense(512, activation='relu'),
    # Shape => [batch, out_steps*features]
    tf.keras.layers.Dense(OUT_STEPS*num_features,
                          kernel_initializer=tf.initializers.zeros()),
    # Shape => [batch, out_steps, features]
    tf.keras.layers.Reshape([OUT_STEPS, num_features])
])

history = compile_and_fit(multi_dense_model, multi_window)

IPython.display.clear_output()
multi_val_performance['Dense'] = multi_dense_model.evaluate(multi_window.val)
multi_performance['Dense'] = multi_dense_model.evaluate(multi_window.test, verbose=0)
multi_window.plot(multi_dense_model)
437/437 [==============================] - 1s 2ms/step - loss: 0.2214 - mean_absolute_error: 0.2850

पीएनजी

सीएनएन

एक दृढ़ मॉडल एक निश्चित-चौड़ाई के इतिहास के आधार पर भविष्यवाणियां करता है, जिससे घने मॉडल की तुलना में बेहतर प्रदर्शन हो सकता है क्योंकि यह देख सकता है कि समय के साथ चीजें कैसे बदल रही हैं:

एक दृढ़ मॉडल देखता है कि समय के साथ चीजें कैसे बदलती हैं

CONV_WIDTH = 3
multi_conv_model = tf.keras.Sequential([
    # Shape [batch, time, features] => [batch, CONV_WIDTH, features]
    tf.keras.layers.Lambda(lambda x: x[:, -CONV_WIDTH:, :]),
    # Shape => [batch, 1, conv_units]
    tf.keras.layers.Conv1D(256, activation='relu', kernel_size=(CONV_WIDTH)),
    # Shape => [batch, 1,  out_steps*features]
    tf.keras.layers.Dense(OUT_STEPS*num_features,
                          kernel_initializer=tf.initializers.zeros()),
    # Shape => [batch, out_steps, features]
    tf.keras.layers.Reshape([OUT_STEPS, num_features])
])

history = compile_and_fit(multi_conv_model, multi_window)

IPython.display.clear_output()

multi_val_performance['Conv'] = multi_conv_model.evaluate(multi_window.val)
multi_performance['Conv'] = multi_conv_model.evaluate(multi_window.test, verbose=0)
multi_window.plot(multi_conv_model)
437/437 [==============================] - 1s 2ms/step - loss: 0.2136 - mean_absolute_error: 0.2788

पीएनजी

आरएनएन

एक आवर्तक मॉडल इनपुट के लंबे इतिहास का उपयोग करना सीख सकता है, यदि यह मॉडल द्वारा की जा रही भविष्यवाणियों के लिए प्रासंगिक है। यहां अगले 24 घंटों के लिए एक भी भविष्यवाणी करने से पहले, मॉडल 24 घंटों के लिए आंतरिक स्थिति जमा करेगा।

इस सिंगल-शॉट प्रारूप में, LSTM केवल पिछली बार कदम पर एक आउटपुट है, तो सेट का उत्पादन करने की जरूरत है return_sequences=False में tf.keras.layers.LSTM

LSTM इनपुट विंडो पर राज्य जमा करता है, और अगले 24 घंटों के लिए एकल भविष्यवाणी करता है

multi_lstm_model = tf.keras.Sequential([
    # Shape [batch, time, features] => [batch, lstm_units].
    # Adding more `lstm_units` just overfits more quickly.
    tf.keras.layers.LSTM(32, return_sequences=False),
    # Shape => [batch, out_steps*features].
    tf.keras.layers.Dense(OUT_STEPS*num_features,
                          kernel_initializer=tf.initializers.zeros()),
    # Shape => [batch, out_steps, features].
    tf.keras.layers.Reshape([OUT_STEPS, num_features])
])

history = compile_and_fit(multi_lstm_model, multi_window)

IPython.display.clear_output()

multi_val_performance['LSTM'] = multi_lstm_model.evaluate(multi_window.val)
multi_performance['LSTM'] = multi_lstm_model.evaluate(multi_window.test, verbose=0)
multi_window.plot(multi_lstm_model)
437/437 [==============================] - 1s 2ms/step - loss: 0.2147 - mean_absolute_error: 0.2866

पीएनजी

उन्नत: ऑटोरेग्रेसिव मॉडल

उपरोक्त सभी मॉडल एक ही चरण में संपूर्ण आउटपुट अनुक्रम की भविष्यवाणी करते हैं।

कुछ मामलों में यह मॉडल के लिए इस भविष्यवाणी को अलग-अलग समय चरणों में विघटित करने में मददगार हो सकता है। फिर, प्रत्येक मॉडल के उत्पादन प्रत्येक चरण में ही में वापस खिलाया जा सकता है और पूर्वानुमान पिछले एक पर वातानुकूलित बनाया जा सकता है, क्लासिक में तरह उत्पन्न दृश्यों के साथ बार-बार होने तंत्रिका नेटवर्क

मॉडल की इस शैली का एक स्पष्ट लाभ यह है कि इसे अलग-अलग लंबाई के साथ आउटपुट का उत्पादन करने के लिए स्थापित किया जा सकता है।

आप इस ट्यूटोरियल के पहले भाग में प्रशिक्षित सिंगल-स्टेप मल्टी-आउटपुट मॉडल में से कोई भी ले सकते हैं और ऑटोरेग्रेसिव फीडबैक लूप में चला सकते हैं, लेकिन यहां आप एक मॉडल बनाने पर ध्यान केंद्रित करेंगे जिसे स्पष्ट रूप से ऐसा करने के लिए प्रशिक्षित किया गया है।

किसी मॉडल के आउटपुट को उसके इनपुट पर प्रतिक्रिया दें

आरएनएन

यह ट्यूटोरियल केवल एक ऑटोरेग्रेसिव आरएनएन मॉडल बनाता है, लेकिन यह पैटर्न किसी भी मॉडल पर लागू किया जा सकता है जिसे सिंगल टाइम स्टेप को आउटपुट करने के लिए डिज़ाइन किया गया था।

एक मॉडल एकल कदम LSTM मॉडल पहले से रूप में एक ही बुनियादी रूप होगा tf.keras.layers.LSTM परत एक के बाद tf.keras.layers.Dense परत धर्मान्तरित कि LSTM मॉडल भविष्यवाणियों के परत के आउटपुट।

एक tf.keras.layers.LSTM एक है tf.keras.layers.LSTMCell उच्च स्तर में लिपटे tf.keras.layers.RNN कि (आप के लिए राज्य और अनुक्रम परिणाम का प्रबंधन करता है की जाँच करें Keras साथ आवर्तक तंत्रिका नेटवर्क (RNN) विवरण के लिए गाइड)।

इस मामले में, मॉडल मैन्युअल, प्रत्येक चरण के लिए आदानों का प्रबंधन करने तो यह का उपयोग करता है tf.keras.layers.LSTMCell निचले स्तर, एक बार कदम इंटरफेस के लिए सीधे।

class FeedBack(tf.keras.Model):
  def __init__(self, units, out_steps):
    super().__init__()
    self.out_steps = out_steps
    self.units = units
    self.lstm_cell = tf.keras.layers.LSTMCell(units)
    # Also wrap the LSTMCell in an RNN to simplify the `warmup` method.
    self.lstm_rnn = tf.keras.layers.RNN(self.lstm_cell, return_state=True)
    self.dense = tf.keras.layers.Dense(num_features)
feedback_model = FeedBack(units=32, out_steps=OUT_STEPS)

पहली विधि इस मॉडल की जरूरत है एक है warmup इनपुट के आधार पर अपनी आंतरिक स्थिति प्रारंभ करने में विधि। एक बार प्रशिक्षित होने के बाद, यह राज्य इनपुट इतिहास के प्रासंगिक भागों पर कब्जा कर लेगा। यह एकल-चरण के बराबर है LSTM पहले से मॉडल:

def warmup(self, inputs):
  # inputs.shape => (batch, time, features)
  # x.shape => (batch, lstm_units)
  x, *state = self.lstm_rnn(inputs)

  # predictions.shape => (batch, features)
  prediction = self.dense(x)
  return prediction, state

FeedBack.warmup = warmup

इस विधि देता है एक ही समय कदम भविष्यवाणी और की आंतरिक स्थिति LSTM :

prediction, state = feedback_model.warmup(multi_window.example[0])
prediction.shape
TensorShape([32, 19])

साथ RNN के राज्य है, और एक प्रारंभिक भविष्यवाणी अब आप बार-बार दोहराना मॉडल इनपुट के रूप में हर कदम पीछे भविष्यवाणियों खिला जारी रख सकते हैं।

उत्पादन भविष्यवाणियों इकट्ठा करने के लिए सबसे सरल दृष्टिकोण एक अजगर की सूची और एक प्रयोग है tf.stack पाश के बाद।

def call(self, inputs, training=None):
  # Use a TensorArray to capture dynamically unrolled outputs.
  predictions = []
  # Initialize the LSTM state.
  prediction, state = self.warmup(inputs)

  # Insert the first prediction.
  predictions.append(prediction)

  # Run the rest of the prediction steps.
  for n in range(1, self.out_steps):
    # Use the last prediction as input.
    x = prediction
    # Execute one lstm step.
    x, state = self.lstm_cell(x, states=state,
                              training=training)
    # Convert the lstm output to a prediction.
    prediction = self.dense(x)
    # Add the prediction to the output.
    predictions.append(prediction)

  # predictions.shape => (time, batch, features)
  predictions = tf.stack(predictions)
  # predictions.shape => (batch, time, features)
  predictions = tf.transpose(predictions, [1, 0, 2])
  return predictions

FeedBack.call = call

उदाहरण इनपुट पर इस मॉडल का परीक्षण करें:

print('Output shape (batch, time, features): ', feedback_model(multi_window.example[0]).shape)
Output shape (batch, time, features):  (32, 24, 19)

अब, मॉडल को प्रशिक्षित करें:

history = compile_and_fit(feedback_model, multi_window)

IPython.display.clear_output()

multi_val_performance['AR LSTM'] = feedback_model.evaluate(multi_window.val)
multi_performance['AR LSTM'] = feedback_model.evaluate(multi_window.test, verbose=0)
multi_window.plot(feedback_model)
437/437 [==============================] - 3s 7ms/step - loss: 0.2267 - mean_absolute_error: 0.3020

पीएनजी

प्रदर्शन

इस समस्या पर मॉडल जटिलता के एक समारोह के रूप में स्पष्ट रूप से कम रिटर्न है:

x = np.arange(len(multi_performance))
width = 0.3

metric_name = 'mean_absolute_error'
metric_index = lstm_model.metrics_names.index('mean_absolute_error')
val_mae = [v[metric_index] for v in multi_val_performance.values()]
test_mae = [v[metric_index] for v in multi_performance.values()]

plt.bar(x - 0.17, val_mae, width, label='Validation')
plt.bar(x + 0.17, test_mae, width, label='Test')
plt.xticks(ticks=x, labels=multi_performance.keys(),
           rotation=45)
plt.ylabel(f'MAE (average over all times and outputs)')
_ = plt.legend()

पीएनजी

इस ट्यूटोरियल की पहली छमाही में बहु-आउटपुट मॉडल के लिए मेट्रिक्स सभी आउटपुट सुविधाओं में औसत प्रदर्शन दिखाते हैं। ये प्रदर्शन समान हैं लेकिन आउटपुट समय चरणों में औसत भी हैं।

for name, value in multi_performance.items():
  print(f'{name:8s}: {value[1]:0.4f}')
Last    : 0.5157
Repeat  : 0.3774
Linear  : 0.2984
Dense   : 0.2800
Conv    : 0.2727
LSTM    : 0.2755
AR LSTM : 0.2903

घने मॉडल से दृढ़ और आवर्तक मॉडल में जाने से प्राप्त लाभ केवल कुछ प्रतिशत (यदि कोई हो) हैं, और ऑटोरेग्रेसिव मॉडल ने स्पष्ट रूप से खराब प्रदर्शन किया। इन अधिक जटिल दृष्टिकोण इस समस्या पर जबकि लायक नहीं हो तो सकता है, लेकिन कोई रास्ता नहीं की कोशिश कर रहा बिना पता करने के लिए था, और इन मॉडलों आपकी समस्या के लिए उपयोगी हो सकता है।

अगला कदम

यह ट्यूटोरियल TensorFlow का उपयोग करके समय श्रृंखला पूर्वानुमान का एक त्वरित परिचय था।

अधिक जानने के लिए, देखें:

यह भी ध्यान रखें कि आप किसी भी लागू कर सकते हैं शास्त्रीय समय श्रृंखला मॉडल TensorFlow-इस ट्यूटोरियल में बस पर केंद्रित है TensorFlow के अंतर्निहित कार्यक्षमता।