我目前正在尝试实现一个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}$
模型中的几个不一致之处:
dense3 = Dense(1 ,activation = 'softmax')(dense2)
:你不能单独在一个神经元上使用softmax。softmax规范化输出的层,使其总和为1。。。在这种情况下,如果只规范化一个值,它将始终输出1。但是这并不是你得到错误的原因label_train
数组是100个长度为145的热向量,所以我假设你想把100个样本分成145个不同的类别。。。这就是keras抱怨的原因,你的网络输出(100,1)和你的目标(标签)是(100145)。你到底想做什么?在编辑:
在注释之后,由于您想预测图像是否属于145个类中的一个,所以必须输出145个值。因此,您必须更改网络的顶层,以便最后一层是
Dense(145, activation='softmax')
。所以我建议你替换与
^{pr2}$如果你真的想有3个密集的层,否则你可以只删除中间一个。。。这将取决于您的用例,因此隐藏层的架构取决于您。我只是坚持你的最后一层应该是
Dense(145, activation='softmax')
。在有道理吗?在
编辑2:
最重要的是,你不应该将你的目标(标签)编码为分类,当你使用稀疏的分类交叉熵时,它是在引擎盖下自动完成的。在
因此,要么使用
keras.utils.to_categorical
对目标使用loss=categorical_crossentropy
或者不使用
keras.utils.to_categorical
转换目标,而使用loss=sparse_categorical_crossentropy
。在它在我的机器上运行。在
相关问题 更多 >
编程相关推荐