Tensorflow2.0入门教程14:CNN网络基础示例

CNN网络结构

包含一个或多个卷积层(Convolutional Layer)、池化层(Pooling Layer)和全连接层(Fully-connected Layer)。
在这里插入图片描述

卷积:

  • 提取局部特征

https://pic.rmb.bdstatic.com/e6871b1259fe02a5192e15294fc684148433.gif

https://img-blog.csdnimg.cn/20181124130023841.gif

池化:

  • 下采样(downsamping)
  • 降维、去除冗余信息、对特征进行压缩、简化网络复杂度、减少计算量、减少内存消耗等等。
  • 平均池化会更多的保留图像的背景信息,而最大池化会更多的保留纹理信息。
    在这里插入图片描述

CNN+NLP
在这里插入图片描述

API介绍:

一、卷积层:tf.keras.layers.Conv2D

参数描述:

inputs:把上一层的输出作为输入(直接将上一层作为参数输入即可)

input_shape:当作为模型的第一层时,需要指出输入的形状(samples,rows,cols,channels) ,只指出后三维即可,第一维度按batch_size自动指定

filters:卷积过滤器的数量,对应输出的维数

kernel_size:整数,过滤器的大小,如果为一个整数则宽和高相同

strides:横向和纵向的步长,如果为一个整数则横向和纵向相同

padding:valid(默认):表示不够卷积核大小的块,则丢弃;same表示不够卷积核大小的块就补0(右下和左下填充,如果只填充一列(一行)就足够了,那么默认在最后一行之后和最后一列之后填充。)

data_format:channels_last为(batch,height,width,channels),channels_first为(batch,channels,height,width)

dilation_rate:整数,空洞卷积的间隔

activation:激活函数,None是线性函数

use_bias:是否使用偏差量

kernel_initializer:卷积核的初始化。

bias_initializer:偏差向量的初始化。如果是None,则使用默认的初始值。

kernel_regularizer:卷积核的正则项

bias_regularizer:偏差向量的正则项

activity_regularizer:输出的正则函数

bias_constraint:映射函数,当偏差向量被Optimizer更新后应用到偏差向量上。

trainable:Boolean类型。

name:字符串,层的名字。

reuse:Boolean类型,表示是否可以重复使用具有相同名字的前一层的权重。


二、池化层API:tf.keras.layers.MaxPool2D、tf.keras.layers.AveragePooling2D

最大池化:tf.keras.layers.MaxPool2D

平均池化:tf.keras.layers.AveragePooling2D

  • pool_size: 2个整数的整数或元组/列表:(pool_height,pool_width),用于指定池窗口的大小.可以是单个整数,以指定所有空间维度的相同值.
  • strides: 2个整数的整数或元组/列表,用于指定池操作的步幅.可以是单个整数,以指定所有空间维度的相同值.
  • padding:“valid”或“same”,不区分大小写
  • data_format: 一个字符串,表示输入中维度的顺序.支持channels_last(默认)和channels_first;channels_last对应于具有形状(batch, height, width, channels)的输入,而channels_first对应于具有形状(batch, channels, height, width)的输入.

三、tensorflow中的conv2d中处理卷积的通道数问题:

在tensorflow中的conv2d中,

input的四个维度是[batch, in_height, in_width, in_channels],

filter的四个维度是[filter_height, filter_width, in_channels, out_channels]。

filter的通道数(深度)与输入层的通道数(深度)是一致的,就是in_channels!!!

filter中out_channels数值 (输出通道数)= filter的数量


四、卷积层输出大小计算(长、宽、深度)

输入矩阵W*H

filter矩阵F*F

stride值S,步长

输出宽高为new_height,new_width

1.valid

new_height = (W - F + 1) / S (结果向上取整)

new_width = (H - F + 1) / S (结果向上取整)

import tensorflow as tf
input_data = tf.random.uniform((1,3,4,3))
input_data.shape
TensorShape([1, 3, 4, 3])
conv1 = tf.keras.layers.Conv2D(filters=3, kernel_size=(2,2), strides=(1,1), padding='valid',
                   activation='relu')

new_height = (H - F + 1) / S = (3-2+1)/1 = 2

