#-*- coding:utf-8 -*- import time import keras import skimage import numpy as np import tensorflow as tf import matplotlib.image as img from scipy import ndimage from skimage import color, data, transform %matplotlib inline
#設置文件目錄 Training = r'F:\\data\\fruits-360\\Training' Test = r'F:\\data\\fruits-360\\Test'
import os from natsort import natsorted #獲取每類水果中的第五張圖像 def load_print_img(root): print_img = [] print_label = [] #遍歷水果種類目錄 for i in range(len(os.listdir(root))): child1 = os.listdir(root)[i] child2 = os.listdir(os.path.join(root, child1)) #對第二層目錄進行自然數排序,os.listder默認為str排序 child2 = natsorted(child2) #取出每類的第五張圖像 path = os.path.join(root, child1, child2[4]) if(path.endswith('.jpg')): print_img.append(skimage.data.imread(path)) print_label.append(child1) return print_img, print_label print_img, print_label = load_print_img(Test) print(np.shape(print_img)) print(np.shape(print_label)) print(print_label) print(print_img)
import matplotlib.pyplot as plt from IPython.core.pylabtools import figsize #打印每類水果的第五張圖像 def print_fruit(print_img, print_label, size) : plt.figure(figsize(size, size)) for i in range(len(print_img)): #圖像輸出格式為11行10列 plt.subplot(11, 10,(i+1)) #打印圖像 plt.imshow(print_img[i]) #打印水果種類 plt.title(format(print_label[i])) plt.axis('off') plt.show() print_img, print_label = load_print_img(Test) #打印水果 print_fruit(print_img, print_label, 15)
import random #隨機獲取水果種類 def get_random_fruits(root, n_classes): #創建一個1到水果種類總數的list fruits = [] for i in range(len(os.listdir(root))): fruits.append(i) #隨機獲取n_classes個隨機不重復的水果種類 random_fruits = random.sample(fruits, n_classes) return random_fruits
#獲取隨機抽取的10類水果的圖像 def load(root, random_fruits): #存放圖像 image_data = [] #存放標簽 image_label = [] #存放圖像標簽碼 num_label = [] #遍歷水果類型 for i in range(len(random_fruits)): #第一層子目錄(水果種類) child1 = os.listdir(root)[i] #第二層子目錄(水果圖像) child2 = os.listdir(os.path.join(root, child1)) #對第二層目錄進行自然數排序,os.listder默認為str排序 child2 = natsorted(child2) #遍歷水果圖像 for j in range(len(child2)): #結合第一二層子目錄 path = os.path.join(root, child1, child2[j]) #只讀取'.jpg'文件(文件后綴是否為'.jpg') if(path.endswith('.jpg')): #把文件讀取為圖像存入image_data image_data.append(skimage.data.imread(path)) #儲存第一層子目錄文件名(即水果名) image_label.append(child1) #把第一層子目錄文件名的下標作為水果類型的編碼 num_label.append(i) #把水果類型編碼轉換為one_hot編碼 num_label = keras.utils.to_categorical(num_label, len(random_fruits)) #print("圖片數:{0}, 標簽數:{1}".format(len(image_data), len(os.listdir(root))) #輸出圖片和標簽數 return image_data, image_label, num_label
#裁剪圖像 def crop(image_data): crop_data = [] for i in image_data: #把圖像轉換成32*32的格式 I_crop = skimage.transform.resize(i, (32, 32)) #把轉換后的圖像放入Icrop_data crop_data.append(I_crop) return crop_data
def fruits_type(random_fruits): print('fruits_type:') for i in random_fruits: print(os.listdir(Training)[i])
#定義水果種類數 n_classes = 10 #batch_size = 256 #定義塊的大小 #batch_num = int(np.array(crop_img).shape[0]/batch_size) #計算取塊的次數 #申請四維占位符,數據類型為float32 x = tf.placeholder(tf.float32,[None, 32, 32, 3]) #申請二維占位符,數據累型為float32 y = tf.placeholder(tf.float32,[None, n_classes]) #申請一維占位符,數據類型為float32 keep_prob = tf.placeholder(tf.float32) #epochs=2 #訓練次數 #每個神經元保留的概率 dropout=0.75 #卷積核大小 k_size = 3 Weights = { "conv_w1" : tf.Variable(tf.random_normal([k_size, k_size, 3, 64]), name = 'conv_w1'), "conv_w2" : tf.Variable(tf.random_normal([k_size, k_size, 64, 128]), name = 'conv_w2'), #"conv_w3" : tf.Variable(tf.random_normal([k_size, k_size, 256, 512]), name = 'conv_w3'), \ "den_w1" : tf.Variable(tf.random_normal([int(32*32/4/4*128), 1024]), name = 'dev_w1'), "den_w2" : tf.Variable(tf.random_normal([1024, 512]), name = 'den_w2'), "den_w3" : tf.Variable(tf.random_normal([512, n_classes]), name = 'den_w3') } bias = { "conv_b1" : tf.Variable(tf.random_normal([64]), name = 'conv_b1'), "conv_b2" : tf.Variable(tf.random_normal([128]), name = 'conv_b2'), #"conv_b3" : tf.Variable(tf.random_normal([512]), name = 'conv_b3'), \ "den_b1" : tf.Variable(tf.random_normal([1024]), name = 'den_b1'), "den_b2" : tf.Variable(tf.random_normal([512]), name = 'den_b2'), "den_b3" : tf.Variable(tf.random_normal([n_classes]), name = 'den_b3') } def conv2d(x,W,b,stride=1): x=tf.nn.conv2d(x,W,strides=[1,stride,stride,1],padding="SAME") x=tf.nn.bias_add(x,b) return tf.nn.relu(x) def maxpool2d(x,stride=2): return tf.nn.max_pool(x,ksize=[1,stride,stride,1],strides=[1,stride,stride,1],padding="SAME")
def conv_net(inputs, W, b, dropout): ## convolution layer 1 ## 輸入32*32*3的數據,輸出16*16*64的數據 conv1 = conv2d(x, W["conv_w1"], b["conv_b1"]) conv1 = maxpool2d(conv1, 2) tf.summary.histogram('ConvLayer1/Weights', W["conv_w1"]) tf.summary.histogram('ConvLayer1/bias', b["conv_b1"]) ## convolution layer2 ## 輸入16*16*64的數據,輸出8*8*128的數據 conv2 = conv2d(conv1, W["conv_w2"], b["conv_b2"]) conv2 = maxpool2d(conv2, 2) tf.summary.histogram('ConvLayer2/Weights', W["conv_w2"]) tf.summary.histogram('ConvLayer2/bias', b["conv_b2"]) ## convolution layer3 #conv3 = conv2d(conv2, W["conv_w3"], b["conv_b3"]) #conv3 = maxpool2d(conv3, 2) #tf.summary.histogram('ConvLayer3/Weights', W["conv_w3"]) #tf.summary.histogram('ConvLayer3/bias', b["conv_b3"]) ## flatten ## 把數據拉伸為長度為8*8*128的一維數據 flatten = tf.reshape(conv2,[-1, W["den_w1"].get_shape().as_list()[0]]) ## dense layer1 ## 輸入8192*1的數據,輸出1024*1的數據 den1 = tf.add(tf.matmul(flatten, W["den_w1"]), b["den_b1"]) den1 = tf.nn.relu(den1) den1 = tf.nn.dropout(den1, dropout) tf.summary.histogram('DenLayer1/Weights', W["den_w1"]) tf.summary.histogram('DenLayer1/bias', b["den_b1"]) ## dense layer2 ## 1024*1的數據,輸出512*1的數據 den2 = tf.add(tf.matmul(den1, W["den_w2"]), b["den_b2"]) den2 = tf.nn.relu(den2) den2 = tf.nn.dropout(den2, dropout) tf.summary.histogram('DenLayer2/Weights', W["den_w2"]) tf.summary.histogram('DenLayer2/bias', b["den_b2"]) ## out ## 512*1的數據,輸出n_classes*1的數據 out = tf.add(tf.matmul(den2, W["den_w3"]), b["den_b3"]) tf.summary.histogram('DenLayer3/Weights', W["den_w3"]) tf.summary.histogram('DenLayer3/bias', b["den_b3"]) return out
pred=conv_net(x,Weights,bias,keep_prob) cost=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred,labels=y)) tf.summary.histogram('loss', cost) optimizer=tf.train.AdamOptimizer(0.01).minimize(cost) correct_pred=tf.equal(tf.argmax(pred,1),tf.argmax(y,1)) accuracy=tf.reduce_mean(tf.cast(correct_pred,tf.float32)) merged=tf.summary.merge_all() def train_and_test(train_x, train_y, test_x, test_y, epochs, batch_size, times = 1) : # 初始化全局變量 init=tf.global_variables_initializer() start_time = time.time() with tf.Session() as sess: sess.run(init) # 把需要可視化的參數寫入可視化文件 writer=tf.summary.FileWriter('F:\\data\\fruits-360\\tensorboard\\Fruit_graph' + str(times), sess.graph) for i in range(epochs): batch_num = int(np.array(train_x).shape[0]/batch_size) sum_cost = 0 sum_acc = 0 for j in range(batch_num): batch_x = get_data(train_x, batch_size, j) batch_y = get_data(train_y, batch_size, j) sess.run(optimizer, feed_dict={x:batch_x,y:batch_y,keep_prob:0.75}) loss,acc = sess.run([cost,accuracy],feed_dict={x:batch_x,y:batch_y,keep_prob: 1.}) sum_cost += loss sum_acc += acc result=sess.run(merged,feed_dict={x:batch_x, y:batch_y, keep_prob:0.75}) writer.add_summary(result, i) arg_cost = sum_cost/batch_num arg_acc = sum_acc/batch_num print("Epoch:", '%04d' % (i+1),"cost=", "{:.9f}".format(arg_cost),"Training accuracy","{:.5f}".format(arg_acc)) end_time = time.time() print('Optimization Completed') print('Testing Accuracy:',sess.run(accuracy,feed_dict={x:test_x, y:test_y,keep_prob: 1})) print('Total processing time:',end_time - start_time) for i in range(10): random_fruits = get_random_fruits(Training, n_classes) img_data, img_label, num_label = load(Training, random_fruits) crop_img = crop(img_data) test_data, test_label, test_num_label = load(Test, random_fruits) crop_test = crop(test_data) print("TIMES"+str(i+1)) fruits_type(random_fruits) print("\n") train_and_test(crop_img, num_label, crop_test, test_num_label, 20, 26, (i+1)) print("\n\n\n")