【问题标题】:Keras Error with Output Dimensions输出尺寸的 Keras 错误
【发布时间】:2018-03-06 09:16:11
【问题描述】:

我有一个时间序列(2 个变量),每个时间序列有大约 80000 个观测值(X),每个观测值对应一个类(Y)。我使用移动窗口方法将时间序列分割成几个区间(每个区间的长度为 30)。然后我对 Y 进行热编码以使其成为分类变量。


然后我使用以下代码创建了批处理大小为 64 的批处理

从 sklearn.preprocessing 导入 OneHotEncoder

def one_hot_encoder(y):

    onehot_encoder = OneHotEncoder(sparse=False)
    y = y.reshape(len(y), 1)
    onehot_encoder = onehot_encoder.fit_transform(y)
    return onehot_encoder

def data_generator(x, y, shuffle=False, batch_size=64):

    # create order
    while True:
        index = np.arange(len(y))
        if shuffle == True:
            np.random.shuffle(index)
            x = x[index]
            y = y[index]

        # generate batches
        imax = int(len(index)/batch_size)
        for i in range(imax):
            yield x[i*batch_size: (i+1)*batch_size], y[i*batch_size: (i+1)*batch_size]


def get_batches(x, y):

    x = np.array(x)
    y = np.array(y)

    return data_generator(x, one_hot_encoder(y))

对于每个批次 print(next(batches)[0].shape) is (64, 30 ,2) -- 30 个观察值,2 个变量 print(next(batches)1.shape) is (64, 3) - 每个观察对应一个热编码类


然后我使用以下代码创建模型:

def create_model():
    model = Sequential()
    model.add(BatchNormalization(axis=1, input_shape=(30, 2)))
    model.add(Conv1D(16, 5, activation='relu'))
    model.add(BatchNormalization(axis=1))
    model.add(MaxPooling1D(2))
    model.add(Conv1D(16, 5, activation='relu'))
    model.add(BatchNormalization(axis=1))
    model.add(MaxPooling1D(3))
    model.add(Conv1D(32, 3, activation='relu'))
    model.add(Dense(100, activation='relu'))
    model.add(BatchNormalization())
    model.add(Dropout(0.5))
    model.add(Dense(3, activation='softmax'))

    return model

model = create_model()
model.compile(RMSprop(lr=0.01), loss='categorical_crossentropy', metrics=['accuracy'])

模型总结如下:

model summary

但是当我使用 fit_generator 训练模型时,我收到以下错误消息。我真的很困惑我的输出尺寸是否不正确?还是我的代码有任何错误。

谢谢。

model.fit_generator(batches, steps_per_epoch=30, nb_epoch=5, validation_data=None, validation_steps=None)

ValueError                                Traceback (most recent call last)
<ipython-input-29-c7ba2e8eddfd> in <module>()
----> 1 model.fit_generator(batches, steps_per_epoch=10, nb_epoch=5, validation_data=None, validation_steps=None)

D:\Programs\Anaconda3\lib\site-packages\keras\legacy\interfaces.py in wrapper(*args, **kwargs)
     85                 warnings.warn('Update your `' + object_name +
     86                               '` call to the Keras 2 API: ' + signature, stacklevel=2)
---> 87             return func(*args, **kwargs)
     88         wrapper._original_function = func
     89         return wrapper

D:\Programs\Anaconda3\lib\site-packages\keras\models.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, initial_epoch)
   1119                                         workers=workers,
   1120                                         use_multiprocessing=use_multiprocessing,
-> 1121                                         initial_epoch=initial_epoch)
   1122 
   1123     @interfaces.legacy_generator_methods_support

D:\Programs\Anaconda3\lib\site-packages\keras\legacy\interfaces.py in wrapper(*args, **kwargs)
     85                 warnings.warn('Update your `' + object_name +
     86                               '` call to the Keras 2 API: ' + signature, stacklevel=2)
---> 87             return func(*args, **kwargs)
     88         wrapper._original_function = func
     89         return wrapper

D:\Programs\Anaconda3\lib\site-packages\keras\engine\training.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
   2040                     outs = self.train_on_batch(x, y,
   2041                                                sample_weight=sample_weight,
-> 2042                                                class_weight=class_weight)
   2043 
   2044                     if not isinstance(outs, list):

D:\Programs\Anaconda3\lib\site-packages\keras\engine\training.py in train_on_batch(self, x, y, sample_weight, class_weight)
   1754             sample_weight=sample_weight,
   1755             class_weight=class_weight,
-> 1756             check_batch_axis=True)
   1757         if self.uses_learning_phase and not isinstance(K.learning_phase(), int):
   1758             ins = x + y + sample_weights + [1.]

D:\Programs\Anaconda3\lib\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_batch_axis, batch_size)
   1380                                     output_shapes,
   1381                                     check_batch_axis=False,
-> 1382                                     exception_prefix='target')
   1383         sample_weights = _standardize_sample_weights(sample_weight,
   1384                                                      self._feed_output_names)

D:\Programs\Anaconda3\lib\site-packages\keras\engine\training.py in _standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
    130                                  ' to have ' + str(len(shapes[i])) +
    131                                  ' dimensions, but got array with shape ' +
--> 132                                  str(array.shape))
    133             for j, (dim, ref_dim) in enumerate(zip(array.shape, shapes[i])):
    134                 if not j and not check_batch_axis:

ValueError: Error when checking target: expected dense_2 to have 3 dimensions, but got array with shape (64, 3)

【问题讨论】:

    标签: python deep-learning keras


    【解决方案1】:

    当您使用 input_shape=(30,2) 时,您将使用 3 个维度定义输入:(batchSize, 30, 2)

    这没关系,但它会以不变的方式通过您的模型,直到它到达密集层。

    密集层不会减少维数,它们会输出(batchSize, 30, denseUnits)

    一种解决方案是使用展平层,减少到仅(batchSize,30*someValue)。然后密集将开始输出(batchSize,units) 这将为您提供与您的 2D 类匹配的 2D 输出。

    在密集层之前:

    model.add(Flatten())
    

    【讨论】:

    • “密集层不会减少维度的数量,它们会输出(batchSize, 30, denseUnits)。” - 那么输入形状的最后一个维度会发生什么,即 (30, 2) 中的 2,密集层会简单地丢弃它?
    • @liang,密集层在最后一个维度“运行”。 2 将通过数学运算转换为“denseUnits”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    • 2018-09-01
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多