Skip to content

Commit 8436757

Browse files
committed
110 of 100 Days of Python
We created our first deep RNN. Also, we learned about how to make predictions about the next N steps, not just the immediate next step. The model was trained for just a few epochs, but performed very well.
1 parent 1bd79a4 commit 8436757

10 files changed

+796
-33
lines changed

HandsOnMachineLearningWithScikitLearnAndTensorFlow/.ipynb_checkpoints/homl_ch15_Processing-sequences-using-RNNs-and-CNNs-checkpoint.ipynb

Lines changed: 298 additions & 12 deletions
Large diffs are not rendered by default.

HandsOnMachineLearningWithScikitLearnAndTensorFlow/homl_ch15_Processing-sequences-using-RNNs-and-CNNs.ipynb

Lines changed: 298 additions & 12 deletions
Large diffs are not rendered by default.

HandsOnMachineLearningWithScikitLearnAndTensorFlow/homl_ch15_Processing-sequences-using-RNNs-and-CNNs.md

Lines changed: 195 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ np.mean(keras.losses.mean_squared_error(y_valid, naive_pred))
126126

127127
Another approach is to use a very simple neural network.
128128
Here we can use a single dense neuron; the output is thus a linear combination of the inputs.
129-
This model can make predictions on the validation data with a MSE of 0.003.
129+
This model can make predictions on the validation data with a MSE of 0.004.
130130

131131

132132
```python
@@ -142,10 +142,9 @@ model.compile(
142142

143143
history = model.fit(
144144
X_train, y_train,
145-
epochs=100,
145+
epochs=20,
146146
validation_data=(X_valid, y_valid),
147-
verbose=0,
148-
callbacks=[keras.callbacks.EarlyStopping(patience=5)]
147+
verbose=0
149148
)
150149
```
151150

@@ -168,7 +167,7 @@ np.mean(keras.losses.mean_squared_error(y_valid, y_pred))
168167

169168

170169

171-
0.00327249
170+
0.0036995797
172171

173172

174173

