使用tensorflow实现花卉分类,训练样本用的是网上的花卉数据集,测试样本是在网上重新下载的各种花的图片,代码如下。
from skimage import io,transform #skimage模块下的io transform(图像的形变与缩放)模块
import glob #glob 文件通配符模块
import os #os 处理文件和目录的模块
import tensorflow as tf
import numpy as np #多维数据处理模块
import time
#数据集地址
path='E:/data/flower/flower_photos/'
#模型保存地址
model_path='E:/data/flower/model/fc_model.ckpt'
#将所有的图片resize成100*100
w=100
h=100
c=3
#读取图片+数据处理
def read_img(path):
#os.listdir(path) 返回path指定的文件夹包含的文件或文件夹的名字的列表
#os.path.isdir(path)判断path是否是目录
#b = [x+x for x in list1 if x+x<15 ] 列表生成式,循环list1,当if为真时,将x+x加入列表b
cate=[path+x for x in os.listdir(path) if os.path.isdir(path+x)]
imgs=[]
labels=[]
for idx,folder in enumerate(cate):
#glob.glob(s+'*.py') 从目录通配符搜索中生成文件列表
for im in glob.glob(folder+'/*.jpg'):
#输出读取的图片的名称
print('reading the images:%s'%(im))
#io.imread(im)读取单张RGB图片 skimage.io.imread(fname,as_grey=True)读取单张灰度图片
#读取的图片
img=io.imread(im)
#skimage.transform.resize(image, output_shape)改变图片的尺寸
img=transform.resize(img,(w,h))
#将读取的图片数据加载到imgs[]列表中
imgs.append(img)
#将图片的label加载到labels[]中,与上方的imgs索引对应
labels.append(idx)
#将读取的图片和labels信息,转化为numpy结构的ndarr(N维数组对象(矩阵))数据信息
return np.asarray(imgs,np.float32),np.asarray(labels,np.int32)
#调用读取图片的函数,得到图片和labels的数据集
data,label=read_img(path)
#打乱顺序
#读取data矩阵的第一维数(图片的个数)
num_example=data.shape[0]
#产生一个num_example范围,步长为1的序列
arr=np.arange(num_example)
#调用函数,打乱顺序
np.random.shuffle(arr)
#按照打乱的顺序,重新排序
data=data[arr]
label=label[arr]
#将所有数据分为训练集和验证集
ratio=0.8
s=np.int(num_example*ratio)
x_train=data[:s]
y_train=label[:s]
x_val=data[s:]
y_val=label[s:]
#-----------------构建网络----------------------
#本程序cnn网络模型,共有7层,前三层为卷积层,后三层为全连接层,前三层中,每层包含卷积、激活、池化层
#占位符设置输入参数的大小和格式
x=tf.placeholder(tf.float32,shape=[None,w,h,c],name='x')
y_=tf.placeholder(tf.int32,shape=[None,],name='y_')
def inference(input_tensor, train, regularizer):
#-----------------------第一层----------------------------
with tf.variable_scope('layer1-conv1'):
#初始化权重conv1_weights为可保存变量,大小为5x5,3个通道(RGB),数量为32个
conv1_weights = tf.get_variable("weight",[5,5,3,32],initializer=tf.truncated_normal_initializer(stddev=0.1))
#初始化偏置conv1_biases,数量为32个
conv1_biases = tf.get_variable("bias", [32], initializer=tf.constant_initializer(0.0))
#卷积计算,tf.nn.conv2d为tensorflow自带2维卷积函数,input_tensor为输入数据,
#conv1_weights为权重,strides=[1, 1, 1, 1]表示左右上下滑动步长为1,padding='SAME'表示输入和输出大小一样,即补0
conv1 = tf.nn.conv2d(input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding='SAME