如何为 CNN 构建图像数据集?

数据挖掘 机器学习 Python 神经网络 喀拉斯 美国有线电视新闻网
2021-09-28 01:49:17

我不明白图像实际上是如何输入 CNN 的。如果我有一个包含几千张图像的目录,我需要采取哪些步骤才能将它们提供给神经网络(例如调整大小、灰度、标记等)?我不明白图像的标签是如何工作的。这个数据集实际上会是什么样子?或者你可以不看它(像一张桌子)?

3个回答

这是一个非常紧凑的问题。让我们尝试通过它,我将尝试提供一些使用 CNN 进行图像处理的示例。

预处理数据

预处理数据(例如调整大小和灰度)是机器学习管道的第一步。大多数深度学习框架都要求您的训练数据具有相同的形状。因此,最好将图像大小调整到某个标准。

每当训练任何类型的机器学习模型时,记住偏差方差权衡是很重要的。模型越复杂,训练就越困难。这意味着最好限制模型中模型参数的数量。您可以通过对图像进行下采样来减少模型的输入数量。出于同样的原因,通常使用灰度。如果图像中的颜色不包含任何区别信息,那么您可以通过灰度化将输入数量减少三分之一。

根据您的数据,可以使用许多其他预处理方法。做一些数据增强也是一个好主意,这是在不改变结果标签的情况下稍微改变你的输入数据,以增加你必须训练模型的实例数量。

如何组织数据?

您将用作 CNN 输入的变量的形状取决于您选择的包。我更喜欢使用谷歌开发的tensorflow。如果您打算使用非常标准的架构,那么有一个非常有用的包装库,名为 Keras,它将帮助您轻松设计和训练 CNN。

使用 tensorflow 时,您需要将一组图像放入一个 numpy 矩阵中。第一个维度是您的实例,然后是您的图像维度,最后一个维度是 for channels

因此,例如,如果您使用如下所示的 MNIST 数据,那么您正在使用的灰度图像的尺寸均为 28 x 28。那么您将输入深度学习模型的 numpy 矩阵形状将是 (n, 28, 28 , 1), 其中 n 是您在数据集中拥有的图像数量。

在此处输入图像描述

如何标记图像?

对于大多数数据,标记需要手动完成。这通常被称为数据收集,是任何机器学习解决方案中最困难和最昂贵的部分。通常最好使用现成的数据,或者如果数据不可用,则使用不太复杂的模型和更多的预处理。


这是一个将 CNN 用于 MNIST 数据集的示例

首先我们加载数据

from keras.datasets import mnist
import numpy as np

(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.

print('Training data shape: ', x_train.shape)
print('Testing data shape : ', x_test.shape)

训练数据形状:(60000, 28, 28)
测试数据形状:(10000, 28, 28)

from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.callbacks import ModelCheckpoint
from keras.models import model_from_json
from keras import backend as K

然后我们需要重塑我们的数据以在我们的 numpy 矩阵的末尾添加通道维度。此外,我们将对标签进行 one-hot 编码。所以你将有 10 个输出神经元,每个神经元代表一个不同的类。

# The known number of output classes.
num_classes = 10

# Input image dimensions
img_rows, img_cols = 28, 28

# Channels go last for TensorFlow backend
x_train_reshaped = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test_reshaped = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)

# Convert class vectors to binary class matrices. This uses 1 hot encoding.
y_train_binary = keras.utils.to_categorical(y_train, num_classes)
y_test_binary = keras.utils.to_categorical(y_test, num_classes)

现在我们设计我们的模型

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

最后我们可以训练模型

epochs = 4
batch_size = 128
# Fit the model weights.
model.fit(x_train_reshaped, y_train_binary,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test_reshaped, y_test_binary))

数据集仅由特征和标签组成。这里的特征是你的图像,标签是类。

每个 CNN 模型都有一个 fit() 方法,它将接受特征和标签,并执行训练。

对于第一层,你需要提到图像的输入维度,输出层应该是一个softmax(如果你正在做分类),维度是你拥有的类数。

model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', input_shape=(64, 64, 3)))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))

model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])

model.fit(x_train, y_train, epochs=10)

以上是训练 Keras 序列模型的代码。

一般要点:

  1. input_shape 应该是 X_train 的维度。
  2. 当你做 X_train.shape (numpy) 时你需要得到这个形状
  3. 然后将卷积与相应的激活一起应用
  4. Dropout 和 Pooling 层是可选的。
  5. 在卷积层之后,数据被展平。使用 Flatten()
  6. 然后它被发送到几个全连接层
  7. 最后一层应该具有类数的维度
  8. 最后一层将是softmax。
  9. 现在,用损失、优化器和度量来编译模型
  10. 然后拟合()

投票;)如果你喜欢它。

我理解你的问题,我去过那里。确保您收集的数据保存在其各自的类文件夹中,例如,名为“狗”的文件夹中的所有狗图像和“猫”中的猫图像等

我认为可能会有所帮助

IMG_SIZE = 50

DATADIR = 'Path/classes'

CATEGORIES = ['class1 #folder name', 'class2', 'class3']

for category in CATEGORIES :
    path = os.path.join(DATADIR, category)
    for img in os.listdir(path):
        img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_UNCHANGED)

training_data = []

def create_training_data():
    for category in CATEGORIES :
        path = os.path.join(DATADIR, category)
        class_num = CATEGORIES.index(category)
        for img in os.listdir(path):
            try :
                img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_UNCHANGED)
                new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
                training_data.append([new_array, class_num])
            except Exception as e:
                pass

create_training_data()

random.shuffle(training_data)

X = [] #features
y = [] #labels

for features, label in training_data:
    X.append(features)
    y.append(label)

X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 3)
y = np.asarray(y)

不是我的代码

来源

向下滚动到准备数据,您将找到创建数据集并将其从计算机导入代码的答案。:)