为什么这个单层网络不起作用

数据挖掘 喀拉斯
2022-02-26 13:03:38

我正在尝试以下代码(从https://www.kdnuggets.com/2017/10/seven-steps-deep-learning-keras.html修改):

def single_layer(input_shape, nb_classes): 
    print("input shape:", input_shape)
    print("print nb_classes:", nb_classes)

    from keras.models import Sequential
    from keras.layers import Dense, Activation

    model = Sequential()
    model.add(Dense(nb_classes, input_shape=input_shape, activation='softmax')) 

    model.compile(optimizer='sgd', loss='categorical_crossentropy') 
    model.summary()
    return model

但是,当我尝试用一X_train​​个维度64,64,3和 17 个类来拟合这个模型时,以下是有错误的输出:

input shape: (64, 64, 3)
print nb_classes: 17
Using TensorFlow backend.
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 64, 64, 17)        68        
=================================================================
Total params: 68
Trainable params: 68
Non-trainable params: 0
_________________________________________________________________
Traceback (most recent call last):
....
....
  File "/home/abcd/.local/lib/python3.5/site-packages/keras/engine/training.py", line 950, in fit
    batch_size=batch_size)
  File "/home/abcd/.local/lib/python3.5/site-packages/keras/engine/training.py", line 787, in _standardize_user_data
    exception_prefix='target')
  File "/home/abcd/.local/lib/python3.5/site-packages/keras/engine/training_utils.py", line 127, in standardize_input_data
    'with shape ' + str(data_shape))
ValueError: Error when checking target: expected dense_1 to have 4 dimensions, but got array with shape (10396, 17)

为什么此代码不起作用,应如何修改以使其起作用?

1个回答

我在您发布的链接中找不到代码,以获取有关您正在使用的数据源类型的更多背景信息。

但是,数据源是60×60×3被描述为高维。您总共有 10,800 个输入特征,需要映射到 17 个不同的类。这实际上是一项非常复杂的任务,使用单层网络不会成功。这样一个简单的网络将没有足够的参数来捕获输入空间中特征之间的非线性。

话虽如此,如果您坚持使用具有大小数据的单层网络60×60×3有 17 个输入类,代码如下。

让我们首先创建一些与您的数据相同维度的人工数据

import numpy as np

n = 1000
x_train = np.zeros((n,64,64,3))
y_train = np.zeros((n,))
for i in range(n):
    x_train[i,:,:,:] = np.random.random((64,64,3))
    y_train[i] = np.random.randint(0,17)

x_train = x_train.reshape(n,64,64,3,)

n = 100
x_test = np.zeros((n,64,64,3))
y_test = np.zeros((n,))
for i in range(n):
    x_test[i,:,:,:] = np.random.random((64,64,3))
    y_test[i] = np.random.randint(0,17)

x_test = x_test.reshape(n,64,64,3,)

print('Training data: ', x_train.shape)
print('Training labels: ', y_train.shape)
print('Testing data: ', x_test.shape)
print('Testing labels: ', y_test.shape)

(1000, 64, 64, 3)
(1000,)
(100, 64, 64, 3)
(100,)

对于分类任务,我们应该将输出转换为分类向量。我们使用 one-hot 编码来识别正确的类。

import keras

# The known number of output classes.
num_classes = 17

# Convert class vectors to binary class matrices. This uses 1 hot encoding.
y_train_binary = keras.utils.to_categorical(y_train, num_classes)
y_test_binary = keras.utils.to_categorical(y_test, num_classes)

然后我们建立模型。

from __future__ import print_function
import keras
from keras.models import Sequential
from keras.layers import Dense, Flatten
from keras.models import model_from_json
from keras import backend as K

input_shape = (64,64,3,)

model = Sequential()
model.add(Flatten(input_shape=input_shape))
model.add(Dense(17, activation='softmax'))


model.compile(loss=keras.losses.mean_squared_error,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

您可以通过使用查看模型的摘要

model.summary()

然后我们可以使用

batch_size = 128
epochs = 10
model.fit(x_train, y_train_binary,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test_binary))

此代码有效。然而,数据是完全随机的,因此模型无法学习任何东西。然而,即使你的数据很容易区分,正如我上面所说的,我不希望这个模型足够复杂,可以将如此大的输入空间与 17 个不同的可能类区分开来。

如果您发布您正在使用的数据源,我们可以设计一个模型以获得良好的结果。