概述
数据集来自51-CTO唐宇迪老师的“tensorflow入门视频教程”
内有500张猫和500张狗的图片(大小不一),我将它们全部放到一个文件夹里,前500张为猫,后500张为狗。
关于模型的保存和读取,这个博客讲的非常好:一份快速完整的Tensorflow模型保存和恢复教程(译)
代码:
import tensorflow as tf
import numpy as np
import cv2
import random
import os
def get_batch(batch_size=32,image_size=64,class_size=2):
x=[]
y=[]
all_image=os.listdir('./training_data')#返回指定的文件夹包含的文件或文件夹的名字的列表
for i in range(batch_size):
random_file=random.randint(0,999)
image=cv2.imread('./training_data/'+all_image[random_file])#我把猫狗图片放在一个文件夹里了,前500张是猫,后500张是狗
image=cv2.resize(image,(image_size,image_size),0,0,cv2.INTER_LINEAR)
image=image.astype(np.float32)#image原来是float64
image=image/255.0
lable=np.zeros(class_size)
if(random_file<500):
lable[0]=1.0
else:
lable[1]=1.0
x.append(image)
y.append(lable)
x=np.array(x)
y=np.array(y)
return x,y
def creat_conv_layer(input,filter_size1, filter_size2, filter_size3, filter_num):
w=tf.Variable(tf.truncated_normal(shape=[filter_size1, filter_size2, filter_size3, filter_num],stddev=0.05))
b=tf.Variable(tf.constant(0.05,shape=[filter_num]))
conv=tf.nn.conv2d(input=input,filter=w,strides=[1,1,1,1],padding='SAME')+b
conv=tf.nn.relu(conv)
conv=tf.nn.max_pool(conv,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#conv=tf.nn.dropout(conv,keep_prob)
return conv
def full_connect_layer(input, w_fc_shape1, w_fc_shape2, w_fc_shape3, unit_num, class_size, keep_prob=0.5):
w_fc = tf.Variable(tf.truncated_normal(shape=[w_fc_shape1*w_fc_shape2*w_fc_shape3, unit_num], stddev=0.05))
b_fc = tf.Variable(tf.constant(0.05, shape=[unit_num]))
input_flat = tf.reshape(input,[-1,w_fc_shape1*w_fc_shape2*w_fc_shape3])
fc=tf.matmul(input_flat,w_fc)+b_fc
fc=tf.nn.dropout(fc,keep_prob)
fc=tf.nn.relu(fc)
w=tf.Variable(tf.truncated_normal(shape=[unit_num, class_size], stddev=0.05))
b=tf.Variable(tf.constant(0.05, shape=[class_size]))
y_predic=tf.matmul(fc,w)+b
return y_predic
def train():
X = tf.placeholder(tf.float32, [None, 64, 64, 3], name='X')#命名好的变量(用于test读取)需放到函数里,放到外边test时会报错
Y = tf.placeholder(tf.float32, [None, 2], name='Y') #我的理解是在test时已经读取了,而全局上又有一个相同的变量,会导致
keep_prob = tf.placeholder(tf.float32, name='keep_prob') #变量重定义
conv1=creat_conv_layer(X,3,3,3,32)
conv2=creat_conv_layer(conv1,3,3,32,32)
conv3=creat_conv_layer(conv2,3,3,32,64)
y_predic=full_connect_layer(conv3,8,8,64,1024,2,keep_prob)
y_sofmax = tf.nn.softmax(y_predic)#对结果softmax得到该图像是猫的概率以及是狗的概率
y_ped_cls = tf.argmax(y_sofmax, 1,name='prediction')#取概率最大的作为预测结果
#是猫结果是0,是狗结果是1
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y_predic,labels=Y))
opt=tf.train.AdamOptimizer(learning_rate=0.0001).minimize(loss)
#之前学习率设为0.01,然后精确度就一直停在50%左右,每个batch总是全预测猫或全是狗,推测是学习率太大,而分类就两个,导致模型在更新的时候容易从一个极端跳到另一个极端,故减小了学习率,精确度就上升了。
correct_prediction=tf.equal(y_ped_cls,tf.argmax(Y,1))#这两步为一个batch的预测值与实际值进行比较,得到精确度。
accuracy=tf.reduce_mean(tf.cast(correct_prediction,'float'))
saver=tf.train.Saver(max_to_keep=1)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
#saver.restore(sess, tf.train.latest_checkpoint('./self_study_model/'))#由于在训练的时候就已经创建了网络模型,再训练只要恢复参数即可
#将sess.run注释,saver.restore打开可以实现模型再训练
batch_size=32
for step in range(6000):#迭代6000次
x_batch,y_batch=get_batch(batch_size,image_size=64,class_size=2)
_,train_loss,acc,prediction,lable=sess.run([opt,loss,accuracy,y_ped_cls,tf.argmax(Y,1)],feed_dict={X:x_batch,Y:y_batch,keep_prob:0.5})
print('step=',step,' prediction',prediction,' Y=',lable)
if (step+1)%10==0:
print(' acc=',acc,
' loss=',train_loss)
if acc>=1.0:
break
saver.save(sess, './self_study_model/my_model.ckpt')
print('模型更新了')
def get_test_data(index=0,image_size=64):
x=[]
all_image = os.listdir('./testing_data/dogs')
random_file = index
image = cv2.imread('./testing_data/dogs/' + all_image[random_file])
image = cv2.resize(image, (image_size, image_size), 0, 0, cv2.INTER_LINEAR)
image = image.astype(np.float32) # image原来是float64
image = image / 255.0
x.append(image)
x=np.array(x)
return x
def test():
sess=tf.Session()
saver=tf.train.import_meta_graph('./self_study_model/my_model.ckpt.meta')#读取网络模型
saver.restore(sess,'./self_study_model/my_model.ckpt')#读取模型里的各种参数
graph=tf.get_default_graph()
X=graph.get_tensor_by_name("X:0")#之前对变量命名在这可以用其名字调出
Y=graph.get_tensor_by_name("Y:0")#占位符一定要全部命名,因为测试时feed_dict需要用到所有的占位符
keep_prob=graph.get_tensor_by_name("keep_prob:0")
prediction=graph.get_tensor_by_name("prediction:0")
image=get_test_data(index=100)
image_prdic=np.zeros((1,2))
feed_dict={X:image,Y:image_prdic,keep_prob:0.5}
result=sess.run(prediction,feed_dict=feed_dict)
classes = ['cat', 'dog']
print(classes[result[0]])
#训练模型
train()
# #step= 1409 acc= 1.0 loss= 0.18543181
#读取模型进行测试
#test()
这份代码可以实现模型的训练,保存,读取(可用于再训练以及测试)。
测试方面,每次可以测试一张图片,判断猫狗,具体精度没测(模型训练时可以在1400步左右精度达到100%),但实际效果还可以。
最后
以上就是彪壮胡萝卜为你收集整理的tensorflow 猫狗识别(卷积神经网络CNN)的全部内容,希望文章能够帮你解决tensorflow 猫狗识别(卷积神经网络CNN)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复