【发布时间】:2019-12-10 02:33:14
【问题描述】:
介绍和问题:
我正在尝试制作一个分类卷积神经网络。一类我的意思是我有一个图像数据集,其中包含大约 200 张尼古拉斯凯奇的图像。通过一个类别分类,我的意思是看一张图像,如果 Nicolas Cage 包含在该图像中,则预测为 1,然后预测为 0 Nicolas Cage 不包含在图像中。
我绝对是机器学习/深度学习的初学者,所以我希望有更多知识和经验的人可以帮助指导我朝着正确的方向前进。这是我现在的问题和疑问。我的网络表现非常糟糕。我尝试使用 Nicolas Cage 的图像进行一些预测,每次都预测为 0。
- 我是否应该收集更多数据才能使其发挥作用?我正在使用包含 207 个图像的小型数据集执行数据增强。我希望数据增强能够帮助网络泛化,但我认为我错了
- 我应该尝试调整 epoch 的数量、每个 epoch 的步数、val 步数,还是我用于梯度下降的优化算法?我正在使用 Adam,但我在想也许我应该尝试使用不同学习率的随机梯度下降?
- 我应该添加更多卷积层还是密集层来帮助我的网络更好地泛化和学习?
- 我是否应该停止尝试进行一类分类并转到正常的二元分类,因为使用具有一类分类的神经网络不太可行?我在这里看到了这篇文章one class classification with keras,看起来 OP 最终使用了隔离林。所以我想我可以尝试使用一些卷积层并输入隔离森林或 SVM?我找不到很多关于人们使用具有一类图像分类的隔离森林的信息或教程。
数据集:
这是我使用名为 google-images-download 的软件包收集的数据集的屏幕截图。它包含大约 200 张尼古拉斯凯奇的图像。我做了两次搜索以下载 500 张图片。在手动清理图像后,我只剩下 200 张 Nic Cage 的高质量图片。 Dataset
导入和模型:
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Activation
classifier = Sequential()
classifier.add(Conv2D(32, (3, 3), input_shape = (200, 200, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size=(2, 2)))
classifier.add(Conv2D(64, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size=(2, 2)))
classifier.add(Flatten())
classifier.add(Dense(units = 64, activation = 'relu'))
classifier.add(Dropout(0.5))
# output layer
classifier.add(Dense(1))
classifier.add(Activation('sigmoid'))
编译和图像增强
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
test_datagen = ImageDataGenerator(rescale = 1./255)
training_set = train_datagen.flow_from_directory('/Users/ginja/Desktop/Code/Nic_Cage/Small_Dataset/train/',
target_size = (200, 200),
batch_size = 32,
class_mode = "binary")
test_set = test_datagen.flow_from_directory('/Users/ginja/Desktop/Code/Nic_Cage/Small_Dataset/test/',
target_size = (200, 200),
batch_size = 32,
class_mode = "binary")
拟合模型
history = classifier.fit_generator(training_set,
steps_per_epoch = 1000,
epochs = 25,
validation_data = test_set,
validation_steps = 500)
Epoch 1/25
1000/1000 [==============================] - 1395s 1s/step - loss: 0.0012 - acc: 0.9994 - val_loss: 1.0000e-07 - val_acc: 1.0000
Epoch 2/25
1000/1000 [==============================] - 1350s 1s/step - loss: 1.0000e-07 - acc: 1.0000 - val_loss: 1.0000e-07 - val_acc: 1.0000
Epoch 3/25
1000/1000 [==============================] - 1398s 1s/step - loss: 1.0000e-07 - acc: 1.0000 - val_loss: 1.0000e-07 - val_acc: 1.0000
Epoch 4/25
1000/1000 [==============================] - 1342s 1s/step - loss: 1.0000e-07 - acc: 1.0000 - val_loss: 1.0000e-07 - val_acc: 1.0000
Epoch 5/25
1000/1000 [==============================] - 1327s 1s/step - loss: 1.0000e-07 - acc: 1.0000 - val_loss: 1.0000e-07 - val_acc: 1.0000
Epoch 6/25
1000/1000 [==============================] - 1329s 1s/step - loss: 1.0000e-07 - acc: 1.0000 - val_loss: 1.0000e-07 - val_acc: 1.0000
.
.
.
该模型看起来收敛到 1.0000e-07 的损失值,因为这在其余时期不会改变
绘制的训练和测试准确度
绘制训练和测试损失
做出预测
from keras.preprocessing import image
import numpy as np
test_image = image.load_img('/Users/ginja/Desktop/Code/Nic_Cage/nic_cage_predict_1.png', target_size = (200, 200))
#test_image.show()
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
result = classifier.predict(test_image)
training_set.class_indices
if result[0][0] == 1:
prediction = 'This is Nicolas Cage'
else:
prediction = 'This is not Nicolas Cage'
print(prediction)
对于预测,我们每次都会得到“这不是尼古拉斯凯奇”。 我感谢任何花时间阅读本文的人,我感谢任何对此部分的帮助。
【问题讨论】:
-
它不是一类分类。这是二元分类你有多少图像有“尼古拉斯凯奇”,有多少图像没有尼古拉斯凯奇?基本上你有多少张图片 1 & 0 ?
-
你不能只用一个类的样本来训练一个模型,类的最小数量是两个,所以你需要“不是尼古拉斯凯奇”的样本。
-
@MatiasValdenegro 如果我只是从谷歌图像中收集“不是尼古拉斯笼子”的随机图像,然后得到尼古拉斯笼子的图像,这会起作用吗?我的直觉是“不是尼古拉斯笼”的图像集太宽泛了,然后网络很难泛化。
-
@venkatakrishnan 是的,我认为这是我的问题,我只将图像设置为 1 而不是 0。所以 1 代表 Nicolas Cage 类。
-
是的。尝试一些随机的图像作为非尼古拉斯笼。并在您的最终预测中设置一个阈值以使其绝对正确
标签: python keras deep-learning classification conv-neural-network