进行了验证码识别的操作成功得训练读取了文件进行预测以后
下面编写一个狗狗分类程序
图片属性均为227*227
将阿拉斯加犬、博美犬、贵宾犬、哈巴犬(狗?)、哈士奇各150张图片组成训练集(感觉训练集可能有点少了,可以之后增加),分别对应种类1、2、3、4、5,编号分别是0-150,151-300,301-450,451-600,601,750
编写了关于标签值狗狗种类对应的csv文件
其中用到了编写文件名的bat文件http://www.360doc.com/content/16/0723/10/5572937_577742312.shtml
不知道数据量足不足 可以先尝试一下:
#author MJY
import tensorflow as tf
import glob
import pandas as pd #涉及文件读取(csv)
import numpy as np
import os
tf.app.flags.DEFINE_integer("is_train", 2, "指定是否是训练模型,还是拿数据去预测")
FLAGS = tf.app.flags.FLAGS
#读取图片数据
def read_pic():
#1.构建文件名队列
#获取文件名列表,用global命令
file_names = glob.glob("./GenPics/*.jpg")
file_names_test = glob.glob("./test/*.jpg")
#print("file_name:\n", file_names)
#即可构建文件名队列
file_queue = tf.train.string_input_producer(file_names)
file_queue_test = tf.train.string_input_producer(file_names_test)
#2.读取与解码
#构造读图片的阅读器
reader = tf.WholeFileReader()
#读取阶段
filename, image = reader.read(file_queue)
filename_test, image_test = reader.read(file_queue_test)
#解码阶段
decoded = tf.image.decode_jpeg(image)
decoded_test = tf.image.decode_jpeg(image_test)
#更新形状,将图片形状确定下来以方便批处理
decoded.set_shape([227,227,3]) #高 宽 通道数
#print("decoded:\n",decoded)
decoded_test.set_shape([227,227,3])
#修改图片的类型 因为此时是unit8,但输入卷积层的数据必须是float32或者float64
image_cast = tf.cast(decoded, tf.float32)
image_cast_test = tf.cast(decoded_test, tf.float32)
#3.批处理
filename_batch, image_batch = tf.train.batch([filename, image_cast],batch_size=100, num_threads=2, capacity=100)
filename_batch_test, image_batch_test = tf.train.batch([filename_test, image_cast_test],batch_size=3, num_threads=1, capacity=3)
return filename_batch, image_batch,filename_batch_test, image_batch_test
#接下来解析csv文件,建立文件名和标签值的对应表格
#可以先在jupyter notebook上面实验 实验成功 运用float()
def parse_csv():
# 读取文件
csv_data = pd.read_csv("./Genpics/labels.csv", names=["file_num", "type"], index_col="file_num")
#创建空列表 遍历
labels = []
for label in csv_data["type"]:
float(label)
label = label - 1
labels.append(label)
csv_data["labels"] = labels
return csv_data
#至此 文件名和标签对应的列表生成完毕
#生成用于测试的 文件名和标签名的对应表格
def parse_csv_test():
# 读取文件
csv_data_test = pd.read_csv("./test/labels.csv", names=["file_num", "type"], index_col="file_num")
#创建空列表 遍历
labels_test = []
for label_test in csv_data_test["type"]:
float(label_test)
label_test = label_test - 1
labels_test.append(label_test)
csv_data_test["labels_test"] = labels_test
return csv_data_test
#至此 用于测试的文件名和标签对应的列表生成完毕
#将文件名与csv_data一一对应通过文件名查表
def filename2label(filename, csv_data):
labels = []
for file_name in filename:
#filter方法判断是否是数字
file_num = "".join(list(filter(str.isdigit, str(file_name))))
#查表
target = csv_data.loc[int(file_num), "labels"]
labels.append(target)
#print("labels:\n", labels)
return np.array(labels)
#用于测试的————将文件名与csv_data_test一一对应通过文件名查表
def filename2label_test(filename_test, csv_data_test):
labels_test = []
for file_name in filename_test:
#filter方法判断是否是数字
file_num = "".join(list(filter(str.isdigit, str(file_name))))
#查表
target_test = csv_data_test.loc[int(file_num), "labels_test"]
labels_test.append(target_test)
#print("labels:\n", labels)
return np.array(labels_test)
#定义权重生成器
def create_weights(shape):
return tf.Variable(initial_value=tf.random_normal(shape=shape,stddev=0.001))
#构建卷积神经网络,得到y_predict
def create_model(x):
#x的形状为[None,227,227,3]
# 1)第一个卷积大层
with tf.variable_scope("conv1"):
# 卷积层
# 定义filter和偏置
conv1_weights = create_weights(shape=[5, 5, 3, 32])
conv1_bias = create_weights(shape=[32])
conv1_x = tf.nn.conv2d(input=x, filter=conv1_weights, strides=[1, 1, 1, 1], padding="SAME") + conv1_bias
# 激活层
relu1_x = tf.nn.relu(conv1_x)
# 池化层....5
pool1_x = tf.nn.max_pool(value=relu1_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
# 2)第二个卷积大层
with tf.variable_scope("conv2"):
# x的形状为[None,114,114,32],卷积向下取整,池化向上取整
# 卷积层
# 定义filter和偏置
conv2_weights = create_weights(shape=[5, 5, 32, 64])
conv2_bias = create_weights(shape=[64])
conv2_x = tf.nn.conv2d(input=pool1_x, filter=conv2_weights, strides=[1, 1, 1, 1], padding="SAME") + conv2_bias
# 激活层
relu2_x = tf.nn.relu(conv2_x)
# 池化层
pool2_x = tf.nn.max_pool(value=relu2_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
# 3)全连接层
# x的形状为[None,57,57,64]
with tf.variable_scope("full_connection"):
# 首先做形状修改
# [None, 57, 57, 64] - ------>[None, 57 * 57 * 64]
# [None, 57 * 57 * 64] * [] = [None, 5] 所以权重为[57 * 57 * 64, 5]
x_fc = tf.reshape(pool2_x, shape=[-1,57 * 57 * 64]) # 注意reshape没有None的用法 需要用-1
weights_fc = create_weights(shape=[57 * 57 * 64, 5])
bias_fc = create_weights(shape=[5])
y_predict = tf.matmul(x_fc, weights_fc) + bias_fc
return y_predict
if __name__ == "__main__":
filename, image, filename_test, image_test = read_pic()
csv_data = parse_csv()
csv_data_test = parse_csv_test()
#1.准备数据
x = tf.placeholder(tf.float32, shape=[None,227,227,3])
y_true = tf.placeholder(tf.float32, shape=[None,5]) #因为计算损失的时候需要一维
#2.构建模型
y_predict = create_model(x)
#3.构造损失函数
loss_list = tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict)
loss = tf.reduce_mean(loss_list)
#4.优化损失
optimizer = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(loss)
#5.准确率计算
with tf.variable_scope("accuracy"):
#训练集准确率计算
#1)比较预测值和真实值最大值所在位置,tf.argmax表示按行返回最大值的索引
equal_list=tf.equal(tf.arg_max(y_true,1),tf.arg_max(y_predict,1))
#2)将布尔值转换为浮点数,求平均,即为准确率
accuracy=tf.reduce_mean(tf.cast(equal_list,tf.float32))
#初始化变量
init = tf.global_variables_initializer()
#(2)收集要显示的变量
#先收集损失和准确率
tf.summary.scalar("losses", loss)
tf.summary.scalar("accuracy",accuracy)
#(3)合并所有变量op
merged = tf.summary.merge_all()
#创建模型保存与加载
saver = tf.train.Saver()
#开启会话
with tf.Session() as sess:
sess.run(init)
#开启线程
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
# (1)创建一个events文件实例
file_writer = tf.summary.FileWriter("./tmp/summary2/", graph=sess.graph)
# 加载模型
if os.path.exists("./tmp/modelckpt2/checkpoint"):
saver.restore(sess, "./tmp/modelckpt2/cnn_model") # 注意modelckpt2这个文件夹要自己建立
# 也就是说 模型保存和加载的时候 也就是saver.save或saver.restore的路径需要自己建立 否则会蓝屏
# 但是创建envents实例化的路径可以不用自己建立
if FLAGS.is_train == 1:
for i in range(1000):
filename_value, image_value = sess.run([filename, image])
# print("filename_value:\n", filename_value)
#print("image_value:\n", image_value)
labels = filename2label(filename_value, csv_data)
#print("labels:\n", labels)
# 将标签值转换为one-hot
labels_value = tf.reshape(tf.one_hot(labels, depth=5), [-1, 5]).eval()
#print("labels_value:\n", labels_value)
y_predict_value = sess.run(y_predict, feed_dict={x: image_value, y_true: labels_value})
#print("y_predict:\n", y_predict_value)
_, error, accuracy_value = sess.run([optimizer, loss, accuracy],
feed_dict={x: image_value, y_true: labels_value})
print("第%d次训练后损失为%f,准确率为%f" % (i + 1, error, accuracy_value))
# 运行合变量op,写入事件文件当中
summary = sess.run(merged, feed_dict={x: image_value, y_true: labels_value})
file_writer.add_summary(summary, i)
if i % 100 == 0:
saver.save(sess, "./tmp/modelckpt2/cnn_model")
else:
# 如果不是训练,则是用测试集对模型进行测试
for i in range(1):
filename_value_test, image_value_test = sess.run([filename_test, image_test])
labels_test = filename2label_test(filename_value_test, csv_data_test)
labels_value_test = tf.reshape(tf.one_hot(labels_test, depth=5), [-1, 5]).eval()
accuracy_value = sess.run(accuracy, feed_dict={x: image_value_test, y_true: labels_value_test})
#print("labels_value_test:\n", labels_value_test)
print("真实值为\n", labels_test)
y_predict_final_print = tf.reshape(y_predict, shape=[-1, 1, 5])
y_predict_final = tf.argmax(tf.reshape(y_predict, shape=[-1, 1, 5]), axis=2)
print("预测值为\n",
sess.run(y_predict_final, feed_dict={x: image_value_test, y_true: labels_value_test}))
print("准确率为:\n", accuracy_value)
#print("y_predict_final_print:\n", sess.run(y_predict_final_print, feed_dict={x: image_value_test, y_true: labels_value_test}))
#回收线程
coord.request_stop()
coord.join(threads)
样本太少效果不是特别好 先把样本做大 用到了图片增强程序使得每一种狗都含有6980张训练图片
其实没必要名称改为1 2 3 4 5 。。。只需要与csv文件对应好就可以