【问题标题】:Fine tuned VGG-16 gives the exact same prediction for all test images微调后的 VGG-16 对所有测试图像给出完全相同的预测
【发布时间】:2018-04-27 14:42:42
【问题描述】:

我对 VGG-16 网络进行了微调,以预测医学图像上是否存在疾病。然后我使用 model.predict() 测试了模型,但我看到的是网络预测完全相同的 22.310%77.690 % 分别表示所有 100 张测试图像是否存在疾病(见屏幕截图。)我在下面附上了我的代码和训练输出。训练看起来还行。请注意,培训是在服务器上完成的,而预测是在我的 PC 上进行的,因此目录不同。 您能帮我找出问题所在吗?

培训代码:

import numpy as np
import os
import time
from vgg16 import VGG16
from keras.preprocessing import image
from imagenet_utils import preprocess_input, decode_predictions
from keras.layers import Dense, Activation, Flatten
from keras.layers import merge, Input
from keras.models import Model
from keras.utils import np_utils
from sklearn.utils import shuffle
from sklearn.cross_validation import train_test_split

# Loading the training data
PATH = '/mount'
# Define data path
data_path = PATH 
data_dir_list = os.listdir(data_path)

img_data_list=[]
y=0;
for dataset in data_dir_list:
    img_list=os.listdir(data_path+'/'+ dataset)
    print ('Loaded the images of dataset-'+'{}\n'.format(dataset))
    for img in img_list:
        img_path = data_path + '/'+ dataset + '/'+ img 
        img = image.load_img(img_path, target_size=(224, 224))
        x = image.img_to_array(img)
        x = np.expand_dims(x, axis=0)
        x = preprocess_input(x)
        x = x/255

        y=y+1
        print('Input image shape:', x.shape)
        print(y)
        img_data_list.append(x)
img_data = np.array(img_data_list)
#img_data = img_data.astype('float32')
print (img_data.shape)
img_data=np.rollaxis(img_data,1,0)
print (img_data.shape)
img_data=img_data[0]
print (img_data.shape)

# Define the number of classes
num_classes = 2
num_of_samples = img_data.shape[0]
labels = np.ones((num_of_samples,),dtype='int64')

labels[0:3001]=0
labels[3001:]=1

names = ['YES','NO']

# convert class labels to on-hot encoding
Y = np_utils.to_categorical(labels, num_classes)

#Shuffle the dataset
x,y = shuffle(img_data,Y, random_state=2)
# Split the dataset
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=2)

image_input = Input(shape=(224, 224, 3))

model = VGG16(input_tensor=image_input, include_top=True,weights='imagenet')

model.summary()

last_layer = model.get_layer('block5_pool').output
x= Flatten(name='flatten')(last_layer)
x = Dense(16, activation='relu', name='fc1')(x)
x = Dense(8, activation='relu', name='fc2')(x)
out = Dense(num_classes, activation='softmax', name='output')(x)
custom_vgg_model2 = Model(image_input, out)

# freeze all the layers except the dense layers
for layer in custom_vgg_model2.layers[:-6]:
    layer.trainable = False

custom_vgg_model2.summary()

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

t=time.time()
#   t = now()
hist = custom_vgg_model2.fit(X_train, y_train, batch_size=128, epochs=10, verbose=1, validation_data=(X_test, y_test))
print('Training time: %s' % (t - time.time()))
(loss, accuracy) = custom_vgg_model2.evaluate(X_test, y_test, batch_size=10, verbose=1)

print("[INFO] loss={:.4f}, accuracy: {:.4f}%".format(loss,accuracy * 100))
custom_vgg_model2.save("vgg_3000_92percent_real.h5")

训练输出:

训练 4800 个样本,验证 1200 个样本
纪元 1/10
4800/4800 [==============================] - 100s - 损失:0.6098 - acc:0.7567 - val_loss:0.3252 - val_acc:0.8667
纪元 2/10
4800/4800 [===============================] - 82s - 损失:0.2644 - acc:0.8985 - val_loss:0.2930 - val_acc:0.8783
时代 3/10
4800/4800 [===============================] - 83s - 损失:0.2297 - acc:0.9127 - val_loss:0.2386 - val_acc:0.9042
4/10 纪元
4800/4800 [===============================] - 83s - 损失:0.1844 - acc:0.9327 - val_loss:0.2273 - val_acc:0.9083
5/10 纪元
4800/4800 [===============================] - 83s - 损失:0.1754 - acc:0.9354 - val_loss:0.2080 - val_acc:0.9167
时代 6/10
4800/4800 [===============================] - 83s - 损失:0.1357 - acc:0.9515 - val_loss:0.2403 - val_acc:0.9183
7/10 纪元
4736/4800 [============================>.] - ETA:0s - 损失:0.1241 - acc:0.9525

预测码

import numpy as np
from keras.preprocessing import image
from imagenet_utils import preprocess_input
from keras import models
import matplotlib.pyplot as plt
import os

model128 = models.load_model('16_8_finally.h5')
list=[]
flag=0
#Path0="D:\\download dump for Deep learnng\\dataset\\kaggle general competition\\test"
Path0="I:\\greenchTestsample\\greendr"
list=os.listdir(Path0)
pred0=[0]*len(list)
pred1=[0]*len(list)
for x in list:
    img_path=Path0+'\\'+ x 
    img = image.load_img(img_path, target_size=(224, 224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    x=x/255
    preds = model128.predict(x)
    z=100*preds
    x1=float(z[0][0])
    x2=float(z[0][1])
    pred0[flag]=x1
    pred1[flag]=x2
    flag=flag+1

【问题讨论】:

  • 您在预测循环中在哪里增加flag?看起来您一直在覆盖 pred0pred1 的第零个元素。不会解释一切,但很明显是一个问题。
  • 使用for i, x in enumerate(list):,然后使用pred0[i] = x1pred1[i] = x2enumerate(list) 提供了一个计数器,当您遍历 list 时会自动递增。
  • @Peter Szoldan 我忘了把flag语句的增量复制到论坛
  • @Engineero:好主意!仍然无法解释为什么pred0pred1所有元素 都填充了相同的值。你对此有什么见解吗?也许[0]*len(list) 创建一个列表,其中数字对象引用相同?看起来她在 Windows 上,这可能是问题吗?
  • @PeterSzoldan:好点。也许list 是问题所在,她多次获得相同的文件名?也许改用img_path = os.path.join(Path0, x)?也许打印出你在每个循环中加载的文件名,以验证你得到的是你认为的。

标签: python-3.x image-processing tensorflow deep-learning keras


【解决方案1】:

好的,所以这不是一个真正的答案,而是向调试迈出的一步。请将预测循环更改为下面的代码并发布输出。

for x in list[ :3 ]: # let's do the first 3 only
    img_path=Path0+'\\'+ x 
    print() # leave an empty line before each image
    print( image_path ) # let's see if the correct files are loaded
    img = image.load_img(img_path, target_size=(224, 224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    x /= 255 # just nitpicking :)
    print( x ) # let's see if the values make sense
    preds = model128.predict(x)
    print( preds ) # see if the error is already present here
    z=100*preds
    x1=float(z[0][0])
    x2=float(z[0][1])
    print( x1, x2 )
    pred0[flag]=x1
    pred1[flag]=x2
    flag += 1 # nitpicking again :)

【讨论】:

  • pred0 的结果是 >77.69013214111328,77.69013214111328,77.69013214111328 Pred1>22.309873580932617,22.309873580932617,932.30987s
  • 还不止predict函数是模型微调的问题吗?我每堂课训练了 3000 张图像
  • 图像路径是否有意义,即您是否加载不同的图像?还有图像的数字向量的输出,它们也不同吗?
  • 是的,也有可能您的模型崩溃了。但总的来说,我发现调试时从琐碎到复杂会更好。如果您怀疑模型崩溃,您应该在训练期间打印一些预测。如果它们也是 22.3 和 77.7,那么是的,那就是模型崩溃。但这需要重新运行微调,所以我会先检查这些琐碎的事情。
  • 那么验证准确率不应该降低吗?另外我如何避免它,因为我已经训练了许多完全连接的配置和参数更改,但最终结果仍然不令人满意
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
  • 2019-04-08
  • 2017-07-08
  • 1970-01-01
相关资源
最近更新 更多