new_width = (W - F + 1) / S = (4-2+1)/1 = 3

conv1(input_data)
<tf.Tensor: id=40, shape=(1, 2, 3, 3), dtype=float32, numpy=
array([[[[0.0000000e+00, 6.9810861e-01, 0.0000000e+00],
         [0.0000000e+00, 2.8018421e-01, 0.0000000e+00],
         [6.7794771e-04, 3.8421594e-02, 0.0000000e+00]],

        [[0.0000000e+00, 7.0559049e-01, 0.0000000e+00],
         [0.0000000e+00, 8.5524663e-02, 0.0000000e+00],
         [0.0000000e+00, 8.8122499e-01, 0.0000000e+00]]]], dtype=float32)>

2.same

new_height = H / S(结果向上取整)

new_width = W / S(结果向上取整)

conv2 = tf.keras.layers.Conv2D(filters=1, kernel_size=(2,2), strides=(1,1), padding='same',
                   activation='relu')

new_height = H / S = 3/1 = 3

new_width = W / S = 4/1 = 4

conv2(input_data)
<tf.Tensor: id=68, shape=(1, 3, 4, 1), dtype=float32, numpy=
array([[[[0.90060335],
         [0.92395264],
         [0.94786555],
         [0.24400437]],

        [[0.67070836],
         [0.9397892 ],
         [1.0766943 ],
         [0.        ]],

        [[0.31393033],
         [0.39762408],
         [0.35296404],
         [0.        ]]]], dtype=float32)>

基于CNN的花卉识别练习

数据集下载:
链接:https://pan.baidu.com/s/1__W9Zl4A3H8szCQTWwiE9Q
提取码:fvrq
需要安装的包:
pip install opencv-python

步骤

  • 1.读取数据集并进行数据处理
  • 2.搭建模型
  • 3.配置模型
  • 4.训练模型
  • 5.验证模型
import cv2
import os
import tensorflow as tf
import numpy as np

一、读取数据并进行数据处理

数据集路径—根据自己的路径进行改写

path=r'flower_photos/'

由于我们的数据集图片大小不一致,所以需要resize成统一大小 这里resize成100x100x3

w=100
h=100
c=3

读取数据集图片并添加标签,最后的形式是data 对应图片, label 是标签,roses 0,daisy 1,sunflowers 2,tulips 3,dandelion 4.

def read_img(path):
    imgs=[]
    labels=[]
    cate=[path+x for x in os.listdir(path) if os.path.isdir(path+x)]
    for idx,i in enumerate(cate):
        for j in os.listdir(i):
            im = cv2.imread(i+'/'+j)
            img = cv2.resize(im, (w, h))/255.
            #print('reading the images:%s'%(i+'/'+j))
            imgs.append(img)
            labels.append(idx)
    return np.asarray(imgs,np.float32),np.asarray(labels,np.int32)
data,label=read_img(path)

将数据集打乱顺序

num_example=data.shape[0] # data.shape是(3029, 100, 100, 3)
arr=np.arange(num_example)# 创建等差数组 0,1,...,3028
np.random.shuffle(arr)# 打乱顺序
data=data[arr]
label=label[arr]
print(label)
[4 1 3 ... 4 2 3]

标签one-hot处理

def to_one_hot(label):
    return tf.one_hot(label,5)
label_oh = to_one_hot(label) 

将所有数据集分为训练集80%、测试集20%

ratio=0.8
s=np.int(num_example*ratio)
x_train=data[:s]
y_train=label_oh.numpy()[:s]
x_val=data[s:]
y_val=label_oh.numpy()[s:]
x_train.shape
(2936, 100, 100, 3)

二、搭建模型

