我有一些需要分类为0或1的数据。这些数据是从一个.npz
文件中加载的。它提供了训练、验证和测试数据。它们看起来是这样的:
x_train = [[[ 0 0 0 ... 0 1 4] [ 0 0 0 ... 4 25 2] [ 6 33 15 ... 33 0 0] ... [ 0 23 4 ... 9 31 0] [ 4 0 0 ... 0 0 12] [ 5 0 0 ... 3 0 0]] [[ 88 71 59 ... 61 62 62] [ 74 88 73 ... 59 70 60] [ 69 61 85 ... 60 58 82] ... [ 68 85 58 ... 55 75 72] [ 69 69 70 ... 81 76 83] [ 74 68 76 ... 60 74 72]] [[ 87 134 146 ... 108 116 157] [108 117 144 ... 102 58 122] [124 148 106 ... 97 135 146] ... [ 96 153 111 ... 104 129 154] [129 140 100 ... 74 114 97] [119 115 160 ... 172 84 148]] ... [[ 92 96 64 ... 69 83 83] [ 85 44 89 ... 115 94 76] [ 93 103 91 ... 92 81 75] ... [ 16 109 81 ... 84 95 20] [100 27 89 ... 66 107 48] [ 24 67 144 ... 104 115 123]] [[ 69 70 74 ... 72 73 75] [ 72 72 76 ... 73 75 76] [ 74 75 72 ... 72 69 73] ... [ 72 72 69 ... 72 76 72] [ 70 72 73 ... 72 76 67] [ 69 72 72 ... 72 71 71]] [[ 65 137 26 ... 134 57 174] [ 91 76 123 ... 39 63 124] [ 81 203 134 ... 192 63 143] ... [ 1 102 96 ... 33 63 169] [ 82 32 108 ... 151 75 151] [ 12 97 164 ... 101 125 60]]]
y_train:[0 0 0 ... 0 0 0]
这些是我的输入形状:
x_train.shape = (5000, 128, 128)y_train.shape = (5000,)
如您所见,y只是标签,而x只是3D数据。因为这是一个二元分类器,我想要构建一个包含3个全连接层的简单神经网络。我的代码如下:
model = Sequential()model.add(Dense(12, input_dim = 8, activation='relu'))model.add(Dense(8, activation='relu'))model.add(Dense(1, activation='sigmoid'))model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])model.fit(x_train, y_train, epochs=150, batch_size=8)
但是由于我的输入,我得到了这个错误:
ValueError: Input 0 of layer sequential_4 is incompatible with the layer: expected axis -1 of input shape to have value 8 but received input with shape (8, 128, 128)
我该如何解决这个问题?我的神经网络对于这种类型的问题来说是否过于简单?
回答:
你的代码存在多个问题。我尝试添加了不同的部分来解释这些问题。请仔细阅读所有内容,并尝试我下面展示的代码示例。
1. 将样本/批次通道作为输入维度传递
你将批次通道作为全连接层的输入形状传递,这是错误的。相反,你需要传递模型应该期望的每个样本的形状,在本例中是(128,128)
。模型会自动在前面添加一个通道,以便批次可以通过计算图流动,如(None, 128, 128)
,如下面的model.summary()
所示。
2. 2D输入用于全连接层
你的每个样本(在本例中总共有5000个样本)是一个形状为128,128的2D矩阵。全连接层无法直接使用它,除非先进行扁平化处理(或者使用更适合处理2D/3D输入的不同层,如后文所述)。
from tensorflow.keras import Sequentialfrom tensorflow.keras.layers import Dense, Flattenmodel = Sequential()model.add(Flatten(input_shape=(128,128)))model.add(Dense(12, activation='relu'))model.add(Dense(8, activation='relu'))model.add(Dense(1, activation='sigmoid'))model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])model.summary()
Model: "sequential_6"_________________________________________________________________Layer (type) Output Shape Param # =================================================================flatten_3 (Flatten) (None, 16384) 0 _________________________________________________________________dense_5 (Dense) (None, 12) 196620 _________________________________________________________________dense_6 (Dense) (None, 8) 104 _________________________________________________________________dense_7 (Dense) (None, 1) 9 =================================================================Total params: 196,733Trainable params: 196,733Non-trainable params: 0_________________________________________________________________
3. 使用不同的架构来解决你的问题
“我的神经网络对于这种类型的问题来说是否过于简单?”
这不是关于架构的复杂性,而是关于能够处理特定类型数据的层类型。在这种情况下,你有单通道的图像(128,128),这是一个2D输入。通常,彩色图像有R
、G
、B
通道,最终形状为(128,128,3)。
一般做法是使用卷积神经网络(CNN)层来处理这种情况。
下面展示了一个例子 –
from tensorflow.keras import Sequentialfrom tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPooling2D, Reshapemodel = Sequential()model.add(Reshape((128,128,1), input_shape=(128,128)))model.add(Conv2D(5, 5, activation='relu'))model.add(MaxPooling2D((2,2)))model.add(Conv2D(10, 5, activation='relu'))model.add(MaxPooling2D((2,2)))model.add(Conv2D(20, 5, activation='relu'))model.add(MaxPooling2D((2,2)))model.add(Conv2D(30, 5, activation='relu'))model.add(MaxPooling2D((2,2)))model.add(Flatten())model.add(Dense(12, activation='relu'))model.add(Dense(8, activation='relu'))model.add(Dense(1, activation='sigmoid'))model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])model.summary()
Model: "sequential_13"_________________________________________________________________Layer (type) Output Shape Param # =================================================================reshape_5 (Reshape) (None, 128, 128, 1) 0 _________________________________________________________________conv2d_16 (Conv2D) (None, 124, 124, 5) 130 _________________________________________________________________max_pooling2d_16 (MaxPooling (None, 62, 62, 5) 0 _________________________________________________________________conv2d_17 (Conv2D) (None, 58, 58, 10) 1260 _________________________________________________________________max_pooling2d_17 (MaxPooling (None, 29, 29, 10) 0 _________________________________________________________________conv2d_18 (Conv2D) (None, 25, 25, 20) 5020 _________________________________________________________________max_pooling2d_18 (MaxPooling (None, 12, 12, 20) 0 _________________________________________________________________conv2d_19 (Conv2D) (None, 8, 8, 30) 15030 _________________________________________________________________max_pooling2d_19 (MaxPooling (None, 4, 4, 30) 0 _________________________________________________________________flatten_9 (Flatten) (None, 480) 0 _________________________________________________________________dense_23 (Dense) (None, 12) 5772 _________________________________________________________________dense_24 (Dense) (None, 8) 104 _________________________________________________________________dense_25 (Dense) (None, 1) 9 =================================================================Total params: 27,325Trainable params: 27,325Non-trainable params: 0_________________________________________________________________