您的位置:首页 > 编程语言

深度学习花朵的识别(花朵+CNN+TensorFlow+多张识别)代码

2020-03-09 22:41 706 查看

之前说过手写数字的识别,那么接下来交流一下花朵图片的识别

亲测可用,不能忽悠你!

本篇直接搂代码,可能相关的深度学习的基本概念需要大家有一定的基础,目前网上关于深度学习的理论也有系统和详细的讲解,我就不班门弄斧了

还是在代码之前,先说一下花朵的数据集,网上花朵的数据集很多,如果没有,推荐一个数据集下载地址:
http://download.tensorflow.org/example_images/flower_photos.tgz

ok,数据集包括5种花朵(daisy雏菊,dandelion蒲公英,rose玫瑰,sunflower向日葵,tulips郁金香)

整个识别程序分成建模和分类两大部分

(1)建立模型=导入库+获取数据集+输入变换+搭建模型+小批量处理+训练模型+保存模型

库的选取

from skimage import io,transform
import glob                        #查找目录和文件模块
import os                          #操作文件夹模块
import tensorflow as tf            #tens框架
import numpy as np                 #数组函数包
import time                        #时间模块

获取数据集

#数据集地址
path='E:/花朵分类/flower_photos/'
#模型保存地址
model_path='E:/花朵分类/ckpt_dir/model'

这时,哲学三问(我是谁,从哪来,到哪去)得到了完美回答。
程序知道了它要啥,输入从哪来,输出到哪去。

接下来就要完成文件夹中的图片转换成深度神经网络理想的输入形式
输入变换

#将所有的图片resize成100*100
w=100       #宽度
h=100       #高度
c=3         #深度

#读取图片
def read_img(path):
cate=[path+x for x in os.listdir(path) if os.path.isdir(path+x)]
imgs=[]
labels=[]
for idx,folder in enumerate(cate):
for im in glob.glob(folder+'/*.jpg'):
print('reading the images:%s'%(im))
img=io.imread(im)
img=transform.resize(img,(w,h))
imgs.append(img)
labels.append(idx)
return np.asarray(imgs,np.float32),np.asarray(labels,np.int32)
data,label=read_img(path)

#打乱顺序
num_example=data.shape[0]
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:]

每块的主要作用已经注释在程序块前,那么我们想更好的理解,还需要稍微的深入研究一下。
enumerate( ):读取当前路径下文件夹,统计名称和对应索引

glob.glob( ):批量抓取某种格式、或者以某个字符打头的文件名

transform.resize( ):裁剪图片,以float64的格式存储,数值的取值范围是(0~1)

np.asarray( ):保存对象的指针

np.arange( ):生成一个从start(包含)到stop(不包含),以step为步长的序列。返回一个list对象。

在这段程序中,我们将花朵图片处理成适合神经网络输入的形式,并对处理后的图片进行标签处理,随机拆分成训练集和测试集。

之后就到了我们的深度学习模型搭建的过程了
在此,搭建了一个卷积神经网络用于特征提取,话不多说,直接上代码

def inference(input_tensor, train, regularizer):
with tf.variable_scope('layer1-conv1'):
conv1_weights = tf.get_variable("weight",[5,5,3,32],initializer=tf.truncated_normal_initializer(stddev=0.1))
conv1_biases = tf.get_variable("bias", [32], initializer=tf.constant_initializer(0.0))
conv1 = tf.nn.conv2d(input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding='SAME')
relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))

with tf.name_scope("layer2-pool1"):
pool1 = tf.nn.max_pool(relu1, ksize = [1,2,2,1],strides=[1,2,2,1],padding="VALID")

with tf.variable_scope("layer3-conv2"):
conv2_weights = tf.get_variable("weight",[5,5,32,64],initializer=tf.truncated_normal_initializer(stddev=0.1))
conv2_biases = tf.get_variable("bias", [64], initializer=tf.constant_initializer(0.0))
conv2 = tf.nn.conv2d(pool1, conv2_weights, strides=[1, 1, 1, 1], padding='SAME')
relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_biases))

