TensorFlow2.0入门到进阶系列——5.2_卷积神经网络

5.2_卷积神经网络

  • 1、理论部分
    • 1.1、卷积神经网络
      • 1.1.1 结构
      • 1.1.2 神经网络遇到的问题
  • 2、实战部分
    • 2.1、keras实现卷积神经网络
    • 2.2、keras实现深度可分离卷积
      • 2.2.1、理论部分
      • 2.2.2、深度可分离卷积网络实战

1、理论部分

  • 卷积神经网络
    • 卷积操作、池化操作
  • 深度可分离卷积
  • 数据增强
  • 迁移学习

1.1、卷积神经网络

1.1.1 结构

  • 卷积神经网络
    • (卷积层 + 池化层(可选)) * N + 全连接层 * M ;
      (其中,N >= 1,M >= 0,卷积层输入输出均为矩阵,全连接层输入输出均为向量。连接方法就是在卷积的最后一层做一个展平处理。全连接层输出可以是一个值,也可以是一个向量,也就是回归和分类。)
    • 分类任务、回归任务;
  • 全卷积神经网络
    • (卷积层 + 池化层(可选)) * N + 反卷积层 * K;
    • 物体分割
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第1张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第2张图片

1.1.2 神经网络遇到的问题

  • 参数过多
    • 计算资源不足
    • 容易过拟合,需要更多训练数据
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第3张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第4张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第5张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第6张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第7张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第8张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第9张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第10张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第11张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第12张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第13张图片
      答案:3 * 3 * 3 * 192
      完美解答
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第14张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第15张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第16张图片
      TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第17张图片

2、实战部分

  • keras实现卷积神经网络
  • keras实现深度可分离卷积
  • keras实战kaggle
    • 10 monkeys和cifar10
    • 数据增强与迁移学习

2.1、keras实现卷积神经网络

TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第18张图片

#深度神经网络
model = keras.models.Sequential()

#定义第一个卷积层
model.add(keras.layers.Conv2D(filters = 32,              #32个通道(32个卷积核)
                              kernel_size=3,             #卷积核大小为3
                              padding='same',            #平均值池化
                              activation='relu',         #加padding是否要输入和输出大小一样
                              input_shape=(28,28,1)))    #输入图片大小 28*28*1
model.add(keras.layers.Conv2D(filters = 32,              #32个通道(32个卷积核)
                              kernel_size=3,             #卷积核大小为3
                              padding='same',            #加padding是否要输入和输出大小一样
                              activation='relu'))        #不需要加input_shape
#池化层
model.add(keras.layers.MaxPool2D(pool_size=2))     #步长和pool_size相同


model.add(keras.layers.Conv2D(filters = 64,              #32个通道(32个卷积核)
                              kernel_size=3,             #卷积核大小为3
                              padding='same',            #平均值池化
                              activation='relu'))        #加padding是否要输入和输出大小一样
model.add(keras.layers.Conv2D(filters = 64,              #32个通道(32个卷积核)
                              kernel_size=3,             #卷积核大小为3
                              padding='same',            #加padding是否要输入和输出大小一样
                              activation='relu'))        #不需要加input_shape
#池化层
model.add(keras.layers.MaxPool2D(pool_size=2))     #步长和pool_size相同


model.add(keras.layers.Conv2D(filters = 128,              #32个通道(32个卷积核)
                              kernel_size=3,             #卷积核大小为3
                              padding='same',            #平均值池化
                              activation='relu'))        #加padding是否要输入和输出大小一样
model.add(keras.layers.Conv2D(filters = 128,              #32个通道(32个卷积核)
                              kernel_size=3,             #卷积核大小为3
                              padding='same',            #加padding是否要输入和输出大小一样
                              activation='relu'))        #不需要加input_shape
#池化层
model.add(keras.layers.MaxPool2D(pool_size=2))     #步长和pool_size相同

#连接全连接层之前,先做一个flatten
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(128,activation='relu'))

model.add(keras.layers.Dense(10, activation="softmax"))

model.compile(loss = "sparse_categorical_crossentropy",     #如果y已经是向量了就用categorical_crossentropy",如果是数字就用sparse_
             optimizer = "sgd",
             metrics = ["accuracy"])
model.summary()

TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第19张图片

#这里演示,使用三个常用的callbaks:TensorBoard, EarlyStopping, ModelCheckpoint
#对于Tensorboard需要一个文件夹,对于ModelCheckpoint来说需要一个文件名
#定义一个文件夹,和文件名
#logdir = './dnn-callbacks'
logdir = os.path.join("cnn-selu-callbacks")
if not os.path.exists(logdir):
    os.mkdir(logdir)
output_model_file = os.path.join(logdir, "fashion_mnist_model.h5")
 
