繁体   English   中英

Keras VGG16传输学习图像分类带来的极高损失

[英]Extremely High Loss with Keras VGG16 transfer learning Image Classification

我正在重新训练VGG16,并对图像分类任务的前2个卷积块进行微调。 培训本身以中等的精度相当顺利地完成。 该微调程序当前正在运行,似乎至少需要几天。 但是,在3个时间段后,损失高达440左右,这是可笑的高,而精度徘徊在0.4左右。 请确认该模型是否存在重大缺陷,以便我可以终止该程序。 我在微调阶段使用了一些数据扩充和l1_l2正则化。 数据集是一小组约8000张肿瘤图像,分为8类。 因此,数据既小又与图像网络图像无关。 这是我的转学代码:

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
from keras.utils.np_utils import to_categorical
import math

img_width, img_height= 224, 224
weight_path= 'bottleneck_fc_model.h5'
train_dir= 'Cancer_Data/Train'
validation_dir= 'Cancer_Data/Validate'
epochs= 150
batch_size= 128

def save_bottleneck_features():

 datagen = ImageDataGenerator(rescale= 1./255)

 model = applications.VGG16(include_top=False, weights='imagenet')

 print 'Extracting Bottleneck Training Features'

 generator = datagen.flow_from_directory(
  train_dir,
  target_size= (img_width, img_height),
  batch_size= batch_size,
  class_mode= None,
  shuffle= False)


 nb_train_samples= len(generator.filenames)
 predict_size_train= int(math.ceil(nb_train_samples / batch_size))
 bottleneck_feature_train =model.predict_generator(generator,predict_size_train)
 np.save(open('bottleneck_feature_train.npy', 'w'), bottleneck_feature_train)

 print "Bottleneck Training Features Saved"

 print "Extracting Bottleneck Validation Features"

 generator2 = datagen.flow_from_directory(
  validation_dir,
  target_size= (img_width, img_height),
  batch_size= batch_size,
  class_mode= None,
  shuffle= False)

 nb_validation_samples= len(generator2.filenames)
 predict_size_validation= int(math.ceil(nb_validation_samples / batch_size))

 bottleneck_feature_validation = model.predict_generator(generator2, predict_size_validation)
 np.save(open('bottleneck_feature_validation.npy', 'w'), bottleneck_feature_validation)

 print "Bottleneck Validation Features Saved"

def train_top_model():

 datagen_top = ImageDataGenerator(rescale=1./255)
 generator_top = datagen_top.flow_from_directory(
  train_dir,
  target_size= (img_width,img_height),
  batch_size=batch_size,
  class_mode='categorical',
  shuffle=False)


 nb_classes = len(generator_top.class_indices)
 np.save('class_indices.npy', generator_top.class_indices)

 train_data = np.load('bottleneck_feature_train.npy')
 train_labels= to_categorical(generator_top.classes, num_classes= nb_classes)

 generator_top2 = datagen_top.flow_from_directory(
  validation_dir,
  target_size=(img_width,img_height),
  batch_size=batch_size,
  class_mode=None,
  shuffle=False)

 validation_data = np.load('bottleneck_feature_validation.npy')
 validation_labels= to_categorical(generator_top2.classes, num_classes= nb_classes)

 model = Sequential()
 model.add(Flatten(input_shape=train_data.shape[1:]))
 model.add(Dense(256, activation='relu'))
 model.add(Dropout(0.5))
 model.add(Dense(nb_classes, activation= 'softmax'))

 model.compile(optimizer= 'adam', loss= 'categorical_crossentropy', metrics= ['accuracy'])

 model.save_weights(weight_path)

 model.fit(train_data, train_labels, epochs= epochs, batch_size= batch_size,
       validation_data= (validation_data, validation_labels))

 (eval_loss, eval_accuracy) = model.evaluate(
  validation_data, validation_labels, batch_size=batch_size, verbose=1)

 print("[INFO] accuracy: {:.2f}%".format(eval_accuracy * 100))
 print("[INFO] Loss: {}".format(eval_loss))

save_bottleneck_features()
train_top_model()

用于微调模型的代码是:

from keras import applications
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.regularizers import l1_l2
from keras.models import Sequential, Model
from keras.layers import Dropout, Flatten, Dense
import PIL
import math


weight_path = 'fine_tuned.h5'
top_model_weight_path = 'top_model.h5'

img_width, img_height = 224, 224

train_dir = 'Cancer_Data/Train'
validation_dir = 'Cancer_Data/Validate'

epochs = 200

batch_size = 128

nb_train_samples = 6454
nb_validation_samples = 1464

base_model =applications.VGG16(weights= 'imagenet', include_top= False, input_shape=(224,224,3))
print "Model Loaded."

top_model= Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))
top_model.add(Dense(256, activation='relu', kernel_regularizer= l1_l2(l1=0.01, l2= 0.01)))
top_model.add(Dense(8, activation= 'softmax'))

top_model.load_weights(top_model_weight_path)

model= Model(inputs= base_model.input, outputs= top_model(base_model.output))

for layer in model.layers[:18]:
 layer.trainable=False

model.compile(optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
          loss='categorical_crossentropy', metrics=['accuracy'])

train_datagen= ImageDataGenerator(
 rescale=1./255,
 shear_range=0.3,
 zoom_range=0.3,
 horizontal_flip=True)

test_datagen= ImageDataGenerator(rescale=1./255)

train_generator= train_datagen.flow_from_directory(
 train_dir,
 target_size=(img_height,img_width),
 batch_size=batch_size,
 class_mode='categorical')

validation_generator= test_datagen.flow_from_directory(
 validation_dir,
 target_size=(img_height,img_width),
 batch_size=batch_size,
 class_mode='categorical')

model.save(weight_path)

model.fit_generator(
 train_generator,
 steps_per_epoch = int(math.ceil(nb_train_samples / batch_size)),
 epochs=epochs,
 validation_data=validation_generator,
 validation_steps = int(math.ceil(nb_validation_samples / batch_size)))

我是python和Keras的新手,所以我无法弄清楚我做错了什么,或者模型本身是否存在结构性问题。 我可以进行哪些更改,并且可以使用哪些技术来减少损失?

对VGG 16的训练不是在[0,1]范围内的数据上,而是在[-128,128]范围内(大约)的数据上,该数据是通过从各个颜色通道中减去相应的平均像素获得的。 另外,VGG 16需要BGR格式的数据。

使用如下所示的预处理(摘自keras源代码)

def preprocess:
    if data_format == 'channels_first':
        if x.ndim == 3:
            # 'RGB'->'BGR'
            x = x[::-1, ...]
            # Zero-center by mean pixel
            x[0, :, :] -= 103.939
            x[1, :, :] -= 116.779
            x[2, :, :] -= 123.68
        else:
            x = x[:, ::-1, ...]
            x[:, 0, :, :] -= 103.939
            x[:, 1, :, :] -= 116.779
            x[:, 2, :, :] -= 123.68
    else:
        # 'RGB'->'BGR'
        x = x[..., ::-1]
        # Zero-center by mean pixel
        x[..., 0] -= 103.939
        x[..., 1] -= 116.779
        x[..., 2] -= 123.68
    return x

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM