Dre*_*day 3 python classification deep-learning conv-neural-network keras
我正在尝试制作一个一类分类卷积神经网络。一类是指我有一个图像数据集,其中包含大约 200 张 Nicolas Cage 的图像。通过一类分类,我的意思是查看图像并预测 1 如果此图像中包含 Nicolas Cage 并预测 0 Nicolas Cage 不包含在图像中。
我绝对是一个机器学习/深度学习初学者,所以我希望有更多知识和经验的人可以帮助指导我朝着正确的方向前进。这是我现在的问题和问题。我的网络表现非常糟糕。我试过用 Nicolas Cage 的图像进行一些预测,每次都预测为 0。
这是我使用名为 google-images-download 的包收集的数据集外观的屏幕截图。它包含大约 200 张尼古拉斯凯奇的图像。我做了两次搜索以下载 500 张图片。手动清理图像后,我只剩下 200 张 Nic Cage 质量的图片。 数据集
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'))
Run Code Online (Sandbox Code Playgroud)
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")
Run Code Online (Sandbox Code Playgroud)
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
.
.
.
Run Code Online (Sandbox Code Playgroud)
该模型看起来像收敛到 1.0000e-07 的损失值,因为这在其余的 epoch 中不会改变
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)
Run Code Online (Sandbox Code Playgroud)
我们每次都得到“这不是尼古拉斯凯奇”的预测。我感谢任何花时间阅读本文的人,我感谢在这方面的任何帮助。
Dre*_*day 11
如果有人从谷歌找到这个,我想通了。我做了几件事:
flow_from_directory它时按字母数字顺序读取文件夹。所以目录中的第一个文件夹将是“0”类。我花了太长时间才弄明白。path = "/Users/ginja/Desktop/Code/Nic_Cage/Random_images"
for i in range(200):
url = "https://picsum.photos/200/200/?random"
response = requests.get(url)
if response.status_code == 200:
file_name = 'not_nicolas_{}.jpg'.format(i)
file_path = path + "/" + file_name
with open(file_path, 'wb') as f:
print("saving: " + file_name)
f.write(response.content)
Run Code Online (Sandbox Code Playgroud)
我shuffle = True在 flow_from_directory 中添加了一个参数来洗牌我们的图像,让我们的网络更好地泛化
我现在的训练准确度为 99%,测试准确度为 91%,我能够成功预测 Nicolas Cage 的图像!
每个人都倾向于二元分类方法。这可能是一个解决方案,但消除了可能是用一类分类器解决它的基本设计目标。根据您想用一类分类器实现的目标,它可能是一个病态问题。根据我的经验,你的最后一点经常适用。
如https://arxiv.org/pdf/1801.05365.pdf 中所述:
在经典的多类分类中,学习特征的目的是最大化类之间的类间距离并最小化类内的类内方差 [2]。然而,在没有多个类的情况下,这种区分方法是不可能的。
它产生了一个简单的解决方案。原因稍后解释:
这种方法最终产生一个简单解决方案的原因是由于损失函数中没有考虑到网络判别能力的正则化项。例如,由于所有类别标签都相同,因此可以通过使所有权重为零来获得零损失。确实,在只有普通椅子对象存在的封闭世界中,这是一个有效的解决方案。但是这样的网络在出现异常椅子物体时的判别能力为零
请注意,这里的描述是关于尝试使用一类分类器来解决不同的类。一类分类器的另一个有用目标是检测例如工厂操作信号中的异常。这就是我目前正在做的工作。在这种情况下,很难获得有关各种损坏状态的知识。破坏机器只是为了看看它在损坏时如何运行以便可以制作一个体面的多项式分类器是荒谬的。以下描述了该问题的一种解决方案:https : //arxiv.org/abs/1912.12502。请注意,在本文中,由于类的随机相似性,也实现了类的判别能力。
我发现通过遵循所描述的指南,特别是删除最后一个激活函数,我的一类分类器可以工作,并且准确度没有给出 0 值。请注意,在您的情况下,您可能还想删除二进制交叉熵,因为这需要二进制输入才能有意义(使用 RMSE)。
这种方法也适用于您的情况。在这种情况下,网络将能够确定哪些照片在数值上远离训练照片类。然而,根据我的经验,由于图片中包含的差异,例如不同的背景、角度等,这可能仍然是一个难以解决的问题......为此,我解决的问题要容易得多,因为有更多的相似性同一工况阶段的工况之间。打个比方,在我的例子中,训练班更像是同一张图片,但噪音水平不同,物体只有轻微的运动。
| 归档时间: |
|
| 查看次数: |
7468 次 |
| 最近记录: |