Top2:CNN 卷积神经网络实现猫狗图片识别二分类

Top2:CNN 卷积神经网络实现猫狗图片识别二分类

系统:Windows10 Professional
环境:python=3.6 tensorflow-gpu=1.14


```python
"""
@Time:  2020/8/25   17:06
@Author:  Carl
@File:  cnn-cat-dog.py
@Software:  PyCharm Professional Edition
"""

import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'# 消除警告
import tensorflow as tf
import random
import matplotlib.pyplot as plt
import numpy as np
from scipy import misc
import tensorflow.contrib as con

# 设置随机种子
tf.set_random_seed(1)

# 获取数据集
all_num = 1000  # 处理的样本总数
split_num = int(all_num * 0.9)
train_num = split_num  # 训练集数量
test_num = all_num - split_num  # 测试集数量

IMGSIZE = 100  # 输入图片的宽度和高度 尺寸不能过小 否则无法识别


def get_all_files(file_path):  # 获取图片路径及其标签
    image_list = []
    label_list = []
    cat_count = 0
    dog_count = 0
    for item in os.listdir(file_path):  # 文件名 形式如 cat.0.jpg
        item_path = file_path + '\\' + item
        if item[:3]=='cat': # 猫标记为'0'
            label_list.append([1,0])
            cat_count += 1
        else: # 狗标记为'1'
            label_list.append([0,1])
            dog_count += 1
        image_list.append(item_path)
    print('数据集中有%d只猫,%d只狗'%(cat_count,dog_count))

    # 乱序
    np.random.seed(10)
    shuffle_indices = np.random.permutation(np.arange(len(label_list)))
    x_shuffled = np.array(image_list)[shuffle_indices]
    y_shuffled = np.array(label_list)[shuffle_indices]

    image_list = x_shuffled[:train_num]
    label_list = y_shuffled[:train_num]
    image_test = x_shuffled[-test_num:]
    label_test = y_shuffled[-test_num:]
    return image_list,label_list,image_test,label_test

image_dir = r'data\train'
train_list,Y_one_hot,test_list,Y_test = get_all_files(image_dir) #这个目录里的文件有标签
print(train_list.shape,Y_one_hot.shape)

#读入图片文件
def readimg(file):
    image = plt.imread(file)
    image = misc.imresize(image,(IMGSIZE,IMGSIZE))
    image = image / 255. #归一化
    return image

imgs = []
imgs_test = []
for i in range(0, train_num):#读入训练集
    image_train = readimg(train_list[i])
    imgs.append(image_train)
    if i % 100 == 0:
        print('read train ',i)
for i in range(0, test_num):#读入测试集
    image_test = readimg(test_list[i])
    imgs_test.append(image_test)
    if i % 100 == 0:
        print('read test ',i)
imgArr = np.array(imgs)  #训练集
imgArrTest = np.array(imgs_test) #测试集


g_b = 0


# 实现next_batch 函数 ,每次返回一批数据
def next_batch(size):
    global g_b
    xb = imgArr[g_b:g_b + size]
    yb = Y_one_hot[g_b:g_b + size]
    g_b = g_b + size
    return xb, yb


# 定义参数
learning_rate = 0.001  # 学习率
training_epochs = 100  # 训练总周期
batch_size = 100  # 训练每批样本数

# 定义占位符
X = tf.placeholder(tf.float32, [None, IMGSIZE, IMGSIZE, 3])
Y = tf.placeholder(tf.float32, [None, 2])  # 独热编码

with tf.variable_scope('conv1'):  # 第一层卷积 输入图片数据(?,IMGSIZE,IMGSIZE,3)
    W1 = tf.Variable(tf.random_normal([3, 3, 3, 16]))  # 卷积核3*3,输入通道3,输出通道16
    L1 = tf.nn.conv2d(X, W1, strides=[1, 1, 1, 1], padding='SAME')  # 卷积输出 (?,IMGSIZE,IMGSIZE,16)
    L1 = tf.nn.relu(L1)
    L1 = tf.nn.max_pool(L1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')  # 池化输出(?,IMGSIZE/2,IMGSIZE/2,16)

with tf.variable_scope('conv2'):  # 第二层卷积 输入图片数据(?,IMGSIZE/2,IMGSIZE/2,16)
    W2 = tf.Variable(tf.random_normal([3, 3, 16, 16], stddev=0.01))  # 卷积核3*3,输入通道16,输出通道16
    L2 = tf.nn.conv2d(L1, W2, strides=[1, 1, 1, 1], padding='SAME')  # 卷积输出 (?,IMGSIZE/2,IMGSIZE/2,16)
    L2 = tf.nn.relu(L2)
    L2 = tf.nn.max_pool(L2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')  # 池化输出 (?,IMGSIZE/4,IMGSIZE/4,16)
    # 变成一维向量
    dim = L2.get_shape()[1].value * L2.get_shape()[2].value * L2.get_shape()[3].value
    L2_flat = tf.reshape(L2, [-1, dim])

with tf.variable_scope('fc1'):  # 全连接1
    W3 = tf.get_variable('W3', shape=[dim, 128], initializer=con.layers.xavier_initializer())
    b3 = tf.Variable(tf.random_normal([128]))
    L3 = tf.nn.relu(tf.matmul(L2_flat, W3) + b3)

with tf.variable_scope('fc2'):  # 全连接2
    W4 = tf.get_variable('W4', shape=[128, 128], initializer=tf.truncated_normal_initializer(stddev=0.005))
    b4 = tf.get_variable('b4', shape=[128], initializer=tf.constant_initializer(0.1))
    L4 = tf.nn.relu(tf.matmul(L3, W4) + b4)
    L4 = tf.nn.dropout(L4, keep_prob=0.9)

with tf.variable_scope('softmax'):  # softmax层
    W5 = tf.get_variable('W5', shape=[128, 2], initializer=tf.truncated_normal_initializer(stddev=0.005))
    b5 = tf.get_variable('b5', shape=[2], initializer=tf.constant_initializer(0.1))
    logits = tf.add(tf.matmul(L4, W5), b5)

# 代价或损失函数
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits, labels=Y))

# 优化器
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

# 准确率
correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

# 创建会话
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())  # 全局变量初始化
    # 迭代训练
    print('开始学习...')
    for epoch in range(training_epochs):
        avg_cost = 0
        total_batch = int(train_num / batch_size)  # 计算总批次
        g_b = 0
        for i in range(total_batch):
            x_data, y_data = next_batch(batch_size)
            feed_dict = {X: x_data, Y: y_data}
            c, _ = sess.run([cost, optimizer], feed_dict=feed_dict)
            avg_cost += c / total_batch
        if epoch % 20 == 0:
            acc = sess.run(accuracy, feed_dict={X: imgArrTest, Y: Y_test})
            print('Epoch:', (epoch + 1), 'cost=', avg_cost, 'acc=', acc)
    print('学习完成')

    # 测试模型检查准确率
    print('Accuracy:', sess.run(accuracy, feed_dict={X: imgArrTest, Y: Y_test}))

    # 在测试集中随机抽一个样本进行测试
    r = random.randint(0, test_num - 1)
    print('Label:', sess.run(tf.argmax(Y_test[r:r + 1], 1)))
    print('Prediction:', sess.run(tf.argmax(logits, 1), feed_dict={X: imgArrTest[r:r + 1]}))

你可能感兴趣的:(深度学习,python,tensorflow,深度学习,神经网络,数据挖掘)