我正在使用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)