验证精度卡住,精度低

时间:2020-08-12 08:45:50

标签: python tensorflow machine-learning keras

我想用Tensorflow创建一个可以检测花朵的机器学习模型。我去了大自然,拍了4个不同物种的照片(每堂课约600个,一堂课得到700个)。

我使用Tensorflow Train Generator加载这些图像:

 train_datagen = ImageDataGenerator(rescale=1./255,
        shear_range=0.2,
        zoom_range=0.15, 
        brightness_range=[0.7, 1.4], 
        fill_mode='nearest', 
        vertical_flip=True,  
        horizontal_flip=True,
        rotation_range=15, 
        
        
        width_shift_range=0.1, 
        height_shift_range=0.1, 
    
        validation_split=0.2) 

    train_generator = train_datagen.flow_from_directory(
        pfad,
        target_size=(imageShape[0],imageShape[1]),
        batch_size=batchSize,
        class_mode='categorical',
        subset='training',
        seed=1,
        shuffle=False,
        #save_to_dir=r'G:\test'
        ) 
    
    validation_generator = train_datagen.flow_from_directory(
        pfad, 
        target_size=(imageShape[0],imageShape[1]),
        batch_size=batchSize,
        shuffle=False,
        seed=1,
        class_mode='categorical',
        subset='validation')

然后我要创建一个简单的模型,如下所示:

model = tf.keras.Sequential([
      
     
      
      keras.layers.Conv2D(128, (3,3), activation='relu', input_shape=(imageShape[0], imageShape[1],3)),
      keras.layers.MaxPooling2D(2,2),
      keras.layers.Dropout(0.5),
      
      keras.layers.Conv2D(256, (3,3), activation='relu'),
      
      keras.layers.MaxPooling2D(2,2), 
     
      keras.layers.Conv2D(512, (3,3), activation='relu'),
      
      keras.layers.MaxPooling2D(2,2),
     
      keras.layers.Flatten(),

      
      
      
      
      keras.layers.Dense(280, activation='relu'),
      
      keras.layers.Dense(4, activation='softmax')
    ])
    
    
    opt = tf.keras.optimizers.SGD(learning_rate=0.001,decay=1e-5)
    model.compile(loss='categorical_crossentropy',
                  optimizer= opt,
                  metrics=['accuracy'])

并要开始训练过程(CPU):

history=model.fit(
        train_generator,
        steps_per_epoch = train_generator.samples // batchSize,
        validation_data = validation_generator, 
        validation_steps = validation_generator.samples // batchSize,
        epochs = 200,callbacks=[checkpoint,early,tensorboard],workers=-1)

结果应该是我的验证准确性提高了,但是从0.3375开始,并且在整个训练过程中一直保持在该水平。验证损失(1.3737)减少0.001。精度从0.15开始,但提高了。

为什么我的验证准确性会卡住? 我在使用正确的损失吗?还是我建立模型错误?我的Tensorflow Train Generator是否对标签进行热编码?

谢谢

4 个答案:

答案 0 :(得分:1)

这是一个类似的示例,不同的是对于4个分类类,以下是二进制。您可能需要将损失更改为分类交叉熵,将火车和测试生成器中的class_mode从二进制更改为分类,并将最终密集层激活更改为softmax。我仍然可以使用model.fit_generator()

image_dataGen = ImageDataGenerator(rotation_range=20,
                                width_shift_range=0.2,height_shift_range=0.2,shear_range=0.1,
                                zoom_range=0.1,fill_mode='nearest',horizontal_flip=True,
                                vertical_flip=True,rescale=1/255)

train_images = image_dataGen.flow_from_directory(train_path,target_size = image_shape[:2],
                                                color_mode = 'rgb',class_mode = 'binary')
                                            
test_images = image_dataGen.flow_from_directory(test_path,target_size = image_shape[:2],
                                               color_mode = 'rgb',class_mode = 'binary',
                                               shuffle = False)
model = Sequential()

model.add(Conv2D(filters = 32, kernel_size = (3,3),input_shape = image_shape,activation = 'relu'))
model.add(MaxPool2D(pool_size = (2,2)))

model.add(Conv2D(filters = 48, kernel_size = (3,3),input_shape = image_shape,activation = 'relu'))
model.add(MaxPool2D(pool_size = (2,2)))

model.add(Flatten())
model.add(Dense(units = 128,activation = 'relu'))
model.add(Dropout(0.5))

model.add(Dense(units = 1, activation = 'sigmoid'))

model.compile(loss = 'binary_crossentropy',metrics = ['accuracy'], optimizer = 'adam')

results = model.fit_generator(train_images, epochs = 10, callbacks = [early_stop],
                             validation_data = test_images)

答案 1 :(得分:1)

我通过使用不带任何参数的RMSprop()解决了这个问题。

所以我从:


opt = tf.keras.optimizers.SGD(learning_rate=0.001,decay=1e-5)
model.compile(loss='categorical_crossentropy',optimizer= opt, metrics=['accuracy'])


```

to:


```

    opt = tf.keras.optimizers.RMSprop()
    model.compile(loss='categorical_crossentropy',
                  optimizer= opt,
                  metrics=['accuracy'])
```

答案 2 :(得分:1)

也许您的学习率太高了。

使用学习率= 0.000001,如果该方法不起作用,请尝试使用另一个优化程序,例如Adam。

答案 3 :(得分:0)

使用model.fit_generator()代替model.fit()以下几点也可能会有所帮助。

为了使用.flow_from_directory,必须在子目录中组织图像。这是绝对要求,否则该方法将无法正常工作。这些目录应仅包含一类图像,因此每类图像一个文件夹。还可以检查训练数据和测试数据的路径是否正确?他们不能指向相同的位置。我已经将ImageGenerator类用于分类问题。您也可以尝试将优化器更改为“亚当”

所需结构: 图像数据文件夹 1类 0.jpg 1.jpg ... 2级 0.jpg 1.jpg ... ... n级