如果图像同时包含狗和猫,则 CNN Keras 狗猫分类
CNN Keras Dog cat classification if image contain both dog and cat
我修改了 dog cat binary classification 以通过在输出层中使用 Sigmoid 激活函数来进行多 class 激活以获得每个个体的预测 class,但它失败了得到预期的结果。
我创建了一个在单个图像中同时包含狗和猫的图像。
预期结果:
狗:70% 或超过 70%,猫:70% 或超过 70%
实际结果:
狗:70 %,猫:25 %
为什么不能高精度地预测个体 class?
import numpy as np
from keras.models import Sequential;
from keras.layers import Conv2D, MaxPooling2D, Dense, Flatten;
from keras.utils.np_utils import to_categorical
from keras import optimizers
classifier = Sequential();
classifier.add(Conv2D(32,(3,3),input_shape=(64,64,3),activation='relu'));
classifier.add(MaxPooling2D((2,2)));
classifier.add(Conv2D(32,(3,3),activation='relu'));
classifier.add(MaxPooling2D((2,2)));
classifier.add(Conv2D(32,(3,3),activation='relu'));
classifier.add(MaxPooling2D((2,2)));
classifier.add(Flatten());
classifier.add(Dense(100, activation='sigmoid'))
classifier.add(Dense(2,activation='sigmoid'));
classifier.compile(optimizer="adam", loss='categorical_crossentropy', metrics=['accuracy'])
from keras.preprocessing.image import ImageDataGenerator
trainingDataOptions = ImageDataGenerator(rescale=1./255,shear_range=0.2,zoom_range=0.2,horizontal_flip=True)
testingDataOptions = ImageDataGenerator(rescale=1./255)
trainingData = trainingDataOptions.flow_from_directory('dataset/training',target_size=(64,64),batch_size=32);
testingData = testingDataOptions.flow_from_directory('dataset/testing',target_size=(64,64),batch_size=32);
classifier.fit_generator(trainingData, samples_per_epoch=1757, nb_epoch=10, validation_data=testingData, nb_val_samples=308)
classifier.save('model.h5')
# Output
from keras.preprocessing import image
test_image = image.load_img('samples/319b5fa.jpg',target_size=(64,64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis=0)
res = classifier.predict(test_image)
label_map = (trainingData.class_indices)
print(res);
i = 0;
for label in label_map:
score = res[0][i]
score = score*100
score = "{0:.0f}".format(score)
print(label,"====>",score,'%');
i = i+1;
我没有在输出层使用 softmax,为什么单个预测的总和不超过 100%?它使 multi-class classification 始终保持在 1.0 以下(我猜这与它分布概率的 softmax 有关)。
准确的说,你想做多标签multi-class class化或者简单的多标签class化(即每张图片可能属于0,1或多个 classes,例如一张图片可能同时包含您提到的猫和狗)。因此,为 Dense 层选择 sigmoid 激活是正确的,因为每个 class 都独立于另一个并且应该得到一个从 0 到 1 的值(即对应于概率)。
但是,您还必须将损失从 'categorical_crossentropy'
更改为 'binary_crossentropy'
,因为在这里您不再进行单标签多 class class 化(即此图像中存在哪只狗或猫?)。然而,您正在执行一堆二进制 classifications(即猫是否存在?狗是否存在?)。这种情况下的适当损失是 'binary_crossentropy'
.
我修改了 dog cat binary classification 以通过在输出层中使用 Sigmoid 激活函数来进行多 class 激活以获得每个个体的预测 class,但它失败了得到预期的结果。
我创建了一个在单个图像中同时包含狗和猫的图像。
预期结果: 狗:70% 或超过 70%,猫:70% 或超过 70%
实际结果: 狗:70 %,猫:25 %
为什么不能高精度地预测个体 class?
import numpy as np
from keras.models import Sequential;
from keras.layers import Conv2D, MaxPooling2D, Dense, Flatten;
from keras.utils.np_utils import to_categorical
from keras import optimizers
classifier = Sequential();
classifier.add(Conv2D(32,(3,3),input_shape=(64,64,3),activation='relu'));
classifier.add(MaxPooling2D((2,2)));
classifier.add(Conv2D(32,(3,3),activation='relu'));
classifier.add(MaxPooling2D((2,2)));
classifier.add(Conv2D(32,(3,3),activation='relu'));
classifier.add(MaxPooling2D((2,2)));
classifier.add(Flatten());
classifier.add(Dense(100, activation='sigmoid'))
classifier.add(Dense(2,activation='sigmoid'));
classifier.compile(optimizer="adam", loss='categorical_crossentropy', metrics=['accuracy'])
from keras.preprocessing.image import ImageDataGenerator
trainingDataOptions = ImageDataGenerator(rescale=1./255,shear_range=0.2,zoom_range=0.2,horizontal_flip=True)
testingDataOptions = ImageDataGenerator(rescale=1./255)
trainingData = trainingDataOptions.flow_from_directory('dataset/training',target_size=(64,64),batch_size=32);
testingData = testingDataOptions.flow_from_directory('dataset/testing',target_size=(64,64),batch_size=32);
classifier.fit_generator(trainingData, samples_per_epoch=1757, nb_epoch=10, validation_data=testingData, nb_val_samples=308)
classifier.save('model.h5')
# Output
from keras.preprocessing import image
test_image = image.load_img('samples/319b5fa.jpg',target_size=(64,64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis=0)
res = classifier.predict(test_image)
label_map = (trainingData.class_indices)
print(res);
i = 0;
for label in label_map:
score = res[0][i]
score = score*100
score = "{0:.0f}".format(score)
print(label,"====>",score,'%');
i = i+1;
我没有在输出层使用 softmax,为什么单个预测的总和不超过 100%?它使 multi-class classification 始终保持在 1.0 以下(我猜这与它分布概率的 softmax 有关)。
准确的说,你想做多标签multi-class class化或者简单的多标签class化(即每张图片可能属于0,1或多个 classes,例如一张图片可能同时包含您提到的猫和狗)。因此,为 Dense 层选择 sigmoid 激活是正确的,因为每个 class 都独立于另一个并且应该得到一个从 0 到 1 的值(即对应于概率)。
但是,您还必须将损失从 'categorical_crossentropy'
更改为 'binary_crossentropy'
,因为在这里您不再进行单标签多 class class 化(即此图像中存在哪只狗或猫?)。然而,您正在执行一堆二进制 classifications(即猫是否存在?狗是否存在?)。这种情况下的适当损失是 'binary_crossentropy'
.