with tf.name_scope("layer4-pool2"):
pool2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')

with tf.variable_scope("layer5-conv3"):
conv3_weights = tf.get_variable("weight",[3,3,64,128],initializer=tf.truncated_normal_initializer(stddev=0.1))
conv3_biases = tf.get_variable("bias", [128], initializer=tf.constant_initializer(0.0))
conv3 = tf.nn.conv2d(pool2, conv3_weights, strides=[1, 1, 1, 1], padding='SAME')
relu3 = tf.nn.relu(tf.nn.bias_add(conv3, conv3_biases))

with tf.name_scope("layer6-pool3"):
pool3 = tf.nn.max_pool(relu3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')

with tf.variable_scope("layer7-conv4"):
conv4_weights = tf.get_variable("weight",[3,3,128,128],initializer=tf.truncated_normal_initializer(stddev=0.1))
conv4_biases = tf.get_variable("bias", [128], initializer=tf.constant_initializer(0.0))
conv4 = tf.nn.conv2d(pool3, conv4_weights, strides=[1, 1, 1, 1], padding='SAME')
relu4 = tf.nn.relu(tf.nn.bias_add(conv4, conv4_biases))

with tf.name_scope("layer8-pool4"):
pool4 = tf.nn.max_pool(relu4, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
nodes = 6*6*128
reshaped = tf.reshape(pool4,[-1,nodes])

with tf.variable_scope('layer9-fc1'):
fc1_weights = tf.get_variable("weight", [nodes, 1024],
initializer=tf.truncated_normal_initializer(stddev=0.1))
if regularizer != None: tf.add_to_collection('losses', regularizer(fc1_weights))
fc1_biases = tf.get_variable("bias", [1024], initializer=tf.constant_initializer(0.1))

fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights) + fc1_biases)
if train: fc1 = tf.nn.dropout(fc1, 0.5)

with tf.variable_scope('layer10-fc2'):
fc2_weights = tf.get_variable("weight", [1024, 512],
initializer=tf.truncated_normal_initializer(stddev=0.1))
if regularizer != None: tf.add_to_collection('losses', regularizer(fc2_weights))
fc2_biases = tf.get_variable("bias", [512], initializer=tf.constant_initializer(0.1))

fc2 = tf.nn.relu(tf.matmul(fc1, fc2_weights) + fc2_biases)
if train: fc2 = tf.nn.dropout(fc2, 0.5)

with tf.variable_scope('layer11-fc3'):
fc3_weights = tf.get_variable("weight", [512, 5],
initializer=tf.truncated_normal_initializer(stddev=0.1))
if regularizer != None: tf.add_to_collection('losses', regularizer(fc3_weights))
fc3_biases = tf.get_variable("bias", [5], initializer=tf.constant_initializer(0.1))
logit = tf.matmul(fc2, fc3_weights) + fc3_biases

return logit

在此阶段,之所以没有对模型做过多的注释,是因为在此部分,可以随便的增添或删减自己的神经网络,这部分不做过多的讲解,目前网上优秀的模型非常多。

接下来干嘛呢
为了能更快的处理图片,我们增加了一个小批量处理环节

#(小处理)将logits乘以1赋值给logits_eval,定义name,方便在后续调用模型时通过tensor名字调用输出tensor
b = tf.constant(value=1,dtype=tf.float32)
logits_eval = tf.multiply(logits,b,name='logits_eval')

loss=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y_)
train_op=tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
correct_prediction = tf.equal(tf.cast(tf.argmax(logits,1),tf.int32), y_)
acc= tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

#定义一个函数,按批次取数据
def minibatches(inputs=None, targets=None, batch_size=None, shuffle=False):
assert len(inputs) == len(targets)
if shuffle:
indices = np.arange(len(inputs))
np.random.shuffle(indices)
for start_idx in range(0, len(inputs) - batch_size + 1, batch_size):
if shuffle:
excerpt = indices[start_idx:start_idx + batch_size]
else:
excerpt = slice(start_idx, start_idx + batch_size)
yield inputs[excerpt], targets[excerpt]

