热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用卷积神经网络区分猫和狗.md

卷积神经网络(ConvolutionnalNeuralNetwork,CNN)是一种前馈神经网络,它的人工神经单元可以响应一部分范围内的的周围单元,对于大型图像有出色的表现。卷积神经网络通
卷积神经网络(Convolutionnal Neural Network, CNN)是一种前馈神经网络,它的人工神经单元可以响应一部分范围内的的周围单元,对于大型图像有出色的表现。
卷积神经网络通常由一个或者多个卷积层(convolution layer)和顶端的全连接(full connect layer)组成,在应用中我们通常还会在卷积层后面加上一个池化层(pooling layer)。
使用的框架为tensorflow,这是google开发的一款开源的机器学习实验与开发平台,他为我们实现了机器学习中很多的底层api,同时他提供了丰富的python接口和文档,在对c和java,c++相关的接口和文档就没有那么完善,因此本次的编程语言选用的是python。

模型介绍

在多次模型的修改中,本次模型建造如下,包括一个输入层,两个卷积层,两个池化层,两个全输入层。

* 输入层:对训练数据文件夹中的图片进行大小的调整,如果不进行调整,会造成内存资源的耗尽。处理完之后会进行数据的归一化(正则化 normalized)。
* 卷基层:进行卷积运算,对权重(weight)和偏离量(bias)进行训练,这就是我们抽象意义上的“特征”。深层学习(deeping learning)与早期的浅层学习不同的是,深层学习重点是学习”特征”,而浅层学习则是另外一个思路,它靠的的是人工来建模,人工来构建特征,这需要建模着对这个问题有着深刻的理解。
* 池化层: 图片数据的像素(pixel)很多,在转化成张量(tensor)时维度很高,所以我们对它进行压缩,它主要利用的是图片像素点周围的点与之差不多,所以就选取这个点来代表这个区域。它改变的是张量的长和宽,但是不会改变张量的厚度。如下图1所示:
图1-----cat.2.jpg
----~~~~~~~~~
------dog.1.jpg
------dog.2.jpg
------dog.3.jpg
+---test_data
------cat.1.jpg
------cat.2.jpg
------dog.1.jpg
------dog.2.jpg
------dog.3.jpg

导入的包


import matplotlib.pyplot as plt
import numpy as np
import os
from IPython.display import display, Image, HTML
import cv2
import tensorflow as tf

定义 常量

#训练图片文件夹
TRAIN_DIR = 'C:\\Users\\longyiyuan\\Desktop\\train_data\\'
#测试图片文件夹
TEST_DIR = 'C:\\Users\\longyiyuan\\Desktop\\test_data\\'
#图片的大小
IMAGE_SIZE = 64
#图片的厚度,rgb为3,灰度图片为1.
CHANNELS = 3
pixel_depth = 255.0
#模型输出文件
OUTFILE = '../smalltest.npsave.bin'
TRAINING_AND_VALIDATION_SIZE_DOGS = 10000
TRAINING_AND_VALIDATION_SIZE_CATS = 10000
TRAINING_AND_VALIDATION_SIZE_ALL = 20000
TEST_SIZE_DOGS = 250
TEST_SIZE_CATS = 250
TRAINING_SIZE = 20000
TEST_SIZE_ALL = 500

提取图片信息

第一步:

#将文件夹中图片的路径全部提取出来
train_images = [TRAIN_DIR + i for i in os.listdir(TRAIN_DIR)]
train_dogs = [TRAIN_DIR + i for i in os.listdir(TRAIN_DIR) if 'dog' in i]
train_cats = [TRAIN_DIR + i for i in os.listdir(TRAIN_DIR) if 'cat' in i]
test_dogs = [TEST_DIR + i for i in os.listdir(TRAIN_DIR) if 'dog' in i]
test_cats = [TEST_DIR + i for i in os.listdir(TRAIN_DIR) if 'cat' in i]
test_images = [TEST_DIR + i for i in os.listdir(TEST_DIR)]

#将猫和狗的路径列表组合起来
train_images = train_dogs[:TRAINING_AND_VALIDATION_SIZE_DOGS] + train_cats[:TRAINING_AND_VALIDATION_SIZE_CATS]
#构建同样顺序的狗和猫的标签数组
train_labels = np.array((['dogs'] * TRAINING_AND_VALIDATION_SIZE_DOGS) + ['cats'] * TRAINING_AND_VALIDATION_SIZE_CATS)

test_images = test_dogs[:TEST_SIZE_DOGS] + test_cats[:TEST_SIZE_CATS]
test_labels = np.array((['dogs'] * TEST_SIZE_DOGS + ['cats'] * TEST_SIZE_CATS))

第二步:

#reshape the image
def read_image(file_path):
img = cv2.imread(file_path, cv2.IMREAD_COLOR) #cv2.IMREAD_GRAYSCALE
if (img.shape[0] >= img.shape[1]): # height is greater than width
resizeto = (IMAGE_SIZE, int (round (IMAGE_SIZE * (float (img.shape[1]) / img.shape[0]))));
else:
resizeto = (int (round (IMAGE_SIZE * (float (img.shape[0]) / img.shape[1]))), IMAGE_SIZE);

img2 = cv2.resize(img, (resizeto[1], resizeto[0]), interpolation=cv2.INTER_CUBIC)
img3 = cv2.copyMakeBorder(img2, 0, IMAGE_SIZE - img2.shape[0], 0, IMAGE_SIZE - img2.shape[1], cv2.BORDER_CONSTANT, 0)

return img3[:,:,::-1] # turn into rgb format

第三步:

#normalize the image , to make the preparation 
def prep_data(images):
count = len(images)
#构建数组,[count, Image_size, image_size, channels],channel表示图片的层数,也就是厚度
data = np.ndarray((count, IMAGE_SIZE, IMAGE_SIZE, CHANNELS), dtype=np.float32)

for i, image_file in enumerate(images):
#print(image_file)
img = read_image(image_file)
#将读到的图片数据变成浮点型的数组
image_data = np.array(img, dtype=np.float32)
#进行第一层的正则化处理
image_data[:, :, 0] = (image_data[:, :, 0].astype(float) - pixel_depth / 2) / pixel_depth
#进行第二层的正则化处理
image_data[:, :, 1] = (image_data[:, :, 1].astype(float) - pixel_depth / 2) / pixel_depth
#进行第三层的正则化处理,rgb图像一共三层
image_data[:, :, 2] = (image_data[:, :, 2].astype(float) - pixel_depth / 2) / pixel_depth

#data[i] = image_data
if i %250 == 0:
print("Processed {} of {}".format(i, count))

return data

train_normalized = prep_data(train_images)
test_normalized = prep_data(test_images)

print("Train shape: {}".format(train_normalized.shape))
print("Test shape: {}".format(test_normalized.shape))

正常输出为:
输出图像1

对数据进行随机打乱

np.random.seed(133)
def randomize(dataset, labels):
permutation = np.random.permutation(labels.shape[0])
shuffled_dataset = dataset[permutation, :, :, :]
shuffled_labels = labels[permutation]
return shuffled_dataset, shuffled_labels

train_dataset_rand, train_labels_rand = randomize(train_normalized, train_labels)
test_dataset, test_labels = randomize(test_normalized, test_labels)

train_dataset = train_dataset_rand[VALID_SIZE:VALID_SIZE+TRAINING_SIZE, :, :, :]
train_labels = train_labels_rand[VALID_SIZE:VALID_SIZE+TRAINING_SIZE]
test_dataset = train_dataset_rand[VALID_SIZE: TEST_SIZE_ALL, :, :, :]
test_labels = train_labels_rand[VALID_SIZE: TEST_SIZE_ALL]
print('Training', train_dataset.shape, train_labels.shape)
print('Test', test_dataset.shape, test_labels.shape)

模型构建

第一步:定义常量

# 图像大小
image_size = IMAGE_SIZE # TODO: redundant, consolidate
# 标签的个数,也就是分类的种数,这里只有猫和狗两种
num_labels = 2
# 图片的厚度,为rgb图像一共三层
num_channels = 3 # rg

第二步:将数据和标签变成tensor

def reformat(dataset, labels):
dataset = dataset.reshape(
(-1, image_size, image_size, num_channels)).astype(np.float32)
labels = (labels=='cats').astype(np.float32); # set dogs to 0 and cats to 1
labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32)
return dataset, labels
train_dataset, train_labels = reformat(train_dataset, train_labels)
test_dataset, test_labels = reformat(test_dataset, test_labels)
print ('Training set', train_dataset.shape, train_labels.shape)
print ('Test set', test_dataset.shape, test_labels.shape)

