<dfn id="hx5t3"><strike id="hx5t3"><em id="hx5t3"></em></strike></dfn>

    <thead id="hx5t3"></thead><nobr id="hx5t3"><font id="hx5t3"><rp id="hx5t3"></rp></font></nobr>

    <listing id="hx5t3"></listing>

    <var id="hx5t3"></var>
    <big id="hx5t3"></big>

      
      

      <output id="hx5t3"><ruby id="hx5t3"></ruby></output>
      <menuitem id="hx5t3"><dfn id="hx5t3"></dfn></menuitem>

      <big id="hx5t3"></big>

        喵先生的進階之路

        喵先生的進階之路 查看完整檔案

        天津編輯河北工業大學  |  軟件工程 編輯夢云智  |  組長 編輯 poshichao.github.io 編輯
        編輯
        _ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 個人簡介什么都沒有

        個人動態

        喵先生的進階之路 贊了文章 · 3月30日

        如何使用RxJS間隔發送一定數量的數據

        最近在開發上傳進度的時候需要一個模擬數據:模擬間隔發送1-100之間的值。此需要在RxJS的支持下可以輕松的實現。代碼如下:

        let i = 0;
        interval(100).pipe(
          take(100),
          map(() => ++i)
        ).subscribe(data => console.log(data));

        控制臺如下:
        image.png

        最終的上傳進度效果如下:
        image.png

        簡單解釋下上述代碼:
        interval(100)為RxJS的方法,表示間隔100ms發送一次數據,take(100)的作用是取前100個數據,從而達到了100ms發送一次數據,共發送100次的目的。
        map()操作符用于數據轉換,最終將++i的值發送給下游,subscribe訂閱到的便是++i的值。

        如果你僅僅是在當前方法中使用,當然也可以省略map操作符:

        let i = 0;
        interval(100).pipe(
          take(100))
        ).subscribe(() => console.log(++i));
        查看原文

        贊 2 收藏 0 評論 0

        喵先生的進階之路 發布了文章 · 3月18日

        多神經元簡單神經網絡的實現

        數據集

        首先數據集選擇使用Cifar-10。

        這個數據集合包含十個類的圖片,每類600032 x 32的圖片,共計60000張圖片,其中50000訓練圖片,10000張測試圖片。

        image.png

        這里下載了python對應的版本:

        image.png

        讀取文件

        Cifar-10的網站,我們可以找到實例代碼,然后按照自己的文件目錄讀?。?/p>

        CIRFA_DIR = "../data/cifar-10-batches-py"
        def load_data(filename):
            # 從文件中讀取數據
            with open(filename, 'rb') as f:
            # pickle 默認是用ASCII編碼,但是待載入文件并不是使用ASCII編碼的,需要聲明encoding, 來正確載入文件
            data = cPickle.load(f, encoding='latin1')
            return data['data'], data['labels']

        這里與實例代碼有點不同,在load()函數中,添加了一個encoding參數,因為默認載入文件是使用ASCII編碼,但是數據集文件并不是使用這個編碼的,所以要正確打開,需要添加encoding='latin1',否則不能正確解碼文件。

        數據處理——加載Cifar樣本

        這里創建一個CifarData類,用來加載樣本文件中的數據:

        class CifarData:
            def __init__(self, filenames, need_shuffle):
                all_data = []
                all_labels = []
                for filename in filenames:
                    data, labels = load_data(filename)
                    all_data.append(data)
                    all_labels.append(labels)
                    
                self._data = np.vstack(all_data)        # 將data縱向合并為一個矩陣
                self._data = self._data / 127.5 - 1     # 將data作一個歸一化,0到1之間
                self._labels = np.hstack(all_labels)    # 將labels橫向合并為一個矩陣
                
                self._num_examples = self._data.shape[0]    # 樣本數
                self._need_shuffle = need_shuffle           # 保留need_shuffle
                self._indicator = 0 # 指明在當前數據集,把這個數據集遍歷到哪個位置上
                
                if self._need_shuffle:
                    self._shuffle_data()

        注意到這里在init函數中,定義了一個need_shuffle的變量。
        對于訓練集來說,需要在訓練一遍之后進行數據的打亂,也就是shuffle,以防順序數據產生的過擬合問題;
        對于測試集來說,不在測試集上進行訓練,只計算損失函數準確率,也就不需要進行shuffle。

        然后在這個類里,還需要定義兩個函數:

        # 重新打亂數據
        def _shuffle_data(self):
            # 對_num_example這些數據進行混排
            p = np.random.permutation(self._num_examples)
            self._data = self._data[p]
            self._labels = self._labels[p]

        首先是shuffle函數,來對訓練集數據進行打亂。

        # 每次返回batch_size個樣本
        def next_batch(self, batch_size):
            end_indicator = self._indicator + batch_size    # 定義每個batch的結束位置
            
            # 如果結束位置大于全部的數組
            if end_indicator > self._num_examples:
                # 如果可以shuffle,
                if self._need_shuffle:
                    self._shuffle_data()
                    self._indicator = 0
                    end_indicator = batch_size
               # 數據集已經遍歷完,并且不允許進行shuffle
               else:
                    raise Exception("have no more examples")
            
            # 驗證batch_size是否比整個樣本數還要大
            if end_indicator > self._num_examples:
                raise Exception("batch size is larger than all examples")
            
            # 返回indicator 到 end_indicator 之間的數據
            batch_data = self._data[self._indicator: end_indicator]
            batch_labels = self._labels[self._indicator: end_indicator]
            self._indicator = end_indicator     # 重新定位indicator
            
            return batch_data, batch_labels

        然后定義了next_batch()函數,用來每次返回batch_size大小的數據。并在每次返回后,對剩余數據進行打亂。

        初始化相關變量

        # 這里占位符的第一維度為None,表示樣本數是不確定的;第二維度為3072,表示每個樣本的維度是3072
        x = tf.placeholder(tf.float32, [None, 3072])
        y = tf.placeholder(tf.int64, [None])
        
        # 定義權重,并在均值為0,方差為1的范圍內進行隨機初始化 (3072 * 10)# 進行多分類,樣本數據總共有十個類
        w = tf.get_variable('w', [x.get_shape()[-1], 10], 
                            initializer=tf.random_normal_initializer(0, 1))
        # 定義偏置,初始化為常量0 (10, )
        b = tf.get_variable('b', [10], initializer=tf.constant_initializer(0.0))
        
        # (None, 3072) * (3072, 10) = (None, 10)
        y_ = tf.matmul(x, w) + b

        在神經網絡中,神經元的基本結構如下,x1、x2、x3...是輸入,h(W*x)是輸出,W*x是一個中間過程,表示讓每個x和其權重做乘積,然后再加起來,再由h函數得到輸出。這里只有一個輸出,就表示是單神經元

        image.png

        這里面的w、x就對應代碼中定義的w和x,然后輸出就是y。這里還有一個偏置b,這就是我們之前數學中所學到截距的概念類似,也就是分類線分類面坐標軸交點的值:

        image.png

        然后y_是一個Wx進行矩陣相乘,它是一個內積值。后面需要將其變成一個概率值。

        然后使用激活函數(即公式中的f)對y_進行激活:

        # 多分類的激活函數: e^x / sum(e^x)
        # [[0.01, 0.9, ..., 0.03], [...]]
        p_y = tf.nn.softmax(y_)

        這是多分類的激活函數softmax(),而二分類的激活函數一般使用sigmoid()函數。

        接著對y進行one_hot編碼,這步主要是為了將yp_y轉換成相同的數據格式:

        # 對y進行 ont_hot 編碼,使得y和p_y保持相同的數據類型,以計算損失函數
        # 5 -> [0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
        y_one_hot = tf.one_hot(y, 10, dtype=tf.float32)

        最后計算損失函數:

        # 計算損失函數
        loss = tf.reduce_mean(tf.square(y_one_hot - p_y))

        這里計算損失函數,采用了平方差的方式。

        最后對準確率進行計算,并對loss做梯度下降(梯度下降算法),找到loss的最小值:

        predict = tf.argmax(y_, 1)                                      # 預測值
        correct_predict = tf.equal(predict, y)                          # 正確的預測值
        accuracy = tf.reduce_mean(tf.cast(correct_predict, tf.float64)) # 準確率
        
        # 對loss做梯度下降
        with tf.name_scope('train_op'):
            train_op = tf.train.AdamOptimizer(1e-3).minimize(loss)

        進行訓練

        首先先執行初始化的變量,然后定義訓練的batch_size、訓練的步數、測試的步數。

        # 執行初始化
        init = tf.global_variables_initializer()
        
        batch_size = 20
        train_steps = 100000
        test_steps = 100

        接著使用session開始執行計算:

        with tf.Session() as sess:
            sess.run(init)
            
            # 循環train_steps,進行訓練
            for i in range(train_steps):
                batch_data, batch_labels = train_data.next_batch(batch_size)
                
                loss_val, accu_val, _ = sess.run(
                    [loss, accuracy, train_op],
                    feed_dict={
                        x: batch_data,
                        y: batch_labels})
                
                # 打印中間過程
                if (i + 1) % 500 == 0:
                    print('[Train] step: %d, loss: %4.5f, acc: %4.5f' % (i + 1, loss_val, accu_val))
                
                # 使用測試集進行評測
                if (i + 1) % 5000 == 0:
                    test_data = CifarData(test_filename, False)
                    all_test_acc_val = []  # 保存總的accuracy
                    for j in range(test_steps):
                        test_batch_data, test_batch_labels = test_data.next_batch(batch_size)
                        test_acc_val = sess.run([accuracy], feed_dict={x: test_batch_data, y: test_batch_labels})
                        all_test_acc_val.append(test_acc_val)
                        
                    test_acc = np.mean(all_test_acc_val)  # 對test的acc做平均
                    
                    print('[Test] step: %d, acc: %4.5f' % (i + 1, test_acc))

        tensorflow只有讓計算圖上的節點在session中執行才能得到結果,sess只有在調用run()函數后才能開始執行計算。而一般調用run()函數后,執行計算會十分消耗資源,所以必須要在結束后執行close()進行關閉:

        sess.run(init)
        sess.close()

        但是手動進行關閉又比較麻煩,有時候還會忘記,所以就是用with語句,結束后自動關閉:

        with tf.Session as sess:
            sess.run(init)

        初始化執行后,開始循環train_steps,進行訓練。

        在每執行500步打印一次中間過程,輸出當前步、損失函數準確率。

        同時,為了做出類似真是環境中的評測,需要在測試集上記性評測。每5000步對已訓練的模型進行一次評測。

        運行結果及總結

        image.png

        我們發現隨著訓練的進行,準確率在整體上有一定程度的提升。

        通過對單個神經元的神經網絡到多個神經元的神經網路的學習,對實現神經網絡的基本過程有了一定程度的了解。

        對于數據處理部分,歸一化處理對結果的影響十分重要:

        self._data = self._data / 127.5 - 1

        沒有進行歸一化之前,訓練的準確率基本沒有什么變化,這是因為未歸一化的數據都比較大,這就導致了運算會偏向某一方,從而導致準確率的變化不大。

        其次,在處理數據的時候,還要多注意數據類型的關系。因為其中很多都是矩陣的乘法,一旦數據類型或格式不能匹配,就不能正確運算。

        對于神經網絡的處理部分,主要就是理解特征集(x)、損失函數(loss)等概念。通過編程的實現,對文章開始部分的方程的理解不僅僅限制在數學層面:

        image.png

        包括推梯度下降的應用,對激活函數的應用等。


        相關參考:
        https://tensorflow.google.cn/versions/r2.0/api_docs/python/tf
        https://www.imooc.com/learn/1063

        查看原文

        贊 1 收藏 0 評論 0

        喵先生的進階之路 發布了文章 · 3月16日

        梯度下降算法

        概述

        梯度下降算法在機器學習中十分廣泛。不論是在線性回歸還是在邏輯回歸中,它的主要目的是通過迭代來找到目標函數的最小值,以最小化損失函數。

        梯度下降原理

        山谷問題

        梯度下降,簡單的來說就是要找到最小的點,而所謂找到最小的點,就類似向山谷中走,每次都希望找到那山谷中的最低點,然后如何確定走到最低點的路徑的問題。

        現在假設,我們并不能直接看到最低點,只能看到自己周圍的一小部分,要一步一步的找到最低點。

        所以現在就以自己的位置為基準,找到最陡峭的方向(即切線方向),然后沿下降方向走一步;再找到最陡峭的方向,再走一步。直到走到最低點。

        image.png

        梯度

        梯度實際就是多變量微分的一般化:

        image.png

        梯度就是對每個變量進行微分,用<>括起來,表示圖梯度是個向量。

        • 單變量函數中,梯度就是該函數的微分,也就是切線的斜率。
        • 多變量函數中,梯度是一個向量,向量的方向表示梯度的方向,即下降最快的方向。

        梯度下降

        在損失函數中,一般情況下有兩種參數:控制信號量的權重(w)調整函數與真實值之間的偏差(b)。

        梯度下降就是不斷的調整權重w偏差b的值,使得損失最小。

        通過對梯度的向量方向分析,我們知道了下降的方向,但是每次要走多少還不知道。

        這就需要定義一個新的概念:學習率(α)

        image.png

        其中ωi表示權重的初始值,ωi+1表示更新后的權重值。在梯度下降中,會重復這個式子多次,然后直到損失函數收斂不變。

        對于α的選擇,不能太大,以防錯過了最低點;也不能太小,使下降的速度緩慢。

        梯度下降過程

        1.循環所有樣本數據

        (1) 計算第i個訓練數據的權重ω偏差b相對于損失函數的梯度。于是我們最終會得到每一個訓練數據的權重和偏差的梯度值。
        (2) 計算所有訓練數據權重ω梯度的總和。
        (3) 計算所有訓練數據偏差b梯度的總和。

        2.更新權重和偏差

        (1) 使用上面第(2)、(3)步所得到的結果,計算所有樣本的權重偏差梯度的平均值。
        (2) 使用下面的式子,更新每個樣本的權重值偏差值。
        image.png
        重復上面的過程,直到損失函數收斂不變。

        梯度下降demo

        1.定義數據集

        from numpy import *
        
        # 數據集大小 即20個數據點
        m = 20
        
        # x的坐標以及對應的矩陣
        X0 = ones((m, 1))  # 生成一個m行1列的向量,也就是x0,全是1
        X1 = arange(1, m+1).reshape(m, 1)  # 生成一個m行1列的向量,也就是x1,從1到m
        X = hstack((X0, X1))  # 按照列堆疊形成數組,其實就是樣本數據
        
        # 對應的y坐標
        Y = array([
            3, 4, 5, 5, 2, 4, 7, 8, 11, 8, 12,
            11, 13, 13, 16, 17, 18, 17, 19, 21
        ]).reshape(m, 1)
        
        # 學習率
        alpha = 0.01

        其中reshape()函數將原數組重新組織成一個m行1列二維數組。

        2.代價函數和梯度函數

        # 定義代價函數
        def cost_function(theta, X, Y):
            diff = dot(X, theta) - Y  # dot() 數組需要像矩陣那樣相乘,就需要用到dot()
         return (1/(2*m)) * dot(diff.transpose(), diff)
         
        # 定義代價函數對應的梯度函數
        def gradient_function(theta, X, Y):
            diff = dot(X, theta) - Y
            return (1/m) * dot(X.transpose(), diff)

        3.梯度下降計算

        # 梯度下降迭代
        def gradient_descent(X, Y, alpha):
            theta = array([1, 1]).reshape(2, 1)
            gradient = gradient_function(theta, X, Y)
            
            while not all(abs(gradient) <= 1e-5):
                theta = theta - alpha * gradient
                gradient = gradient_function(theta, X, Y)
            return theta
            
        optimal = gradient_descent(X, Y, alpha)
        print('optimal:', optimal)
        print('cost function:', cost_function(optimal, X, Y)[0][0])

        當梯度小于1e-5時,表示這時候已經到達谷底。這時候迭代就不會取得比較大的效果,所以退出循環,結束迭代。

        4.畫出圖像

        # 根據數據畫出對應的圖像
        def plot(X, Y, theta):
            import matplotlib.pyplot as plt
            ax = plt.subplot(111)   # 繪制子圖
            ax.scatter(X, Y, s=30, c="red", marker="s")
            plt.xlabel("X")
            plt.ylabel("Y")
            x = arange(0, 21, 0.2)  # x的范圍
         y = theta[0] + theta[1]*x
            ax.plot(x, y)
            plt.show()
        plot(X1, Y, optimal)

        5.效果圖

        image.png

        得到一個樣本數據的線性擬合。


        參考:

        https://zhuanlan.zhihu.com/p/68468520
        https://blog.csdn.net/qq_41800366/article/details/86583789
        https://www.w3cschool.cn/tensorflow_python/

        查看原文

        贊 0 收藏 0 評論 0

        喵先生的進階之路 發布了文章 · 3月15日

        支持向量機

        支持向量機(SVM)是一種將按監督學習的方式對數據進行二元分類的線性分類器。其決策邊界是對學習樣本求解的最大超平面。

        SVM基本型式

        支持向量機的基本思想就是,在樣本空間中找到一個線性可分的直線或是超平面(n維歐式空間中其余維度等于1的線性子空間,即必須是n-1維度,是二維空間中直線、三維空間中平面的延伸),將不同類別的樣本分開。

        在數學上,認為在樣本空間中,對不同類別的樣本進行分開的直線或是超平面的方程為:

        image.png

        例如下圖,實線將'+''-'進行分類:

        image.png

        對于樣本空間中的任意一點超平面的距離為:

        image.png

        支持向量機的基本型式就是找到滿足條件的、且具有最大間距的劃分超平面。

        SVM的核函數

        之前討論的是原始樣本線性可分的情況,但是實際情況是,一些任務的原始樣本并不一定存在一種能正確分為兩類的超平面。

        然而對于這種非線性的情況,SVM考慮使用將原始樣本映射到更高維的空間,然后在高維空間中構造出最優超平面,從而解決原始線性空間不可分的問題。

        如下圖,左邊在二維平面上并不能進行線性分類,但是將映射到右邊的三維空間上,求解出一個分離超平面:

        image.png

        數學上的表示為:
        image.png

        擬合線性回歸

        使用svm方式,就是擬合的直線使得其SVM的最大間距能夠盡可能多的包含已知點,且我們認為被包含的已知點的損失為0。

        使用Tensorflow進行編程的主要步驟主要分為四步:

        1.生成訓練數據

        對于訓練數據,通過模擬生成:

        image.png

        2.定義訓練模型

        SVM模型中,我們選擇間距最小的損失函數:

        curry_y = x * a + b
        epsilon = tf.constant([0.25])   # 創建常量,表示間距為0.25
        loss = tf.reduce_sum(tf.maximum(0, tf.subtract(tf.abs(tf.subtract(curr_y, y)), epsilon)))

        其中,reduce_sum()為求和函數;
        maximum(x, y, name=None)為計算元素x,y中的最大值;
        subtract(x, y, name=None)計算x-y;
        abs(x)計算x的絕對值。

        3.數據訓練

        4.運行總結

        隨著訓練的進行,擬合的值與目標不斷接近:

        image.png

        將擬定的間距寬度值調小,再次進行訓練??梢钥吹?,將間距調小后,擬合直線的誤差更小。

        image.png

        image.png

        擬合邏輯回歸

        對于擬合線性回歸,我們需要找到一條直線來表示樣本的大致分布;而對于邏輯回歸,同樣是需要找到一條直線,但目的是將樣本點進行分類。

        SVM算法的提出,主要是為了解決‘是’‘否’這樣的二值分類的問題。

        進行擬合邏輯回歸主要需要以下幾步:

        1.準備樣本數據
        2.定義訓練模型
        3.訓練樣本數據
        4.選擇優化器

        在SVM模型中,選取的損失函數為:

        classification_term = tf.reduce_mean(tf.maximum(0., tf.subtract(1., tf.multiply(y, y_))))
        cross_entropy = tf.add(classification_term, tf.multiply(alpha, 12_norm))
        查看原文

        贊 1 收藏 0 評論 0

        喵先生的進階之路 發布了文章 · 3月11日

        Tensorflow基本概念

        Tensorflow基本概念

        1.Tensor

        Tensorflow張量,是Tensorflow中最基礎的概念,也是最主要的數據結構。它是一個N維數組。

        2.Variable

        Tensorflow變量,一般用于表示圖中的各計算參數,包括矩陣,向量等。它在圖中有固定的位置。

        3.placeholder

        Tensorflow占位符,用于表示輸入輸出數據的格式,允許傳入指定的類型和形狀的數據。

        4.Session

        Tensorflow會話,在Tensorflow中是計算圖的具體執行者,與圖進行實際的交互。

        5.Operation

        Tensorflow操作,是Tensorflow圖中的節點,它的輸入和輸出都是Tensor。它的操作都是完成各種操作,包括算數操作、矩陣操作、神經網絡構建操作等。

        6.Queue

        Tensorflow隊列,也是圖中的一個節點,是一種有狀態的節點。

        7.QueueRunner

        隊列管理器,通常會使用多個線程來讀取數據,然后使用一個線程來使用數據。使用隊列管理器來管理這些讀寫隊列的線程。

        8.Coordinator

        使用QueueRunner時,由于入隊和出隊由各自線程完成,且未進行同步通訊,導致程序無法正常結束的情況。為了實現線程之間的同步,需要使用Coordinator。

        Tensorflow程序步驟

        (一)加載訓練數據

        1.生成或導入樣本數據集。
        2.歸一化處理。
        3.劃分樣本數據集為訓練樣本集測試樣本集。

        (二)構建訓練模型

        1.初始化超參數
        2.初始化變量和占位符
        3.定義模型結構
        4.定義損失函數

        (三)進行數據訓練

        1.初始化模型
        2.加載數據進行訓練

        (四)評估和預測

        1.評估機器學習模型
        2.調優超參數
        3.預測結果

        加載數據

        在Tensorflow中加載數據的方式一共有三種:預加載數據、填充數據和從文件讀取數據。

        預加載數據

        在Tensorflow中定義常量或變量來保存所有數據,例如:

        a = tf.constant([1, 2])
        b = tf.constant([3, 4])
        x = tf.add(a, b)
        因為常數會直接存儲在數據流圖數據結構中,在訓練過程中,這個結構體可能會被復制多次,從而導致內存的大量消耗。

        填充數據

        將數據填充到任意一個張量中。然后通過會話run()函數中的feed_dict參數進行獲取數據:

        數據量大時,填充數據的方式也存在消耗內存的問題。

        從CVS文件中讀取數據

        要存文件中讀取數據, 首先需要使用讀取器將數據讀取到隊列中,然后從隊列中獲取數據進行處理:

        1.創建隊列
        2.創建讀取器獲取數據
        3.處理數據

        讀取TFRecords數據

        Tensorflow針對處理數據量巨大的應用場景進行了優化,定義了TFRecords格式。

        采用這種讀取方式讀取數據分為兩個步驟:

        1.把樣本數據轉換為TFRecords二進制文件。
        2.讀取TFRecords格式。

        存儲和加載模型

        Tensorflow中提供了tf.train.Saver類實現訓練模型的保存和加載。

        存儲模型

        在模型的設計和訓練的過程中,會消耗大量的時間。為了降低訓練過程中意外情況發生造成的不良影響,所以會對訓練過程中模型進行定期存儲。(模型復用,節省整體訓練時間)

        saver = tf.train.Saver(max_to_keep, keep_checkpoint_event_n_hours)

        存儲的模型,會生成四個文件:

        image.png

        加載模型

        為了保證意外中斷的模型能夠繼續訓練以及訓練完成的模型加載在其他數據上直接使用,會對模型進行加載使用。

        加載存儲好的模型,包括了兩個步驟:

        1.加載模型:

        saver = tf.train.import_meta_graph("my_test_model-100.meta")

        2.加載訓練參數:

        saver.restore(sess, tf.train.latest_checkpoint('./'))
        查看原文

        贊 1 收藏 0 評論 0

        喵先生的進階之路 發布了文章 · 3月9日

        DKT程序的學習

        深度知識追蹤(DKT)這方面,已經看了多篇論文,對其中的一些模型也是做了簡單的了解。所以在這個基礎上,我對一個已有的DKT程序進行調試學習。本文主要是對訓練模型的過程進行學習總結。

        環境的調整

        在進行程序調試的時候,首先遇到的問題就是環境不能滿足程序的運行。雖然說配置環境是一個并不是很難, 但是容易處處出現問題。

        python的版本選擇

        首先是python的版本問題,在下載程序以前,我的電腦上是存在一個版本的python。但是根據程序所需要的版本與我本機上的不同,同時我也并不想刪除原有版本的python,所以這就需要設計python版本切換的問題了。

        這里使用的開發工具是pycharm,下好對應版本的python后,通過設置選擇對應的版本:

        image.png

        使用這個工具的好處是,我不需要對環境變量進行更改,直接就可以切換我所需要的版本,同時還不會影響到其他程序使用的版本問題。

        tensorflow

        tensorflow-cputensorflow-gpu的選擇。在一般進行小數據量的處理時,選擇兩種之間的差別并不大,但是在進行大數據量的計算的時候,cpu版的計算時間就會出現明顯的增加。

        基于該程序性的數據量比較大的基礎,這里就選擇使用gpu版。

        安裝tensorflow-gpu直接使用python包管理安裝工具pip進行安裝。

        pip install tensorflow-gpu==1.10.0
        注意:如果在安裝的過程中提示出現pip版本的問題,直接將pip更新到最新的版本就可以了。

        CUDA

        因為上面選擇了tensorflow-gpu==1.10.0,所以對CUDA的版本也是有對應的要求,這就跟我之前的版本出現了沖突,

        tensorflow:ImportError: Could not find 'cudart64_90.dll'

        按照報錯的提示,tensorflow的導入需要CUDA9的版本。

        去官網下載完CUDA9之后,在進行環境變量配置的時候,一定要將CUDA_PATH設置為版本9的對路徑。

        CUDNN

        安裝完CUDA后,依然會出現報錯:

        ImportError: Could not find ‘cudnn64_7.dll’

        報錯提示導入需要cudnn7的支持,在官網上找到對應CUDA9版本的cudnn,然后進行下載解壓,并將對應文件放到安裝好的cuda的文件夾下:

        bin\cudnn64_7.dll放到\bin目錄下。

        include\cudnn.h放到\include目錄下。

        lib\x64\cudnn.lib放到\lib\x64目錄下。

        numpy

        繼續報錯:

        ValueError: numpy.ufunc size changed, may indicate binary incompatibility. Expected 216 from C header, got 192 from PyObject

        出現該報錯的主要原因,是numpy的版本不對,需要將numpy的版本更新為1.16.0。

        pip install -U numpy==1.16.0

        更新numpy,直接使用pip進行更新。

        pip show numpy

        更新后查看一下numpy的版本,成功更新到1.16.0:

        image.png

        顯存不足

        ResourceExhaustedError: OOM when allocating tensor with shape[512] and type float on /job:localhost

        出現該報錯的原因是:網絡tensor過大,訓練時參數過多,導致顯存不夠,資源耗盡。

        因為按照訓練的要求,訓練參數不能修改,所以在解決時,將batch_size改小。

        在tensorflow中,batch_size是每個訓練批次的大小,它主要影響完成每個epoch(全數據集)所需要的時間,以及每個迭代(iteration)之間梯度的平滑程度。

        一般來說,在合理范圍內適當的增大batch_size能夠增加內存的利用率,提高大矩陣乘法的并行效率。這就使得完成每個epoch的時間減少。

        但是同時,增大batch_size也可能會使得內存的容量不夠,這也就是導致我們上面的問題。

        解決:

        1.縮小batch_size:程序開始時,batch_size設置的大小為16,將其縮小一半后,未能解決問題,繼續縮小,最后,將其設置為4.

        2.關閉電腦中其他運行的無關程序:其他運行的程序也會在一定程度上占用內存,所以將這些程序關閉,也能增大一些可以使用的內存。

        tensorflow.saver

        在訓練循環中,定期調用saver.save()方法,向文件夾中寫入包含了當前模型中所有可訓練變量的 checkpoint文件。

        saver.save(sess, FLAGS.train_dir, global_step=step)

        其中sess是tensorflow中的會話控制(session);FLAGS.train_dir是訓練的checkpoint的存儲位置;global_step是指訓練的第幾步。

        image.png

        每次訓練都會出現后面的三個文件,第一次訓練會出現checkpoint文件,并且每次都會在該文件中創建一個檢查點。

        注意:save方法中的路徑并不能自動創建,所以在保存之前一定需要先建立好相應的文件夾。

        相關參考:

        https://blog.csdn.net/u011311291/article/details/81393933
        https://blog.csdn.net/zhaotun123/article/details/99680151
        https://blog.csdn.net/qq_37099552/article/details/105023680
        https://stackoverflow.com/questions/60323366/valueerror-numpy-ufunc-size-changed-may-indicate-binary-incompatibility-expec
        https://blog.csdn.net/winycg/article/details/78572438
        https://blog.csdn.net/hl1hl/article/details/85638276

        查看原文

        贊 1 收藏 0 評論 0

        喵先生的進階之路 發布了文章 · 1月22日

        LTSM 網絡

        循環神經網絡(RNN)

        要理解LTSM,首先要理解RNN。

        類似人類的思考,人從來都不會從頭思考,而是從已有的知識上再做深入的思考。

        而傳統的神經網絡并不能夠完成這一點,所以循環神經網絡很好的解決了這個問題。

        循環神經網絡(RNN)是一種循環的網絡,他可以是信息持久存在。

        RNN已經廣泛使用到如:語音識別,語言建模,翻譯,圖像字幕等眾多的領域,而取得這些成就的關鍵就是LTSM網絡模型,它的出現使許多任務都比標準模型要好很多。

        長期依賴問題

        RNN的一個特點就是能夠使用前面的信息。但是有時候,我們的所需信息和相關信息之間的差距很小,這樣就不需要上下文的幫助。而相反,有時候所需信息又會與相關信息之間差距很大,這樣就需要很多上下文的輔助。

        理論上,RNN是可以完成這樣的長期依賴問題,但是實際上,RNN完全不能學習他們。而LTSM完全沒有問題。

        長短期記憶網絡(LTSM)

        LTSM是一種特殊的RNN模型,它可以學習長期依賴問題。

        所有的遞歸神經網絡都具有神經網絡的重復模塊鏈的形式。在標準RNN中,此重復模塊將具有非常簡單的結構,例如單個tanh層。

        image.png

        LSTM也具有這種鏈狀結構,但是重復模塊具有不同的結構。而不是只有一個神經網絡層,而是有四個以非常特殊的方式進行交互。

        image.png

        LSTMs的關鍵是單元狀態,即貫穿圖頂部的水平線。單元狀態有點像傳送帶。它沿著整個鏈條直行,只有一些微小的線性相互作用。信息很容易就這樣一成不變地流動。

        image.png

        LSTM確實有能力移除或向細胞狀態添加信息,這些信息由稱為的結構仔細調節。是一種選擇性地讓信息通過的方式。它們由一個sigmoid神經網絡層和一個逐點乘法運算組成。

        image.png

        LTSM步驟

        1.確定要從單元狀態中丟棄的信息

        2.確定要在單元狀態下存儲哪些新信息

        首先,一個稱為“輸入門層”的S形層決定了我們將更新哪些值。接下來,tanh層創建一個新候選值的向量??梢詫⑵涮砑拥綘顟B中。在下一步中,我們將兩者結合起來以創建狀態更新。

        image.png

        3.該更新舊單元格狀態了

        image.png

        4.決定要輸出的內容

        此輸出將基于我們的單元狀態,但將是過濾后的版本。

        image.png

        對于語言模型示例,由于它只是看到一個主語,因此可能要輸出與動詞相關的信息,以防萬一。例如,它可能輸出主語是單數還是復數,以便我們知道如果接下來是動詞,則應將動詞以哪種形式共軛。


        相關參考:

        http://colah.github.io/posts/2015-08-Understanding-LSTMs/

        查看原文

        贊 1 收藏 0 評論 0

        喵先生的進階之路 發布了文章 · 1月11日

        基于深度學習的知識追蹤

        Knowledge Tracking Model Based on Learning Process一文中,介紹了一種知識追蹤模型LPKT。這是一種基于現存深度學習的知識追蹤模型的改進,該模型采用了記憶增強神經網絡(MANN)的思想。

        現存模型的缺陷

        1. 對于計算知識增長的局限性
        2. 模型遺忘機制不完善

        知識追蹤模型

        知識追蹤的任務是根據學生與智能教學系統之間的交互,自動跟蹤學生的知識狀態隨時間的變化過程,所以,知識追蹤具有自動化個性化的特點。

        目前典型的知識追蹤方法有:貝葉斯知識追蹤(BKT)和深度知識追蹤(DKT)

        BKT

        BKT模型存在以下的問題:

        1. 它需要標記數據
        2. 對每個知識點分別進行表達

        所以BKT不能捕捉不同概念之間的相關性,不能有效地表示復雜的概念狀態轉化。

        DKT

        DKT模型,是基于長短時記憶網絡(LSTM)的深度知識追蹤網絡。它不僅比BKT模型有更好的預測能力,同時不需要專家對習題的知識點進行標注。

        但是LSTM是將所有的記憶存儲在一個隱藏的向量中,這使得它很難準確地記住超過數百個時間步長的序列

        記憶增強神經網絡(MANN)就是用來解決這個問題的。

        DKVMN

        動態鍵值記憶網絡(DKVMN),它借鑒了MANN的思想,同時又結合的BKTDKT的優點,所以總體來說,它的預測性能是比較好的。與LSTM相比,它能避免過擬合、參數少,以及通過潛在概念自動發現相似練習。

        存在的缺陷:

        1. 計算知識增長的局限性
        2. 過于依賴模型本身的遺忘機制
        3. 預測過程中沒有考慮遺忘機制

        基于學習過程的知識追蹤(LPKT)

        LPKT旨在通過模擬學生的學習和記憶過程來完成知識追蹤。

        LPKT過程:

        1. 注意機制:計算一個問題涉及的知識點數和每個知識點所占的比例
        2. 讀過程:觀察一段時間內學生在學習系統中的學習序列數據
        3. 寫過程:給定一個學生問答活動,代表學生的知識狀態矩陣V由t-1時刻狀態到t時刻狀態

        image.png

        讀過程中,模型根據當前知識狀態計算知識遺忘量,再參考LSTM的遺忘機制,計算下一個時刻的知識狀態。這個知識狀態就比較符合學生的學習規律。

        寫過程則是根據MANN模型機制,在知識追蹤的過程中跟新學生的動態知識狀態。在更新狀態時,會同時考慮遺忘機制,在DKVMN中被稱作erase。遺忘過程中,不應該只考慮知識增量,同時還應該考慮學生學習持續時間。

        總結

        LPKT相較于傳統的BKTDKT,都有較大的優勢。同時它又結合了DKVMN的思想與優點,改進了遺忘機制上的不足,使得知識追蹤的效率得到提高。


        參考文獻:Knowledge Tracking Model Based on Learning Process

        查看原文

        贊 1 收藏 0 評論 0

        喵先生的進階之路 發布了文章 · 2020-12-20

        因素分析法

        因素分析法

        一種統計技術,希望從眾多的可觀測的“變量”中,概括和推論少數“因素”。用少數“因素”來概括和解釋大量的觀測事實。又叫“因子分析法”。

        KMO和Bartlett球形檢驗

        用于檢驗試卷是否適合進行因素分析。

        KMO計算方法:

        ix = inv(X); // X表示原始數據的相關系數矩陣,inv表示求X的逆矩陣
        S2 = diag(diag((iX.^-1)));     // 將ix對角線元素全部取倒數,其余元素變0,得矩陣S2
        AIS = S2*iX*S2;        // AIS是反映像協方差矩陣
        IS = X + AIS - 2 * S2; // IS 是映像協方差矩陣
        Dai = diag(diag(sqrt(AIS)));    // 將矩陣AIS對角線上的元素開平方,并且將其余元素都變成0,得到矩陣Dai
        IR = inv(Dai) * IS * inv(Dai);    // IR是映像相關矩陣
        AIR = inv(Dai) * AIS * inv(Dai);// AIR是反映像相關矩陣
        a = sum((AIR - diag(diag(AIR))).^2);    // diag(diag(AIR))表示將矩陣AIR的對角線取出來,再構造成一個對角矩陣(即對角線之外元素都是 0);. 表示將偏相關系數矩陣AIR - diag(diag(AIR))的每一個元素乘方,這樣得到矩陣a
        AA = sum(a);     // 偏相關系數矩陣AIR - diag(diag(AIR))中所有偏相關系數的平方和AA,但不考慮其對角線上的數值。
        b = sum((X - eye(size(X))).^2);        // eye()是單位矩陣;b就是將相關系數矩陣R中每一個元素乘方,但X對角線元素全部變成0
        BB = sum(b);        // BB就是所有變量之間(不包括變量自己與自己)的相關系數的平方和。
        kmo=BB/(AA+BB);        // KMO就是所有變量之間相關系數的平方和除以它與所有變量之間偏相關系數平方和的商,但不考慮變量  自己與自己的相關系數1以及偏相關系數。

        在這里,我通過SPSS計算和按照上面的步驟進行計算,做出驗證,得出了相同的結果。

        測試數據如下,后面的計算都基于這一組數據

        image.png

        SPSS的KMO巴特利特檢驗結果:

        image.png

        需要說明的是,在使用SPSS進行數據分析的時候,數據量最少是變量數的10倍。

        手動結果:

        KMOimage.png

        經檢驗,兩者結果基本一致。

        當KMO值大于0.8,說明適合做因子分析。這里由于是使用隨便給的一組數,所以并不適合做因子分析。

        巴特利特球形檢驗的公式:

        H0:原始數據的相關系數矩陣X與同維度的單位矩陣一致
        H1:原始數據的相關系數矩陣X與同維度的單位矩陣不一致
        χ2 = -[n-(2p+11)/6]ln|X|;   // 近似卡方
        df = p(p-1)/2;              // 自由度

        其中:n是數據記錄的條數;p是因子分析的變量數目;ln()自然對數函數;|X|是相關系數矩陣X的行列式的值。

        顯著性計算:在Excel中輸入函數:=CHISQ.DIST.RT(χ2所在單元格地址,df所在單元格地址)從而得到P概率值。

        p < 0.05或0.01或0.001,則拒絕H0而認可H1。

        SPSS的巴特利特檢驗結果:

        image.png

        手動結果:

        巴特利特檢驗:image.png

        顯著性計算這一部分目前只能通過excel計算,沒有找到具體的計算公式。

        主成分分析——相關矩陣或協方差矩陣

        目的:減少需要分析的變量的數量,盡量減少變量包含信息的損失,已達到對所收集數據的全面分析。

        相關矩陣:即相關系數矩陣(上面求過)

        1. 對原數據進行標準化:xi = (xi - X)/St
          其中xi為原數據,X為該變量的平均值,St為該變量的標準差
        2. 計算標準化后的相關系數矩陣
        3. 計算特征值特征向量
          (1)計算特征值,并按從大到小排序
          (2)計算特征值對應的特征向量
          (3)計算主成分貢獻率和累計貢獻率:
          貢獻率 = 特征值/所有特征值的和;
          累計貢獻率 = 之前的貢獻率相加
        4. 計算主成分載荷:特征值開方 * 特征向量

        SPSS的結果:

        image.png

        image.png

        手動結果:

        image.png

        主成分載荷:image.png

        經驗證,結果基本一致。

        協方差:衡量兩個隨機變量的相關程度

        求解過程和相關矩陣的相同,只在第二步的時候計算協方差矩陣。

        Promax和Direct Oblimin 斜交旋轉

        Direct Oblimin(直接斜交變換):使因素負荷量的差積(cross-products)最小化。

        Promax(迫近最大方差斜交旋轉):基本原理是使每個變量在盡可能少的因子上有比較高的載荷,讓某個變量某個因子上的載荷趨近于1,而在其他因子上的載荷趨近于0。允許因子間相關,適合于大量數據。

        image.png

        1. 對A使用varimax旋轉得到矩陣T(即上圖中的T)
        2. 將T的各元素取絕對值的k次冪(2,4,6),并保留原符號,得到矩陣H
        3. 建立T對H的最小二乘估計,即令T x C = H
          將T左乘上式兩邊,然后用(TT)逆左乘方程兩邊得:
          C=(TT)逆TH
        4. 將C按列規格化,得到斜交參考矩陣
        5. 將A逆按行規格化處理,得到斜因子變換矩陣T^
        6. 斜因子相關陣:L=T^T
          結構陣:S=AT
          模型陣:B=AT逆

        具體旋轉公式還是沒有找到,大部分文章中都認為計算量很大,需要用正交陣多次去乘載荷矩陣,建議這部分使用spss進行計算。

        總結

        因子分析的步驟:

        1. 適用性檢驗,判斷數據是否可以使用因子分析法
        2. 主成分分析,確定因子個數
        3. 因子旋轉
        4. 得出最終模型,并作出解釋

        相關參考:

        因子分析
        HSK[高級]客觀卷的構想效度初探
        https://bbs.pinggu.org/thread-2421588-1-1.html
        Promax斜旋轉理論及在機能實驗學中的應用
        Factor Rotations in Factor Analyses.

        查看原文

        贊 0 收藏 0 評論 0

        喵先生的進階之路 發布了文章 · 2020-12-17

        Hadoop集群的部署(二)

        在上一篇文章中,介紹了Hadoop集群的偽分布的部署,在讀這篇前,建議先讀上篇文章:Hadoop集群的部署(一)

        這篇文章中我們將介紹Hadoop集群分布式的部署。

        分布式集群的部署

        虛擬機準備

        分布式的集群,當然需要多個虛擬機的準備。這是使用3臺虛擬機,其中一個為主節點,另外兩個為從節點。其中,上篇文章中已經配置好的虛擬機當做主節點。

        ip和主機名

        兩個從節點的ip分別為:192.168.19.11192.168.19.12。

        兩個從節點的主機名分別為:hadoop101hadoop102。

        配置過程參見上一篇文章。

        注意:這里在配置hosts文件的時候,不僅要配置自己的ip和主機名,還要設置另外兩臺的ip和主機名。即每臺機器都要有如下的配置。

        image.png

        防火墻的關閉

        防火墻都進行關閉。

        ssh免密碼登錄

        這一步在配置的時候有點不同。

        偽分布時只有一臺機器,所以只用實現自己登錄自己就可以了。

        但是在集群中設置免密碼登錄的時候,至少要實現主節點免密碼登錄其他所有節點。

        注意:這里之前要看自己的三臺機器的ip是否屬于同一網段。如果不是,可能會出現連接不上的情況。

        主節點的機器上,使用命令:

        ssh-copy-id -i hadoop101
        ssh-copy-id -i hadoop102

        image.png

        這一步的時候還是需要輸入對應從節點機器的密碼的,然后再用ssh連接的時候就可以實現免密登錄了。

        image.png

        拷貝jdk

        將主節點上我們之前上傳好的jdk拷貝到另外兩天從節點上:

        scp -rq /opt/jdk1.8/ hadoop101:/opt/

        然后還需要將環境變量的配置文件拷貝過去:

        scp -rq /etc/profile hadoop101:/etc/

        然后我們到hadoop101機器上去確認一下:

        image.png

        接著再拷貝另一個從節點的。

        hadoop安裝

        因為我們這里從偽分布式換成分布式,所以首先需要對之前的一些配置文件做些修改。

        hdfs-site.xml:

        <configuration>
            <property>
                <name>dfs.replication</name>
                <value>2</value>
            </property>
            <property>
                <name>dfs.namenode.secondary.http-address</name>
                <value>hadoop100:50090</value>
            </property>
        </configuration>
        注意:這里有兩個從節點了,所以我們的備份數量改為2。然后設定secondaryNameNode的這個進程也是在主節點上啟動。

        yarn-site.xml:

        <configuration>
            <property>
                <name>yarn.nodemanager.aux-services</name>
                <value>mapreduce_shuffle</value>
            </property>
            <property>
                <name>yarn.nodemanager.env-whitelist</name>
                <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
            </property>
            <property>
                <name>yarn.resourcemanager.hostname</name>
                <value>hadoop100</value>
            </property>
        </configuration>
        注意:這里多個一個屬性,用來指定resourcemanager在主節點的機器上啟動

        workers:

        因為現在是集群的結構,我們需要告訴機器那些是從節點。

        vim etc/hadoop/workers

        image.png

        默認是將本機作為從節點的,我們要將hadoop101hadoop102兩臺機器作為從節點。

        刪掉之前的,將兩臺機器的主機名加上:

        hadoop101
        hadoop102

        拷貝hadoop目錄到另外兩臺機器上:

        scp -rq /opt/hadoop-3.2.1/ hadoop101:/opt

        重新格式化

        因為我們這里相當是安裝了一個新的集群,在首次啟動集群前,需要對集群進行格式化。后面在啟動就不需要了。

        刪除文件:

        刪除/data/hadoop_repo/文件夾。

        格式化:

        cd /opt/hadoop-3.2.1
        bin/hdfs namenode -fotmat

        啟動集群

        啟動:

        sbin/start-all.sh

        查看進程:

        image.png

        image.png

        image.png

        主節點上3個進程,從節點上2個進程。啟動成功。

        總結

        偽分布式分布式,整體的部署原理是基本一致的,但是在一些小的細節上有略微的差異。處理好這些差異,才能配置成功。


        參考:

        https://www.imooc.com/video/20729

        查看原文

        贊 2 收藏 0 評論 0

        認證與成就

        • 獲得 75 次點贊
        • 獲得 3 枚徽章 獲得 0 枚金徽章, 獲得 0 枚銀徽章, 獲得 3 枚銅徽章

        擅長技能
        編輯

        開源項目 & 著作
        編輯

        (??? )
        暫時沒有

        注冊于 2018-05-21
        個人主頁被 2.9k 人瀏覽

        一本到在线是免费观看_亚洲2020天天堂在线观看_国产欧美亚洲精品第一页_最好看的2018中文字幕