美文网首页
22、CNN(卷积神经网络)

22、CNN(卷积神经网络)

作者: 羽天驿 | 来源:发表于2020-05-12 11:09 被阅读0次

    一、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(卷积神经网络)

          本文链接:https://www.haomeiwen.com/subject/keybihtx.html