【问题标题】:How to Increase Accuracy of CNN on Image Recognition如何提高 CNN 在图像识别上的准确率
【发布时间】:2021-02-20 05:12:22
【问题描述】:

我正在训练一个用于图像分类的 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)

【问题讨论】:

  • 到目前为止,您为优化模型做了哪些尝试?您能否提供有关您的训练数据的更多信息?数据集中有多少张图像?你是如何设置训练数据和测试数据之间的溢出的?如果它是一个免费提供的数据集,如果您分享它的来源,将会有很大帮助。
  • 感谢您的回复。我对深度学习很陌生,所以除了批量大小(更高的批量大小产生更高的准确性)之外,我没有做太多的超参数优化。这是我的数据集的链接:www.kaggle.com/richardcao1/labeled-frames-resized。共有 39 个独特的音素,数据集中的每张图像(64x64 展平为 4096)对应一个音素。我将数据集(10142 张图像)分成 80% 用于训练和 20% 用于测试。对于我应该为模型试验的参数或我应该对数据集进行的任何更改,我愿意接受任何建议。
  • 为什么使用一维卷积而不是二维?有什么具体原因吗?
  • 到目前为止我只使用过 Conv1d,因为它看起来更容易。你认为使用 Conv2d 会有很大的不同吗?
  • 能否更新您问题中的代码并提供您的完整代码?我需要看看X_trainy_train 在传递给模型之前是如何进行预处理的。

标签: python keras deep-learning computer-vision conv-neural-network


【解决方案1】:

您可以轻松地将其转换为 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 卷积提取的信息不仅仅是 1D 卷积。

说明:

您确实可以在图像上使用一维卷积,但并非在所有情况下都可以。 (我可能错了)当你将它们展平时,每个像素都会成为一个特征。如果我们希望每个像素都成为一个特征,那么我们也可以在展平后使用普通的Dense 层。但是会有很多参数需要训练。我的意思是 (不包括总参数大小)

model= tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(...)
...
])

当您将它们展平时,您可能会破坏图像的空间连贯性。使用 2D 卷积可能会提高您的准确性。我们对 2D 卷积所做的是访问图像,看看我们可以提取什么作为重要特征,使用最大或平均池化。

  • 您将无法使用一维卷积捕获那么多信息。

  • 我们可以在进行预测之前将池化的特征图输入全连接层。

【讨论】:

  • 感谢您的帮助。我会尝试 conv2D。
  • 在 SO 中,表示感谢的最佳方式是接受答案,如果它解决了您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-18
  • 2021-02-28
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多