使用迁移学习对单类数据集进行图像分类[关闭]
Posted
技术标签:
【中文标题】使用迁移学习对单类数据集进行图像分类[关闭]【英文标题】:Image Classification with single class dataset using Transfer Learning [closed] 【发布时间】:2020-03-23 07:15:29 【问题描述】:我只有大约 1000 张计算机图像。我需要训练一个可以识别图像是计算机还是非计算机的模型。我没有非计算机的数据集,因为它可以是任何东西。
我想最好的方法是应用迁移学习。我正在尝试在预训练的 VGG19 模型上训练数据。但是,我仍然不知道如何在没有任何非计算机图像的情况下仅使用计算机图像来训练模型。
我是 ML 的新手
【问题讨论】:
这个话题是独一无二的,因为这个问题是题外话(不是编程问题,必须在 se/datascience 或 se/crossvalidated 上提出),所有答案都必须删除,因为它们都是cmets/opinions 但不是明确问题的解决方案。 您可以做两件事: 1. 在非计算机上收集数据并构建您的二进制分类模型。 2.实施一类分类模型。下面发布的垃圾答案摘要。 【参考方案1】:没办法,对不起。您将需要大量(至少其他 1000 张图像)非计算机图像。您可以从任何地方获取它们,它们“变化”越多,您的模型就能更好地提取计算机的哪些特征。
想象一下,你是一个受过训练的婴儿,他总是在某事面前说“是”,下次你看到某事时,无论你面前是什么,你都会说“是”......
对于机器学习模型也是如此,您需要正例和负例,否则您的模型将通过始终预测“是”来获得 100% 的准确度。
如果您想以数学/几何方式查看它,您可以将每个样本(在您的情况下为图像)视为特征空间中的一个点:想象为您拥有的每个属性绘制一个轴 (x,y,z以此类推),图像将成为该空间中的一个点。
为简单起见,让我们考虑一个二维空间,这意味着每个图像可以用 2 个属性来描述(图像不是这种情况,通常特征很多,但为简单起见,想象 feature_1 = 颜色数,feature_2 =角度数),在这个例子中,我们可以简单地在笛卡尔图中画一个点,每个图像一个点:
分类器的目标是画一条线,更好地将红点与蓝点分开,这意味着将正样本与负样本分开。
如果您只给模型提供 正 个样本(这就是您将要做的),那么您将拥有 100% 准确率的无限模型!因为你可以在任何你想要的地方放一条线,唯一的要求就是不要“剪切”你的数据集。
鉴于我假设您是初学者,我只会告诉您该怎么做,而不是怎么做,因为这需要数年时间;)
1) 收集数据——正如我告诉你的,即使是反面例子,至少还有其他 1000 个样本
2) 将数据拆分为训练/测试 - 一个好的拆分可能是训练集中样本的 2/3 和测试集中的 1/3。 [记住] 保持最终类分布的一致性,即如果你有 50%-50% 的类“计算机”-“非计算机”,你应该保持训练集和测试集的百分比
3) 训练模型 - 查看 this 链接以获取指导示例,它使用 MNIST 数据集,这是一个著名的图像分类数据集,您应该使用您的数据
4) 在测试集上测试模型并查看性能
【讨论】:
【参考方案2】:虽然取出属于一个唯一一类数据的数据,然后使用方法对其他数据是否属于同一类进行分类并非不可能,但通常不会以这种方式获得太好的准确性。
做到这一点的一种方法是使用称为“自动编码器”的东西。这里的重点是您使用相同的图像作为输入和目标,并确保(通常是神经网络)以某种方式强制压缩图像,以便它只存储重建计算机图像的重要内容.理想情况下,这应该会产生一个擅长重建计算机图像的模型,而在其他所有方面都不好,这意味着你可以测试输出的损失有多高,如果它高于你决定的某个阈值,你认为它是别的东西。同样,这样做您可能不会获得接近 90% 的准确率,但它是解决您的问题的一种方法。
更好的方法是寻找已经在某些数据集上预先训练过的模型,这些数据集将计算机作为数据集的一部分,采用相同的数据集并将所有计算机设置为一个类别(+您自己的图像,确保它们遵守数据集格式)和选择其他图像到其他类。确保不要让类太不平衡,否则你的模型会受到影响。用几层扩展预训练模型,完全连接应该可以做得很好,并使模型的预训练部分不可训练,所以当你实际上告诉它时,你不会弄乱那里的好权重忽略所有不是计算机的东西。 这可能是您最好的选择,但您需要付出更多努力才能找到实现它所需的所有这些部分,并了解如何将这些代码集成到您的代码中。
【讨论】:
这是评论/意见/建议,不是解决方案/答案。 Stack Overflow 认为有关软件算法的问题是适当的。虽然问题没有具体提到这一点,但可以根据标签合理地推断出来。自动编码器可以被认为是一种适合特定问题的算法。一些意见被抛在脑后,但如果不允许任何意见,我们可能不得不清除很多问题和答案。 两个问题: 1. 本帖没有编程题。 2. 回答有意见是100%没问题,这是回答问题的本质,但你的回答是100%意见和0%代码。您的贡献将是一个完美的评论,但不是答案,因为它不能解决问题,它只是提供建议。这对 cmets 来说非常好,但这不是答案的目的。 How to Answer 强烈建议只回答问得好问题。另请参阅:Should one advise on off-topic questions?【参考方案3】:-
您可以使用 imagenet 数据集上的预训练模型进行迁移学习。正如另一个答案中提到的,imagenet 中有一堆类靠近计算机和电子设备(如显示器、CD 播放器、笔记本电脑、扬声器等)。因此,您可以在数据集上微调模型并对其进行训练以预测计算机(在大约 750 张图像上进行训练并在剩余的 250 张图像上进行测试)。
您可以手动收集计算机以外的物体的图像,最好是很多电子设备(因为它们靠近计算机)和一堆其他家居用品(有一个home objects dataset by Caltech)。您应该收集大约 1000 张这样的图像才能达到类平衡。拥有此数据集后,您可以训练自己的自定义模型。
【讨论】:
这是评论/意见/建议,不是解决方案/答案。【参考方案4】:没问题!
第一步:安装您选择的深度学习工具包。这些天他们都有很好的教程。
第二步:获取预训练的 imagenet 模型。在该模型中,已经内置了一些计算机类! (“desktop_computer”、“laptop”、“notebook”,以及手持计算机的另一个类“hand-held_computer”)
第三步:使用模型进行预测。为此,您需要使图片尺寸正确。
更多步骤:进一步微调模型...更高级一些,但会给您一些收获。
要考虑的是你的目标是什么?准确性?误报/负数等?从一开始就确定你需要完成的目标总是好的。
编辑:可能最简单的入门方法(如果您没有库、gpu 等)是转到 google colab (https://colab.research.google.com/notebooks/welcome.ipynb) 并在浏览器中创建一个笔记本并运行以下代码。
#some code take and modded from https://www.learnopencv.com/keras-tutorial- using-pre-trained-imagenet-models/
import keras
import numpy as np
from keras.applications import vgg16
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.imagenet_utils import decode_predictions
import matplotlib.pyplot as plt
from PIL import Image
import requests
from io import BytesIO
%matplotlib inline
vgg_model = vgg16.VGG16(weights='imagenet')
def predict_image(image_url, model):
response = requests.get(image_url)
original = Image.open(BytesIO(response.content))
newsize = (224, 224)
original = original.resize(newsize)
# convert the PIL image to a numpy array
# IN PIL - image is in (width, height, channel)
# In Numpy - image is in (height, width, channel)
numpy_image = img_to_array(original)
# Convert the image / images into batch format
# expand_dims will add an extra dimension to the data at a particular axis
# We want the input matrix to the network to be of the form (batchsize, height, width, channels)
# Thus we add the extra dimension to the axis 0.
image_batch = np.expand_dims(numpy_image, axis=0)
plt.imshow(np.uint8(image_batch[0]))
plt.show()
# prepare the image for the VGG model
processed_image = vgg16.preprocess_input(image_batch.copy())
# get the predicted probabilities for each class
predictions = model.predict(processed_image)
# convert the probabilities to class labels
# We will get top 5 predictions which is the default
label = decode_predictions(predictions)
print label[0][0:2] #just display top 2
urls = ['https://4.imimg.com/data4/CO/YS/MY-29352968/samsung-desktop-computer-500x500.jpg', 'https://cdn.britannica.com/77/170477-050-1C747EE3/Laptop-computer.jpg']
for u in urls:
predict_image(u, vgg_model)
这应该是一个很好的起点。哦,如果最上面的预测标签不在计算机、笔记本电脑等集合中,那么它就不是计算机!
【讨论】:
这是评论/意见/建议,不是解决方案/答案。 这是一个解决方案...必须从某个地方开始。自己运行吧。 非问题的解决方案? OP 只是在寻找一般建议,帖子必须关闭,而不是回答。 我投票决定关闭帖子和答案。 我同意这个过程。我只是不同意他得到的基本上是“不”或“需要更多技能”或“需要更多数据”的回答。如果他们确实在“询问”我的想法(这可能与我的解释不同,同意!),我不希望他们离开时认为这是不可能的......所以我用代码压缩了一个答案来演示它可能完全可能取决于他们的目标是什么。我很高兴将整个内容删除/删除/删除......我没有附加。我只是希望它有帮助。我很感激你删除了你投的反对票。以上是关于使用迁移学习对单类数据集进行图像分类[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
PyTorch深度学习实战 | 搭建卷积神经网络进行图像分类与图像风格迁移
图像分类猫狗分类实战—基于pytorch框架的迁移学习(ResNet50模型实现分类实战)