callbacks = [
    keras.callbacks.TensorBoard(logdir),
    keras.callbacks.ModelCheckpoint(output_model_file,save_best_only = True),
    keras.callbacks.EarlyStopping(patience = 5, min_delta = 1e-3),
]
#callbacks是在训练过程中做一些监听,所以要添加到fit函数中
history = model.fit(x_train_scaler, y_train, epochs=10, 
                    validation_data = (x_valid_scaled, y_valid), 
                    callbacks = callbacks)

TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第20张图片

#绘图查看history中的变量变化过程
def plot_learning_curves(history):
    pd.DataFrame(history.history).plot(figsize = (8,5))   #将数据转换成DataFrame,然后调用plot实现
    plt.grid(True)      #绘制网格
    plt.gca().set_ylim(0, 2)       #设定y坐标的范围
    plt.show()
    
plot_learning_curves(history)

TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第21张图片

#在测试集上进行测试
model.evaluate(x_test_scaled, y_test)

TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第22张图片
注:将网络中所有relu激活函数换成selu后,模型的效果会得到不错的提升。(有时也会变得更糟糕)

  • 可以自行尝试

2.2、keras实现深度可分离卷积

2.2.1、理论部分

TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第23张图片
TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第24张图片
TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第25张图片
TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第26张图片
TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第27张图片
TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第28张图片
TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第29张图片
TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第30张图片
TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第31张图片

2.2.2、深度可分离卷积网络实战

修改建模部分代码

'''深度可分离卷积-神经网络Conv2D -> SeparableConv2D'''

model = keras.models.Sequential()

#定义第一个卷积层
model.add(keras.layers.Conv2D(filters = 32,              #32个通道(32个卷积核)
                              kernel_size=3,             #卷积核大小为3
                              padding='same',            #大小不变
                              activation='relu',         #加padding是否要输入和输出大小一样
                              input_shape=(28,28,1)))    #输入图片大小 28*28*1
model.add(keras.layers.SeparableConv2D(filters = 32,              #32个通道(32个卷积核)
                                       kernel_size=3,             #卷积核大小为3
                                       padding='same',            #加padding是否要输入和输出大小一样
                                       activation='relu'))        #不需要加input_shape
#池化层
model.add(keras.layers.MaxPool2D(pool_size=2))     #步长和pool_size相同


model.add(keras.layers.SeparableConv2D(filters = 64,              #32个通道(32个卷积核)
                                       kernel_size=3,             #卷积核大小为3
                                       padding='same',            #大小不变
                                       activation='relu'))        #加padding是否要输入和输出大小一样
model.add(keras.layers.SeparableConv2D(filters = 64,              #32个通道(32个卷积核)
                                       kernel_size=3,             #卷积核大小为3
                                       padding='same',            #加padding是否要输入和输出大小一样
                                       activation='relu'))        #不需要加input_shape
#池化层
model.add(keras.layers.MaxPool2D(pool_size=2))     #步长和pool_size相同


model.add(keras.layers.SeparableConv2D(filters = 128,              #32个通道(32个卷积核)
                                       kernel_size=3,             #卷积核大小为3
                                       padding='same',            #大小不变
                                       activation='relu'))        #加padding是否要输入和输出大小一样
model.add(keras.layers.SeparableConv2D(filters = 128,              #32个通道(32个卷积核)
                                       kernel_size=3,             #卷积核大小为3
                                       padding='same',            #加padding是否要输入和输出大小一样
                                       activation='relu'))        #不需要加input_shape
#池化层
model.add(keras.layers.MaxPool2D(pool_size=2))     #步长和pool_size相同

#连接全连接层之前,先做一个flatten
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(128,activation='relu'))

model.add(keras.layers.Dense(10, activation="softmax"))

model.compile(loss = "sparse_categorical_crossentropy",     #如果y已经是向量了就用categorical_crossentropy",如果是数字就用sparse_
             optimizer = "sgd",
             metrics = ["accuracy"])
model.summary()

TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第32张图片
由上面可知cnn的网络参数为443306个参数
使用了深度可分离卷积网络参数变为184234
在这里插入图片描述
训练结果精度和训练曲线如下图所示:
TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第33张图片
TensorFlow2.0入门到进阶系列——5.2_卷积神经网络_第34张图片
:上图训练结果非常差,因为训练的轮数太少将epochs由10 -> 100效果会有明显提升,改为300更佳。
结论:
**优点:**训练参数可以大大减少
**缺点:**精度有所下降,训练的时间更长,迭代的轮数也应该变得更多轮。
由上图可以看出,训练的精度在第8-9步才有所的提升,训练曲线也很明显的展现出这个问题。

你可能感兴趣的:(TensorFlow入门到进阶,神经网络,深度学习,tensorflow,卷积)