@@ -195,10 +194,9 @@ simple_rnn.compile(
195194

196195
history = simple_rnn.fit(
197196
X_train, y_train,
198-
epochs=100,
197+
epochs=20,
199198
validation_data=(X_valid, y_valid),
200-
verbose=0,
201-
callbacks=[keras.callbacks.EarlyStopping(patience=5)]
199+
verbose=0
202200
)
203201
```
204202

@@ -221,8 +219,196 @@ np.mean(keras.losses.mean_squared_error(y_valid, y_pred))
221219

222220

223221

224-
0.011389356
222+
0.13912646
225223

226224

227225

228226
### Deep RNNs
227+
228+
Keras makes it easy to make a deep RNN by just stacking `SimpleRNN` layers.
229+
Note that it is necessary to explicitly tell each layer to output the entire sequence so that the next layer doesn't just receive the final output of the previous one.
230+
231+
We can use another `SimpleRNN` for the final layer, but it is often preferrable to use a single `Dense` neuron.
232+
One reason is that there is only one hidden variable for the single recurrent neuron whereas the normal neuron has a weight for each input.
233+
Also, the recurrent neuron uses the tanh activation function, limiting the output to between -1 and 1.
234+
235+
236+
```python
237+
deep_rnn = keras.models.Sequential([
238+
keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]),
239+
keras.layers.SimpleRNN(20, return_sequences=False),
240+
keras.layers.Dense(1)
241+
])
242+
243+
deep_rnn.compile(
244+
optimizer=keras.optimizers.Nadam(),
245+
loss=keras.losses.MeanSquaredError()
246+
)
247+
248+
history = deep_rnn.fit(
249+
X_train, y_train,
250+
epochs=10,
251+
validation_data=(X_valid, y_valid),
252+
verbose=0
253+
)
254+
```
255+
256+
257+
```python
258+
pd.DataFrame(history.history).plot(figsize=(8, 6))
259+
plt.show()
260+
```
261+
262+
263+
![png](homl_ch15_Processing-sequences-using-RNNs-and-CNNs_files/homl_ch15_Processing-sequences-using-RNNs-and-CNNs_19_0.png)
264+
265+
266+
267+
```python
268+
y_pred = deep_rnn.predict(X_valid)
269+
np.mean(keras.losses.mean_squared_error(y_valid, y_pred))
270+
```
271+
272+
273+
274+
275+
0.003383608
276+
277+
278+
279+
### Forecasting several time steps ahead
280+
281+
So far, we have only predicted the value at the next time step, but we could have predicted the value after 10 additional steps by changing how we split the mock data into X and y datasets.
282+
But what if we wanted to predict all of the next 10 steps.
283+
284+
One way to do this is to use the model trained above to predict the next step, then add that output to the input and have it predict the next step after that, and so on.
285+
286+
287+
```python
288+
np.random.seed(2)
289+
series = generate_time_series(1, n_steps + 10)
290+
X_new, Y_new = series[:, :n_steps], series[:, n_steps:]
291+
X = X_new
292+
for step_ahead in range(10):
293+
y_pred_one = model.predict(X[:, step_ahead:])[:, np.newaxis, :]
294+
X = np.concatenate([X, y_pred_one], axis=1)
295+
296+
Y_pred = X[:, n_steps:]
297+
```
298+
299+
300+
```python
301+
fig = plt.figure(figsize=(8, 5))
302+
plt.plot(range(X_new.shape[1]),
303+
X_new[0, :, 0],
304+
'k-o')
305+
plt.plot(range(X_new.shape[1], X_new.shape[1] + Y_new.shape[1]),
306+
Y_new[0, :, 0],
307+
'g--x', label='real')
308+
plt.plot(range(X_new.shape[1], X_new.shape[1] + Y_pred.shape[1]),
309+
Y_pred[0, :, 0],
310+
'r--o', label='forecast')
311+
plt.xlabel('time step', fontsize=14)
312+
plt.ylabel('value', fontsize=14)
313+
plt.title('Forecasting several times steps ahead', fontsize=18)
314+
plt.legend(loc='best')
315+
plt.show()
316+
```
317+
318+
319+
![png](homl_ch15_Processing-sequences-using-RNNs-and-CNNs_files/homl_ch15_Processing-sequences-using-RNNs-and-CNNs_23_0.png)
320+
321+
322+
Another option is to train the RNN to predict all 10 next values at once.
323+
We will still use a sequence to vector model, but there will be 10 output values instead of 1.
324+
We must first, however, change the targets to be vectors containing the last 10 values.
325+
326+
327+
```python
328+
np.random.seed(0)
329+
series = generate_time_series(10000, n_steps + 10)
330+
X_train, Y_train = series[:7000, :n_steps], series[:7000, -10:, 0]
331+
X_valid, Y_valid = series[7000:9000, :n_steps], series[7000:9000, -10:, 0]
332+
X_test, Y_test = series[9000:, :n_steps], series[9000:, -10:, 0]
333+
```
334+
335+
The only change to the model is that the final dense layer must have 10 neurons.
336+
337+
338+
```python
339+
deep_rnn_10steps = keras.models.Sequential([
340+
keras.layers.SimpleRNN(20, return_sequences=True, input_shape=[None, 1]),
341+
keras.layers.SimpleRNN(20),
342+
keras.layers.Dense(10)
343+
])
344+
345+
deep_rnn_10steps.compile(
346+
optimizer=keras.optimizers.Nadam(),
347+
loss=keras.losses.MeanSquaredError()
348+
)
349+
350+
history = deep_rnn_10steps.fit(
351+
X_train, Y_train,
352+
epochs=20,
353+
validation_data=(X_valid, Y_valid),
354+
verbose=0
355+
)
356+
```
357+
358+
359+
```python
360+
pd.DataFrame(history.history).plot(figsize=(8, 6))
361+
plt.show()
362+
```
363+
364+
365+
![png](homl_ch15_Processing-sequences-using-RNNs-and-CNNs_files/homl_ch15_Processing-sequences-using-RNNs-and-CNNs_28_0.png)
366+
367+
368+
369+
```python
370+
Y_pred = deep_rnn_10steps.predict(X_valid)
371+
np.mean(keras.losses.mean_squared_error(Y_valid, Y_pred))
372+
```
373+
374+
375+
376+
377+
0.008342622
378+
379+
380+
381+
382+
```python
383+
Y_pred = deep_rnn_10steps.predict(X_new)
384+
385+
fig = plt.figure(figsize=(8, 5))
386+
plt.plot(range(X_new.shape[1]),
387+
X_new[0, :, 0],
388+
'k-o')
389+
plt.plot(range(X_new.shape[1], X_new.shape[1] + Y_new.shape[1]),
390+
Y_new[0, :, 0],
391+
'g--x', label='real')
392+
plt.plot(range(X_new.shape[1], X_new.shape[1] + Y_pred.shape[1]),
393+
Y_pred[0, :],
394+
'r--o', label='forecast')
395+
plt.xlabel('time step', fontsize=14)
396+
plt.ylabel('value', fontsize=14)
397+
plt.title('Forecasting several times steps ahead', fontsize=18)
398+
plt.legend(loc='best')
399+
plt.show()
400+
```
401+
402+
403+
![png](homl_ch15_Processing-sequences-using-RNNs-and-CNNs_files/homl_ch15_Processing-sequences-using-RNNs-and-CNNs_30_0.png)
404+
405+
406+
We can do still better by having the model constantly trying to predict the next 10 steps from the very beginning, not just the very end.
407+
This basically increases the amount of training data for the model.
408+
409+
**To-Do**: finish up this section, tomorrow.
410+
411+
412+
```python
413+
414+
```
Loading
Loading
Loading
Loading
Loading
Loading

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,3 +494,8 @@ I began the chapter on Recurrent Neural Networks (chapter 15).
494494
**Day 109 - February 12, 2020:**
495495
We covered the basics of RNNs and the different types based on their input and output shapes.
496496
We began a simple example on mock training data.
497+
498+
**Day 110 - February 13, 2020:**
499+
We created our first deep RNN.
500+
Also, we learned about how to make predictions about the next N steps, not just the immediate next step.
501+
The model was trained for just a few epochs, but performed very well.

0 commit comments

Comments
 (0)