Керас застрял в первой эпохе только при использовании генератора проверки - PullRequest
0 голосов
/ 18 июня 2020

Я читаю книгу по глубокому обучению под названием Глубокое обучение с python. Книга устарела с точки зрения кода, но я прочитал официальную документацию, чтобы разобраться в ней. В любом случае

Это программа, которая должна обучать простую модель для прогнозирования температуры временных рядов с использованием доступного набора данных здесь .

Программа выглядит следующим образом

import numpy as np
from keras.models import Sequential
from keras import layers
from keras.optimizers import RMSprop

#Loading file 
f = open(fname) # fname is the filepath for the csv file
data = f.read()
f.close()
lines = data.split('\n')
header = lines[0].split(',')
lines = lines[1:]

# Converting into numpy array
float_data = np.zeros((len(lines), len(header) - 1))
for i, line in enumerate(lines):
values = [float(x) for x in line.split(',')[1:]]
float_data[i, :] = values

# Normalizing the data 
mean = float_data[:200000].mean(axis=0)
float_data -= mean
std = float_data[:200000].std(axis=0)
float_data /= std

Существует функция генератора для создания набора данных (я читал, что tensorflow.keras.utils.Sequence является предпочтительным выбором, но мне не удалось преобразовать этот генератор в подкласс Sequence

def generator(data, lookback, delay, min_index, max_index, shuffle=False, batch_size=128, step=6):
  if max_index is None:
    max_index = len(data) - delay - 1
  i = min_index + lookback

  while 1:
    if shuffle:
      rows = np.random.randint(min_index + lookback, max_index, size=batch_size)
    else:
      if i + batch_size >= max_index:
        i = min_index + lookback

      rows = np.arange(i, min(i + batch_size, max_index))
      i += len(rows)

    samples = np.zeros((len(rows),lookback // step,data.shape[-1]))
    targets = np.zeros((len(rows),))

    for j, row in enumerate(rows):
      indices = range(rows[j] - lookback, rows[j], step)
      samples[j] = data[indices]
      targets[j] = data[rows[j] + delay][1]
    yield samples, targets

Вот параметр подробности

1) data - исходный массив данных с плавающей запятой, нормализованный

2) lookback - на сколько шагов назад входные данные должны go.

3) delay - сколько временных шагов в будущем должно быть у цели.

4) min_index и max_index - индексы в массиве данных, которые определяют, какие временные шаги следует брать. Это полезно для хранения одного сегмента данных для проверки, а другого - для тестирования.

5) shuffle - перетасовать ли образцы или нарисовать их в хронологическом порядке.

6) batch_size - количество выборок в пакете.

7) step - период в временных шагах, в который вы производите выборку данных. Вы установите его на 6, чтобы отображать одну точку данных каждый час.

И эти генераторы

lookback = 1440
step = 6
delay = 144
batch_size = 128

train_gen = generator(float_data,
lookback=lookback,
delay=delay,
min_index=0,
max_index=200000,
shuffle=True,
step=step,
batch_size=batch_size)

val_gen = generator(float_data,
lookback=lookback,
delay=delay,
min_index=200001,
max_index=300000,
step=step,
batch_size=batch_size)

test_gen = generator(float_data,
lookback=lookback,
delay=delay,
min_index=300001,
max_index=None,
step=step,
batch_size=batch_size)

val_steps = (300000 - 200001 - lookback)
test_steps = (len(float_data) - 300001 - lookback)

Схема сети выглядит следующим образом:

model = Sequential()
model.add(layers.Flatten(input_shape=(lookback // step, float_data.shape[-1])))
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(1))
model.compile(optimizer=RMSprop(), loss='mae')
model.compile(optimizer=RMSprop(), loss='mae')
history = model.fit(train_gen,steps_per_epoch=500,epochs=20,validation_data=test_gen,validation_steps=test_steps)

Однако модель застревает на

Train for 500 steps, validate for 119110 steps
Epoch 1/20
497/500 [============================>.] - ETA: 0s - loss: 0.3524

Моя модель застревает во время оценки на наборе проверки. Чтобы убедиться, что train_gen и val_gen где все в порядке, я попробовал

next(train_gen)
next(val_gen)

И они оба отображают разные значения каждый раз, например

(array([[[ 0.34593055,  0.49507501,  0.4628141 , ...,  0.16203687,
           0.18470667,  0.84378526],
         [ 0.36243914,  0.6283707 ,  0.59460993, ...,  0.2921889 ,
           0.94414397,  0.60710086],
         [ 0.35182647,  0.64305582,  0.60912981, ...,  1.78242962,
           1.59631612,  0.43507171],
         ...,

Что здесь не так?

1 Ответ

1 голос
/ 19 июня 2020

Количество шагов проверки выглядит подозрительно, так как оно не рассчитывается с учетом размера пакета, поэтому оно больше, чем должно быть, что значительно продлит этап проверки во времени. Решение состоит в том, чтобы разделить количество шагов на размер пакета:

val_steps = val_steps // batch_size
test_steps = test_steps // batch_size

Это приведет к тому, что шаги будут иметь правильное значение.

...