吳裕雄 python 神經網絡——TensorFlow 卷積神經網絡水果圖片識別


#-*- 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")

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM