Keras:Fit_generator在训练期间工作,但模型无法预测/ 3D CNN

时间:2017-12-19 17:15:43

标签: image-processing keras conv-neural-network

我正在使用Keras 2.1.1中的卷积神经网络进行3D图像分割,并将张量流作为后端。我正在使用fit_generator函数,因为3D图像非常耗费内存,我在每次更新之前都会应用大量数据。

编辑:我还在github上引用了这篇文章,并添加了一个小型演示,演示了有问题的行为:https://github.com/keras-team/keras/issues/8837

import sys
import numpy as np
import h5py
import random
import tensorflow as tf
import random
import scipy.misc as misc
import datetime
import time
import cv2


from keras.callbacks import EarlyStopping
from keras.callbacks import ModelCheckpoint
from keras.optimizers import Adam


print("Loading net")

ada = Adam(lr=0.00005, beta_1=0.1, beta_2=0.001, epsilon=1e-08, decay=0.0)
net = Net(input_shape=(128,160,144, 4),outputChannel=5,momentum=0.5)
net.compile(optimizer="Adam",loss=jaccard_distance_loss)
print("Finished loading net")

filename = 'fold0_1.hdf5'
f = h5py.File(filename, 'r')

train_gen = generateData(f[u'train_x'],f[u'train_y'],augmentor=random_geometric_transformation)
val_gen = generateData(f[u'valid_x'],f[u'valid_y'])

filepath="Model-{epoch:02d}.h5"
checkpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=True, mode='min')
callbacks_list = [checkpoint]

#Train Model
net.fit_generator(generator = train_gen,
                  steps_per_epoch = 200,
                  validation_data=val_gen,
                  validation_steps = 37,
                  epochs = 800,
                  callbacks=callbacks_list)

问题是虽然训练期间报告的误差相对较低,但预测训练或测试图像时的误差与最低训练状态相当(第一个值是整体损失,其他值是每个班级各自的损失。请注意,在未经训练的模型中,第一类的损失接近于0,因为它只是预测背景):

#Loss before training
[3.9978203773498535, 0.032198667526245117, 0.99983119964599609, 0.99984711408615112, 0.99907118082046509, 0.96687209606170654]

在非常简短地对任何给定(训练/测试)样本进行网络训练后,评估错误将与训练期间报告的错误相匹配:

Epoch 1/5
1/1 [==============================] - 9s 9s/step - loss: 2.0542 - slice_layer_1_loss: 0.0048 - slice_layer_2_loss: 0.9998 - slice_layer_3_loss: 0.3026 - slice_layer_4_loss: 0.6302 - slice_layer_5_loss: 0.1167
Epoch 2/5
1/1 [==============================] - 1s 592ms/step - loss: 2.0278 - slice_layer_1_loss: 0.0045 - slice_layer_2_loss: 0.9998 - slice_layer_3_loss: 0.2916 - slice_layer_4_loss: 0.6191 - slice_layer_5_loss: 0.1128
Epoch 3/5
1/1 [==============================] - 1s 582ms/step - loss: 2.0066 - slice_layer_1_loss: 0.0043 - slice_layer_2_loss: 0.9998 - slice_layer_3_loss: 0.2888 - slice_layer_4_loss: 0.6066 - slice_layer_5_loss: 0.1071
Epoch 4/5
1/1 [==============================] - 1s 590ms/step - loss: 1.9909 - slice_layer_1_loss: 0.0042 - slice_layer_2_loss: 0.9998 - slice_layer_3_loss: 0.2872 - slice_layer_4_loss: 0.5959 - slice_layer_5_loss: 0.1038
Epoch 5/5
1/1 [==============================] - 1s 572ms/step - loss: 1.9787 - slice_layer_1_loss: 0.0041 - slice_layer_2_loss: 0.9998 - slice_layer_3_loss: 0.2855 - slice_layer_4_loss: 0.5875 - slice_layer_5_loss: 0.1019

#Loss after training
1/1 [==============================] - 0s 190ms/step
[2.1015677452087402, 0.0048453211784362793, 0.99983119964599609, 0.33013522624969482, 0.64043641090393066, 0.1263195276260376]

问题似乎与这篇文章非常相似: ResNet: 100% accuracy during training, but 33% prediction accuracy with the same data

然而,本演示中使用的模型已经在整个数据集上训练了200个时期,并且更多的时期不能解决问题。此外,在训练期间报告的验证集错误没有任何减少,但是对测试图像的预测显示出与上述相同的行为。

当批量大小仅为1时,使用fit_generator进行批量标准化时是否存在某种问题?

PS:这里是生成器的代码

import numpy as np
import random

def reverseArgMax(array,n):
    newArray = np.empty(list(array.shape+(n,)))

    for i in range(n):
        temp = array.copy()

        if i==1:
            temp[temp!=1] = 0
        elif i==0:
            temp[temp==1] = 2
            temp[temp==i] = 1
            temp[temp!=1] = 0
        else:
            temp[temp==1] = 0
            temp[temp==i] = 1
            temp[temp!=1] = 0
        newArray[...,i]=temp
    return newArray

def generateData(data,labels,augmentor=None,batch_size=1):
    #Generates batches of samples

    while 1:
        # Generate batches
        imax = list(range(len(data)))
        np.random.shuffle(imax)

        for i in imax:
            x = np.array(data[i])
            y = np.array((labels[i]))
            x = np.transpose(x,axes=[0,2,3,1])
            x = np.array([x])
            y = np.array([y])
            x = x.astype(np.float32)
            y = y.astype(np.float32)
            y=reverseArgMax(y,5)

            #Augment
            if augmentor!=None:
                x,y = augmentor(x,y)

            x = x.astype(np.float32)
            y = y.astype(np.float32)
            y = np.transpose(y,[4,0,1,2,3])
            y = np.reshape(y,[5,1,-1])

            yield x, list(y)

0 个答案:

没有答案