我想用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是否对标签进行热编码?
谢谢
答案 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级