- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在使用 Keras 微调 Inception 模型时遇到问题。
我已经成功地使用教程和文档生成了一个完全连接的顶层模型,该模型使用 Inception 中的瓶颈特征将我的数据集分类到正确的类别中,准确率超过 99%。
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras import applications
# dimensions of our images.
img_width, img_height = 150, 150
#paths for saving weights and finding datasets
top_model_weights_path = 'Inception_fc_model_v0.h5'
train_data_dir = '../data/train2'
validation_data_dir = '../data/train2'
#training related parameters?
inclusive_images = 1424
nb_train_samples = 1424
nb_validation_samples = 1424
epochs = 50
batch_size = 16
def save_bottlebeck_features():
datagen = ImageDataGenerator(rescale=1. / 255)
# build bottleneck features
model = applications.inception_v3.InceptionV3(include_top=False, weights='imagenet', input_shape=(img_width,img_height,3))
generator = datagen.flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
bottleneck_features_train = model.predict_generator(
generator, nb_train_samples // batch_size)
np.save('bottleneck_features_train', bottleneck_features_train)
generator = datagen.flow_from_directory(
validation_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False)
bottleneck_features_validation = model.predict_generator(
generator, nb_validation_samples // batch_size)
np.save('bottleneck_features_validation', bottleneck_features_validation)
def train_top_model():
train_data = np.load('bottleneck_features_train.npy')
train_labels = np.array(range(inclusive_images))
validation_data = np.load('bottleneck_features_validation.npy')
validation_labels = np.array(range(inclusive_images))
print('base size ', train_data.shape[1:])
model = Sequential()
model.add(Flatten(input_shape=train_data.shape[1:]))
model.add(Dense(1000, activation='relu'))
model.add(Dense(inclusive_images, activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy',
optimizer='Adam',
metrics=['accuracy'])
proceed = True
#model.load_weights(top_model_weights_path)
while proceed:
history = model.fit(train_data, train_labels,
epochs=epochs,
batch_size=batch_size)#,
#validation_data=(validation_data, validation_labels), verbose=1)
if history.history['acc'][-1] > .99:
proceed = False
model.save_weights(top_model_weights_path)
save_bottlebeck_features()
train_top_model()
Epoch 50/50 1424/1424 [==============================] - 17s 12ms/step - loss: 0.0398 - acc: 0.9909
我还能够将这个模型堆叠在初始之上以创建我的完整模型并使用该完整模型成功地对我的训练集进行分类。
from keras import Model
from keras import optimizers
from keras.callbacks import EarlyStopping
img_width, img_height = 150, 150
top_model_weights_path = 'Inception_fc_model_v0.h5'
train_data_dir = '../data/train2'
validation_data_dir = '../data/train2'
#how many inclusive examples do we have?
inclusive_images = 1424
nb_train_samples = 1424
nb_validation_samples = 1424
epochs = 50
batch_size = 16
# build the complete network for evaluation
base_model = applications.inception_v3.InceptionV3(weights='imagenet', include_top=False, input_shape=(img_width,img_height,3))
top_model = Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))
top_model.add(Dense(1000, activation='relu'))
top_model.add(Dense(inclusive_images, activation='softmax'))
top_model.load_weights(top_model_weights_path)
#combine base and top model
fullModel = Model(input= base_model.input, output= top_model(base_model.output))
#predict with the full training dataset
results = fullModel.predict_generator(ImageDataGenerator(rescale=1. / 255).flow_from_directory(
train_data_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='categorical',
shuffle=False))
检查此完整模型的处理结果与瓶颈生成的全连接模型的准确性相匹配。
import matplotlib.pyplot as plt
import operator
#retrieve what the softmax based class assignments would be from results
resultMaxClassIDs = [ max(enumerate(result), key=operator.itemgetter(1))[0] for result in results]
#resultMaxClassIDs should be equal to range(inclusive_images) so we subtract the two and plot the log of the absolute value
#looking for spikes that indicate the values aren't equal
plt.plot([np.log(np.abs(x)+10) for x in (np.array(resultMaxClassIDs) - np.array(range(inclusive_images)))])
问题是:当我使用这个完整的模型并尝试对其进行训练时,即使验证率保持在 99% 以上,准确性也会下降到 0。
model2 = fullModel
for layer in model2.layers[:-2]:
layer.trainable = False
# compile the model with a SGD/momentum optimizer
# and a very slow learning rate.
#model.compile(loss='binary_crossentropy', optimizer=optimizers.SGD(lr=1e-4, momentum=0.9), metrics=['accuracy'])
model2.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
train_datagen = ImageDataGenerator(rescale=1. / 255)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
callback = [EarlyStopping(monitor='acc', min_delta=0, patience=3, verbose=0, mode='auto', baseline=None)]
# fine-tune the model
model2.fit_generator(
#train_generator,
validation_generator,
steps_per_epoch=nb_train_samples//batch_size,
validation_steps = nb_validation_samples//batch_size,
epochs=epochs,
validation_data=validation_generator)
Epoch 1/50 89/89 [==============================] - 388s 4s/step - loss: 13.5787 - acc: 0.0000e+00 - val_loss: 0.0353 - val_acc: 0.9937
随着事情的进展,情况会变得更糟
Epoch 21/50 89/89 [==============================] - 372s 4s/step - loss: 7.3850 - acc: 0.0035 - val_loss: 0.5813 - val_acc: 0.8272
我唯一能想到的是,在最后一列火车上训练标签以某种方式分配不当,但我之前使用 VGG16 使用类似代码成功地做到了这一点。
我搜索了代码,试图找到一个差异来解释为什么在 99% 的时间内做出准确预测的模型会降低其训练准确性,同时在微调期间保持验证准确性,但我无法弄清楚。任何帮助将不胜感激。
关于代码和环境的信息:
看起来很奇怪的事情,但本来就是这样的:
我正在使用:
我已经 checkout :
但它们似乎无关。
最佳答案
注意:由于您的问题有点奇怪并且在没有经过训练的模型和数据集的情况下难以调试,因此这个答案只是在考虑了许多可能出错的事情之后的(最佳)猜测。请提供您的反馈,如果它不起作用,我将删除此答案。
由于 inception_V3 包含 BatchNormalization
层,当您将 trainable
参数设置为 False 时,问题可能是由于该层的(不知何故模棱两可或意外的)行为
(1,2,3,4)。
现在,让我们看看这是否是问题的根源:as suggested by @fchollet , 定义微调模型时设置学习阶段:
from keras import backend as K
K.set_learning_phase(0)
base_model = applications.inception_v3.InceptionV3(weights='imagenet', include_top=False, input_shape=(img_width,img_height,3))
for layer in base_model.layers:
layer.trainable = False
K.set_learning_phase(1)
top_model = Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))
top_model.add(Dense(1000, activation='relu'))
top_model.add(Dense(inclusive_images, activation='softmax'))
top_model.load_weights(top_model_weights_path)
#combine base and top model
fullModel = Model(input= base_model.input, output= top_model(base_model.output))
fullModel.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
#####################################################################
# Here, define the generators and then fit the model same as before #
#####################################################################
旁注:这不会对您的情况造成任何问题,但请记住,当您使用 top_model(base_model.output)
时,整个 Sequential 模型(即top_model
) 存储为 fullModel
的一层。您可以使用 fullModel.summary()
或 print(fullModel.layers[-1])
来验证这一点。因此,当您使用时:
for layer in model2.layers[:-2]:
layer.trainable = False
你实际上并没有卡住 base_model
的最后一层。但是,由于它是一个 Concatenate
层,因此没有可训练的参数,因此不会出现任何问题,它会按照您的预期运行。
关于python - Keras:微调 Inception 时精度下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52282108/
我想循环遍历 gpx 文件并计算总上升和下降。我有一个函数可以计算两组经纬度点之间的高程差异,我已经设置了 simplexml 来读取和循环遍历 gpx 文件 trkseg 点。 问题是,这不准确(实
我有两个在不同时间段拍摄的数组。如何通过将新玩家标记为上升来检查哪些玩家在列表中上升/下降? 附言- 数组已经根据分数排序。 pastData:[ { playerName:'Jo
我想捕获 ctrl/alt/etc 键的起伏,无论表单上的哪个控件获取 keyup 或 keydown 事件。由于我的表单上有大约 100 个控件,如果我要为每个单独的控件添加代码,那将非常难看。我怎
vector1 = c(2, 2, 2, 2, 2, 2) vector2 = c(2, 2, 3, 3, 3, 3) vector3 = c(2, 2, 1, 2, 2, 2) 我想知道向量中的数字
我不知道如何遵循编译器的建议:consider using a let binding to create a longer lived value。 Playground #![allow(unus
我希望有人能帮助我理解 AngularJS 中的 $scope 遇到的一个恼人的问题。请参阅下面我的代码中的注释: app.controller('MyController', function ($
我有一个 flex 搜索集群,其中有2个节点在2核CPU 8GB ram实例上运行。每个节点都传入了参数“ES_JAVA_OPTS = -Xms3g -Xmx3g”。我有4个索引,每个索引有2个分片和
我正在学习 R(及其通过 quantmod lib 在交易任务中的应用)并定期浏览社区以从这里获得许多新知识和技巧。我对 R 的总体印象和特别是 quantmod lib 的印象 - 它很棒。 在这一
当我们点击屏幕时,我正在绘制纹理正方形。我正在使用相同的纹理。在新 ios 设备中点击几次后,FPS 从 120 下降到 4 左右。每次手指点击时,我都会将点击的点以及纹理和纹理的大小传递给着色器。
只有当对象被点击并且需要从列表中移除时它才会掉落。这是代码: if(event.type == TouchEvent.TOUCH_DOWN){ for(Bottle bottl
我有一个基于SpriteKit的小游戏。 在这个游戏中,我使用了很多带有字母(或字母组合)的节点,用户可以四处移动来构建单词。 这些节点基本上是带有 SKLabelNode 的 SKSpriteNod
我有一个简单的CSS布局 wrapper header left-sidebar / main-content / right-sidebar footer 但我的主要内容似乎下降了(float dr
在标题中,我给出了四个不同的部分,并使用 float 属性使所有内容都显示在一条水平线上。 当我调整浏览器窗口大小时,最后一个 div 位于黑色边框线下方。 如何解决。 http://jsfiddle
CSS: .desc{ text-align: center; color:#60A8D5; padding-top: 17px;
这是一段简单的代码,但我为这个问题尝试过的解决方案都没有奏效。 #ONE { float: left; border: 1
我有一个 SceneKit 设置,其中有一个 Sphere 设置为 Dynamic body。 我能够运行该应用程序并看到球体落在静态 body 地板上。 我想做的是设置场景,这样 sfere 最初就
首先,我的类(class): export class FooBar { ... isFavorite: boolean = false; constructor() { this.isF
我正在尝试删除所有端口上的所有传出 RST 和传入 RST。我正在使用 Debian Linux。我尝试了互联网上列出的所有可能的命令组合,但似乎没有任何效果。 例如,我试过: iptables -A
我正在做这样的事情: fn main() { //[1, 0, 0, 0, 99]; // return [2, 0, 0, 0, 99] //[2, 3, 0, 3, 99]; //
我正在使用 Rusqlite,它可以让你做这样的查询: statement.query_row(params!([1, 2, 3]), ...); params!()定义如下: macro_rules
我是一名优秀的程序员,十分优秀!