python - 如何提高 CNN 在图像识别上的准确率
问题描述
我正在训练 CNN 进行图像分类。具体来说,我正在尝试创建一个唇读器,该读唇器能够将分段嘴巴的图像及其相关音素进行分类。这些图像的尺寸为 64x64,并被展平为长度为 4096 的一维数组。我在下面插入了当前模型的代码及其性能图和指标。有人对我如何继续修改此模型以提高准确性有任何建议吗?
df = pd.read_csv("/kaggle/input/labeled-frames-resized/labeled_frames.csv", error_bad_lines=False)
labelencoder = LabelEncoder()
df['Phoneme'] = labelencoder.fit_transform(df['Phoneme'])
labels = np.asarray(df[['Phoneme']].copy())
df = df.drop(df.columns[0], axis = 1)
X_train, X_test, y_train, y_test = train_test_split(df, labels, random_state = 42, test_size = 0.2, stratify = labels)
X_train = tf.reshape(X_train, (8113, 4096, 1))
X_test = tf.reshape(X_test, (2029, 4096, 1))
model = Sequential()
model.add(Conv1D(filters= 128, kernel_size=3, activation ='relu',strides = 2, padding = 'valid', input_shape= (4096, 1)))
model.add(MaxPooling1D(pool_size=2))
model.add(Conv1D(filters= 128, kernel_size=3, activation ='relu',strides = 2, padding = 'valid'))
model.add(MaxPooling1D(pool_size=2))
model.add(Dropout(0.5))
model.add(MaxPooling1D(pool_size=2))
model.add(Conv1D(filters= 128, kernel_size=3, activation ='relu',strides = 2, padding = 'valid'))
model.add(MaxPooling1D(pool_size=2))
model.add(Dropout(0.2))
model.add(MaxPooling1D(pool_size=2))
model.add(Conv1D(filters= 128, kernel_size=3, activation ='relu',strides = 2, padding = 'valid'))
model.add(MaxPooling1D(pool_size=2))
model.add(Dropout(0.2))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(39))
model.add(Activation('softmax'))
optimizer = keras.optimizers.Adam(lr=0.4)
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
history = model.fit(X_train,y_train, epochs = 500, batch_size = 2048, validation_data = (X_test, y_test), shuffle = True)
解决方案
您可以轻松地将其转换为 2D 卷积:
model.add(Conv2D(filters= 128, kernel_size=(3,3), activation ='relu',strides = (2,2),
padding = 'valid', input_shape= (64,64,1)))
model.add(MaxPooling2D(pool_size=(2,2))
...
model.add(Flatten())
model.add(Dense(39))
model.add(Activation('softmax'))
到目前为止,我只使用过 Conv1d,因为它看起来更容易。
可以在图像上使用一维卷积吗?
- 是的,你可以,但不推荐,除非你有一个非常具体的案例并且知道你在做什么。假设您的图像为 1024x1024,当您将它们展平时会发生什么?您使用 2D Convolutions 提取的信息不仅仅是 1D Convolutions。
解释:
您确实可以在图像上使用一维卷积,但并非在所有情况下都可以。(我可能错了)当你将它们展平时,每个像素都会成为一个特征。如果我们希望每个像素都成为一个特征,那么我们也可以Dense
在展平后使用普通层。但是会有很多参数需要训练。我的意思是(不包括总参数大小):
model= tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(...)
...
])
当您将它们展平时,您可能会破坏图像的空间连贯性。使用 2D 卷积可能会提高您的准确性。我们对 2D 卷积所做的是我们访问图像,看看我们可以提取什么作为重要特征,使用最大或平均池化。
- 您将无法使用一维卷积捕获那么多信息。
- 在进行预测之前,我们可以将池化的特征图输入全连接层。
推荐阅读
- xml - XMLTABLE 函数中的名称空间
- powershell - 无需 RSAT 即可安装 Active Directory
- batch-file - 如何在 CMAKE 中通过 COMMAND 执行路径中有空格的 .bat 文件
- javascript - Javascript Chrome 扩展:未捕获的类型错误:无法读取未定义的属性“parentNode”
- python-3.x - 需要帮助在 for 循环中加快 seaborn 热图到 png
- allure - 引诱报告:是否可以生成可以从任何机器查看的通用 index.html?
- aspose.words - 使用 Aspose.Words Net 在折线图中显示最新值
- python - Python中读取的声音文件和波形文件之间的幅度差异
- kubernetes - 您没有明确设置 kubernetes 作业中的默认 .spec.activeDeadlineSeconds 是什么
- r - 导出多个匹配模式