使用 CNN 进行多 class 图像 class 化
Multi class image classification using CNN
我想对包含五个 类 的图像进行分类。我想使用 CNN。但是当我尝试使用多个模型时,训练准确率不会增加超过 20%。请有人帮助我克服这一点。大多数模型将在 3 个 epoches 内训练,并且当 epoches 增加时,准确性没有提高。任何人都可以建议我一个解决方案或模型,或者可以指定可能是什么问题吗?
下面是我用过的其中一个模型
#defining training and test sets
x_train,x_val,y_train,y_val=train_test_split(x,y,test_size=0.2, random_state=42)
print('Training data and target sizes: \n{}, {}'.format(x_train.shape,y_train.shape))
print('Test data and target sizes: \n{}, {}'.format(x_val.shape,y_val.shape))
训练数据和目标大小:
(2398, 224, 224, 3), (2398,)
测试数据和目标尺寸:
(600, 224, 224, 3), (600,)
img_rows, img_cols, img_channel = 224, 224, 3
base_model = applications.inception_v3.InceptionV3(include_top=False, weights='imagenet',pooling='avg', input_shape=(img_rows, img_cols, img_channel))
print(base_model.summary())
#Adding custom Layers
add_model = Sequential()
add_model.add(Dense(1024, activation='relu',input_shape=base_model.output_shape[1:]))
add_model.add(Dropout(0.60))
add_model.add(Dense(1, activation='sigmoid'))
print(add_model.summary())
# creating the final model
model = Model(inputs=base_model.input, outputs=add_model(base_model.output))
# compile the model
opt = optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
reduce_lr = ReduceLROnPlateau(monitor='val_acc',
patience=5,
verbose=1,
factor=0.1,
cooldown=10,
min_lr=0.00001)
model.compile(
loss='categorical_crossentropy',
metrics=['acc'],
optimizer='adam'
)
print(model.summary())
n_fold = 5
kf = model_selection.KFold(n_splits = n_fold, shuffle = True)
eval_fun = metrics.roc_auc_score
model.fit(x_train,y_train,epochs=50,batch_size=50,validation_data=(x_val,y_val))
您必须在编译后使用 model.fit() 来实际训练模型。现在,它具有随机初始化的权重,因此可以进行随机预测。由于您有五个 类,准确度约为 1/5 = 20%。训练您的模型可能需要一些时间,具体取决于模型大小和您拥有的数据量。
您可以分享您拟合模型的代码部分吗?它在 post.
中不可用
并且由于缺少数据导致输出无法重现,我建议您完成此 link https://www.kaggle.com/kenconstable/alzheimer-s-multi-class-classification
解释得非常好,它给出了基于迁移学习以及从头开始的多class-class化的最佳实践。如果您觉得这没有帮助,分享包含 model.fit() 代码的训练脚本会很有帮助。
好的,问题来了,
在您的代码中,您可能正在使用 inception V3 创建一个基础模型,但是,您并没有真正将该基础模型添加到您的 add_model
变量中。
您的 add_model
变量本质上是一个密集网络,而不是 CNN。另外,还有一件事,尽管这没什么大不了的,但您正在创建自己的优化器 opt
而不是在 model.compile
中使用它
你能试试这个代码吗,如果有效请告诉我:
# function to build the model
def build_transfer_model(conv_base,dropout,dense_node,learn_rate,metric):
"""
Build and compile a transfer learning model
Input: a base model, dropout rate, the number of filters in the dense node,
the learning rate and performance metrics
Output: A compiled CNN model
"""
# clear previous run
backend.clear_session()
# build the model
model = Sequential()
model.add(conv_base)
model.add(Dropout(dropout))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(dense_node,activation='relu'))
model.add(Dense(1,activation='sigmoid'))
# complile the model
model.compile(
optimizer = tensorflow.keras.optimizers.Adam(lr=learn_rate),
loss = 'categorical_crossentropy',
metrics = metric )
model.summary()
return model
img_rows, img_cols, img_channel = 224, 224, 3
base_model = applications.inception_v3.InceptionV3(include_top=False, weights='imagenet',pooling='avg', input_shape=(img_rows, img_cols, img_channel))
model = build_transfer_model(conv_base=base_model,dropout=0.6,dense_node =1024,learn_rate=0.001,metric=['acc'])
print(model.summary())
model.fit(x_train,y_train,epochs=50,batch_size=50,validation_data=(x_val,y_val))
如果你在函数中注意,我们首先添加到 Sequential()
实例的是基础层(在你的例子中是 InceptionV3)。但是你直接添加了一个致密层。虽然它可能从基础 inception V3 的输出层获得权重,但它将是一个密集网络,而不是 CNN。所以请检查一下。
我可能更改了变量名,尽管我已尝试不这样做。并且,请根据您的要求更改 build_transfer_model 函数中图层的顺序。
如果它不起作用,请告诉我。
谢谢。
我想对包含五个 类 的图像进行分类。我想使用 CNN。但是当我尝试使用多个模型时,训练准确率不会增加超过 20%。请有人帮助我克服这一点。大多数模型将在 3 个 epoches 内训练,并且当 epoches 增加时,准确性没有提高。任何人都可以建议我一个解决方案或模型,或者可以指定可能是什么问题吗?
下面是我用过的其中一个模型
#defining training and test sets
x_train,x_val,y_train,y_val=train_test_split(x,y,test_size=0.2, random_state=42)
print('Training data and target sizes: \n{}, {}'.format(x_train.shape,y_train.shape))
print('Test data and target sizes: \n{}, {}'.format(x_val.shape,y_val.shape))
训练数据和目标大小: (2398, 224, 224, 3), (2398,) 测试数据和目标尺寸: (600, 224, 224, 3), (600,)
img_rows, img_cols, img_channel = 224, 224, 3
base_model = applications.inception_v3.InceptionV3(include_top=False, weights='imagenet',pooling='avg', input_shape=(img_rows, img_cols, img_channel))
print(base_model.summary())
#Adding custom Layers
add_model = Sequential()
add_model.add(Dense(1024, activation='relu',input_shape=base_model.output_shape[1:]))
add_model.add(Dropout(0.60))
add_model.add(Dense(1, activation='sigmoid'))
print(add_model.summary())
# creating the final model
model = Model(inputs=base_model.input, outputs=add_model(base_model.output))
# compile the model
opt = optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
reduce_lr = ReduceLROnPlateau(monitor='val_acc',
patience=5,
verbose=1,
factor=0.1,
cooldown=10,
min_lr=0.00001)
model.compile(
loss='categorical_crossentropy',
metrics=['acc'],
optimizer='adam'
)
print(model.summary())
n_fold = 5
kf = model_selection.KFold(n_splits = n_fold, shuffle = True)
eval_fun = metrics.roc_auc_score
model.fit(x_train,y_train,epochs=50,batch_size=50,validation_data=(x_val,y_val))
您必须在编译后使用 model.fit() 来实际训练模型。现在,它具有随机初始化的权重,因此可以进行随机预测。由于您有五个 类,准确度约为 1/5 = 20%。训练您的模型可能需要一些时间,具体取决于模型大小和您拥有的数据量。
您可以分享您拟合模型的代码部分吗?它在 post.
中不可用并且由于缺少数据导致输出无法重现,我建议您完成此 link https://www.kaggle.com/kenconstable/alzheimer-s-multi-class-classification
解释得非常好,它给出了基于迁移学习以及从头开始的多class-class化的最佳实践。如果您觉得这没有帮助,分享包含 model.fit() 代码的训练脚本会很有帮助。
好的,问题来了,
在您的代码中,您可能正在使用 inception V3 创建一个基础模型,但是,您并没有真正将该基础模型添加到您的 add_model
变量中。
您的 add_model
变量本质上是一个密集网络,而不是 CNN。另外,还有一件事,尽管这没什么大不了的,但您正在创建自己的优化器 opt
而不是在 model.compile
你能试试这个代码吗,如果有效请告诉我:
# function to build the model
def build_transfer_model(conv_base,dropout,dense_node,learn_rate,metric):
"""
Build and compile a transfer learning model
Input: a base model, dropout rate, the number of filters in the dense node,
the learning rate and performance metrics
Output: A compiled CNN model
"""
# clear previous run
backend.clear_session()
# build the model
model = Sequential()
model.add(conv_base)
model.add(Dropout(dropout))
model.add(BatchNormalization())
model.add(Flatten())
model.add(Dense(dense_node,activation='relu'))
model.add(Dense(1,activation='sigmoid'))
# complile the model
model.compile(
optimizer = tensorflow.keras.optimizers.Adam(lr=learn_rate),
loss = 'categorical_crossentropy',
metrics = metric )
model.summary()
return model
img_rows, img_cols, img_channel = 224, 224, 3
base_model = applications.inception_v3.InceptionV3(include_top=False, weights='imagenet',pooling='avg', input_shape=(img_rows, img_cols, img_channel))
model = build_transfer_model(conv_base=base_model,dropout=0.6,dense_node =1024,learn_rate=0.001,metric=['acc'])
print(model.summary())
model.fit(x_train,y_train,epochs=50,batch_size=50,validation_data=(x_val,y_val))
如果你在函数中注意,我们首先添加到 Sequential()
实例的是基础层(在你的例子中是 InceptionV3)。但是你直接添加了一个致密层。虽然它可能从基础 inception V3 的输出层获得权重,但它将是一个密集网络,而不是 CNN。所以请检查一下。
我可能更改了变量名,尽管我已尝试不这样做。并且,请根据您的要求更改 build_transfer_model 函数中图层的顺序。
如果它不起作用,请告诉我。 谢谢。