22、CNN(卷积神经网络)

一、CNN

参考文章https://www.cnblogs.com/kongweisi/p/10987870.html

卷积运算结构.png

  • 层与层之间的连除了矩阵运算,还有CNN。
  • convolution neural network 卷积神经网络
  • convolution 卷积是一种数学的运算
  • 运算法则:

input image* kernel = feature map

第一步.png

第二步.png
  • 行乘以行相加再求和(对应的位置相乘)。
  • 每次都是移动一列(这个扫描移动的距离是可以控的)
  • kernel(卷积核多大,每次扫描就是多大)
  • 卷积扫描后与原数据相比,数据就变少了。


    CNN.png
  • input layer 数据
  • convolvtional layter 1
  • pooling layer 1 池化操作
    *池化操作:--数据变少了


    池化.png
  • 池化提取大的特征,过滤小的特征。
  • 上面图片中的池化的操作,就是四个中选中最大的值,得到数据就行了。
  • 池化的大小--一般统一都是2*2操作。


    CNN计算过程.png

    参数对应.png

    多层参数.png
  • bias ---偏差
  • 相当于方程中的截距

二、卷积神经网络代码实现及作用

import warnings
warnings.filterwarnings('ignore')
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist
import tensorflow as tf
(X_train,y_train),(X_test,y_test) = mnist.load_data()
X_train = tf.cast(X_train/255.0,tf.float32)
y_train = tf.one_hot(y_train,depth=10)#10分类问题
X_test = tf.cast(X_test/255,tf.float32)
y_test = tf.one_hot(y_test,depth=10)
# X_train 60000个,重复了100次,每次取512
data_train = tf.data.Dataset.from_tensor_slices((X_train,y_train)).repeat(100).shuffle(2000).batch(512).prefetch(1)
# X_test 10000个,可以取5次,重复50次,250次
data_test = tf.data.Dataset.from_tensor_slices((X_test,y_test)).repeat(50).shuffle(2000).batch(2000).prefetch(1)

repeat(100)重复多少次,shuffle(2000)打乱,batch(512)一批取出的数量,prefetch(1)预先取出数据加快速度。

image

声明变量

# w系数,卷积核,输入数据是28,28,颜色通道是1,黑白图片
w = {'kernel1':tf.Variable(tf.random.normal(shape = [3,3,1,64],stddev=0.01)),
        #tf.random.normal--tf中随机生成数据的方法      
     'kernel2':tf.Variable(tf.random.normal(shape = [3,3,64,128],stddev=0.01)),#第二层卷积核,以第一层卷积核的结果作为输入
     'kernel3':tf.Variable(tf.random.normal(shape = [3,3,128,256],stddev = 0.01)),
     'fc':tf.Variable(tf.random.normal(shape = [4*4*256,1024],stddev = 0.01)),
     # fc ---定义全连接层
  
     'out':tf.Variable(tf.random.normal(shape = [1024,10],stddev = 0.01))}
    # out--输出层
b = {'bias1':tf.Variable(tf.random.normal(shape = [64],stddev=0.01)),
     'bias2':tf.Variable(tf.random.normal(shape = [128],stddev=0.01)),
     'bias3':tf.Variable(tf.random.normal(shape = [256],stddev=0.01)),
     'fc':tf.Variable(tf.random.normal(shape = [1024],stddev=0.01)),
     'out':tf.Variable(tf.random.normal(shape = [10],stddev = 0.01))}
# w定义卷积核(filter),定义b,计算结果后加上这个b
# 457万系数,变量!
3*3*64 + 3*3*64*128 +3*3*128*256 + 4*4*256*1024 + 10240
4573760

构造神经网络的模型、损失、准确率、优化算法

def cnn(X):
    X = tf.reshape(X,shape = [-1,28,28,1])
#     第一层卷积运算
    conv1 = tf.nn.conv2d(input=X,filters=w['kernel1'],strides=[1,1,1,1],padding='SAME') + b['bias1']#卷积
    conv1 = tf.nn.max_pool(conv1,ksize = [1,2,2,1],strides=[1,2,2,1],padding='SAME')#池化
    conv1 = tf.nn.relu(conv1)#激活 conv1.shape = [-1,14,14,64]
    
