Python Keras fit_generator()不';我不能正常训练

Python Keras fit_generator()不';我不能正常训练,python,tensorflow,tensorflow2.0,tf.keras,Python,Tensorflow,Tensorflow2.0,Tf.keras,我正在尝试使用Keras和TensorFlow 2.0.0后端创建一个图像分类器 我正在我的本地机器上训练这个模型,在一个定制的数据集上,它包含总共17000张图像。图像大小不同,位于三个不同的文件夹(培训、验证和测试)中,每个文件夹包含两个子文件夹(每个类一个子文件夹)。 我尝试了一种类似于VGG16的体系结构,它在过去的数据集上产生了非常好的结果。注意,数据中存在轻微的等级不平衡(52:48) 当我调用fit\u generator()时,模型训练不好;虽然训练损失在第一个时期略有降低,但之

我正在尝试使用Keras和TensorFlow 2.0.0后端创建一个图像分类器

我正在我的本地机器上训练这个模型,在一个定制的数据集上,它包含总共17000张图像。图像大小不同,位于三个不同的文件夹(培训、验证和测试)中,每个文件夹包含两个子文件夹(每个类一个子文件夹)。 我尝试了一种类似于VGG16的体系结构,它在过去的数据集上产生了非常好的结果。注意,数据中存在轻微的等级不平衡(52:48)

当我调用
fit\u generator()
时,模型训练不好;虽然训练损失在第一个时期略有降低,但之后变化不大。使用这种具有更高规则性的架构,我在过去的55个纪元之后达到了85%的准确率

导入和超参数

import tensorflow as tf
from tensorflow import keras
from keras import backend as k
from keras.layers import Dense, Dropout, Conv2D, MaxPooling2D, Flatten, Input, UpSampling2D
from keras.models import Sequential, Model, load_model
from keras.utils import to_categorical
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import ModelCheckpoint

TRAIN_PATH = 'data/train/'
VALID_PATH = 'data/validation/'
TEST_PATH = 'data/test/'
TARGET_SIZE = (256, 256)
RESCALE = 1.0 / 255
COLOR_MODE = 'grayscale'
EPOCHS = 2
BATCH_SIZE = 16
CLASSES = ['Damselflies', 'Dragonflies']
CLASS_MODE = 'categorical'
CHECKPOINT = "checkpoints/weights.hdf5"
模型

在过去,我创建了一个自定义管道来重塑、灰度、翻转和规格化图像;然后,我使用我的CPU对批量处理的图像训练模型

我尝试使用ImageDataGenerator、来自目录的flow_和GPU支持重复这个过程

# randomly flip images, and scale pixel values
trainGenerator = ImageDataGenerator(rescale=RESCALE, 
                                    horizontal_flip=True,  
                                    vertical_flip=True)

# only scale the pixel values validation images
validatioinGenerator = ImageDataGenerator(rescale=RESCALE)

# only scale the pixel values test images
testGenerator = ImageDataGenerator(rescale=RESCALE)

# instanciate train flow
trainFlow = trainGenerator.flow_from_directory(
    TRAIN_PATH,
    target_size = TARGET_SIZE,
    batch_size = BATCH_SIZE,
    classes = CLASSES,
    color_mode = COLOR_MODE,
    class_mode = CLASS_MODE,
    shuffle=True
) 

# instanciate validation flow
validationFlow = validatioinGenerator.flow_from_directory(
    VALID_PATH,
    target_size = TARGET_SIZE,
    batch_size = BATCH_SIZE,
    classes = CLASSES,
    color_mode = COLOR_MODE,
    class_mode= CLASS_MODE,
    shuffle=True
)
然后,使用fit_生成器对模型进行拟合

checkpoints = ModelCheckpoint(CHECKPOINT, monitor='val_accuracy', verbose=1, save_best_only=True, mode='max')

with tf.device('/GPU:0'):
    model.fit_generator(
        trainFlow,
        validation_data=validationFlow, 
        callbacks=[checkpoints],
        epochs=EPOCHS
    )
我试着训练了40个时代。 分类器在第一个历元之后达到52%,并且不会随着时间的推移而改善

测试分类器

testFlow = testGenerator.flow_from_directory(
    TEST_PATH,
    target_size = TARGET_SIZE,
    batch_size = BATCH_SIZE,
    classes = CLASSES,
    color_mode = COLOR_MODE,
    class_mode= CLASS_MODE,
)

ans = model.predict_generator(testFlow)
当我查看预测时,模型预测所有测试图像为具有相同置信度的大多数类
[0.48498476,0.51501524]

我确定数据是正确的吗

对。我测试了生成器是否正确生成经过处理的图像及其相应的标签

我是否尝试过更改损失函数、激活函数和优化器

对。我尝试将类模式更改为二进制,将损失更改为二进制交叉熵,并将最后一层更改为生成带有sigmoid激活的单个输出。不,我没有更改优化器。然而,我确实试图提高学习率

我是否尝试过改变模型的架构

对。我尝试增加和减少模型的复杂性。 具有较少正则化的更多层和具有较多正则化的更少层都会产生类似的结果

蛋鸡可以训练吗

GPU支持是否正确实施

我希望如此

