<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    十.Tensorflow+Opencv實現CNN自定義圖像分類案例及與KNN對比

    VSole2021-11-17 21:53:33

    前一篇文章詳細講解了卷積神經網絡CNN原理,并通過TensorFlow編寫CNN實現了MNIST分類學習案例。本篇文章將通過Tensorflow和Opencv實現CNN自定義圖像分類案例,它能解決我們現實論文或實踐中的圖像分類問題,并與機器學習的圖像分類算法進行對比實驗。

    本專欄主要結合作者之前的博客、AI經驗和相關文章及論文介紹,后面隨著深入會講解更多的Python人工智能案例及應用。基礎性文章,希望對您有所幫助,如果文章中存在錯誤或不足之處,還請海涵。作者作為人工智能的菜鳥,希望大家能與我在這一筆一劃的博客中成長起來。寫了這么多年博客,嘗試第一個付費專欄,但更多博客尤其基礎性文章,還是會繼續免費分享,但該專欄也會用心撰寫,望對得起讀者,共勉!

    文章目錄:

    • 一.圖像分類
    • 二.基于KNN算法的圖像分類
    • 1.KNN算法
    • 2.數據集
    • 3.KNN圖像分類
    • 三.Tensorflow+Opencv實現CNN圖像分類
    • 1.OpenCV庫安裝
    • 2.讀取文件夾圖像
    • 3.搭建CNN
    • 4.定義損失函數和優化器
    • 5.模型訓練和預測
    • 6.完整代碼及實驗結果
    • 四.總結

    代碼下載地址(歡迎大家關注點贊):

    • https://github.com/eastmountyxz/
    • AI-for-TensorFlow
    • https://github.com/eastmountyxz/
    • AI-for-Keras
    學Python近八年,認識了很多大佬和朋友,感恩。作者的本意是幫助更多初學者入門,因此在github開源了所有代碼,也在公眾號同步更新。深知自己很菜,得拼命努力前行,編程也沒有什么捷徑,干就對了。希望未來能更透徹學習和撰寫文章,也能在讀博幾年里學會真正的獨立科研。同時非常感謝參考文獻中的大佬們的文章和分享。
    - https://blog.csdn.net/eastmount

    一.圖像分類

    圖像分類(Image Classification)是對圖像內容進行分類的問題,它利用計算機對圖像進行定量分析,把圖像或圖像中的區域劃分為若干個類別,以代替人的視覺判斷。圖像分類的傳統方法是特征描述及檢測,這類傳統方法可能對于一些簡單的圖像分類是有效的,但由于實際情況非常復雜,傳統的分類方法不堪重負。現在,廣泛使用機器學習和深度學習的方法來處理圖像分類問題,其主要任務是給定一堆輸入圖片,將其指派到一個已知的混合類別中的某個標簽。

    在下圖中,圖像分類模型將獲取單個圖像,并將為4個標簽{cat,dog,hat,mug},分別對應概率{0.6, 0.3, 0.05, 0.05},其中0.6表示圖像標簽為貓的概率,其余類比。該圖像被表示為一個三維數組。在這個例子中,貓的圖像寬度為248像素,高度為400像素,并具有紅綠藍三個顏色通道(通常稱為RGB)。因此,圖像由248×400×3個數字組成或總共297600個數字,每個數字是一個從0(黑色)到255(白色)的整數。圖像分類的任務是將這接近30萬個數字變成一個單一的標簽,如“貓(cat)”。

    那么,如何編寫一個圖像分類的算法呢?

    又怎么從眾多圖像中識別出貓呢?這里所采取的方法和教育小孩看圖識物類似,給出很多圖像數據,讓模型不斷去學習每個類的特征。在訓練之前,首先需要對訓練集的圖像進行分類標注,如圖所示,包括cat、dog、mug和hat四類。在實際工程中,可能有成千上萬類別的物體,每個類別都會有上百萬張圖像。

    圖像分類是輸入一堆圖像的像素值數組,然后給它分配一個分類標簽,通過訓練學習來建立算法模型,接著使用該模型進行圖像分類預測,具體流程如下:

    • 輸入: 輸入包含N個圖像的集合,每個圖像的標簽是K種分類標簽中的一種,這個集合稱為訓練集。
    • 學習: 第二步任務是使用訓練集來學習每個類的特征,構建訓練分類器或者分類模型。
    • 評價: 通過分類器來預測新輸入圖像的分類標簽,并以此來評價分類器的質量。通過分類器預測的標簽和圖像真正的分類標簽對比,從而評價分類算法的好壞。如果分類器預測的分類標簽和圖像真正的分類標簽一致,表示預測正確,否則預測錯誤。

    常見的分類算法包括樸素貝葉斯分類器、決策樹、K最近鄰分類算法、支持向量機、神經網絡和基于規則的分類算法等,同時還有用于組合單一類方法的集成學習算法,如Bagging和Boosting等。

    二.基于KNN算法的圖像分類

    1.KNN算法

    K最近鄰分類(K-Nearest Neighbor Classifier)算法是一種基于實例的分類方法,是數據挖掘分類技術中最簡單常用的方法之一。該算法的核心思想是從訓練樣本中尋找所有訓練樣本X中與測試樣本距離(歐氏距離)最近的前K個樣本(作為相似度),再選擇與待分類樣本距離最小的K個樣本作為X的K個最鄰近,并檢測這K個樣本大部分屬于哪一類樣本,則認為這個測試樣本類別屬于這一類樣本。

    假設現在需要判斷下圖中的圓形圖案屬于三角形還是正方形類別,采用KNN算法分析如下:

    • 當K=3時,圖中第一個圈包含了三個圖形,其中三角形2個,正方形一個,該圓的則分類結果為三角形。
    • 當K=5時,第二個圈中包含了5個圖形,三角形2個,正方形3個,則以3:2的投票結果預測圓為正方形類標。設置不同的K值,可能預測得到不同的結果。

    簡而言之,一個樣本與數據集中的k個最相鄰樣本中的大多數的類別相同。由其思想可以看出,KNN是通過測量不同特征值之間的距離進行分類,而且在決策樣本類別時,只參考樣本周圍k個“鄰居”樣本的所屬類別。因此比較適合處理樣本集存在較多重疊的場景,主要用于預測分析、文本分類、降維等處理。

    KNN在Sklearn機器學習包中,實現的類如下,簡稱KNN算法。構造方法為:

    • neighbors.KNeighborsClassifier
    KNeighborsClassifier(algorithm='ball_tree', 
        leaf_size=30, 
        metric='minkowski',
        metric_params=None, 
        n_jobs=1, 
        n_neighbors=3, 
        p=2, 
        weights='uniform')
    

    KNeighborsClassifier可以設置3種算法:brute、kd_tree、ball_tree,設置K值參數為n_neighbors=3。調用方法如下:

    • from sklearn.neighbors import KNeighborsClassifier
    • knn = KNeighborsClassifier(n_neighbors=3, algorithm=“ball_tree”)

    它包括兩個步驟:

    • 訓練:nbrs.fit(data, target)
    • 預測:pre = clf.predict(data)

    2.數據集

    該部分主要使用Scikit-Learn包進行Python圖像分類處理。Scikit-Learn擴展包是用于Python數據挖掘和數據分析的經典、實用擴展包,通常縮寫為Sklearn。Scikit-Learn中的機器學習模型是非常豐富的,包括線性回歸、決策樹、SVM、KMeans、KNN、PCA等等,用戶可以根據具體分析問題的類型選擇該擴展包的合適模型,從而進行數據分析,其安裝過程主要通過“pip install scikit-learn”實現。

    實驗所采用的數據集為Sort_1000pics數據集,該數據集包含了1000張圖片,總共分為10大類,分別是人(第0類)、沙灘(第1類)、建筑(第2類)、大卡車(第3類)、恐龍(第4類)、大象(第5類)、花朵(第6類)、馬(第7類)、山峰(第8類)和食品(第9類),每類100張。如圖所示。

    接著將所有各類圖像按照對應的類標劃分至“0”至“9”命名的文件夾中,如圖所示,每個文件夾中均包含了100張圖像,對應同一類別。

    比如,文件夾名稱為“6”中包含了100張花的圖像,如下圖所示。


    3.KNN圖像分類

    下面是調用KNN算法進行圖像分類的完整代碼,它將1000張圖像按照訓練集為70%,測試集為30%的比例隨機劃分,再獲取每張圖像的像素直方圖,根據像素的特征分布情況進行圖像分類分析。

    KNeighborsClassifier()核心代碼如下:

    • from sklearn.neighbors import KNeighborsClassifier
    • clf = KNeighborsClassifier(n_neighbors=11).fit(XX_train, y_train)
    • predictions_labels = clf.predict(XX_test)

    完整代碼及注釋如下:

    # -*- coding: utf-8 -*-
    import os
    import cv2
    import numpy as np
    from sklearn.cross_validation import train_test_split
    from sklearn.metrics import confusion_matrix, classification_report
    #----------------------------------------------------------------------------------
    # 第一步 切分訓練集和測試集
    #----------------------------------------------------------------------------------
    X = [] #定義圖像名稱
    Y = [] #定義圖像分類類標
    Z = [] #定義圖像像素
    for i in range(0, 10):
        #遍歷文件夾,讀取圖片
        for f in os.listdir("photo/%s" % i):
            #獲取圖像名稱
            X.append("photo//" +str(i) + "http://" + str(f))
            #獲取圖像類標即為文件夾名稱
            Y.append(i)
    X = np.array(X)
    Y = np.array(Y)
    #隨機率為100% 選取其中的30%作為測試集
    X_train, X_test, y_train, y_test = train_test_split(X, Y,
                                                        test_size=0.3, random_state=1)
    print len(X_train), len(X_test), len(y_train), len(y_test)
    #----------------------------------------------------------------------------------
    # 第二步 圖像讀取及轉換為像素直方圖
    #----------------------------------------------------------------------------------
    #訓練集
    XX_train = []
    for i in X_train:
        #讀取圖像
        #print i
        image = cv2.imread(i)
        
        #圖像像素大小一致
        img = cv2.resize(image, (256,256),
                         interpolation=cv2.INTER_CUBIC)
        #計算圖像直方圖并存儲至X數組
        hist = cv2.calcHist([img], [0,1], None,
                                [256,256], [0.0,255.0,0.0,255.0])
        XX_train.append(((hist/255).flatten()))
    #測試集
    XX_test = []
    for i in X_test:
        #讀取圖像
        #print i
        image = cv2.imread(i)
        
        #圖像像素大小一致
        img = cv2.resize(image, (256,256),
                         interpolation=cv2.INTER_CUBIC)
        #計算圖像直方圖并存儲至X數組
        hist = cv2.calcHist([img], [0,1], None,
                                [256,256], [0.0,255.0,0.0,255.0])
        XX_test.append(((hist/255).flatten()))
    #----------------------------------------------------------------------------------
    # 第三步 基于KNN的圖像分類處理
    #----------------------------------------------------------------------------------
    from sklearn.neighbors import KNeighborsClassifier
    clf = KNeighborsClassifier(n_neighbors=11).fit(XX_train, y_train)
    predictions_labels = clf.predict(XX_test)
    print u'預測結果:'
    print predictions_labels
    print u'算法評價:'
    print (classification_report(y_test, predictions_labels))
    #輸出前10張圖片及預測結果
    k = 0
    while k<10:
        #讀取圖像
        print X_test[k]
        image = cv2.imread(X_test[k])
        print predictions_labels[k]
        #顯示圖像
        cv2.imshow("img", image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        k = k + 1
    

    代碼中對預測集的前十張圖像進行了顯示,其中“818.jpg”圖像如圖所示,其分類預測的類標結果為“8”,表示第8類山峰,預測結果正確。

    下圖展示了“452.jpg”圖像,其分類預測的類標結果為“4”,表示第4類恐龍,預測結果正確。

    下圖展示了“507.jpg”圖像,其分類預測的類標結果為“7”,錯誤地預測為第7類恐龍,其真實結果應該是第5類大象。

    使用KNN算法進行圖像分類實驗,最后算法評價的準確率(Precision)、召回率(Recall)和F值(F1-score)如圖所示,其中平均準確率為0.64,平均召回率為0.55,平均F值為0.50,其結果不是非常理想。

    那么,如果采用CNN卷積神經網絡進行分類,通過不斷學習細節是否能提高準確度呢?


    三.Tensorflow實現CNN圖像分類

    首先,我們需要在TensorFlow環境下安裝OpenCV擴展包;其次需要通過TensorFlow環境搭建CNN神經網絡;最后通過不斷學實現圖像分類實驗。

    1.OpenCV庫安裝

    第一步,打開Anaconda程序,并選擇已經安裝好的“TensorFlow”環境,運行Spyder。

    第二步,我們需要在TensorFlow環境中安裝opencv-python擴展包,否則會提示錯誤“ModuleNotFoundError: No module named ‘cv2’”。調用Anaconda Prompt安裝即可,如下圖所示:

    activate tensorflow
    pip install opencv-python
    

    安裝成功如下圖所示。

    但是,由于anaconda的.org服務器在國外,下載速度很慢,提示錯誤“Anaconda An HTTP error occurred when trying to retrieve this URL.HTTP errors are often intermittent”。

    • 解決方法一:從國內清華的鏡像下載
    • 解決方法二:從PYPI網站下載對應版本的opencv-python,在再安裝本地下載的.whl文件。下載地址:
    • https://www.lfd.uci.edu/~gohlke/pythonlibs/#OpenCV

    由于第一種方法一直失敗,這里推薦讀者嘗試第二種方法,同時作者會將“opencv_python-4.1.2-cp36-cp36m-win_amd64.whl”文件上傳供大家直接使用。(4.1.2代表opencv的版本,cp36代表用的python3.6,并且是64位)。

    第三步,調用PIP安裝本地opencv擴展包。

    activate tensorflow
    pip install C:\Users\xiuzhang\Desktop\TensorFlow\opencv_python-4.1.2-cp36-cp36m-win_amd64.whl
    

    這種方法非常迅速,推薦大家使用。安裝成功之后,開始編寫我們的代碼吧!


    2.讀取文件夾圖像

    該部分具體步驟如下:

    • 定義函數read_img(),讀取文件夾“photo”中“0”到“9”的圖像
    • 調用cv2.imread()函數循環獲取每張圖片的所有像素值,并通過
    • cv2.resize()統一修改為32*32大小
    • 依次獲取圖像像素、圖像類標和圖像路徑名稱:fpaths, data, label = read_img(path)
    • 將圖像的順序隨機調整,并按照2-8比例劃分數據集,其中80%的數據用于訓練,20%的數據用于測試

    #---------------------------------第一步 讀取圖像-----------------------------------
    def read_img(path):
        cate = [path + x for x in os.listdir(path) if os.path.isdir(path + x)]
        imgs = []
        labels = []
        fpath = []
        for idx, folder in enumerate(cate):
            # 遍歷整個目錄判斷每個文件是不是符合
            for im in glob.glob(folder + '/*.jpg'):
                #print('reading the images:%s' % (im))
                img = cv2.imread(im)             #調用opencv庫讀取像素點
                img = cv2.resize(img, (32, 32))  #圖像像素大小一致
                imgs.append(img)                 #圖像數據
                labels.append(idx)               #圖像類標
                fpath.append(path+im)            #圖像路徑名
                #print(path+im, idx)
                
        return np.asarray(fpath, np.string_), np.asarray(imgs, np.float32), np.asarray(labels, np.int32)
    # 讀取圖像
    fpaths, data, label = read_img(path)
    print(data.shape)  # (1000, 256, 256, 3)
    # 計算有多少類圖片
    num_classes = len(set(label))
    print(num_classes)
    # 生成等差數列隨機調整圖像順序
    num_example = data.shape[0]
    arr = np.arange(num_example)
    np.random.shuffle(arr)
    data = data[arr]
    label = label[arr]
    fpaths = fpaths[arr]
    # 拆分訓練集和測試集 80%訓練集 20%測試集
    ratio = 0.8
    s = np.int(num_example * ratio)
    x_train = data[:s]
    y_train = label[:s]
    fpaths_train = fpaths[:s] 
    x_val = data[s:]
    y_val = label[s:]
    fpaths_test = fpaths[s:] 
    print(len(x_train),len(y_train),len(x_val),len(y_val)) #800 800 200 200
    print(y_val)
    

    3.搭建CNN

    該部分具體步驟如下:

    • 首先定義Placeholder,用于傳入輸入值,xs表示圖片32*32像素點,并且包含RGB三個圖層,故大小設置為32 * 32 * 3;ys表示每張圖片最終預測的類標值。
    • 調用tf.layers.conv2d()函數定義卷積層,包括20個卷積核,卷積核大小為5,激勵函數為Relu;調用tf.layers.max_pooling2d()函數定義池化處理,步長為2,縮小一倍。
    • 接著定義第二個卷積層和池化層,現共有conv0, pool0和conv1, pool1。
    • 通過tf.layers.dense()函數定義全連接層,轉換為長度為400的特征向量,加上DropOut防止過擬合。
    • 輸出層為logits,包括10個數字,最終預測結果為predicted_labels,即為tf.arg_max(logits, 1)。
    #---------------------------------第二步 建立神經網絡-----------------------------------
    # 定義Placeholder
    xs = tf.placeholder(tf.float32, [None, 32, 32, 3])  #每張圖片32*32*3個點
    ys = tf.placeholder(tf.int32, [None])               #每個樣本有1個輸出
    # 存放DropOut參數的容器 
    drop = tf.placeholder(tf.float32)                   #訓練時為0.25 測試時為0
    # 定義卷積層 conv0
    conv0 = tf.layers.conv2d(xs, 20, 5, activation=tf.nn.relu)    #20個卷積核 卷積核大小為5 Relu激活
    # 定義max-pooling層 pool0
    pool0 = tf.layers.max_pooling2d(conv0, [2, 2], [2, 2])        #pooling窗口為2x2 步長為2x2
    print("Layer0:", conv0, pool0)
     
    # 定義卷積層 conv1
    conv1 = tf.layers.conv2d(pool0, 40, 4, activation=tf.nn.relu) #40個卷積核 卷積核大小為4 Relu激活
    # 定義max-pooling層 pool1
    pool1 = tf.layers.max_pooling2d(conv1, [2, 2], [2, 2])        #pooling窗口為2x2 步長為2x2
    print("Layer1:", conv1, pool1)
    # 將3維特征轉換為1維向量
    flatten = tf.layers.flatten(pool1)
    # 全連接層 轉換為長度為400的特征向量
    fc = tf.layers.dense(flatten, 400, activation=tf.nn.relu)
    print("Layer2:", fc)
    # 加上DropOut防止過擬合
    dropout_fc = tf.layers.dropout(fc, drop)
    # 未激活的輸出層
    logits = tf.layers.dense(dropout_fc, num_classes)
    print("Output:", logits)
    # 定義輸出結果
    predicted_labels = tf.arg_max(logits, 1)
    

    4.定義損失函數和優化器

    利用交叉熵定義損失,同時用AdamOptimizer優化器進行深度學習,核心代碼如下。

    one-hot類型數據又稱為一位有效編碼,主要是采用N位狀態寄存器來對N個狀態進行編碼,每個狀態都由他獨立的寄存器位,并且在任意時候只有一位有效。例如[0 0 0 1 0 0 0 0 0 0…] 表示為“動物”。
    # 利用交叉熵定義損失
    losses = tf.nn.softmax_cross_entropy_with_logits(
            labels = tf.one_hot(ys, num_classes),       #將input轉化為one-hot類型數據輸出
            logits = logits)
    # 平均損失
    mean_loss = tf.reduce_mean(losses)
    # 定義優化器 學習效率設置為0.0001
    optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(losses)
    

    5.模型訓練和預測

    定義標記變量train,當它為True時進行訓練操作并保存訓練模型;當其為False時進行預測,20%預測集進行圖像分類預測實驗。

    #------------------------------------第四步 模型訓練和預測-----------------------------------
    # 用于保存和載入模型
    saver = tf.train.Saver()
    # 訓練或預測
    train = False
    # 模型文件路徑
    model_path = "model/image_model"
    with tf.Session() as sess:
        if train:
            print("訓練模式")
            # 訓練初始化參數
            sess.run(tf.global_variables_initializer())
            # 定義輸入和Label以填充容器 訓練時dropout為0.25
            train_feed_dict = {
                    xs: x_train,
                    ys: y_train,
                    drop: 0.25
            }
            # 訓練學習1000次
            for step in range(1000):
                _, mean_loss_val = sess.run([optimizer, mean_loss], feed_dict=train_feed_dict)
                if step % 50 == 0:  #每隔50次輸出一次結果
                    print("step = {}\t mean loss = {}".format(step, mean_loss_val))
            # 保存模型
            saver.save(sess, model_path)
            print("訓練結束,保存模型到{}".format(model_path))
        else:
            print("測試模式")
            # 測試載入參數
            saver.restore(sess, model_path)
            print("從{}載入模型".format(model_path))
            # label和名稱的對照關系
            label_name_dict = {
                0: "人類",
                1: "沙灘",
                2: "建筑",
                3: "公交",
                4: "恐龍",
                5: "大象",
                6: "花朵",
                7: "野馬",
                8: "雪山",
                9: "美食"
            }
            # 定義輸入和Label以填充容器 測試時dropout為0
            test_feed_dict = {
                xs: x_val,
                ys: y_val,
                drop: 0
            }
            
            # 真實label與模型預測label
            predicted_labels_val = sess.run(predicted_labels, feed_dict=test_feed_dict)
            for fpath, real_label, predicted_label in zip(fpaths_test, y_val, predicted_labels_val):
                # 將label id轉換為label名
                real_label_name = label_name_dict[real_label]
                predicted_label_name = label_name_dict[predicted_label]
                print("{}\t{} => {}".format(fpath, real_label_name, predicted_label_name))
            # 評價結果
            print("正確預測個數:", sum(y_val==predicted_labels_val))
            print("準確度為:", 1.0*sum(y_val==predicted_labels_val) / len(y_val))
    

    6.完整代碼及實驗結果

    完整代碼如下所示,這里參考了王詩爺老師的部分代碼,強烈推薦大家學習他的博客。地址:https://blog.csdn.net/wills798

    """
    Created on Sun Dec 29 19:21:08 2019
    @author: xiuzhang Eastmount CSDN
    """
    import os
    import glob
    import cv2
    import numpy as np
    import tensorflow as tf
    # 定義圖片路徑
    path = 'photo/'
    #---------------------------------第一步 讀取圖像-----------------------------------
    def read_img(path):
        cate = [path + x for x in os.listdir(path) if os.path.isdir(path + x)]
        imgs = []
        labels = []
        fpath = []
        for idx, folder in enumerate(cate):
            # 遍歷整個目錄判斷每個文件是不是符合
            for im in glob.glob(folder + '/*.jpg'):
                #print('reading the images:%s' % (im))
                img = cv2.imread(im)             #調用opencv庫讀取像素點
                img = cv2.resize(img, (32, 32))  #圖像像素大小一致
                imgs.append(img)                 #圖像數據
                labels.append(idx)               #圖像類標
                fpath.append(path+im)            #圖像路徑名
                #print(path+im, idx)
                
        return np.asarray(fpath, np.string_), np.asarray(imgs, np.float32), np.asarray(labels, np.int32)
    # 讀取圖像
    fpaths, data, label = read_img(path)
    print(data.shape)  # (1000, 256, 256, 3)
    # 計算有多少類圖片
    num_classes = len(set(label))
    print(num_classes)
    # 生成等差數列隨機調整圖像順序
    num_example = data.shape[0]
    arr = np.arange(num_example)
    np.random.shuffle(arr)
    data = data[arr]
    label = label[arr]
    fpaths = fpaths[arr]
    # 拆分訓練集和測試集 80%訓練集 20%測試集
    ratio = 0.8
    s = np.int(num_example * ratio)
    x_train = data[:s]
    y_train = label[:s]
    fpaths_train = fpaths[:s] 
    x_val = data[s:]
    y_val = label[s:]
    fpaths_test = fpaths[s:] 
    print(len(x_train),len(y_train),len(x_val),len(y_val)) #800 800 200 200
    print(y_val)
    #---------------------------------第二步 建立神經網絡-----------------------------------
    # 定義Placeholder
    xs = tf.placeholder(tf.float32, [None, 32, 32, 3])  #每張圖片32*32*3個點
    ys = tf.placeholder(tf.int32, [None])               #每個樣本有1個輸出
    # 存放DropOut參數的容器 
    drop = tf.placeholder(tf.float32)                   #訓練時為0.25 測試時為0
    # 定義卷積層 conv0
    conv0 = tf.layers.conv2d(xs, 20, 5, activation=tf.nn.relu)    #20個卷積核 卷積核大小為5 Relu激活
    # 定義max-pooling層 pool0
    pool0 = tf.layers.max_pooling2d(conv0, [2, 2], [2, 2])        #pooling窗口為2x2 步長為2x2
    print("Layer0:", conv0, pool0)
     
    # 定義卷積層 conv1
    conv1 = tf.layers.conv2d(pool0, 40, 4, activation=tf.nn.relu) #40個卷積核 卷積核大小為4 Relu激活
    # 定義max-pooling層 pool1
    pool1 = tf.layers.max_pooling2d(conv1, [2, 2], [2, 2])        #pooling窗口為2x2 步長為2x2
    print("Layer1:", conv1, pool1)
    # 將3維特征轉換為1維向量
    flatten = tf.layers.flatten(pool1)
    # 全連接層 轉換為長度為400的特征向量
    fc = tf.layers.dense(flatten, 400, activation=tf.nn.relu)
    print("Layer2:", fc)
    # 加上DropOut防止過擬合
    dropout_fc = tf.layers.dropout(fc, drop)
    # 未激活的輸出層
    logits = tf.layers.dense(dropout_fc, num_classes)
    print("Output:", logits)
    # 定義輸出結果
    predicted_labels = tf.arg_max(logits, 1)
    #---------------------------------第三步 定義損失函數和優化器---------------------------------
    # 利用交叉熵定義損失
    losses = tf.nn.softmax_cross_entropy_with_logits(
            labels = tf.one_hot(ys, num_classes),       #將input轉化為one-hot類型數據輸出
            logits = logits)
    # 平均損失
    mean_loss = tf.reduce_mean(losses)
    # 定義優化器 學習效率設置為0.0001
    optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(losses)
    #------------------------------------第四步 模型訓練和預測-----------------------------------
    # 用于保存和載入模型
    saver = tf.train.Saver()
    # 訓練或預測
    train = False
    # 模型文件路徑
    model_path = "model/image_model"
    with tf.Session() as sess:
        if train:
            print("訓練模式")
            # 訓練初始化參數
            sess.run(tf.global_variables_initializer())
            # 定義輸入和Label以填充容器 訓練時dropout為0.25
            train_feed_dict = {
                    xs: x_train,
                    ys: y_train,
                    drop: 0.25
            }
            # 訓練學習1000次
            for step in range(1000):
                _, mean_loss_val = sess.run([optimizer, mean_loss], feed_dict=train_feed_dict)
                if step % 50 == 0:  #每隔50次輸出一次結果
                    print("step = {}\t mean loss = {}".format(step, mean_loss_val))
            # 保存模型
            saver.save(sess, model_path)
            print("訓練結束,保存模型到{}".format(model_path))
        else:
            print("測試模式")
            # 測試載入參數
            saver.restore(sess, model_path)
            print("從{}載入模型".format(model_path))
            # label和名稱的對照關系
            label_name_dict = {
                0: "人類",
                1: "沙灘",
                2: "建筑",
                3: "公交",
                4: "恐龍",
                5: "大象",
                6: "花朵",
                7: "野馬",
                8: "雪山",
                9: "美食"
            }
            # 定義輸入和Label以填充容器 測試時dropout為0
            test_feed_dict = {
                xs: x_val,
                ys: y_val,
                drop: 0
            }
            
            # 真實label與模型預測label
            predicted_labels_val = sess.run(predicted_labels, feed_dict=test_feed_dict)
            for fpath, real_label, predicted_label in zip(fpaths_test, y_val, predicted_labels_val):
                # 將label id轉換為label名
                real_label_name = label_name_dict[real_label]
                predicted_label_name = label_name_dict[predicted_label]
                print("{}\t{} => {}".format(fpath, real_label_name, predicted_label_name))
            # 評價結果
            print("正確預測個數:", sum(y_val==predicted_labels_val))
            print("準確度為:", 1.0*sum(y_val==predicted_labels_val) / len(y_val))
    

    訓練輸出結果如下所示:

    (1000, 32, 32, 3)
    10
    800 800 200 200
    [2 8 6 9 9 5 2 2 9 3 7 0 6 0 0 1 3 2 7 3 4 6 9 5 8 6 4 1 1 4 4 8 6 2 6 1 2
     5 0 7 9 5 2 4 6 8 7 5 8 1 6 5 1 4 8 1 9 1 8 8 6 1 0 5 3 3 1 2 9 1 8 7 6 0
     8 1 8 0 2 1 3 5 3 6 9 8 7 5 2 5 2 8 8 8 4 2 2 4 3 5 3 3 9 1 1 5 2 6 7 6 7
     0 7 4 1 7 2 9 4 0 3 8 7 5 3 8 1 9 3 6 8 0 0 1 7 7 9 5 4 0 3 0 4 5 7 2 2 3
     0 8 2 0 2 3 5 1 7 2 1 6 5 8 1 4 6 6 8 6 5 5 1 7 2 8 7 1 3 9 7 1 3 6 0 8 7
     5 8 0 1 2 7 9 6 2 4 7 7 2 8 0]
    Layer0:
    Tensor("conv2d_1/Relu:0", shape=(?, 28, 28, 20), dtype=float32) 
    Tensor("max_pooling2d_1/MaxPool:0", shape=(?, 14, 14, 20), dtype=float32)
    Layer1:
    Tensor("conv2d_2/Relu:0", shape=(?, 11, 11, 40), dtype=float32) 
    Tensor("max_pooling2d_2/MaxPool:0", shape=(?, 5, 5, 40), dtype=float32)
    Layer2:
     Tensor("dense_1/Relu:0", shape=(?, 400), dtype=float32)
    Output:
     Tensor("dense_2/BiasAdd:0", shape=(?, 10), dtype=float32)
    訓練模式
    step = 0         mean loss = 66.93688201904297
    step = 50        mean loss = 3.376957654953003
    step = 100       mean loss = 0.5910811424255371
    step = 150       mean loss = 0.061084795743227005
    step = 200       mean loss = 0.013018212281167507
    step = 250       mean loss = 0.006795921362936497
    step = 300       mean loss = 0.004505819175392389
    step = 350       mean loss = 0.0032660639844834805
    step = 400       mean loss = 0.0024683878291398287
    step = 450       mean loss = 0.0019308131886646152
    step = 500       mean loss = 0.001541870180517435
    step = 550       mean loss = 0.0012695763725787401
    step = 600       mean loss = 0.0010685999877750874
    step = 650       mean loss = 0.0009132082923315465
    step = 700       mean loss = 0.0007910516578704119
    step = 750       mean loss = 0.0006900889566168189
    step = 800       mean loss = 0.0006068988586775959
    step = 850       mean loss = 0.0005381597438827157
    step = 900       mean loss = 0.0004809059901162982
    step = 950       mean loss = 0.0004320790758356452
    訓練結束,保存模型到model/image_model
    

    預測輸出結果如下圖所示,最終預測正確181張圖片,準確度為0.905。相比之前機器學習KNN的0.500有非常高的提升。

    測試模式
    INFO:tensorflow:Restoring parameters from model/image_model
    從model/image_model載入模型
    b'photo/photo/3\\335.jpg'       公交 => 公交
    b'photo/photo/1\\129.jpg'       沙灘 => 沙灘
    b'photo/photo/7\\740.jpg'       野馬 => 野馬
    b'photo/photo/5\\564.jpg'       大象 => 大象
    ...
    b'photo/photo/9\\974.jpg'       美食 => 美食
    b'photo/photo/2\\220.jpg'       建筑 => 公交
    b'photo/photo/9\\912.jpg'       美食 => 美食
    b'photo/photo/4\\459.jpg'       恐龍 => 恐龍
    b'photo/photo/5\\525.jpg'       大象 => 大象
    b'photo/photo/0\\44.jpg'        人類 => 人類
    正確預測個數: 181
    準確度為: 0.905
    

    四.總結

    寫到這里,這篇文章就講解完畢,更多TensorFlow深度學習文章會繼續分享,同時實驗評價、RNN、LSTM、各專業的案例都會進行深入講解。

    最后,希望這篇基礎性文章對您有所幫助,如果文章中存在錯誤或不足之處,還請海涵~作為人工智能的菜鳥,我希望自己能不斷進步并深入,后續將它應用于圖像識別、網絡安全、對抗樣本等領域,指導大家撰寫簡單的學術論文,一起加油!

    感恩有你,一路同行。

    機器學習深度學習
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    工業互聯網是新一代信息通信技術與工業控制技術深度融合的新型基礎設施,通過對人、機、物、系統等的全面連接,構建起覆蓋全產業鏈、全價值鏈的全新制造和服務體系,為工業乃至產業數字化、網絡化、智能化發展提供了實現途徑。
    美國國防高級研究計劃局(DARPA)一直處在人工智能研究的前沿,可以說,美國人工智能的發展很大程度上歸功于DARPA的支持。從20世紀60年代初至今,在60余年的研究中,從最初的基礎研究項目到軍事應用研究,DARPA在基礎研究和應用研究之間建立了平衡,先后進行了自然語言理解、感知和機器人、可解釋的人工智能、下一代人工智能、人機融合、基于人工智能的網絡攻擊與防御技術等領域的研究。
    安全專家與網絡罪犯間的戰爭已成貓鼠游戲,肩負信息保護責任的安全專家與意圖破壞數據完整性的網絡罪犯勢成水火,技術比拼與戰術對抗,道高一尺,魔鬼一丈。舉個例子,白帽子剛開始用加密工具對抗某種惡意行為,幾乎馬上就會出現另一種形式的惡意威脅。數字連接性的增加和商業領域整個價值鏈中幾乎所有過程的自動化,催生出了敏捷性這種東西,也發展出了相當高端的威脅,極大地增加了網絡安全風險。
    下一代工業防火墻,對應英文翻譯為Next Industry Firewall,簡寫為NIFW。下面從技術要求、核心功能、擴展功能和成熟度評估四個方面定義下一代工業防火墻。
    在信息安全測試領域,基于機器學習的應用系統深度指紋識別技術對應用系統進行漏洞檢測時,可快速獲取應用系統指紋信息,并且能夠根據系統深度指紋信息進行精確的自適應漏洞檢測。通過研究面向 http 協議的信息收集爬蟲技術、基于字符串匹配的識別技術和目標安全缺陷利用技術,基于目標指紋特征提出并搭建了樸素貝葉斯模型,實現了基于機器學習的應用系統指紋識別技術,識別目標應用系統信息,發現缺陷和自適應漏洞檢測。最后
    如今機器學習以及深度學習在各個領域廣泛應用,包括醫療領域、金融領域、網絡安全領域等等。深度學習的首要任務在于數據收集,然而在數據收集的過程中就可能產生隱私泄露的風險,而隱私泄露將導致用戶不再信任人工智能,將不利于人工智能的發展。本文總結了目前在深度學習中常見的隱私保護方法及研究現狀,包括基于同態加密的隱私保護技術、差分隱私保護技術等等。
    新方法和舊方法會如何發生碰撞?
    SCA評估的指引方向
    所以在最壞的安全假設下,噪聲成為降低攻擊效率的主要條件。GE表示正確密鑰的位置排名。每條能量跡有25萬個樣本點,對其中1400個特征點進行分析。漢明重量泄露模型下特征點數量和PI的關系在高信噪比的情況下,神經網絡顯示出優于高斯模板攻擊的性能。圖中顯示了每個單獨的密鑰字節達到猜測熵為1 時所需的攻擊軌跡數。
    在安全和隱私保護需求的驅動下,網絡通信加密化已經成為不可阻擋的趨勢。加密網絡流量呈現爆炸增長,給流量審計與網絡空間治理帶來了挑戰。盡管機器學習已解決了部分加密流量識別的問題,但仍存在無法自動提取特征等局限。深度學習可以自動提取更本質、更有效的特征,已被用于加密流量識別,并取得了高精度。基于深度學習的加密流量識別的相關研究工作,提出基于深度學習的加密流量識別的框架,并通過數據集、特征構造和模型架構回
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类