CNN模型不适用于4种,但适用于2种

时间:2020-05-28 15:10:23

标签: python tensorflow keras

我在两个类别上尝试了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

3 个答案:

答案 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功能的公式器

Formular for SoftMax function

4个用于Sigmoid函数的公式

Formular for Sigmoid function

让我在这里举一个例子来说明第二点。可以说,我们有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激活函数和分类交叉熵作为损失函数。