第三步:定义变量和常用函数

xs = tf.placeholder(tf.float32, [None, 64, 64, 3])
ys = tf.placeholder(tf.float32, [None, 2])

#保留概率,为了防止过拟合,使用dropout的方法丢掉一些值
keep_prob = tf.placeholder(tf.float32)
x_image = tf.reshape(xs, [-1, 64, 64, 3])

#define the weight_variable funciton
def Weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)


#define the bias_variable funtion
def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)

#define the conv funciton
def con2d(inputs, weight):
return tf.nn.conv2d(inputs, weight, strides=[1,1,1,1], padding='SAME')

#define the pool fuction
def max_pooling_2x2(inputs):
return tf.nn.max_pool(inputs, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

#define the computer accracy function
def computer_accuracy(v_xs, v_ys):
global prediction
y_re = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1})
#这里的500为测试的样本大小,在改变测试样本大小时要记得同时改变这个数字
return (np.sum(np.argmax(y_re, 1) == np.argmax(v_ys, 1)) / 500)

第四步:模型的搭建

#厚度一开始为3,由于每次步长为1,而每次池化步长为2,所以宽度和长度各缩减为原来的一般
#the first convolution
W_conv1 = Weight_variable([5, 5, 3, 32])
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(con2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pooling_2x2(h_conv1) #长宽 = [32*32]


#the second convolution
W_conv2 = Weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(con2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pooling_2x2(h_conv2) #长宽 = [16*16]

#the first full connection layer
w_f1 = Weight_variable([16*16*64, 4096])
b_f1 = bias_variable([4096])
h_pool2_flat = tf.reshape(h_pool2, [-1, 16*16*64])
h_f1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_f1) + b_f1)
h_f1_drop = tf.nn.dropout(h_f1, keep_prob)

w_f2 = Weight_variable([4096, 2])
b_f2 = bias_variable([2])
prediction = tf.nn.softmax(tf.matmul(h_f1_drop, w_f2) + b_f2)

#the loss between prediction and real data
cross_entropy = tf.reduce_mean(-tf.reduce_sum(-ys*tf.log(prediction),
reduction_indices=[1]))

train_step = tf.train.GradientDescentOptimizer(0.001).minimize(cross_entropy)

第五步:启动图,开始训练。

sess = tf.Session()
sess.run(tf.initialize_all_variables())
#2000为训练的步数
for i in range(20000):
#1000为每次训练的样本数量
offset = (i * 1000) % (train_labels.shape[0] - 1000)
batch_xs = train_dataset[offset:(offset + 1000), :, :, :]
batch_ys = train_labels[offset:(offset + 1000), :]
sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 0.8})
#计算精度
val = computer_accuracy(test_dataset, test_labels)
print("Train step %d:" %i ,val)

此模型的准确率只能达到百分之七十左右,各种参数还可以优化。作为一名新手,如果对于其中的tensorflow不是很了解的话,建议可以去看一下tensorflow的官方文档,tensorflow是一个框架,需要安装,可以使用pip install tensorflow 安装CPU版本。猫和狗的数据可以从kaggle的dog vs cat比赛中下载。


推荐阅读
  • [论文笔记] Crowdsourcing Translation: Professional Quality from Non-Professionals (ACL, 2011)
    Time:4hoursTimespan:Apr15–May3,2012OmarZaidan,ChrisCallison-Burch:CrowdsourcingTra ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 深入解析JVM垃圾收集器
    本文基于《深入理解Java虚拟机:JVM高级特性与最佳实践》第二版,详细探讨了JVM中不同类型的垃圾收集器及其工作原理。通过介绍各种垃圾收集器的特性和应用场景,帮助读者更好地理解和优化JVM内存管理。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 资源推荐 | TensorFlow官方中文教程助力英语非母语者学习
    来源:机器之心。本文详细介绍了TensorFlow官方提供的中文版教程和指南,帮助开发者更好地理解和应用这一强大的开源机器学习平台。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 数据管理权威指南:《DAMA-DMBOK2 数据管理知识体系》
    本书提供了全面的数据管理职能、术语和最佳实践方法的标准行业解释,构建了数据管理的总体框架,为数据管理的发展奠定了坚实的理论基础。适合各类数据管理专业人士和相关领域的从业人员。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
author-avatar
向日葵一样2502932413
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有