Python 为什么我的deep模型会出现不一致的损失行为?

Python 为什么我的deep模型会出现不一致的损失行为?,python,tensorflow,machine-learning,keras,deep-learning,Python,Tensorflow,Machine Learning,Keras,Deep Learning,我正在研究一个图像分类结果。我的训练和测试使用相同的随机状态。模型定义是相同的。但是,当我多次运行模型时,四次中有三次,模型没有学习,损失函数没有下降;四分之一的时候,模型在学习,我能得到很好的分类结果。我怀疑随机性来自ImageDataGenerator()。但我不知道如何让模型每次都学习 我有一个相对较小的标记数据集,我没有增加数据大小的方法 我尝试了不同的优化器,不同的批量大小。这没用。我发现,当我减少可训练的层并使后面完全连接的层更小(减少到256个单元)时,模型每次都开始学习。但为什么

我正在研究一个图像分类结果。我的训练和测试使用相同的随机状态。模型定义是相同的。但是,当我多次运行模型时,四次中有三次,模型没有学习,损失函数没有下降;四分之一的时候,模型在学习,我能得到很好的分类结果。我怀疑随机性来自ImageDataGenerator()。但我不知道如何让模型每次都学习

我有一个相对较小的标记数据集,我没有增加数据大小的方法


我尝试了不同的优化器,不同的批量大小。这没用。我发现,当我减少可训练的层并使后面完全连接的层更小(减少到256个单元)时,模型每次都开始学习。但为什么大型网络即使在培训数据集上也不能很好地学习???我的理解是,模型将过度拟合,但为什么在这种情况下,它根本没有学习

IMAGE_WIDTH=128
IMAGE_HEIGHT=128
IMAGE_SIZE=(IMAGE_WIDTH, IMAGE_HEIGHT)
IMAGE_CHANNELS=3 # RGB color

os.chdir(r"XXX")
filenames = os.listdir(r"XXX")
ref_db= pd.read_csv(r"XXX")
ref_db['obj_id']= [str(i)+ '.tif' for i in  ref_db.OBJECTID.values  ]
ref_db2= ref_db[['label', 'obj_id' ]]
ref_db2['label'] = ref_db2['label'].apply(str)


train_df, validate_df = train_test_split(ref_db2, test_size=0.20, random_state=42)
train_df = train_df.reset_index(drop=True)
validate_df = validate_df.reset_index(drop=True)

total_train = train_df.shape[0]
total_validate = validate_df.shape[0]
batch_size=64   

train_datagen = ImageDataGenerator(
    rotation_range=15,
    rescale=1./255,
    shear_range=0.1,
    zoom_range=0.2,
    horizontal_flip=True,
    width_shift_range=0.1,
    height_shift_range=0.1
)

train_generator = train_datagen.flow_from_dataframe(
    train_df, 
    r"XXX", 
    x_col='obj_id',
    y_col='Green_Roof',
    target_size=IMAGE_SIZE,
    class_mode='binary',
    batch_size=batch_size
)                                       


inputs= Input(shape=(IMAGE_WIDTH, IMAGE_HEIGHT, 3))
base_model = VGG19(weights='imagenet', include_top=False,)
for layer in base_model.layers[:-3]:
    layer.trainable = False

x = base_model(inputs)
x = Flatten()(x)
x = Dense(1024, activation="relu")(x)
#x = Dropout(0.5)(x)
x = Dense(512, activation="relu")(x)
predictions = Dense(1, activation="sigmoid")(x)    
model_vgg= Model(inputs=inputs , outputs=predictions)
model_vgg.compile(optimizer='Adam', loss='binary_crossentropy', metrics=['accuracy'])

#########################
history = model_vgg.fit_generator(
    train_generator, 
    epochs=50,
    validation_data=validation_generator,
    validation_steps=total_validate//batch_size,
    steps_per_epoch=total_train//batch_size,
    verbose=2
)



这是不必要的行为,模型没有学习,所有观察值都预测为1,损失没有下降

Found 756 validated image filenames belonging to 2 classes.
Found 190 validated image filenames belonging to 2 classes.
Epoch 1/50
 - 4s - loss: 4.0464 - acc: 0.6203 - val_loss: 4.9820 - val_acc: 0.6875
Epoch 2/50
 - 2s - loss: 4.3811 - acc: 0.7252 - val_loss: 4.8856 - val_acc: 0.6935
Epoch 3/50
 - 2s - loss: 5.0209 - acc: 0.6851 - val_loss: 5.3556 - val_acc: 0.6641
Epoch 4/50
 - 2s - loss: 4.3583 - acc: 0.7266 - val_loss: 4.1142 - val_acc: 0.7419
Epoch 5/50
 - 2s - loss: 4.9317 - acc: 0.6907 - val_loss: 4.7329 - val_acc: 0.7031
Epoch 6/50
 - 2s - loss: 4.6275 - acc: 0.7097 - val_loss: 5.3998 - val_acc: 0.6613
Epoch 7/50
这是预期的行为,模型正在学习,1和0都被预测,损失正在下降

Found 756 validated image filenames belonging to 2 classes.
Found 190 validated image filenames belonging to 2 classes.
Epoch 1/50
 - 4s - loss: 2.1181 - acc: 0.6484 - val_loss: 0.8013 - val_acc: 0.6562
Epoch 2/50
 - 2s - loss: 0.6609 - acc: 0.7096 - val_loss: 0.5670 - val_acc: 0.7581
Epoch 3/50
 - 2s - loss: 0.6539 - acc: 0.6912 - val_loss: 0.5923 - val_acc: 0.6953
Epoch 4/50
 - 2s - loss: 0.5695 - acc: 0.7083 - val_loss: 0.5426 - val_acc: 0.6774
Epoch 5/50
 - 2s - loss: 0.5262 - acc: 0.7176 - val_loss: 0.5386 - val_acc: 0.6875

尝试将输入功能缩放到[0,1]。由于TF输入权重初始化的特殊性,对于值[0,255](以及类似值),初始超平面不会得到任何负/正结果,结果梯度为零。我发现,当我减少可训练层并使后面的完全连接层更小(减少到256个单位)时,模型每次都开始学习。但为什么大型网络即使在培训数据集上也不能很好地学习???我的理解是,模型会过拟合,但为什么在这种情况下,它根本没有学习?这个问题没有简单的答案。这很可能是因为梯度太小,但原因太多了——从消失梯度问题到数据的特殊性。您是否碰巧在隐藏层中使用了sigmoid激活?请尝试将输入功能缩放到[0,1]。由于TF输入权重初始化的特殊性,对于值[0,255](以及类似值),初始超平面不会得到任何负/正结果,结果梯度为零。我发现,当我减少可训练层并使后面的完全连接层更小(减少到256个单位)时,模型每次都开始学习。但为什么大型网络即使在培训数据集上也不能很好地学习???我的理解是,模型会过拟合,但为什么在这种情况下,它根本没有学习?这个问题没有简单的答案。这很可能是因为梯度太小,但原因太多了——从消失梯度问题到数据的特殊性。你是不是碰巧在隐藏层中使用了乙状结肠激活?