<form id="9h9n7"></form>

        <address id="9h9n7"><address id="9h9n7"></address></address>

        <span id="9h9n7"></span><noframes id="9h9n7">

        歡迎來到長春三峰光電儀器制造有限公司!

        長春三峰光電儀器制造有限公司

        高精度編碼器成功進入中國航天領域

        被列為重點攻關計劃并已多次榮獲科技創新項目基金!

        咨詢熱線
        0431-85102283
        新聞中心
        您的位置:首頁 > 行業新聞 > 詳細內容

        TensorFlow 2:使用自編碼器進行插值

        發布者:長春三峰光電儀器制造有限公司2021-02-22

        自編碼

        自編碼器是另一種用于以壓縮方式再現輸入的神經網絡。自編碼器有一個特殊的特性,即輸入神經元的數目與輸出神經元的數目相同。

        請看上圖。Autoencoder的目標是在輸出層創建輸入的表示,使得輸出和輸入是相似的。

        Autoencoder的實際用途是確定具有最低數據丟失量的輸入數據的壓縮版本。這與主成分分析非常相似,但是是以黑盒的方式進行的。自編碼器的編碼器部分在壓縮數據的同時,確保重要數據不丟失,但數據的大小減少。

        使用Autoencoder進行插值的缺點是壓縮數據是一種黑盒表示法—我們不知道壓縮版本中數據的結構。

        假設有一個有10個參數的數據集,我們在這個數據上訓練一個自編碼器。編碼器并沒有為了更好的表示而忽略一些參數,但是它將這些參數融合在一起以創建一個壓縮的版本(將參數的數量從10個減少到5個)。

        自編碼器有兩個部分,編碼器和解碼器。編碼器壓縮輸入數據,解碼器則相反地產生數據的未壓縮版本,以產生盡可能接近原始輸入的重構輸入。

        插值方法

        插值是在兩個數據點之間猜測函數值的過程。例如,給定x=[1,3,5,7,9],y=[230.02,321.01,305.00,245.75,345.62],再給定x=4,你想知道y的值是多少。

        有大量的插值方法,有些是基于模型的,有些是無模型的,即數據驅動的。實現插值最常用的方法是通過數據擬合。例如,使用線性回歸分析將線性模型擬合到給定的數據。

        在線性回歸中,給定預測變量X和響應變量Y,使用公式Y=β0+β1X擬合數據,其中β0和β1使用最小二乘擬合確定。

        顧名思義,線性回歸是線性的,也就是說,即使預測變量和響應變量之間的關系可能是非線性的,它也是一條直線或者超平面。

        然而,最普遍的插值形式是多項式擬合。給定k個采樣點,擬合k-1次多項式是很簡單的。給定數據集*{xi, yi}*,多項式擬合是通過確定函數的多項式系數ai來獲得的。

        通過以下表達式求解矩陣求逆:

        一旦我們有了系數ai,我們就可以找到任意x的函數f的值。

        有一些多項式擬合的特殊情況,其中用分段三次多項式來擬合數據。其他一些非參數方法包括三次樣條、平滑樣條、回歸樣條、核回歸和密度估計。

        本文的重點不是多項式擬合,而是插值。多項式擬合恰好有助于插值。多項式擬合方法存在一個問題——無論是參數擬合還是非參數擬合,它們的行為方式都與所教的相同。它的意思是,如果數據是干凈的,擬合將是干凈和平滑的,但如果數據是有噪聲的,擬合將是有噪聲的。

        此問題在傳感器數據中更為普遍,例如,從心率傳感器捕獲的心跳數據、從激光雷達獲取的距離數據、從汽車獲取的CAN總線速度數據、GPS數據等。

        https://medium.com/analytics-vidhya/how-does-a-self-driving-vehicle-see-using-lidar-49f569ededf2

        此外,由于噪聲的存在,它們更難處理,特別是當你的算法需要對這些數據執行雙重或二階導數時。

        一般來說,這些傳感器數據是時間序列數據,即它們是隨時間收集的,因此響應變量可能是一些物理量,例如速度、物體與安裝在自動駕駛汽車頂部的激光雷達的距離、心率,并且預測變量是時間。

        在對這些數據進行操作時,可能有幾個目標:我想將數據插值到某個時間戳上,在該時間戳上,我的傳感器無法記錄任何響應,但由于傳感器在實時世界中工作,并且由于潛在的物理原因,這些數據保持嘈雜,我還想要一個可靠的插值,不受傳感器噪聲的影響。

        此外,我的要求還可能包括此類時間序列數據的導數。但是導數往往會放大潛在時間序列數據中的噪聲。如果有一種方法,我可以得到數據的底層表示,同時拋棄噪聲呢?在這種情況下,自編碼器可以來實現我的目標。

        自編碼器作為插補器

        為了演示使用Autoencoder的去噪+插值目標,我使用了一個由我的實驗室從車輛收集的距離數據的例子,其中因變量是前一輛車在我的車輛前面的距離,自變量是時間。

        我在GitHub repo上提供了一小部分數據,作為演示的一部分,你可以自由使用。但是它非常小,除了本文所描述的教程之外,沒有其他用途。

        https://github.com/rahulbhadani/medium.com/blob/master/data/lead_dist_sample.csv

        好了,現在該編碼了。

        注意:在使用數據之前,我應該指出時間(自變量)和響應變量(因變量)必須重新縮放。在我的例子中,原始時間從1594247088.289515開始(POSIX格式,以秒為單位),到1594247110.290019結束。我使用公式(time - start_time)/(end_time - start_time)規范化了我的時間值。類似地,響應變量使用(message - message_min)/(message_max -message_min)進行規范化。

        我的GitHub中提供的示例數據已經標準化了,你可以直接重用它。

        訓練

        import globimport numpy as npimport matplotlib.pyplot as pltimport pandas as pdimport numpy as npdf = pd.read_csv("../data/lead_dist_sample.csv")time = df['Time']message = df['Message']import tensorflow as tfmodel = tf.keras.Sequential()model.add(tf.keras.layers.Dense(units = 1, activation = 'linear', input_shape=[1]))model.add(tf.keras.layers.Dense(units = 128, activation = 'relu'))model.add(tf.keras.layers.Dense(units = 64, activation = 'relu'))model.add(tf.keras.layers.Dense(units = 32, activation = 'relu'))model.add(tf.keras.layers.Dense(units = 64, activation = 'relu'))model.add(tf.keras.layers.Dense(units = 128, activation = 'relu'))model.add(tf.keras.layers.Dense(units = 1, activation = 'linear'))model.compile(loss='mse', optimizer="adam")model.summary()# 訓練model.fit( time, message, epochs=1000, verbose=True)如你所見,我沒有執行任何正則化,因為我要進行過擬合,以便能夠充分利用數據的基本特征,F在是時候做出預測了。

        你將看到,在進行預測之前,我將時間軸重新縮放回原始值。對于本例,time_original[0] = 1594247088.289515 ,time_original[-1] = 1594247110.290019 , msg_min = 33, msg_max = 112

        newtimepoints_scaled = np.linspace(time[0] - (time[1] - time[0]),time[-1], 10000)y_predicted_scaled = model.predict(newtimepoints_scaled)newtimepoints = newtimepoints_scaled*(time_original[-1] - time_original[0]) + time_original[0]y_predicted = y_predicted_scaled*(msg_max - msg_min) + msg_min注意,我正在用可變的newtimepoints_scaled創建更密集的時間點,它允許我在看不見的時間點上插入數據。最后,曲線如下:

        # 顯示結果import matplotlib.pylab as pylabparams = {'legend.fontsize': 'x-large', 'figure.figsize': (15, 5), 'axes.labelsize': 'x-large', 'axes.titlesize':'x-large', 'xtick.labelsize':'x-large', 'ytick.labelsize':'x-large'}pylab.rcParams.update(params)plt.scatter(time*(1594247110.290019 - 1594247088.289515) + 1594247088.289515, message*(112 - 33) + 33, label='Original Data')plt.scatter(newtimepoints, y_predicted, c = 'red', s = 1, label = 'Interpolated Data')plt.xlabel('Time')plt.ylabel('Message')plt.legend()plt.show()

        結尾

        雖然我只訓練了1000個epoch,但如果你的數據很大的話,你的訓練可能不會那么短。這種方法的最大優點是采用導數,從下面的圖中可以看出,對原始數據執行的導數很差——甚至可能不能代表真正的導數!

        df_interpolation = pd.DataFrame()df_interpolation['Time'] = newtimepointsdf_interpolation['Message'] = y_predicteddf_interpolation['diff'] = df_interpolation['Message'].diff()/df_interpolation['Time'].diff()df_original = pd.DataFrame()df_original['Time'] = time*(1594247110.290019 - 1594247088.289515) + 1594247088.289515df_original['Message'] = message*(112 - 33) + 33df_original['diff'] = df_original['Message'].diff()/df_original['Time'].diff()# 顯示結果import matplotlib.pylab as pylabparams = {'legend.fontsize': 'x-large', 'figure.figsize': (15, 5), 'axes.labelsize': 'x-large', 'axes.titlesize':'x-large', 'xtick.labelsize':'x-large', 'ytick.labelsize':'x-large'}pylab.rcParams.update(params)plt.scatter(df_original['Time'], df_original['diff'], label='Derivative on Original Data')plt.scatter(df_interpolation['Time'], df_interpolation['diff'], s= 10, c = 'red', label='Derivative on Interpolated Data')plt.xlabel('Time')plt.ylabel('Message')plt.legend()plt.show()

        這種方法唯一的缺點是時間復雜。根據數據點的數量,可能需要數小時才能完成訓練。但是,如果你可以訪問高性能計算集群、amazonec2或類似的應用程序,那么訓練自編碼器可能不會花費太多時間。

        久久亚洲国产精品亚洲_欧美乱亚洲_色婷婷五月色综合小说_欧美日韩国产在线一区二区_A级特黄色大片