#     第二层卷积运算,计算的是,第一层,运算的结果
    conv2 = tf.nn.conv2d(input=conv1,filters=w['kernel2'],strides=[1,1,1,1],padding='SAME') + b['bias2']#卷积
    conv2 = tf.nn.max_pool(conv2,ksize = [1,2,2,1],strides=[1,2,2,1],padding='SAME')#池化
    conv2 = tf.nn.relu(conv2)#激活 conv1.shape = [-1,7,7,128]
    
#     第三层卷积运算,计算的是,第二层,运算的结果
    conv3 = tf.nn.conv2d(input=conv2,filters=w['kernel3'],strides=[1,1,1,1],padding='SAME') + b['bias3']#卷积
    conv3 = tf.nn.max_pool(conv3,ksize = [1,2,2,1],strides=[1,2,2,1],padding='SAME')#池化
    conv3 = tf.nn.relu(conv3)#激活 conv1.shape = [-1,4,4,256] 数据形状是4维
    
#     全连接层,矩阵操作
    fc = tf.reshape(conv3,shape = [-1,4*4*256])
    fc = tf.matmul(fc,w['fc']) + b['fc'] #昨天所讲的深度神经网络呢
    fc = tf.nn.relu(fc)# 输出的形状 [-1,1024]
    
#     输出层,真实值,进行对比
    y_pred = tf.matmul(fc,w['out']) + b['out']
    y_pred = tf.nn.softmax(y_pred)#转变成概率
    return y_pred # 输出的形状[-1,10]
# 构建损失,交叉熵
def cross_entropy(y_true,y_pred):
    y_pred = tf.clip_by_value(y_pred,1e-9,1.0)
    loss = tf.reduce_mean(tf.reduce_sum(tf.multiply(y_true,tf.math.log(1/y_pred)),axis = -1))
    return loss

# 构建计算准确率方法
def accuracy(y_true,y_pred):
    y_true = tf.argmax(y_true,axis = -1)
    y_pred = tf.argmax(y_pred,axis = -1)
    acc = tf.reduce_mean(tf.cast(tf.equal(y_true,y_pred),dtype=tf.float16)).numpy()
    return acc

# 声明优化算法
sgd = tf.optimizers.Adam(0.001)

全连接层中的每个神经元与其前一层的所有神经元进行全连接.全连接层可以整合卷积层或者池化层中具有类别区分性的局部信息.为了提升 CNN网络性能,全连接层每个神经元的激励函数一般采用ReLU函数。

定义优化方法(定义损失函数)

def run_optimizer(X_train,y_train):
    with tf.GradientTape() as g:
        y_pred = cnn(X_train)
        loss = cross_entropy(y_train,y_pred)
    gradients = g.gradient(loss,list(w.values()) + list(b.values()))# 计算梯度,偏导数
    sgd.apply_gradients(zip(gradients,list(w.values()) + list(b.values())))

for循环进行训练

for i,(X_train,y_train) in enumerate(data_train.take(100),1):
    run_optimizer(X_train,y_train)
    if i %10 == 0:
        for (X_test,y_test) in data_test.take(1):
            y_pred = cnn(X_test)
            acc = accuracy(y_test,y_pred)
            print('执行次数是:%d。准确率是:%0.4f'%(i,acc))
执行次数是:10。准确率是:0.1190
执行次数是:20。准确率是:0.5630
执行次数是:30。准确率是:0.7002
执行次数是:40。准确率是:0.8047
执行次数是:50。准确率是:0.8711
执行次数是:60。准确率是:0.9004
执行次数是:70。准确率是:0.8755
执行次数是:80。准确率是:0.9199
执行次数是:90。准确率是:0.9238
执行次数是:100。准确率是:0.9380

你可能感兴趣的:(22、CNN(卷积神经网络))