如果在TensorFlow中构建3D-CNN数据集

电子说

1.3w人已加入

描述

  3D-CNN简介

  MNIST数据集分类被认为是计算机视觉领域的 hello world 程序。MNIST数据集帮助初学者理解卷积神经网络(CNN)的概念和实现。

  许多人认为图像只是一个普通矩阵,但实际上并非如此。图像拥有所谓的空间信息。考虑如下所示的 3X3 矩阵。

  [a b c

  d e f

  g h i]

  在正则矩阵中,矩阵中的值将相互独立。相邻值不会携带矩阵中特定字段的任何关系或信息。例如,在矩阵中代替“e”的值与出现在其他位置的值(如“a”、“b”等)没有任何联系。图像中的情况并非如此。

  在图像中,矩阵中的每个位置代表图像中的一个像素,每个位置的值代表该像素的值。像素值可以是 8 位图像中的 [0-255]。每个像素与其相邻像素有某种关系。任何像素的邻域是其周围的一组像素。对于任何像素,有 3 种方法来表示其邻域,称为 N-4、ND 和 N-8。让我们详细了解它们。

  N-4:它表示存在于参考像素的顶部、底部、右侧和左侧的像素。对于像素“e”,N-4 包含“b”、“f”、“h”和“d”。

  ND:它表示从参考像素对角线可访问的像素。对于像素“e”,ND 包含“a”、“c”、“i”和“g”。

  N-8:它代表它周围存在的所有像素。它包括 N-4 和 ND 像素。对于像素“e”,N-8 包含“a”、“b”、“c”、“d”、“f”、“g”、“h”和“i”。

  N-4、N-8 和 ND 像素有助于提取有关像素的信息。例如,这些参数可用于将像素分类为边界或内部或外部像素。这是图像的特殊性。人工神经网络(ANN )接收一维数组形式的输入。图像始终存在于具有 1 个或多个通道的 2D 阵列中。当图像数组转换为一维数组时,它会丢失空间信息,因此人工神经网络无法捕获此信息并且在图像数据集上表现不佳。而这就是 CNN 擅长的地方。

  CNN 接受 2D 数组作为输入,并使用掩码(或过滤器或内核)执行卷积操作并提取这些特征。执行称为池化的过程,该过程减少了提取的特征数量并降低了计算复杂度。完成这些操作后,我们将提取的特征转换为一个1D数组,并将其提供给学习进行分类的神经网络层。

  本文旨在扩展对 3D 数据进行卷积操作的概念。我们将构建一个 3D CNN,它将在 3D MNIST 数据集上执行分类

  数据集概述

  我们将在数据集中使用fulldatasetvectors.h5文件。该文件具有从所有 3D 点云的体素化 (x:16, y:16, z:16) 获得的 4096-D 向量。该文件包含 10000 个训练样本和 2000 个测试样本。数据集也有可以使用的点云数据。

  数据集

  导入模块

  由于数据以h5格式存储,我们将使用h5py模块从 fulldatasetvectors 文件中的数据加载数据集。TensorFlow和Keras将用于构建和训练 3D-CNN。to_categorical函数有助于对 目标变量执行 one-hot 编码。我们还将使用 earlystopping 回调来停止训练并防止模型过度拟合。


	import numpy as np  import h5py from tensorflow.keras.utils import to_categorical from tensorflow.keras import layers from tensorflow.keras.models import Sequential from tensorflow.keras.initializers import Constant from tensorflow.keras.optimizers import Adam from tensorflow.keras.callbacks import EarlyStopping 

  加载数据集

  如前所述,我们将使用 h5py 模块从 fulldatasetvectors.h5 文件中加载数据。

  使用 h5py.File(‘。./input/3d-mnist/full_dataset_vectors.h5’, ‘r’) 作为数据集:


	xtrain, xtest = dataset[“X_train”][:], dataset[“X_test”][:] ytrain, ytest = dataset[“y_train”][:], dataset[“y_test”][:] xtrain = np.array(xtrain) xtest = np.array(xtest) print(‘train shape:’, xtrain.shape) print(‘test shape:’, xtest.shape) xtrain = xtrain.reshape(xtrain.shape[0], 1616161) xtest = xtest.reshape(xtest.shape[0], 1616161) ytrain, ytest = to_categorical(ytrain, 10), to_categorical(ytest, 10) 我们可以看到训练数据有 10000 个样本,而测试数据有 2000 个样本,每个样本包含 4096 个特征。

	train shape: (100004096) test shape: (20004096) 

  构建 3D-CNN

  3D-CNN,就像任何普通的 CNN 一样,有两部分——特征提取器和 ANN 分类器,并且以相同的方式执行。

  与普通 CNN 不同,3D-CNN 执行 3D 卷积而不是 2D 卷积。我们将使用 Keras 的Sequential API 来构建 3D CNN。前 2 层将是具有 32 个过滤器和 ReLU 作为激活函数的 3D 卷积层,然后是用于降维的最大池化层。这些层还添加了一个偏置项,其值为 0.01。默认情况下,偏差值设置为 0。

  再次使用同一组图层,但使用 64 个过滤器。然后是 dropout 层和 flatten 层。flatten 层有助于将特征重塑为可由人工神经网络处理的一维阵列,即密集层。ANN部分由 2 层组成,分别有 256 和 128 个神经元,以 ReLU 作为激活函数。然后是具有 10 个神经元的输出层,因为数据集中存在 10 个不同的类别或标签。


	model = Sequential() model.add(layers.Conv3D(32,(3,3,3),activation='relu',input_shape=(16,16,16,1),bias_initializer=Constant(0.01))) model.add(layers.Conv3D(32,(3,3,3),activation='relu',bias_initializer=Constant(0.01))) model.add(layers.MaxPooling3D((2,2,2))) model.add(layers.Conv3D(64,(3,3,3),activation='relu')) model.add(layers.Conv3D(64,(2,2,2),activation='relu')) model.add(layers.MaxPooling3D((2,2,2))) model.add(layers.Dropout(0.6)) model.add(layers.Flatten()) model.add(layers.Dense(256,'relu')) model.add(layers.Dropout(0.7)) model.add(layers.Dense(128,'relu')) model.add(layers.Dropout(0.5)) model.add(layers.Dense(10,'softmax')) model.summary() 这是 3D-CNN 的架构。

	Model: "sequential_2" _________________________________________________________________ Layer (type)                 Output Shape              Param #    ================================================================= conv3d_5 (Conv3D)            (None14141432)    896        _________________________________________________________________ conv3d_6 (Conv3D)            (None12121232)    27680      _________________________________________________________________ max_pooling3d_2 (MaxPooling3 (None66632)       0          _________________________________________________________________ conv3d_7 (Conv3D)            (None44464)       55360      _________________________________________________________________ conv3d_8 (Conv3D)            (None33364)       32832      _________________________________________________________________ max_pooling3d_3 (MaxPooling3 (None11164)       0          _________________________________________________________________ dropout_4 (Dropout)          (None11164)       0          _________________________________________________________________ flatten_1 (Flatten)          (None64)                0          _________________________________________________________________ dense_3 (Dense)              (None256)               16640      _________________________________________________________________ dropout_5 (Dropout)          (None256)               0          _________________________________________________________________ dense_4 (Dense)              (None128)               32896      _________________________________________________________________ dropout_6 (Dropout)          (None128)               0          _________________________________________________________________ dense_5 (Dense)              (None10)                1290       ================================================================= Total params: 167,594 Trainable params: 167,594 Non-trainable params: 0 

  训练 3D-CNN

  我们将使用 Adam 作为优化器。分类交叉熵将用作训练模型的损失函数,因为它是一个多类分类。准确率将用作训练的损失指标。

  如前所述,在训练模型和 dropout 层时,将使用 Earlystopping 回调。一旦任何参数(如损失或准确性)在一定数量的时期内没有改善,Earlystopping 回调有助于停止训练过程,这反过来又有助于防止模型的过度拟合。

  Dropout 通过在训练时随机关闭一些神经元并使模型学习而不是记忆,来帮助防止模型的过度拟合。dropout 值不宜过高,否则可能导致模型欠拟合,并不理想。


	model.compile(Adam(0.001),'categorical_crossentropy',['accuracy']) model.fit(xtrain,ytrain,epochs=200,batch_size=32,verbose=1,validation_data=(xtest,ytest),callbacks=[EarlyStopping(patience=15)]) 这些是训练 3D-CNN 的一些时期。

	Epoch 1/200 313/313 [==============================] - 39123ms/step - loss: 2.2782 - accuracy: 0.1237 - val_loss: 2.1293 - val_accuracy: 0.2235 Epoch 2/200 313/313 [==============================] - 39124ms/step - loss: 2.0718 - accuracy: 0.2480 - val_loss: 1.8067 - val_accuracy: 0.3395 Epoch 3/200 313/313 [==============================] - 39125ms/step - loss: 1.8384 - accuracy: 0.3382 - val_loss: 1.5670 - val_accuracy: 0.4260 ... ... Epoch 87/200 313/313 [==============================] - 39123ms/step - loss: 0.7541 - accuracy: 0.7327 - val_loss: 0.9970 - val_accuracy: 0.7061 

  测试 3D-CNN

  3D-CNN在训练数据上达到了73.3%的准确率,在测试数据上达到了70.6%的准确率。由于数据集非常小且不平衡,因此准确性可能略低。


	_, acc = model.evaluate(xtrain, ytrain) print('training accuracy:', str(round(acc*1002))+'%') _, acc = model.evaluate(xtest, ytest) print('testing accuracy:', str(round(acc*1002))+'%') 

	313/313 [==============================] - 1134ms/step - loss: 0.7541 - accuracy: 0.7327 training accuracy: 73.27% 63/63 [==============================] - 234ms/step - loss: 0.9970 - accuracy: 0.7060 testing accuracy: 70.61% 

  结论

  综上所述,本文涵盖了以下主题:

  图像中像素的邻域

  为什么 ANN 在图像数据集上表现不佳

  CNN 和 ANN 的区别

  CNN的工作

  在 TensorFlow 中构建和训练 3D-CNN

  为了进一步继续这个项目,可以尝试通过将像素值投影到另一个轴上,从 MNIST 数据集创建一个新的自定义 3D 数据集。x 轴和 y 轴将与任何图像中的相同,但像素值将投影在 z 轴上。这种从 2D 数据创建 3D 数据的转换可以在执行图像增强之后应用,这样我们就有了一个平衡且通用的数据集,可用于训练 3D-CNN 并获得更好的准确性。

  审核编辑:郭婷


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分