我在两个类别上尝试了CNN模型,但获得了80%的成绩,但是当我在4个类别上尝试了相同的模型时,结果却非常糟糕。请帮忙的原因是什么? 我使用的CNN模型是:
model= Sequential()
model.add(Conv2D(64,(3,3),input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
#opt = SGD( lr=0.01)
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
history = model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples//batch_size,
epochs=epochs,
validation_data = validation_generator,
validation_steps = validation_generator.samples // batch_size,
)
像这样的2个类的结果我丢失了它的实际结果:
Epoch 29/35
46/46 [==============================] - 188s 4s/step - loss: 0.6511 - accuracy: 0.5880 - val_loss: 0.7534 - val_accuracy: 0.5175
具有4个类的结果是:
46/46 [==============================] - 367s 8s/step - loss: -10550614391401.7266 - accuracy: 0.2541 - val_loss: -15023441182720.0000 - val_accuracy: 0.2354
答案 0 :(得分:5)
输出层正在使用sigmoid
激活函数,该函数只能用于二进制分类问题。
对于两个以上的类,请使用softmax
激活函数和密集层,然后再具有num_of_classes
节点。
model.add(Dense(numclasses)) # numclasses = 4 in your case
model.add(Activation('softmax'))
也应将损失从binary_crossentropy
更改为categorical_crossentropy
(这是您的案件中显示出奇怪损失的主要原因)。
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
注意::categorical_crossentropy
需要one-hot
个向量。如果您拥有的标签只是一维数组,而不是一个热点向量,请使用sparse_categorical_crossentropy
答案 1 :(得分:3)
您与4个班级建立关系的网络应该看起来像这样
model= Sequential()
model.add(Conv2D(64,(3,3),input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(4 activation='softmax'))
#opt = SGD( lr=0.01)
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
损失应为categorical_crossentropy
,最后一层应为softmax
,可能产生4
。
答案 2 :(得分:2)
Sigmoid与Softmax之间的区别
Sigmoid函数与Softmax函数在深度学习中的区别 Softmax函数可以理解为S型函数的广义形式或S型函数的扩展。 Softmax函数通常用于神经网络的输出层。
以下是Sigmoid和Softmax函数之间的一些区别:
1。。Sigmoid函数用于两类(二进制)分类问题,而softmax函数用于多类分类问题。
2。。所有softmax单位的总和应该为1。在S型中,这不是必需的。 Sigmoid仅使输出介于0到1之间。softmax强制所有输出类别的概率之和等于1,因此,为了增加特定类别的概率,softmax必须相应地降低至少一个概率其他类别的
使用softmax时,基本上可以得到每个类别的和(联合分布和多项式似然)的概率必定为和。如果您使用S形进行多类别分类,那就像是边际分布和伯努利似然法。
3个用于MaxMax功能的公式器
4个用于Sigmoid函数的公式
让我在这里举一个例子来说明第二点。可以说,我们有6个输入:
[1,2,3,4,5,6]
如果将这些输入通过sigmoid函数传递,则会得到以下输出:
[0.5,0.73,0.88,0.95,0.98,0.99]
上述输出单位的总和是5.03,大于1。
但是在softmax的情况下,输出单位的总和始终为1。让我们看看如何?将相同的输入传递给softmax函数,我们得到以下输出:
[0.001,0.009,0.03,0.06,0.1,0.8]总计为1。
5。。Sigmoid通常在隐藏层中用作激活函数(但现在我们使用ReLU),而在输出层中使用Softmax
一般的经验法则是在神经网络的隐藏层中使用ReLU作为激活函数,在输出层中使用softmax。
了解更多详情,here
因此,对于多类分类案例,您必须使用softmax激活函数和分类交叉熵作为损失函数。