热门标签 | 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比赛中下载。


推荐阅读
  • cs231n Lecture 3 线性分类笔记(一)
    内容列表线性分类器简介线性评分函数阐明线性分类器损失函数多类SVMSoftmax分类器SVM和Softmax的比较基于Web的可交互线性分类器原型小结注:中文翻译 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • 本人学习笔记,知识点均摘自于网络,用于学习和交流(如未注明出处,请提醒,将及时更正,谢谢)OS:我学习是为了上 ... [详细]
  • 安装Tensorflow-GPU文档第一步:通过Anaconda安装python从这个链接https:www.anaconda.comdownload#window ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 开源Keras Faster RCNN模型介绍及代码结构解析
    本文介绍了开源Keras Faster RCNN模型的环境需求和代码结构,包括FasterRCNN源码解析、RPN与classifier定义、data_generators.py文件的功能以及损失计算。同时提供了该模型的开源地址和安装所需的库。 ... [详细]
  • 通过Anaconda安装tensorflow,并安装运行spyder编译器的完整教程
    本文提供了一个完整的教程,介绍了如何通过Anaconda安装tensorflow,并安装运行spyder编译器。文章详细介绍了安装Anaconda、创建tensorflow环境、安装GPU版本tensorflow、安装和运行Spyder编译器以及安装OpenCV等步骤。该教程适用于Windows 8操作系统,并提供了相关的网址供参考。通过本教程,读者可以轻松地安装和配置tensorflow环境,以及运行spyder编译器进行开发。 ... [详细]
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社区 版权所有