模型的最后肯定就是要训练啦
那么就开始吧!

n_epoch=10
batch_size=64
saver=tf.train.Saver()
sess=tf.Session()
sess.run(tf.global_variables_initializer())
for epoch in range(n_epoch):
start_time = time.time()

#training
train_loss, train_acc, n_batch = 0, 0, 0
for x_train_a, y_train_a in minibatches(x_train, y_train, batch_size, shuffle=True):
_,err,ac=sess.run([train_op,loss,acc], feed_dict={x: x_train_a, y_: y_train_a})
train_loss += err; train_acc += ac; n_batch += 1
print("   train loss: %f" % (np.sum(train_loss)/ n_batch))
print("   train acc: %f" % (np.sum(train_acc)/ n_batch))

#validation
val_loss, val_acc, n_batch = 0, 0, 0
for x_val_a, y_val_a in minibatches(x_val, y_val, batch_size, shuffle=False):
err, ac = sess.run([loss,acc], feed_dict={x: x_val_a, y_: y_val_a})
val_loss += err; val_acc += ac; n_batch += 1
print("   validation loss: %f" % (np.sum(val_loss)/ n_batch))
print("   validation acc: %f" % (np.sum(val_acc)/ n_batch))
saver.save(sess,model_path)
sess.close()

训练后不要忘记保存模型哟!

(2)分类程序
模型在手,不试试能行吗?真金还需火炼!
Let‘s Go

分类程序=多张图片导入+读取图片+导入模型+分类结果

先开始导入图片

path1 = "E:/flower_photos/dandelion/822355d2f_n.jpg"
path2 = "E:/flower_photos/dandelion/7355d3078_m.jpg"
path3 = "E:/flower_photos/roses/39492cf8d_n.jpg"
path4 = "E:/flower_photos/sunflowers/69536bf4ea3.jpg"
path5 = "E:/flower_photos/tulips/107912168491604.jpg"

flower_dict = {0:'dasiy',1:'dandelion',2:'roses',3:'sunflowers',4:'tulips'}

简单不,ok不,欧不,路径一改,天下你有

读取

w=100
h=100
c=3

def read_one_image(path):
img = io.imread(path)
img = transform.resize(img,(w,h))
return np.asarray(img)

没的问题是吧,和之前的一样

接下来干嘛,导入模型训练那

with tf.Session() as sess:
data = []
data1 = read_one_image(path1)
data2 = read_one_image(path2)
data3 = read_one_image(path3)
data4 = read_one_image(path4)
data5 = read_one_image(path5)
data.append(data1)
data.append(data2)
data.append(data3)
data.append(data4)
data.append(data5)

saver = tf.train.import_meta_graph('E:/花朵分类/ckpt_dir/.meta')
saver.restore(sess,tf.train.latest_checkpoint('E:/花朵分类/ckpt_dir/'))

graph = tf.get_default_graph()
x = graph.get_tensor_by_name("x:0")
feed_dict = {x:data}

logits = graph.get_tensor_by_name("logits_eval:0")
classification_result = sess.run(logits,feed_dict)

这块也不复杂

快出结果吧,等不及了都

#打印出预测矩阵
print(classification_result)
#打印出预测矩阵每一行最大值的索引
print(tf.argmax(classification_result,1).eval())
#根据索引通过字典对应花的分类
output = []
output = tf.argmax(classification_result,1).eval()
for i in range(len(output)):
print("第",i+1,"朵花预测:"+flower_dict[output[

然后就可以看到非常非常理想的结果啦!

peace of the world

  • 点赞 1
  • 收藏
  • 分享
  • 文章举报
干啥啥不行下课散会 发布了10 篇原创文章 · 获赞 21 · 访问量 2950 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