# model = tf.keras.Sequential([
#      tf.keras.layers.Conv2D(filters=32, input_shape=(28,28,1),kernel_size=(3,3), strides=(1,1), padding='valid',
#                    activation='relu'),
#     tf.keras.layers.MaxPool2D(pool_size=(2,2)),
#     tf.keras.layers.Flatten(),
#     tf.keras.layers.Dense(32, activation='relu'),
#     tf.keras.layers.Dense(10, activation='softmax')
#  ])
# model = tf.keras.Sequential()
# model.add(tf.keras.layers.Conv2D(input_shape=(x_train.shape[1], x_train.shape[2], x_train.shape[3]),
#                         filters=32, kernel_size=(3,3), strides=(1,1), padding='valid',
#                        activation='relu'))
# model.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))
# model.add(tf.keras.layers.Flatten())
# model.add(tf.keras.layers.Dense(32, activation='relu'))
# # 分类层
# model.add(tf.keras.layers.Dense(10, activation='softmax'))
class CNN(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.conv1 = tf.keras.layers.Conv2D(
            filters=64,             # 卷积层神经元(卷积核)数目
            kernel_size=[3, 3],     # 感受野大小
            padding='valid',         # padding策略(vaild 或 same)
            activation=tf.nn.relu   # 激活函数
        )
        self.pool1 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=1)
        self.conv2 = tf.keras.layers.Conv2D(
            filters=32,
            kernel_size=[5, 5],
            padding='valid',
            activation=tf.nn.relu
        )
        self.pool2 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
        self.flatten = tf.keras.layers.Flatten()
        self.dense1 = tf.keras.layers.Dense(units=128, activation=tf.nn.relu)
        self.dense2 = tf.keras.layers.Dense(units=5)

    def call(self, inputs):
        x = self.conv1(inputs)                 
        x = self.pool1(x)                                          
        x = self.flatten(x)                     
        x = self.dense1(x)                      
        x = self.dense2(x)                     
        output = tf.nn.softmax(x)
        return output
model = CNN()

三、配置模型

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
              loss = tf.keras.losses.categorical_crossentropy,
              metrics=[tf.keras.metrics.categorical_accuracy])

四、训练模型

history = model.fit(x_train, y_train, batch_size=64, epochs=10, validation_split=0.2)
Train on 2348 samples, validate on 588 samples
Epoch 1/10
2348/2348 [==============================] - 29s 13ms/sample - loss: 11.3972 - categorical_accuracy: 0.3147 - val_loss: 1.3492 - val_categorical_accuracy: 0.4456
Epoch 2/10
2348/2348 [==============================] - 28s 12ms/sample - loss: 1.1495 - categorical_accuracy: 0.5486 - val_loss: 1.2279 - val_categorical_accuracy: 0.4541
Epoch 3/10
2348/2348 [==============================] - 28s 12ms/sample - loss: 0.9416 - categorical_accuracy: 0.6431 - val_loss: 1.0787 - val_categorical_accuracy: 0.5510
Epoch 4/10
2348/2348 [==============================] - 28s 12ms/sample - loss: 0.6518 - categorical_accuracy: 0.7777 - val_loss: 1.1170 - val_categorical_accuracy: 0.5374
Epoch 5/10
2348/2348 [==============================] - 29s 12ms/sample - loss: 0.4046 - categorical_accuracy: 0.8931 - val_loss: 1.1310 - val_categorical_accuracy: 0.5510
Epoch 6/10
2348/2348 [==============================] - 28s 12ms/sample - loss: 0.2228 - categorical_accuracy: 0.9476 - val_loss: 1.2393 - val_categorical_accuracy: 0.5544
Epoch 7/10
2348/2348 [==============================] - 29s 12ms/sample - loss: 0.1196 - categorical_accuracy: 0.9804 - val_loss: 1.2748 - val_categorical_accuracy: 0.5731
Epoch 8/10
2348/2348 [==============================] - 29s 12ms/sample - loss: 0.0756 - categorical_accuracy: 0.9889 - val_loss: 1.5054 - val_categorical_accuracy: 0.5408
Epoch 9/10
2348/2348 [==============================] - 29s 12ms/sample - loss: 0.0561 - categorical_accuracy: 0.9932 - val_loss: 1.5839 - val_categorical_accuracy: 0.5340
Epoch 10/10
2348/2348 [==============================] - 29s 12ms/sample - loss: 0.0388 - categorical_accuracy: 0.9966 - val_loss: 1.5596 - val_categorical_accuracy: 0.5510

五、验证模型

model.evaluate(x_val,y_val,verbose=2)
734/1 - 2s - loss: 1.3128 - categorical_accuracy: 0.580
[1.460774506794984, 0.58038145]
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值