无法将输出层设置为分类

2024-04-25 11:45:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在尝试实现一个CNN,其目的是执行分类,但由于某些原因,我不能将我的输出维度定义为1。在

下面是一个示例代码:

import keras
from keras.layers.merge import Concatenate
from keras.models import Model
from keras.layers import Input, Dense
from keras.layers import Dropout
from keras.layers.core import Dense, Activation, Lambda, Reshape,Flatten
from keras.layers import Conv2D, MaxPooling2D, Reshape, ZeroPadding2D
import numpy as np

train_data_1 = np.random.randint(100,size=(100,3,6,3))
train_data_2 = np.random.randint(100,size=(100,3,6,3))
test_data_1 = np.random.randint(100,size=(10,3,6,3))
test_data_2 = np.random.randint(100,size=(10,3,6,3))
labels_train_data =np.random.randint(145,size=100)
labels_test_data =np.random.randint(145,size=10)


input_img_1 = Input(shape=(3, 6, 3))
input_img_2 = Input(shape=(3, 6, 3))

conv2d_1_1 = Conv2D(filters = 32, kernel_size = (3,3) , padding = "same" , activation = 'relu' , name = "conv2d_1_1" )(input_img_1)
conv2d_2_1 = Conv2D(filters = 64, kernel_size = (3,3) , padding = "same" , activation = 'relu' )(conv2d_1_1)
conv2d_3_1 = Conv2D(filters = 64, kernel_size = (3,3) , padding = "same" , activation = 'relu' )(conv2d_2_1)
conv2d_4_1 = Conv2D(filters = 32, kernel_size = (1,1) , padding = "same" , activation = 'relu' )(conv2d_3_1)
conv2d_4_1_flatten = Flatten()(conv2d_4_1)

conv2d_1_2 = Conv2D(filters = 32, kernel_size = (3,3) , padding = "same" , activation = 'relu' , name = "conv2d_1_2")(input_img_2)
conv2d_2_2 = Conv2D(filters = 64, kernel_size = (3,3) , padding = "same" , activation = 'relu' )(conv2d_1_2)
conv2d_3_2 = Conv2D(filters = 64, kernel_size = (3,3) , padding = "same" , activation = 'relu' )(conv2d_2_2)
conv2d_4_2 = Conv2D(filters = 32, kernel_size = (1,1) , padding = "same" , activation = 'relu' )(conv2d_3_2)
conv2d_4_2_flatten = Flatten()(conv2d_4_2)


merge = keras.layers.concatenate([conv2d_4_1_flatten, conv2d_4_2_flatten])

dense1 = Dense(100, activation = 'relu')(merge)
dense2 = Dense(50,activation = 'relu')(dense1)
dense3 = Dense(1 ,activation = 'softmax')(dense2)


model = Model(inputs = [input_img_1, input_img_2] , outputs = dense3)
model.compile(loss="sparse_categorical_crossentropy", optimizer="adam")

print model.summary()

labels_train = keras.utils.to_categorical(labels_train_data, num_classes=145)
labels_test = keras.utils.to_categorical(labels_test_data, num_classes=145)

hist_current = model.fit(x = [train_data_1, train_data_2],
                    y = labels_train,
                    shuffle=False,
                    validation_data=([test_data_1 ,test_data_2], labels_test),
                    validation_split=0.1,
                    epochs=150000,
                    batch_size = 15,
                    verbose=1)

错误信息是:

^{2}$

Tags: testimportdatasizelabelstrainactivationkernel
1条回答
网友
1楼 · 发布于 2024-04-25 11:45:23

模型中的几个不一致之处:

  1. dense3 = Dense(1 ,activation = 'softmax')(dense2):你不能单独在一个神经元上使用softmax。softmax规范化输出的层,使其总和为1。。。在这种情况下,如果只规范化一个值,它将始终输出1。但是这并不是你得到错误的原因
  2. 你有几节课?从你的网络中,你输出一个值(最后一层是稠密的(1)),所以我预计你想要预测2个类(输出1或0)。但在这里我们看到你的输出是一个有145种可能性的绝对。。。你的label_train数组是100个长度为145的热向量,所以我假设你想把100个样本分成145个不同的类别。。。这就是keras抱怨的原因,你的网络输出(100,1)和你的目标(标签)是(100145)。你到底想做什么?在

编辑:

在注释之后,由于您想预测图像是否属于145个类中的一个,所以必须输出145个值。因此,您必须更改网络的顶层,以便最后一层是Dense(145, activation='softmax')。所以我建议你替换

dense1 = Dense(100, activation = 'relu')(merge)
dense2 = Dense(50,activation = 'relu')(dense1)
dense3 = Dense(1 ,activation = 'softmax')(dense2)

^{pr2}$

如果你真的想有3个密集的层,否则你可以只删除中间一个。。。这将取决于您的用例,因此隐藏层的架构取决于您。我只是坚持你的最后一层应该是Dense(145, activation='softmax')。在

有道理吗?在

编辑2:

最重要的是,你不应该将你的目标(标签)编码为分类,当你使用稀疏的分类交叉熵时,它是在引擎盖下自动完成的。在

因此,要么使用keras.utils.to_categorical对目标使用loss=categorical_crossentropy

或者不使用keras.utils.to_categorical转换目标,而使用loss=sparse_categorical_crossentropy。在

它在我的机器上运行。在

相关问题 更多 >

    热门问题