• 基于tensorflow的CNN卷积神经网络对Fasion-MNIST数据集的分类器(1)


    写一个基于tensorflow的cnn,分类fasion-MNIST数据集

    这个就是fasion-mnist数据集

    这张图片是CNN的一般结构

    先上代码,在分析:

    import tensorflow as tf
    import pandas as pd
    import numpy as np
    
    config = tf.ConfigProto()
    config.gpu_options.per_process_gpu_memory_fraction = 0.3
    
    train_data = pd.read_csv('test.csv')
    test_data = pd.read_csv('test.csv')
    
    
    def Weight(shape):
        initial = tf.truncated_normal(shape, stddev=0.1)
        return tf.Variable(initial, tf.float32)
    
    
    def biases(shape):
        initial = tf.constant(0.1, shape=shape)
        return tf.Variable(initial, tf.float32)
    
    
    def conv(inputs, w):
        return tf.nn.conv2d(inputs, w, strides=[1, 1, 1, 1], padding='SAME')
    
    
    def pool(inputs):
        return tf.nn.max_pool(inputs, ksize=[1, 1, 1, 1], strides=[1, 2, 2, 1], padding='SAME')
    
    
    x = tf.placeholder(tf.float32, [None, 784])
    y = tf.placeholder(tf.int64, [None])
    x_image = tf.reshape(x, [-1, 28, 28, 1])
    
    w1 = Weight([5, 5, 1, 32])
    b1 = biases([32])
    conv1 = tf.nn.relu(conv(x_image, w1) + b1)
    p1 = pool(conv1)
    
    w2 = Weight([5, 5, 32, 64])
    b2 = biases([64])
    conv2 = tf.nn.relu(conv(p1, w2) + b2)
    p2 = pool(conv2)
    
    flattended = tf.reshape(p2, [-1, 7 * 7 * 64])
    
    w_fc1 = Weight([7 * 7 * 64, 1024])
    b_fc1 = biases([1024])
    fc1 = tf.matmul(flattended, w_fc1) + b_fc1
    h_fc1 = tf.nn.relu(fc1)
    
    w_fc2 = Weight([1024, 10])
    b_fc2 = biases([10])
    logits = tf.matmul(h_fc1, w_fc2) + b_fc2
    
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y)
    correct_prediction = tf.equal(y, tf.argmax(logits, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
    
    init = tf.global_variables_initializer()
    sess = tf.Session(config=config)
    sess.run(init)
    
    for i in range(10000):
        choice = np.random.choice(6000, 100)
        batch = train_data.iloc[choice]
        labels = np.array(batch.iloc[:, 0])
        features = np.array(batch.iloc[:, 1:]).astype(np.float32)
        sess.run(train_step, feed_dict={x: features, y: labels})
        if i % 50 == 0:
            test_batch = test_data.iloc[0:1000, :]
            test_labes = np.array(test_batch.iloc[:, 0])
            test_features = np.array(test_batch.iloc[:, 1:]).astype(np.float32)
            print(sess.run(accuracy, feed_dict={x: test_features, y: test_labes}))
    sess.close()

    1.用pandas读取训练集和测试集的数据.经过这一步,csv文件中的数据将会被转化成pandas中的DataFrame数据类型

    train_data = pd.read_csv('test.csv')
    test_data = pd.read_csv('test.csv')

    2.定义Weight, biases, conv层, pool层

    def Weight(shape):
        initial = tf.truncated_normal(shape, stddev=0.1)
        return tf.Variable(initial, tf.float32)
    
    
    def biases(shape):
        initial = tf.constant(0.1, shape=shape)
        return tf.Variable(initial, tf.float32)
    
    
    def conv(inputs, w):
        return tf.nn.conv2d(inputs, w, strides=[1, 1, 1, 1], padding='SAME')
    
    
    def pool(inputs):
        return tf.nn.max_pool(inputs, ksize=[1, 1, 1, 1], strides=[1, 2, 2, 1], padding='SAME')

    在这段代码中, 卷积层的,步幅都是1, 用SAME的padding方式,池化层的步幅是x y轴都是2, 这样,数据每次经过一次卷积和池化, 图像的宽和长都会变成原来的二分之一,也就是 原先 28x28 的图像 将会经过 14*14 到 7*7的变化

    2. 定义placeholder

    #define the placeholder
    x = tf.placeholder(tf.float32,  [None, 784])
    y = tf.placeholder(tf.int64, [None])
    x_image = tf.reshape(x, [-1, 28, 28, 1])

    我们定义x和y占位符,其中x是图像的特征,y是标签,x大小为784,就是图像28*28pixels,y的大小是10,因为总共有10钟类型的图片。将x reshape成[-1, 28, 28 1],其中-1代表一次输入的样本数量是不确定的,28*28是图像的大小,1 是图像的通道,这里的数据集是黑白,所以通道(channel)是1

    3.第一层的卷积层

    #define the first convolutional layer
    w1 = Weight([5, 5, 1, 32])
    b1 = biases([32])
    conv1 = tf.nn.relu(conv(x_image, w1) + b1)
    p1 = pool(conv1)

    这里我们定义卷积层的patch为5*5, 输入的channls是1,经过卷积后的channels变成32,也就是说通过卷积图像高度从1变成了32,从[-1, 28, 28, 1]变成了[-1, 28, 28, 32],我们再把relu函数应用上,再通过一个stride为[1, 2, 2, 1]的max_pool输出的p1最终变成了[-1. 14. 14. 32]

    4 第二层的卷积层

    #define the second convolutional layer
    w2 = Weight([5, 5, 32, 64])
    b2 = biases([64])
    conv2 = tf.nn.relu(conv(p1, w2)+ b2)
    p2 = pool(conv2)

    和前面的卷积层一样,第二层的卷积层把[-1, 14, 14, 32] 的数据卷积成[-1, 7, 7, 64]的输出。

    5.数据扁平化

    #fattending 
    flattended = tf.reshape(p2, [-1, 7*7*64])

    输入数据经过两次卷积池化,我们接下来要进行两次全连接得到logits,在全连接之前,我们需要把每一个[ 7, 7, 64]的样本扁平化成一列向量,这里我们直接用tf.reshape,成一个[-1, 7*7*64]的矩阵,-1还是代表不确定的样本数量

    6.定义第一个全连接层

    #define the first fully connected layer
    w_fc1 = Weight([7*7*64, 1024])
    b_fc1 = biases([1024])
    fc1 = tf.matmul(flattended, w_fc1) + b_fc1
    h_fc1 = tf.nn.relu(fc1)

    第一个全连接层把7*7*64的样本变成为1024的输出。在经过relu激活函数

    7.定义第二个全连接层

    #define the second fully connected layer
    w_fc2 = Weight([1024, 10])
    b_fc2 = biases([10])
    logits = tf.matmul(h_fc1, w_fc2) + b_fc2

    第二个全连接层将[1024]的输入变为[10]的logits,这一次没有设置激活函数,因为等会计算交叉熵(cross entropy)时候我们将会用到tf.nn.sparse_softmax_cross_entropy_with_logits()函数,他会给输入应用上softmax函数,所以输入的数据是不能经过scaleing的.

    8.模型的一些计算

    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y)
    correct_prediction = tf.equal(y, tf.argmax(logits, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

    首先是cross_entropy也就是交叉熵,这里我们用tf.nn.sparse_softmax_cross_entropy_with_logits()这个函数进行计算,关于这些交叉熵函数可以参考我的另一篇博客https://www.cnblogs.com/francischeng/p/9836341.html, 然后就是正确的预测用equal函数对比logits中概率最大的索引和输入的label,可以返回一个boolean形式的列表,比如[True , True, False, False], 下一步计算准确度accuracy,他用了两个函数 tf.cast()将前面的boolean的列表转化成float32,那前面的例子来说会把[True, True , Flase, Flase]转化成[1, 1, 0, 0]在计算reduce_mean这个数据的结果将会是百分之50了

    9.初始化

    init = tf.global_variables_initializer()
    sess = tf.Session(config=config)
    sess.run(init)

    这边的config就是开头对gpu的配置了(看到第一个发的完整代码)

    10.开始跑数据

    for i in range(10000):
        choice = np.random.choice(6000, 100)
        batch = train_data.iloc[choice]
        labels =np.array(batch.iloc[:,0])
        features = np.array(batch.iloc[:,1:]).astype(np.float32)
        sess.run(train_step, feed_dict={x: features, y:labels})
        if i %50 == 0:
            test_batch = test_data.iloc[0:1000,:]
            test_labes = np.array(test_batch.iloc[:,0])
            test_features = np.array(test_batch.iloc[:,1:]).astype(np.float32)
            print(sess.run(accuracy, feed_dict={x:test_features, y:test_labes}))
    sess.close()

    这里我们设置每次跑的数据(batch)为100, 测试的数据都是从测试集中随机抽取的100个,这里要注意数据转换,labels已经是int64的所以可以不用转,而features需要把他从int64转换成float32,每50次用检验集中的数据算一次accuracy。

    最后结果显示:

    可以看到准确率几乎回到100,但是我的代码计算准确率时只是用了验证机的1000个数据,不是很合理

  • 相关阅读:
    Tomcat+Nginx+Linux+Mysql部署豆瓣TOP250的项目到腾讯云服务器
    使用JSP+Servlet+Jdbc+Echatrs实现对豆瓣电影Top250的展示
    环境搭建-CentOS集群搭建
    环境搭建-Hadoop集群搭建
    ELK搭建实时日志分析平台
    Flume和Kafka完成实时数据的采集
    Python日志产生器
    腐竹木耳炒肉
    [转]Apple耳机兼容非Mac设置
    文件及文件夹操作
  • 原文地址:https://www.cnblogs.com/francischeng/p/9886422.html
Copyright © 2020-2023  润新知