简体   繁体   English

CNN 无法对图像进行分类

[英]CNN is not able to classify images

My dataset consists of visualized binaries.我的数据集由可视化的二进制文件组成。 Those binaries are either part of malware family 1 or malware family 2 .这些二进制文件是malware family 1malware family 2 Those grayscale images have very specific features.这些灰度图像具有非常具体的特征。 Some examples (upper family 1, lower family 2):一些例子(上族 1,下族 2):

恶意软件家族 1 恶意软件家族 1 恶意软件家族 1

恶意软件家族 2 恶意软件家族 2 恶意软件家族 2

There are 2474 samples of malware family 1 and 2930 samples of malware family 2 . malware family 1有 2474 个样本, malware family 1 malware family 2 2930 个样本。 As we can see, the similarities between samples of the same family are very strong.我们可以看到,同一家族的样本之间的相似性非常强。 A CNN should not have too much problems classifying them. CNN 对它们进行分类不应该有太多问题。

Nonetheless, the CNN that I used only achieves around 50% accuracy (and 0.25 loss).尽管如此,我使用的 CNN 只能达到 50% 左右的准确率(和 0.25 损失)。 In addition to that, I also implemented the InceptionV3 model.除此之外,我还实现了InceptionV3模型。 But that model also achieves only 50% accuracy (and 0.50 loss).但该模型也只能达到 50% 的准确率(和 0.50 的损失)。 What could be the error here?这里可能是什么错误?

Load images:加载图像:

idx = 0
for elem in os.listdir(directory):
    img = cv2.imread(full_path,cv2.IMREAD_UNCHANGED)
    if idx in train_index:
        dataset4_x_train.append(img)
        dataset4_y_train.append(0)
    else:
        dataset4_x_test.append(img)
        dataset4_y_test.append(0)
dataset4_x_train = np.array(dataset4_x_train)
dataset4_x_test = np.array(dataset4_x_test)

dataset4_x_train = dataset4_x_train.reshape(-1, 192, 192, 1)
dataset4_x_test = dataset4_x_test.reshape(-1, 192, 192, 1)

Custom CNN:自定义CNN:

model = Sequential()
model.add(tf.keras.layers.Conv2D(8, 5, activation="relu", input_shape=(192,192,1)))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(8, 3, activation="relu"))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(8, 3, activation="relu"))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(8, 3, activation="relu"))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(16, 3, activation="relu"))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(80, 4, activation="relu"))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(2, activation='softmax'))

opt = tf.keras.optimizers.Adam(lr=0.01)
model.compile(opt, loss="mse",metrics=['accuracy'])

model.fit(dataset4_x_train, dataset4_y_train, epochs=100, batch_size=50)   

model.evaluate(dataset4_x_test, dataset4_y_test)

InceptionV3:创始V3:

incept_v3 = tf.keras.applications.inception_v3.InceptionV3(input_shape=(192,192,1), include_top=False, weights=None)
incept_v3.summary()

last_output = incept_v3.get_layer("mixed10").output
x = tf.keras.layers.Flatten()(last_output)
x = tf.keras.layers.Dense(2, activation="softmax")(x)

model = tf.keras.Model(incept_v3.input, x)

opt = tf.keras.optimizers.Adam(lr=0.001)
model.compile(opt, loss="mse",metrics=['accuracy'])

model.fit(dataset4_x_train, dataset4_y_train, epochs=100, batch_size=50)   

model.evaluate(dataset4_x_test, dataset4_y_test)

MSE is normally used for regression problems, and it sounds like your task is moreso classification, so you should use a different loss function. MSE 通常用于回归问题,听起来您的任务更像是分类,因此您应该使用不同的损失函数。 For example, you can use tf.keras.losses.BinaryCrossentropy .例如,您可以使用tf.keras.losses.BinaryCrossentropy This is most likely the main cause for the low accuracy.这很可能是导致精度低的主要原因。

In addition, CNN's normally have more than one hidden linear layer, for example, the following.此外,CNN 通常有不止一个隐藏的线性层,例如以下。 This would normally have a relatively small performance impact compared to the above.与上述相比,这通常对性能的影响相对较小。

model = Sequential()
model.add(tf.keras.layers.Conv2D(8, 5, activation="relu", input_shape=(192,192,1)))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(8, 3, activation="relu"))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(8, 3, activation="relu"))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(8, 3, activation="relu"))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(16, 3, activation="relu"))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(80, 4, activation="relu"))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(2, activation='softmax'))

Your Model is under-fitting the dataset, this is why you have a low accuracy.您的模型对数据集欠拟合,这就是您的准确率低的原因。
Fortunately, increasing the model size fixes the problem.幸运的是,增加模型大小可以解决这个问题。
Again, increasing the model size makes it more vulnerable to overfitting.同样,增加模型大小使其更容易过拟合。 To fix that issue, I would suggest to use dropout layers as shown below.为了解决这个问题,我建议使用如下所示的 dropout 层。
This is a binary classification problem, for which binary_crossentropy loss function will work better, and a low learning to converge to a better accuracy.这是一个二元分类问题, binary_crossentropy损失函数会更好地工作,并且低学习收敛到更好的精度。

model = Sequential()
model.add(tf.keras.layers.Conv2D(16, 3, activation="relu",padding='same', input_shape=(192,192,1)))
model.add(tf.keras.layers.Conv2D(16, 3, activation="relu", padding='same'))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(32, 3, activation="relu", padding='same'))
model.add(tf.keras.layers.Conv2D(32, 3, activation="relu", padding='same'))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(64, 3, activation="relu", padding='same'))
model.add(tf.keras.layers.Conv2D(64, 3, activation="relu", padding='same'))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Conv2D(92, 3, activation="relu", padding='same'))
model.add(tf.keras.layers.Conv2D(92, 3, activation="relu", padding='same'))
model.add(tf.keras.layers.MaxPool2D(2))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dropout(0.2))
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dropout(0.2))
model.add(tf.keras.layers.Dense(2, activation='softmax'))

opt = tf.keras.optimizers.Adam(lr=0.0008)
model.compile(opt, loss="binary_crossentropy", metrics=['accuracy'])

model.fit(dataset4_x_train, dataset4_y_train, epochs=100, batch_size=50)   

model.evaluate(dataset4_x_test, dataset4_y_test)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM