- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我目前正在尝试了解如何重用 VGG19(或其他架构)以改进我的小型图像分类模型。我将图像(在本例中为绘画)分为 3 类(比方说,15、16 和 17 世纪的绘画)。我有一个相当小的数据集,每类 1800 个训练示例,验证集中每类 250 个。
我有以下实现:
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
from keras.callbacks import ModelCheckpoint
from keras.regularizers import l2, l1
from keras.models import load_model
# set proper image ordering for TensorFlow
K.set_image_dim_ordering('th')
batch_size = 32
# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1./255)
# this is a generator that will read pictures found in
# subfolers of 'data/train', and indefinitely generate
# batches of augmented image data
train_generator = train_datagen.flow_from_directory(
'C://keras//train_set_paintings//', # this is the target directory
target_size=(150, 150), # all images will be resized to 150x150
batch_size=batch_size,
class_mode='categorical')
# this is a similar generator, for validation data
validation_generator = test_datagen.flow_from_directory(
'C://keras//validation_set_paintings//',
target_size=(150, 150),
batch_size=batch_size,
class_mode='categorical')
model = Sequential()
model.add(Conv2D(16, (3, 3), input_shape=(3, 150, 150)))
model.add(Activation('relu')) # also tried LeakyRelu, no improvments
model.add(MaxPooling2D(pool_size=(2, 3), data_format="channels_first"))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 3), data_format="channels_first"))
model.add(Flatten())
model.add(Dense(64, kernel_regularizer=l2(.01)))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(3))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='adam', # also tried SGD, it doesn't perform as well as adam
metrics=['accuracy'])
fBestModel = 'best_model_final_paintings.h5'
best_model = ModelCheckpoint(fBestModel, verbose=0, save_best_only=True)
hist = model.fit_generator(
train_generator,
steps_per_epoch=2000 // batch_size,
epochs=100,
validation_data=validation_generator,
validation_steps=200 // batch_size,
callbacks=[best_model],
workers=8 # cpu generation is run in parallel to the gpu training
)
print("Maximum train accuracy:", max(hist.history["acc"]))
print("Maximum train accuracy on epoch:", hist.history["acc"].index(max(hist.history["acc"]))+1)
print("Maximum validation accuracy:", max(hist.history["val_acc"]))
print("Maximum validation accuracy on epoch:", hist.history["val_acc"].index(max(hist.history["val_acc"]))+1)
如果我使架构更深,如果我更严格地对其进行正则化,它要么会过度拟合,要么像疯了一样跳来跳去,甚至在某一时刻达到 100%:
我也尝试过使用 BatchNormalization,但是模型几乎没有学习,它在训练集上的准确率不超过 50%。尝试使用和不使用丢弃。
除了过度改变架构之外,我正在寻找其他改进模型的方法。我看到的选项之一是重用现有架构及其权重并将其插入到我的模型中。但我找不到任何真实的例子来说明如何去做。我主要关注这篇博文: https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html
它谈到了重用 VGG19 来提高准确性,但并没有真正解释它是如何完成的。还有其他我可以效仿的例子吗?我将如何使其适应我当前的实现?我找到了一个完整的模型架构,但无法在我的硬件上运行它,因此我正在寻找一种方法来重用已经训练好的带有权重的模型,然后根据我的问题对其进行调整。
此外,我不理解博客在 VGG 部分中谈到的“瓶颈功能”背后的概念。如果有人能解释一下,我们会很高兴。
最佳答案
你绝对应该试试 Transfer Learning (链接是“迁移学习 Keras”的第一个 Google 结果,有很多关于该主题的教程)。本质上,TL 是对具有新分类层的大型数据集(即最常见的 Imagenet)进行预训练的网络的微调。背后的想法是,您希望保留在网络较低层学习到的所有好的特征(因为您的图像很可能也具有这些特征),并且只在这些特征之上学习一个新的分类器。这往往很有效,特别是如果您的数据集较小,不允许从头开始对网络进行全面训练(这也比全面训练快得多)
请注意,有多种方法可以进行 TL(我鼓励您研究该主题以找到最适合您的方法)。在我的应用程序中,我只是使用从 Imagenet 公共(public)检查点获取的权重初始化网络,删除最后一层并从那里训练所有内容(使用足够低的学习率,否则你会弄乱你的低级功能实际上想保留)。这种方法允许数据扩充。
另一种方法是使用瓶颈。在这种情况下,瓶颈(在其他情况下也称为嵌入)是您的输入样本之一在网络中某个深度级别的内部表示。换句话说,当网络的输出在 N 层后停止时,您可以看到 N 级的瓶颈。为什么这有用?因为您可以使用预训练网络预先计算所有样本的瓶颈,然后仅模拟网络最后一层的训练,而无需实际重新计算网络的所有(昂贵的)部分直到瓶颈点。
假设您有一个具有以下结构的网络:
in -> A -> B -> C -> D -> E -> out
其中 in
和 out
是输入和输出层,另一个是您可能在网络中拥有的任何类型的层。假设您发现在某处发布了在 Imagenet 上预训练的网络检查点。 Imagenet 有 1000 个类,您不需要任何一个。因此,您将丢弃网络的最后一层(分类器)。然而,其他图层包含您要保留的功能。让 E
成为我们示例中的分类器层。
从您的数据集中获取样本,将它们提供给 in
并收集匹配的瓶颈值 作为层 D
的输出。您对数据集中的所有样本执行一次此操作。瓶颈集合是您将用于训练新分类器的新数据集。
您构建了一个具有以下结构的虚拟网络:
bottleneck_in -> E' -> out
您现在像往常一样训练这个网络,但不是从您的数据集中提供样本,而是从瓶颈数据集中提供匹配的瓶颈。请注意,这样做会保存从 A
到 D
的所有层的计算,但这样您就不能在训练期间应用任何数据扩充 (当然,您仍然可以构建瓶颈,但您将有大量数据要存储)。
最后,要构建您的最终分类器,您的网络架构将是
in -> A -> B -> C -> D -> E' -> out
权重 A
到 D
来自公共(public)检查点,权重 E'
来自您的训练。
关于python - 如何在 Keras 中重用 VGG19 进行图像分类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46150757/
我已经使用 VGG 作为图像分类模型实现了图像字幕。我读过关于 YOLO 是一种快速图像分类和检测模型的文章,它主要用于多目标检测。但是对于图像字幕,我只想要类而不是边界框。 最佳答案 我完全同意 P
你能告诉我每层有多少个神经元吗?我觉得这将增进我对 VGG 正在发生的事情的理解。 让我们在这里使用这段代码只是为了得到一些具体的东西。 https://github.com/machrisaa/te
我的问题是如何将从预训练 Vgg16 模型加载的常量张量转换为 tf.Variable 张量?动机是我需要计算关于 Conv4_3 层内核的特定损失的梯度,但是,内核似乎设置为 tf.Constant
我正在使用使用 VGG(神经网络)的基于转移式的深度学习方法。后者适用于小尺寸(512x512 像素)的图像,但是当输入图像很大(尺寸 > 1500 像素)时它会提供失真的结果。该方法的作者建议将输入
我所做的是: from keras.applications.vgg16 import VGG16 from keras.layers import * from keras.models impor
我想知道是否可以将自定义模型添加到 keras 中的损失函数。例如: def model_loss(y_true, y_pred): inp = Input(shape=(128, 128,
我加载了预训练的 VGG 人脸 CNN 并成功运行。我想从第 3 层和第 8 层提取超列平均值。我正在关注关于从 here 中提取超列的部分。 .但是,由于 get_output 函数不起作用,我不得
我正在使用 Python 3.7.7 和 Tensorflow 2.1.0。 我想创建一个 VGG16 自动编码器网络,向它加载一个权重文件,然后获取它的编码器和解码器。 获取 VGG16 自编码器网
我有一个 VGG19 编码器,它接受 (256,256,3) 的输入图像 y 并返回维度 (32,32, 512) 的张量 来自 vgg 的 conv-4-1 层。我需要将其转换为 numpy 数组以
当使用 torchvision.models 模块加载预训练的 VGG 网络并使用它对任意 RGB 图像进行分类时,网络的输出在每次调用之间明显不同。为什么会这样?根据我的理解,VGG 前向传播的任何
我已关注this加载并运行预训练的 VGG 模型。但是,我试图从隐藏层中提取特征图,并尝试复制“提取任意特征图”部分 here 中的结果。 。我的代码如下: #!/usr/bin/python imp
我正在尝试使用来自 keras 的预训练 VGG 16。但我真的不确定输入范围应该是多少。 快速回答,这些颜色顺序中的哪些? RGB BGR 哪个范围? 0 到 255? 从大约 -125 平衡到大约
我正在使用包含 3k 图像的数据集从头开始训练 VGG-16 模型。 我使用 Tensorflow 平台和 8 个 CPU,没有任何 GPU。 训练率 - 0.01, 重量衰减 - 0.0005, 动
这个问题是对 this answer 评论中讨论的跟进。 . 据我了解,preprocess_input() function 确实意味着输入图像的减法和 std-dev dvision。平均值是在训
刚接触pytorch,想用Vgg做迁移学习。我想删除全连接层并添加一些新的全连接层。我还想使用灰度输入而不是 RGB 输入。为此,我将添加输入层的权重并获得单个权重。所以三个 channel 的权重会
我使用 VGG16 基础创建了一个自定义 Keras 模型,并对其进行训练和保存: from keras.applications import VGG16 from keras import mod
我正在尝试打印所有已知类别及其概率值。第一个值是概率最高的类别。 这是迄今为止我的代码: from keras.applications.vgg16 import VGG16 from keras.p
我试图将具有以下形状的数据拟合到预训练的 keras vgg19 模型中。 图像输入形状为(32383, 96, 96, 3)标签形状为 (32383, 17)我收到了这个错误 expected bl
我正在使用预先训练的 VGG-16 网络将图像转换为特征。我可以按顺序完成这个工作。但是,我想并行执行此操作,但我不确定如何正确构建批处理。 具体来说,假设我加载了 16 个保存在 numpy 数组中
我实际上正在尝试使用 Keras 获得 VGG16 的顺序模型版本。功能版本可以通过以下方式获得: from __future__ import division, print_function im
我是一名优秀的程序员,十分优秀!