【深度学习手记】使用DNN训练与CNN训练对数据集的要求不一样,为什么CNN网络训练输入的数据需要4维的

前言

        当我将神经网络添加了一个CNN—Layer之后,我发现我的模型无法训练了。我们以经典的Mnist数据来了解一下这个简单的原因。

【深度学习手记】使用DNN训练与CNN训练对数据集的要求不一样,为什么CNN网络训练输入的数据需要4维的_第1张图片


【深度学习手记】使用全连接神网络训练与卷积训练对数据集的要求有什么不一样

前言

运行情况

正常

【code】       

【print】 

添加CNN-Layer变异常:

【code】 

 【print】

解释

卷积结构图

reshap变成卷积可训数据集


运行情况

正常


【code】       

import os
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, optimizers, datasets
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

(x_train,y_train),(x_test,y_test)=datasets.mnist.load_data()
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128,activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(10,activation=tf.nn.softmax))
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.fit(x_train,y_train,epochs=5) #训练模型

【print】 

【深度学习手记】使用DNN训练与CNN训练对数据集的要求不一样,为什么CNN网络训练输入的数据需要4维的_第2张图片

添加CNN-Layer变异常:


 目前一切还是正常的,但是如果我们将模型的网络层小小的添加一个卷积层,一切都不一样了。

【code】 

model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(filters=64,kernel_size=(7,7),padding='same',input_shape=(28,28,1),activation='relu'),
    tf.keras.layers.MaxPool2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(10,activation='softmax')
])
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.fit(x_train,y_train,epochs=5) #训练模型

 【print】

 ValueError: Input 0 of layer sequential_2 is incompatible with the layer: expected ndim=4, found ndim=3. Full shape received: [32, 28, 28]

   ValueError:层sequential_2的输入0与层不兼容:预期的ndim=4,找到的ndim=3。收到的完整形状:[32,28,28]

解释

卷积结构图


        其实原因非常简单,这不是数据集的错,而是卷积核的因素,我们来看看卷积核的结构究竟是怎么样的?

在这里插入图片描述

         想必看完这张图,知道卷积核是三维的之后,大家就能够恍然大悟了。

        因为CNN层中的卷积的过程在空间表达上正是一个卷积核在图像上不断平移的过程,如下图所示:(一个3x3x1的卷积核提取特征过程)

在这里插入图片描述

         说白了,当数据集是二维——三维数据集(由于数据集构成时,第一个维度是数据的数量,比如Mnist数据集的训练集维度是(70000,34,34,1),表示7W张(34,34,1)的手写体图片。所以是一个三维数据存储起来变成数据集是4维度数据集,这样子做其实也是为了方便训练。数据存储在后面的维度上,所以数据的实际维度是数据集减去第一个维度后的样子),三维的卷积核没有办法在二维的数据(三维数据集)上进行空间平移试想一下一个三维的人是不可能踩在一个没有高度(厚度)的平面上的,大概就能够理解了。

        值得一提的是:对于投喂给模型(fit操作)的X(数据),Y(标签)中的X,不论是深度学习还是机器学习格式都是这样的:第一个维度都是数量,后面的维度才是数据的维度,也就是X.shape=(数据数量+数据维度)的格式,比如Mnist数据中的X.shape=(70000, 28, 28, 1)正是说有7W个(28,28, 1)的数据。最后有一点差点忘记讲的是:数据集一般都是np.array的格式。

reshap变成卷积可训数据集

        那好,想必我已经解释的非常清楚了,那么我需要怎么样修改数据集的维度,使得我们的数据集可以投入卷积神经网络训练呢?如下:

x_train4D = x_train.reshape(x_train.shape[0],28,28,1).astype('float32')
x_test4D = x_test.reshape(x_test.shape[0],28,28,1).astype('float32')
x_train,x_test = x_train4D/255.0,x_test4D/255.0 # 归一化,为了更好的训练可以不做

【深度学习手记】使用DNN训练与CNN训练对数据集的要求不一样,为什么CNN网络训练输入的数据需要4维的_第3张图片

        binggo! 运行成功啦!可以看到,卷积核的效果还是超过全连接层的,同样的epoch5次,CNN准确率到达了98.4%,回顾以下DNN层:

【深度学习手记】使用DNN训练与CNN训练对数据集的要求不一样,为什么CNN网络训练输入的数据需要4维的_第4张图片

        只有94.1% !

你可能感兴趣的:(深度学习,#,numpy手撕神经网络,深度学习,神经网络,人工智能)