print(“可用的GPU数量:”,len(tf.config.experimental.list\u物理设备('GPU'))

可用GPU数量:1

a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a') 
b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b') 
c = tf.matmul(a, b)

config = tf.compat.v1.ConfigProto(log_device_placement=True) 
config.gpu_options.allow_growth = True 
sess = tf.compat.v1.Session(config=config)
print(sess) 
设备映射: /作业:本地主机/副本:0/任务:0/设备:GPU:0->设备:0,名称:NVIDIA GeForce GTX 1050,带Max-Q设计,pci总线id:0000:03:00.0,计算能力:6.1

我试过迁移学习吗

还没有

我在2017年发现了一个类似的未回答问题


想法?

问题在于你的模型。我复制了你的代码,并在我以前使用过的数据集上运行了它(精度很高),得到了与你类似的结果。然后我替换了下面的简单模型

model = tf.keras.Sequential([
    Conv2D(16, 3, padding='same', activation='relu', input_shape=(256 , 256,1)),
    MaxPooling2D(),
    Conv2D(32, 3, padding='same', activation='relu' ),
    MaxPooling2D(),
    Conv2D(64, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Conv2D(128, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Conv2D(256, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Flatten(),
    Dense(128, activation='relu'),
    Dropout(.3),
    Dense(64, activation='relu'),
    Dropout(.3),
    Dense(2, activation='softmax')
])
model.compile(loss='categorical_crossentropy',
              optimizer='Adam', metrics=['accuracy'])
这个模特训练得很好。顺便说一下,model.fit_生成器已折旧。您现在可以只使用model.fit,它现在可以处理发电机。然后我拿了你的模型,移除了所有的退出层,除了最后一层,并且你的模型得到了正确的训练。代码是:

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu',
                 input_shape=(256, 256, 1), padding='same'))

model.add(Conv2D(32, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
#model.add(Dropout(0.1))

model.add(Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
#model.add(Dropout(0.1))

model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
#model.add(Dropout(0.1))

model.add(Flatten())
model.add(Dense(516, activation='relu'))
#model.add(Dropout(0.1))

model.add(Dense(128, activation='relu'))
model.add(Dropout(0.1))

model.add(Dense(2, activation='softmax'))
model.compile(loss='categorical_crossentropy',
              optimizer='Adam', metrics=['accuracy'])
@Gerry p

无意中,我找到了导致错误的原因。 从Keras导入后端删除
作为k
解决了模型无法学习的问题

还不止这些。我还发现,您定义的模型、未调用ModelCheckpoint以及未自定义类名都会影响拟合过程

model = Sequential([
    Conv2D(16, 3, padding='same', activation='relu', input_shape=(256 , 256, 1)),
    MaxPooling2D(),
    Conv2D(32, 3, padding='same', activation='relu' ),
    MaxPooling2D(),
    Conv2D(64, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Conv2D(128, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Conv2D(256, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Flatten(),
    Dense(128, activation='relu'),
    Dropout(.3),
    Dense(64, activation='relu'),
    Dropout(.3),
    Dense(2, activation='softmax')
])
我对导入进行了注释,以尝试解决复制粘贴顺序模型时发生的错误。然后,当我测试它时,我忘了取消它的注释。在第三个纪元之后,我达到了80%以上的准确率。然后,我恢复了更改并在我的数据集上进行了尝试,但再次失败。 作为奖励,不导入Keras的后端减少了培训模型所需的时间

最近,我不得不重新安装Keras和TensorFlow,因为他们再也检测不到我的GPU了。我可能犯了一个错误,安装了一个不兼容的Keras版本

CUDA==10.0
tensorflow-gpu==2.0.0
keras==2.3.1
注意,它仍然不是100%的解决方案,而且问题时常出现

编辑:

当它不起作用时,简化模型。 更改批量大小并停止学习?简化模型。
进一步增强图像并停止学习?简化模型。

对于验证数据集,您应该将shuffle设置为False。嘿,由于验证不用于更新权重,只用于通知我们模型的运行情况,这有关系吗?它会影响模特的训练过程吗@M.Innathanks@Gerry P我试着应用你的建议并删除掉的层。不幸的是,它对我不起作用<代码>第1/20纪元损失:0.6956-精度:0.5163-瓦卢损失:0.6519-瓦卢精度:0.5235-第2/20纪元损失:0.6924-精度:0.5207-瓦卢损失:0.6509-瓦卢精度:0.5235-第3/20纪元损失:0.6925-精度:0.5207-瓦卢损失:0.6568-瓦卢精度:0.5235-第4/20纪元损失:0.6924-精度:0.5207-瓦卢损失:0.6589-瓦卢精度:0.5235同样的预测[0.4853577,0.5146423]奇怪的对我来说效果不错。你试过我提供的型号吗?我复制了您所有的代码,但tf.device('/GPU:0')::行除外,所以我唯一能想到的是数据的性质。如果您在Kaggle上,请尝试在下载此数据集,并查看模型是否在其上正确训练谢谢!我发现了问题。从keras导入后端删除导入
,因为k
解决了问题。很抱歉,我没有找到它
CUDA==10.0
tensorflow-gpu==2.0.0
keras==2.3.1