代码
1、首先下载数据集,存放于电脑E盘,图片路径path,e:flowers;
2、读取数据。将图片存放在data中,标签存放在label中
#读取图片 def read_img(path): #os.listdir(path)表示在path路径下的所有文件和和文件夹列表 #用cate记录五种花的文件路径 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))#im表示某张图片的路径 img=io.imread(im) img=transform.resize(img,(w,h))#图片resize为100*100 imgs.append(img) labels.append(idx) #不用array的原因是copy时不会占用新的内存 return np.asarray(imgs,np.float32),np.asarray(labels,np.int32)
12345678910111213141516'3、从每类花中选取部分图片可视化。设置要显示的每类花的数量show_num,获取每类花的总数量max_n。对每类花,随机生成show_num个在0,max_n-1之间的数据,表示在该类花中随机选择的图片。由于data中花是按顺序存放Dev,所以i类花的第j个花在data中的位置为i*max_n+j。调用matplotlib.pyplot显示图片。
#部分图片可视化,每种花分别选取show_num 张 ###1.每类花选择show_num张图片显示 ###2.获取每类花的数量max_n ###3.对每类花,随机生成show_num个在0,max_n-1之间的数据,表示该类花随机选择的图片 ###由于data中花是按顺序存放,i类花的第j个在data中的位置为i*max_n+j def show(data,label): show_num = 5 plt.figure() max_n = np.int(data.shape[0]/5) for i in range(show_num): a=[random.randint(0,max_n) for _ in range(show_num)] for j in range(show_num): plt.subplot(show_num,show_num,show_num*i+j+1) plt.imshow(data[a[j]+np.int(max_n*i)-1]) plt.axis('off') plt.show()
12345678910111213141516'结果:
4、将所有图片归一化为100×100×3,打乱顺序后,选取60%作为训练集,20%为验证集,20%作为测试集。
训练集:用来训练网络参数,使得模型能够拟合数据。
验证集:调整超参数,防止模型发生过拟合,从而决定训练的结束。
测试集:用来测试模型的泛华能力,检查模型是否能很好的拟合训练过程中没有出现过的新数据,以此反应模型的真实能力。
#打乱顺序 ###调用np.random.shuffle函数将有序数组变无序 ###返回打乱顺序后的图片和对应的标签 def disturb(data,lable): num_example=data.shape[0] arr=np.arange(num_example) np.random.shuffle(arr) img=data[arr] labels=label[arr] return img,labels #将所有数据分为训练集和验证集测试集 def allocate(data,label): inter1 = 0.6 inter2 = 0.8 num_example = data.shape[0] s1 = np.int(num_example*inter1) s2 = np.int(num_example*inter2) x_train = data[:s1] y_train = label[:s1] x_val = data[s1:s2] y_val = label[s1:s2] x_test = data[s2:] y_test = label[s2:] return x_train,y_train,x_val,y_val,x_test,y_test
123456789101112131415161718192021222324'5、构建CNN卷积网络,下图为CNN网络图。输入为100×100,3个通道的图像;
第一层:Convolution5×5的卷积核32个,步幅为2,max_pooling卷积核2×2,Relu激活函数后,后输出第一层tensor为50×50×32。
第二层:Convolution 5×5的卷积核64个,步幅为2,max_pooling卷积核2×2,Relu激活函数后输出tensor为25×25×64
第三层:Convolution3×3的卷积核128个,步幅为2,max_pooling卷积核2×2,Relu激活函数后输出tensor为12×12×128
第四层:Convolution3×3的卷积核128个,步幅为2,max_pooling卷积核2×2,Relu激活函数后输出tensor为6×6×128
进入全连接层
第一层全连接层:1024维,将第四层输出的6×6×128tensor连接成为一个一维向量,作为该层的输入。
第二层全连接层:512维
第三层全连接层:5维
Softmax层:输出为5,即属于五类花中每类花的概率。
在训练时,从数据集中按批次取数据,设置的大小为64,训练次数分别设置为10次和20次,得到测试结果。
#-----------------构建网络---------------------- def Network(): #占位符 #第一个卷积层(100——>50) conv1=tf.layers.conv2d( inputs=x, filters=32, kernel_size=[5, 5], padding="same", activation=tf.nn.relu, kernel_initializer=tf.truncated_normal_initializer(stddev=0.01)) pool1=tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2) #第二个卷积层(50->25) conv2=tf.layers.conv2d( inputs=pool1, filters=64, kernel_size=[5, 5], padding="same", activation=tf.nn.relu, kernel_initializer=tf.truncated_normal_initializer(stddev=0.01)) pool2=tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2) #第三个卷积层(25->12) conv3=tf.layers.conv2d( inputs=pool2, filters=128, kernel_size=[3, 3], padding="same", activation=tf.nn.relu, kernel_initializer=tf.truncated_normal_initializer(stddev=0.01)) pool3=tf.layers.max_pooling2d(inputs=conv3, pool_size=[2, 2], strides=2) #第四个卷积层(12->6) conv4=tf.layers.conv2d( inputs=pool3, filters=128, kernel_size=[3, 3], padding="same", activation=tf.nn.relu, kernel_initializer=tf.truncated_normal_initializer(stddev=0.01)) pool4=tf.layers.max_pooling2d(inputs=conv4, pool_size=[2, 2], strides=2) re1 = tf.reshape(pool4, [-1, 6 * 6 * 128]) #全连接层 dense1 = tf.layers.dense(inputs=re1, units=1024, activation=tf.nn.relu, kernel_initializer=tf.truncated_normal_initializer(stddev=0.01), kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003)) dense2= tf.layers.dense(inputs=dense1, units=512, activation=tf.nn.relu, kernel_initializer=tf.truncated_normal_initializer(stddev=0.01), kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003)) logits= tf.layers.dense(inputs=dense2, units=5, activation=None, kernel_initializer=tf.truncated_normal_initializer(stddev=0.01), kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003)) return logits
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556576、训练模型,将训练好的模型保存在modle.ckpt中。
#训练和测试数据,可将n_epoch设置更大一些 def train(x_train,y_train,x_val,y_val,train_op,loss,acc): n_epoch=10 batch_size=64 # 用于保存和载入模型 saver = tf.train.Saver(max_to_keep=1) sess=tf.InteractiveSession() sess.run(tf.global_variables_initializer()) #保存训练过程中训练损失和训练集的正确率 Train_loss= np.zeros(n_epoch) Train_acc = np.zeros(n_epoch) #保存训练过程中验证损失和验证集的正确率 Val_loss= np.zeros(n_epoch) Val_acc = np.zeros(n_epoch) 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('epoch',epoch+1) Train_loss[epoch] = train_loss/ n_batch Train_acc[epoch] = train_acc/ n_batch print(" train loss: %f" % Train_loss[epoch]) print(" train acc: %f" % Train_acc[epoch]) #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 Val_loss[epoch] = val_loss/ n_batch Val_acc[epoch] = val_acc/ n_batch print(" validation loss: %f" % Val_loss[epoch]) print(" validation acc: %f" % Val_acc[epoch]) N = [i+1 for i in range(n_epoch)] saver.save(sess,modle_path) sess.close() return Train_loss,Train_acc,Val_loss,Val_acc,N
12345678910111213141516171819202122232425262728293031323334353637383940414243'最终训练10次时训练集正确率达到58.82%,下图为训练损失、训练正确率、验证损失和验证集正确率随训练次数的变化。
7、测试模型。载入训练好的模型,读取模型参数,将测试集数据传人网络得到输出,输出与正确标签对比获得测试集正确率。
def test(x_test,y_test): with tf.Session() as sess: saver = tf.train.import_meta_graph('E:/flowers/modle.ckpt.meta') saver.restore(sess,tf.train.latest_checkpoint('E:/flowers/')) #获取默认系统图 graph = tf.get_default_graph() x = graph.get_tensor_by_name("x:0") feed_dict = {x:x_test} logits = graph.get_tensor_by_name("logits_eval:0") #得到预测结果 classification_result = sess.run(logits,feed_dict) #根据索引通过字典对应花的分类 output = [] output = tf.argmax(classification_result,1).eval() print(output) Real = tf.equal(output,y_test).tolist.count(True) test_acc = Real / x_test.shape[0] return test_acc
123456789101112131415161718'8、预测花朵类别。读取训练好的模型,输入待测试图片,最终输出花朵种类。本文从网上一共找了10张图片进行测试。
# -*- coding: utf-8 -*- import matplotlib.pyplot as plt import numpy as np import tensorflow as tf from skimage import io,transform def predict(img): with tf.Session() as sess: saver = tf.train.import_meta_graph('E:/flowers/modle.ckpt.meta') saver.restore(sess,tf.train.latest_checkpoint('E:/flowers/')) graph = tf.get_default_graph() x = graph.get_tensor_by_name("x:0") feed_dict = {x:img} logits = graph.get_tensor_by_name("logits_eval:0") #得到预测结果 classification_result = sess.run(logits,feed_dict) output = tf.argmax(classification_result,1).eval() return output imgs = [] for i in range(1,10): img = io.imread('e:/test/'+str(i)+'.jpg') img = transform.resize(img,(100,100)) imgs.append(img) imgs = np.asarray(imgs,np.float32) output = predict(imgs) #acc = test(x_test,y_test) class_flower = ["daisy","dandelion","rose","sunflowers","tulips"] plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus'] = False print('预测结果:',output) for i in range(9): plt.figure(i+1) img = io.imread('e:/test/'+str(i+1)+'.jpg') plt.imshow(img) plt.xlabel('预测结果为:'+class_flower[output[i]])
12345678910111213141516171819202122232425262728293031323334结果:
相关知识
“花朵分类“ 手把手搭建【卷积神经网络】
使用PyTorch实现对花朵的分类
第10章 项目:多类花朵分类
转移学习:使用VGGNet对花朵图像进行分类
机器学习花朵图像分类
室内花架如何摆放花朵 室内花架分类有哪些
Pytorch之AlexNet花朵分类
使用TensorFlow给花朵分类
百合分类
桂花分类
网址: python+Tensorflow+CNN花朵分类 https://m.huajiangbk.com/newsview343192.html
上一篇: 婚礼森系主题婚礼花门 森系婚礼主 |
下一篇: 桂花的象征意义与寓意(桂花的芬芳 |