CNN

作者: VaultHunter | 来源:发表于2017-08-18 09:42 被阅读0次

    利用CNN识别MNIST手写字,很普通的一个例程。
    输入数据经过卷积层,池化层,卷积层,池化层,全连接层,Softmax输出层,使用Relu激活函数。
    MNIST数据集:它有60000个训练样本集和10000个测试样本集。

    from tensorflow.examples.tutorials.mnist import input_data
    import tensorflow as tf
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
    

    one hot

    LeNet-5各层参数
    在卷积层中,神经元的个数 = feature map的像素个数 * feature map 个数
    可训练参数个数 = filter参数个数 * filter 个数 + filter 个数

    卷积层:

    卷积过程
    引用 <<------feature map 的计算公式
    为什么要用卷积:在传统的神经网络中,神经元要与图片上的每一个像素相连,参数甚多,采用卷积使神经元与图片中的部分像素连接,参数变少。
    传统神经网络
    卷积神经网络
    权值共享用一个filter去扫整个图片,这个filter中的参数,即权重,是不变的,不同的filter权重才不同。

    池化层:对feature map 再进行下采样,把参数再减小。与卷积过程基本类似。

    Softmax

    from tensorflow.examples.tutorials.mnist import input_data
    import tensorflow as tf
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
    sess = tf.InteractiveSession()        #建立会话
    def Weights_variable(shape):        #定义Weights函数,在构造层时可直接使用,
        initial = tf.truncated_normal(shape,stddev=0.1)    #产生张量shape型的  标准差为 0.1的截断式正太分布,当产生的随机数距离均值大于两倍的标准差时就会重新生成 
        return tf.Variable(initial)      #在tf中,变量是要声明的
    
    def Bias_variable(shape):
        initial=tf.constant(0.1,shape=shape)    #定义张量shape型的0.1常量
        return tf.Variable(initial)
    
    def Conv2d(x,w):
        return tf.nn.conv2d(x,w,strides=[1,1,1,1],padding='SAME')
    def max_pool_2x2(x):
        return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
    with tf.name_scope('inputs'):  # tensorboard语句
        x = tf.placeholder(tf.float32,[None,784],name='x_images_input')#tf大部分只能处理float32的数据。28 * 28 =784 None代表不知道有多少张
        y_ = tf.placeholder(tf.float32,[None,10],name='y_labels_input')
        x_image = tf.reshape(x,[-1,28,28,1]) #把1*784 变成28*28 
    with tf.name_scope('firstlayer'):
        w_conv1 = Weights_variable([5,5,1,32]) #5x5的卷积核 输入通道为1 输出32个通道,即输出32个 feature map
        b_conv1 = Bias_variable([32])
        h_conv1 = tf.nn.relu(Conv2d(x_image,w_conv1)+b_conv1)
        h_pool1 = max_pool_2x2(h_conv1)
    with tf.name_scope('secondlayer'):
        w_conv2 = Weights_variable([5,5,32,64])
        b_conv2 = Bias_variable([64])
        h_conv2 = tf.nn.relu(Conv2d(h_pool1,w_conv2)+b_conv2)
        h_pool2 = max_pool_2x2(h_conv2)
    with tf.name_scope('fclayer'):
        w_fc1 = Weights_variable([7*7*64,1024])#64个7*7的小图  隐藏层节点1024个
        b_fc1 = Bias_variable([1024])
        h_pool2_flat = tf.reshape(h_pool2,[-1,7*7*64]) #再变为一维
        h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat,w_fc1)+b_fc1)
        keep_prob = tf.placeholder(tf.float32) #dropout 防止过拟合,在训练数据中扔掉一部分
        h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)
    
    with tf.name_scope('softmaxlayer'):
        w_fc2 = Weights_variable([1024,10])
        b_fc2 = Bias_variable([10])
        y = tf.nn.softmax(tf.matmul(h_fc1_drop,w_fc2)+b_fc2)
    with tf.name_scope('calculation'):
        cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y),reduction_indices=[1]))
    #reduction_indices=[1] 按行求解,计算交叉熵。
        train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
        correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1)) 
        accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
        tf.summary.scalar('loss',cross_entropy)
        
    
    
    merged = tf.summary.merge_all()
    writer = tf.summary.FileWriter("logs/",sess.graph)  #WIN10 要用CHROME打开 并且要断网,生成的logs文件夹要放在c盘第一层下
    #tensorboard --logdir=文件名  
    tf.global_variables_initializer().run()
    
    for i in range(1001):
            batch_xs,batch_ys = mnist.train.next_batch(50)
            train_step.run(feed_dict={x: batch_xs, y_: batch_ys, keep_prob: 0.5})
        
            if i%100==0:
                train_accuracy = accuracy.eval(feed_dict={x:batch_xs,y_:batch_ys,keep_prob:1.0})
                print("step %d and train_accuracy is %g" %(i,train_accuracy))
                result=sess.run(merged,feed_dict={x:batch_xs,y_:batch_ys,keep_prob:1.0})
                writer.add_summary(result,i)
    print("test accuracy %g"%accuracy.eval
              (feed_dict={x:mnist.test.images,y_:mnist.test.labels,keep_prob:1.0}))
    

    tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)

    input : [batch, in_height, in_width, in_channels]
                  图片数量, 图片高度, 图片宽度, 图像通道数
                  
        filter: [filter_height, filter_width, in_channels, out_channels]
                    [卷积核的高度,卷积核的宽度,图像通道数,卷积核个数]
                 filter中的in_channels就是input中的in_channels
                 输出是1x2x2x1,其中2=(3-2)/1+1,即(图片大小-filter大小)/步长+1
                 
        strides: 第一个参数表示在batch方向移动的步长,
                  第四个参数表示在channels上移动的步长,这两个参数都设置为1就好。
                  重点就是第二个,第三个参数的意义,也就是在height于width方向上的步长,这里也都设置为1。 
    
        padding='SAME'时,填充0,卷积后的图片大小计算公式:
                  out_height = ceil(float(in_height) / float(strides[1]))
                  out_width = ceil(float(in_width) / float(strides[2]))
               ='VAILD'时,舍弃元素,计算公式:
                  out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
                  out_width = ceil(float(in_width - filter_width + 1) / float(strides[2]))
                  ceil()返回上入整数
    

    相关文章

      网友评论

          本文标题:CNN

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