日本无码免费高清在线|成人日本在线观看高清|A级片免费视频操逼欧美|全裸美女搞黄色大片网站|免费成人a片视频|久久无码福利成人激情久久|国产视频一二国产在线v|av女主播在线观看|五月激情影音先锋|亚洲一区天堂av

  • 手機(jī)站
  • 小程序

    汽車測(cè)試網(wǎng)

  • 公眾號(hào)
    • 汽車測(cè)試網(wǎng)

    • 在線課堂

    • 電車測(cè)試

論文復(fù)現(xiàn)——基于預(yù)測(cè)的自動(dòng)駕駛?cè)驅(qū)Ш叫l(wèi)星系統(tǒng)欺騙攻擊檢測(cè)

2021-03-09 17:46:58·  來源:軒轅實(shí)驗(yàn)室  作者:軒轅實(shí)驗(yàn)室  
 
本文將介紹如何利用已有的數(shù)據(jù)集訓(xùn)練lstm網(wǎng)絡(luò)實(shí)現(xiàn)多變量時(shí)序預(yù)測(cè)模型,以此來檢測(cè)GNSS欺騙攻擊。我們使用了來自 Comma.ai 的真實(shí)數(shù)據(jù)集,名為 Comma2k19,其中包含各種自動(dòng)駕駛車輛傳感器數(shù)據(jù)。該數(shù)據(jù)集的下載和處理過程請(qǐng)參考上篇文章Comma2k19數(shù)據(jù)集使用。
本文將介紹如何利用已有的數(shù)據(jù)集訓(xùn)練lstm網(wǎng)絡(luò)實(shí)現(xiàn)多變量時(shí)序預(yù)測(cè)模型,以此來檢測(cè)GNSS欺騙攻擊。我們使用了來自 Comma.ai 的真實(shí)數(shù)據(jù)集,名為 Comma2k19,其中包含各種自動(dòng)駕駛車輛傳感器數(shù)據(jù)。該數(shù)據(jù)集的下載和處理過程請(qǐng)參考上篇文章Comma2k19數(shù)據(jù)集使用。
 
*本文來自本實(shí)驗(yàn)室涂俊的研究成果和學(xué)習(xí)筆記
 
1.數(shù)據(jù)準(zhǔn)備
Comma.ai 使用的視聽設(shè)備有一個(gè)前置攝像頭、溫度計(jì)和9軸慣性測(cè)量單元。除了這些傳感器數(shù)據(jù),Comma2k19 數(shù)據(jù)集還包含來自全球?qū)Ш叫l(wèi)星系統(tǒng)(GNSS)和控制區(qū)域網(wǎng)絡(luò)(CAN)的測(cè)量值(見表 1 和表 2)。數(shù)據(jù)收集使用了可跟蹤全球?qū)Ш叫l(wèi)星系統(tǒng)的 u-blox M8 全球?qū)Ш叫l(wèi)星系統(tǒng)模塊,水平位置精度為 2.5 米。位置測(cè)量使用了全球定位系統(tǒng)(GPS)和全球軌道導(dǎo)航衛(wèi)星系統(tǒng)(GLONASS)信號(hào)。此外,使用開源的GNSS處理庫(kù) Laika 來減少定位誤差,定位誤差降低了 40%。
在這里我們選擇部分?jǐn)?shù)據(jù)用于接下來的模型中:
  • GNSS數(shù)據(jù)集包含來自 u-blox 和 Qcom 的實(shí)時(shí)和原始導(dǎo)航衛(wèi)星系統(tǒng)數(shù)據(jù)。每個(gè)實(shí)時(shí)數(shù)據(jù)包括緯度、經(jīng)度、速度、utc 時(shí)間戳、高度和方位角數(shù)據(jù)。但它們都是未被Laika優(yōu)化的數(shù)據(jù),為了得到更好的效果,我們采用 global_pose文件夾中的 frame_position、 frame_gps_times和 frame_velocities的數(shù)據(jù),后續(xù)可看情況加入 frame_orientations數(shù)據(jù)。綜合起來用于訓(xùn)練的GNSS數(shù)據(jù)有時(shí)間,經(jīng)緯度(高度可不考慮)和速度,如下表所示: 其中 global_pose\frame_position中的坐標(biāo)是ECEF的(x, y, z),須將其轉(zhuǎn)化為GPS常用的經(jīng)緯度坐標(biāo)(wgs845),Python代碼實(shí)現(xiàn)如下:
import pyproj

transformer = pyproj.Transformer.from_crs(
    {"proj":'geocent', "ellps":'WGS84', "datum":'WGS84'},
    {"proj":'latlong', "ellps":'WGS84', "datum":'WGS84'},
    )
lon, lat, alt = transformer.transform(x,y,z,radians=False)
print (lat1, lon1, alt1 )

要注意返回的經(jīng)緯度順序是Longitude在前,與常規(guī)有所區(qū)別。

  • 相關(guān)的 CAN數(shù)據(jù)是CAN時(shí)間,車速和方向盤轉(zhuǎn)角數(shù)據(jù)(見表2),可分別從 processed_log/CAN/speed/t、 processed_log/CAN/speed/value和 processed_log/CAN/steering_angle/value讀取, 樣例如下表所示。 
  • 同樣,相關(guān)的IMU數(shù)據(jù)是三個(gè)方向的加速度,可分別從processed_log/IMU/accelerometer/t和processed_log/IMU/accelerometer/value中讀取,樣例如下表所示。
時(shí)間處理
值得注意的是,用于分析的數(shù)據(jù)集包含7200個(gè)GNSS觀測(cè)值、35726個(gè)CAN觀測(cè)值和72148個(gè)IMU觀測(cè)值,GNSS、CAN和IMU數(shù)據(jù)的頻率分別為10、50和100赫茲。這意味著不同數(shù)據(jù)源的時(shí)間是有略微不同的,在本項(xiàng)目中GNSS時(shí)間被用作參考時(shí)間,所有其他傳感器數(shù)據(jù)被同步,以便為L(zhǎng)STM模型準(zhǔn)備訓(xùn)練和測(cè)試數(shù)據(jù)集。為了在作為參考時(shí)間的準(zhǔn)確時(shí)間獲得CAN和IMU的數(shù)據(jù),在GNSS的兩個(gè)最近觀測(cè)值之間要對(duì)CAN和IMU進(jìn)行插值,在這里我采用scipy的樣條插值方法,Python代碼實(shí)現(xiàn)如下:
from scipy.interpolate import make_interp_spline

CAN_time = np.load(example_segment + 'processed_log/CAN/speed/t')
gps_time = np.load(example_segment + 'global_pose/frame_times')
# 對(duì)CAN的速度進(jìn)行插值
CAN_speed = np.load(example_segment + 'processed_log/CAN/speed/value')
new_CAN_speed = make_interp_spline(CAN_time, CAN_speed)(gps_time)

plt.figure(figsize=(12, 12))
    plt.plot(CAN_time, CAN_speed, label='CAN')
    plt.plot(gps_time, new_CAN_speed, label='new_CAN')
    plt.legend(fontsize=25)
    plt.xlabel('boot time (s)', fontsize=18)
    plt.ylabel('speed (m/s)', fontsize=18)
    plt.show()

當(dāng)處理時(shí)間數(shù)據(jù)的時(shí)候我發(fā)現(xiàn)它們存在一些小瑕疵——有重復(fù)值,而且即使是同樣來自CAN的數(shù)據(jù),speed的時(shí)間和steering_angle的時(shí)間也是不一致的,這意味著它們要分別讀取,分別插值。Python代碼實(shí)現(xiàn): # 數(shù)組去重
def unique(old_list):
    newList = []
    # 判斷相鄰時(shí)間是否相等
    if np.any(old_list[1:] == old_list[:-1]):
        for x in old_list:
            if x in newList:
                # 若相等,則加上一個(gè)微小的數(shù)使其不等
                x = x + 0.005
            newList.append(x)
        return np.array(newList)
    else: return old_list
    
temp_CAN_times = np.load(main_dir + '\\processed_log\\CAN\\speed\\t')
# 確保時(shí)間無重復(fù)值
temp_CAN_speed_times = unique(temp_CAN_times)
# CAN_angles_times和CAN_speed_times有時(shí)不一致
temp_CAN_angles_times = np.load(main_dir + '\\processed_log\\CAN\\steering_angle\\t')
temp_CAN_angles_times = unique(temp_CAN_angles_times)
temp_IMU_times = np.load(main_dir + '\\processed_log\\IMU\\accelerometer\\t')

距離計(jì)算

當(dāng)我們預(yù)測(cè)自動(dòng)駕駛車輛當(dāng)前位置和最近未來位置之間的行駛距離時(shí),從上一個(gè)時(shí)間步長(zhǎng)開始的每個(gè)時(shí)間步長(zhǎng)中的行駛距離是使用緯度和經(jīng)度坐標(biāo)以及以下哈弗辛大圓公式計(jì)算的:Python實(shí)現(xiàn)如下: import math
EARTH_REDIUS = 6378.137

def rad(d):
    return d * math.pi / 180.0
def getDistance(lats1, lngs1, lats2, lngs2):
    # 對(duì)數(shù)組取元素做運(yùn)算
    res = []
    for i in range(len(lat1)):
        radLat1 = rad(lat1[i])
        radLat2 = rad(lat2[i])
        a = radLat1 - radLat2
        b = rad(lng1[i]) - rad(lng2[i])
        s = 2 * math.asin(math.sqrt(math.pow(math.sin(a / 2), 2) + math.cos(radLat1) * math.cos(radLat2) * math.pow(
            math.sin(b / 2), 2)))
        s = s * EARTH_REDIUS * 1000
        res.append(s)
    return res
    
# 計(jì)算距離    
distance = getDistance(lats1, lngs1, lats2, lngs2)
plt.plot(times[:-1], distance, label='distance')
plt.title('Traveled distance between two consecutive timestamps', fontsize=20);
plt.legend(fontsize=20);
plt.xlabel('boot time (s)', fontsize=18);
plt.ylabel('distance(m) ', fontsize=18);
plt.show()

在這里插入圖片描述

與速度圖相比較,可以發(fā)現(xiàn)形狀相似,說明計(jì)算無誤。對(duì)一個(gè)segment的distance繪圖沒有問題,但如果對(duì)一個(gè)route的多個(gè)segment一個(gè)繪圖就會(huì)發(fā)現(xiàn)存在異常值,如下圖所示:可以看到異常值使得曲線非常不光滑藍(lán)色框中的數(shù)據(jù)和周邊數(shù)據(jù)明顯不同,對(duì)于這個(gè)問題我咨詢comma.ai得到的解釋是:每個(gè)segment的數(shù)據(jù)是分別優(yōu)化的,并不保證segment之間坐標(biāo)的連續(xù)性,所以每跨一個(gè)段時(shí)(60s),就會(huì)出現(xiàn)這樣的異常值。由于這些異常值占比極小,可忽略不計(jì)。

合并數(shù)據(jù)集
對(duì)比GNSS的速度與CAN的速度我們會(huì)發(fā)現(xiàn)存在偏差,考慮到CAN速度會(huì)比GNSS速度更能反映實(shí)際情況,故只采用CAN的速度,我們使用LSTM模型來預(yù)測(cè)每個(gè)時(shí)間戳的當(dāng)前位置和最近的未來位置之間的距離,使用無攻擊的CAN、IMU和GNSS數(shù)據(jù)。在本文中,我們使用的LSTM模型由一個(gè)輸入層、一個(gè)具有50個(gè)神經(jīng)元的遞歸隱藏層和一個(gè)輸出層組成。訓(xùn)練LSTM模型的輸入數(shù)據(jù)包括來自控制器局域網(wǎng)的速度和轉(zhuǎn)向角數(shù)據(jù)以及來自慣性測(cè)量單元的前向加速度數(shù)據(jù)。輸出是每個(gè)時(shí)間戳當(dāng)前位置和最近未來位置之間的距離。在訓(xùn)練數(shù)據(jù)規(guī)模上我們有考量,每個(gè)chunk之間甚至同一個(gè)chunk內(nèi)不同route的數(shù)據(jù)都是不相關(guān)的,他們之間的不連續(xù)性使得它們沒法反映真實(shí)情況,所幸同一個(gè)route之間的segments是基本連續(xù)的,我們將訓(xùn)練范圍縮小至一個(gè)route文件夾的數(shù)據(jù),如果用其他場(chǎng)景豐富且時(shí)間連續(xù)的數(shù)據(jù)集訓(xùn)練效果會(huì)更好,讀取數(shù)據(jù)的代碼實(shí)現(xiàn)如下:
dataset_directory = 'D:\comma2k19'
    chunk_set = []
    for chunk in os.listdir(dataset_directory):
        # 忽略生成的csv文件
        if ".csv" in chunk:
            continue
        # 如果序號(hào)為單個(gè)時(shí)在前補(bǔ)零,以便后面排序
        if len(chunk) == 7:
            used_name = chunk
            chunk = str_insert(chunk,6,'0')
            os.rename(os.path.join(dataset_directory, used_name), os.path.join(dataset_directory, chunk))
        chunk_set.append(os.path.join(dataset_directory, chunk))
    # 將序號(hào)小的片段放在前面
    chunk_set.sort()
    # 選一個(gè)chunk來訓(xùn)練(200分鐘)
    chunk_index = 0
    route_set = []
    for route_id in os.listdir(chunk_set[chunk_index]):
        # 忽略生成的csv文件
        if ".csv" in route_id:
            continue
        route_set.append(os.path.join(chunk_set[chunk_index], route_id))
    segment_set = []
    # 選一個(gè)路段訓(xùn)練
    route_index = 9
    for segment in os.listdir(route_set[route_index]):
        # 如果序號(hào)為單個(gè)時(shí)在前補(bǔ)零,以便后面排序
        if len(segment) == 1:
            used_name = segment
            segment = '0'+segment
            os.rename(os.path.join(route_set[route_index], used_name),os.path.join(route_set[route_index], segment))
        segment_set.append(os.path.join(route_set[route_index], segment))
    # 將序號(hào)小的片段放在前面
    segment_set.sort()
    times = []
    lons = []
    lats = []
    orientations = []
    CAN_speeds = []
    steering_angles = []
    acceleration_forward = []
    for main_dir in segment_set:
        # 導(dǎo)入GNSS的時(shí)間和位置(pose)并將位置轉(zhuǎn)化為經(jīng)緯度
        temp_GNSS_time = np.load(main_dir + '\\global_pose\\frame_times')
        times = np.append(times, temp_GNSS_time)
        # 打印每一段的長(zhǎng)度
        print(len(temp_GNSS_time))
        positions = np.load(main_dir + '\\global_pose\\frame_positions')
        positions = position_transformer.transform(positions[:, 0], positions[:, 1], positions[:, 2], radians=False)
        lats = np.append(lats, positions[1])
        lons = np.append(lons, positions[0])
        temp_CAN_times = np.load(main_dir + '\\processed_log\\CAN\\speed\\t')
        # 確保時(shí)間無重復(fù)值
        temp_CAN_speed_times = unique(temp_CAN_times)
        # 對(duì)CAN數(shù)據(jù)按照GNSS參考時(shí)間插值
        temp_CAN_speeds = make_interp_spline(temp_CAN_speed_times, np.load(main_dir + '\\processed_log\\CAN\\speed\\value'))(temp_GNSS_time).flatten()
        CAN_speeds = np.append(CAN_speeds, temp_CAN_speeds)
        # CAN_angles_times和CAN_speed_times有時(shí)不一致
        temp_CAN_angles_times = np.load(main_dir + '\\processed_log\\CAN\\steering_angle\\t')
        temp_steering_angles = np.load(main_dir + '\\processed_log\\CAN\\steering_angle\\value')
        temp_CAN_angles_times = unique(temp_CAN_angles_times)
        temp_steering_angles = make_interp_spline(temp_CAN_angles_times, temp_steering_angles)(temp_GNSS_time)
        steering_angles = np.append(steering_angles, temp_steering_angles)
        # 對(duì)IMU數(shù)據(jù)按照GNSS參考時(shí)間插值
        temp_IMU_times = np.load(main_dir + '\\processed_log\\IMU\\accelerometer\\t')
        temp_acceleration_forward = make_interp_spline(temp_IMU_times, np.load(main_dir +
                                '\\processed_log\\IMU\\accelerometer\\value')[:, 0])(temp_GNSS_time)
        acceleration_forward = np.append(acceleration_forward, temp_acceleration_forward)        
轉(zhuǎn)化為監(jiān)督學(xué)習(xí)問題

該問題本質(zhì)是監(jiān)督學(xué)習(xí)問題,當(dāng)前是時(shí)刻的速度,轉(zhuǎn)角和前向加速度是feature,下一時(shí)刻位置離當(dāng)前時(shí)刻位置的距離將作為標(biāo)簽,更多有關(guān)時(shí)序數(shù)據(jù)預(yù)測(cè)問題轉(zhuǎn)化為監(jiān)督學(xué)習(xí),參考https://blog.csdn.net/qq_28031525/article/details/79046718,Python代碼實(shí)現(xiàn)如下: def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    n_vars = 1 if type(data) is list else data.shape[1]
    df = pd.Dataframe(data)
    column_names = ['lats', 'lons', 'CAN_speeds', 'steering_angles', 'acceleration_forward']
    cols, names = list(), list()
    # input sequence (t-n, ... t-1)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names += [('%s(t-%d)' % (j, i)) for j in column_names]
    # forecast sequence (t, t+1, ... t+n)
    for i in range(0, n_out):
        cols.append(df.shift(-i))
        if i == 0:
            names += [('%s(t)' % (j)) for j in column_names]
        else:
            names += [('%s(t+%d)' % (j, i)) for j in column_names]
    # put it all together
    agg = pd.concat(cols, axis=1)
    agg.columns = names
    # drop rows with NaN values
    if dropnan:
        agg.dropna(inplace=True)
    return agg
    
DataSet = list(zip(times, lats, lons, CAN_speeds, steering_angles, acceleration_forward))
column_names = ['times', 'lats', 'lons', 'CAN_speeds', 'steering_angles', 'acceleration_forward']
df = pd.Dataframe(data=DataSet, columns=column_names)
times = df['times'].values
df = df.set_index(['times'], drop=True)
values = df.values.astype('float64')
# 轉(zhuǎn)為監(jiān)督學(xué)習(xí)問題, 其實(shí)就是將下一時(shí)刻的特征(distance)作為當(dāng)前時(shí)刻的標(biāo)簽
reframed = series_to_supervised(values, 1, 1)
# 計(jì)算距離
lons_t = reframed['lons(t)'].values
lats_t = reframed['lats(t)'].values
distance = np.array(getDistance(lats[:-1], lons[:-1], lats_t, lons_t))
# drop columns we don't want to predict including(CAN_speed,steering_angel, acceleration_forward)
reframed.drop(reframed.columns[[0, 1, 5, 6, 7, 8, 9]], axis=1, inplace=True)
# 時(shí)間和計(jì)算的距離添加到數(shù)據(jù)集
reframed['distance'] = distance
reframed['times'] = times[: -1]
# for i in distance:
#     if i > 100:
#         print(i)
plt.plot(times[:-1], distance)
plt.xlabel('Boot time (s)', fontsize=18)
plt.ylabel('Distance travelled during single timestamp (m) ', fontsize=12)
plt.show()
# 將合并的數(shù)據(jù)保存為.csv文件
reframed.to_csv(route_set[route_index]+".csv", index=False, sep=',')

這部分工作可以讓我們?cè)谥付ǖ姆秶鷥?nèi)提取我們想要的數(shù)據(jù),生成可供讀寫的.csv文件,可供訓(xùn)練和測(cè)試階段直接利用。

模型訓(xùn)練和評(píng)估
讀取數(shù)據(jù)
首先你需要任意選擇兩個(gè)route文件夾的數(shù)據(jù)分別做訓(xùn)練集合測(cè)試集,這可以通過data_prepare.py完成,接下來就是將他們分別讀進(jìn)來,并做一些處理,其中歸一化可以提升訓(xùn)練效果和收斂速度,示例代碼如下:
train_CSV_FILE_PATH = 'D:\\comma2k19\\Chunk_01\\b0c9d2329ad1606b_2018-08-02--08-34-47.csv'
test_CSV_FILE_PATH = 'D:\\comma2k19\\Chunk_01\\b0c9d2329ad1606b_2018-08-01--21-13-49.csv'
train_df = pd.read_csv(train_CSV_FILE_PATH)
test_df = pd.read_csv(test_CSV_FILE_PATH)
train_values = train_df.to_numpy()
train_times = train_values[:, -1]
train_distance = train_values[:, -2]
test_values = test_df.to_numpy()
test_times = test_values[:, -1]
test_distance = test_values[:, -2]
# 將輸入特征歸一化
scaler = MinMaxScaler(feature_range=(0, 1))
train_X, train_y = scaler.fit_transform(train_values[:, :-2]), train_distance
test_X, test_y = scaler.fit_transform(test_values[:, :-2]), test_distance
設(shè)計(jì)網(wǎng)絡(luò)并訓(xùn)練

我們直接使用keras的lstm模塊來建立網(wǎng)絡(luò)模型,請(qǐng)確保你已搭建好相應(yīng)環(huán)境?,F(xiàn)在可以搭建LSTM模型了。LSTM模型中,隱藏層有50個(gè)神經(jīng)元,輸出層1個(gè)神經(jīng)元(回歸問題),輸入變量是一個(gè)時(shí)間步(t-1)的特征,損失函數(shù)采用Mean Absolute Error(MAE),優(yōu)化算法采用Adam。  # 設(shè)計(jì)網(wǎng)絡(luò)
model = Sequential()
model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
model.add(Dense(1))
# 設(shè)置學(xué)習(xí)率等參數(shù)
# adam = optimizers.Adam(lr=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
model.compile(loss='mae', optimizer='adam')
# fit network
history = model.fit(train_X, train_y, epochs=500, batch_size=1200, validation_data=(test_X, test_y), verbose=2,
                    shuffle=False)
model.save('lstm.model')
# full_X = values[:, :3]
# full_X = full_X.reshape((full_X.shape[0], 1, full_X.shape[1]))
train_yhat = model.predict(train_X)[:, 0]
test_yhat = model.predict(test_X)[:, 0]
rmse = math.sqrt(mean_squared_error(test_yhat, test_y))
print('Test RMSE: %.3f' % rmse)
# plot history
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='test')
plt.legend()
plt.show()

學(xué)習(xí)率可以通過optimizer來設(shè)置,adam默認(rèn)為0.01,其他超參數(shù)可參考表4:評(píng)估的python代碼如下: import pandas as pd
import math
from sklearn.metrics import mean_squared_error
import matplotlib.pyplot as plt
import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler
gpus = tf.config.experimental.list_physical_devices('GPU')
for gpu in gpus:
    tf.config.experimental.set_memory_growth(gpu, True)
def average(seq, total=0.0):
  num = 0
  for item in seq:
    total += item
    num += 1
  return total / num

if __name__ == '__main__':

    CSV_FILE_PATH = 'D:\\comma2k19\\Chunk_03\\99c94dc769b5d96e_2018-05-01--08-13-53.csv'
    df = pd.read_csv(CSV_FILE_PATH)
    values = df.to_numpy()
    times = values[:, -1]
    distance = values[:, -2]
    model = tf.keras.models.load_model('lstm.model')
    test_X = values[:, :3]
    # 因?yàn)橛?xùn)練的時(shí)候輸入特征是歸一化的,所以預(yù)測(cè)的時(shí)候也要將輸入特征歸一化
    scaler = MinMaxScaler(feature_range=(0, 1))
    test_X = scaler.fit_transform(test_X)
    test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
    # train_len = (int)(0.75 * len(values[:, 0]))
    # train = values[:train_len, :]
    # test = values[train_len:, :]
    test_y = distance
    yhat = model.predict(test_X)[:, 0]
    rmse = math.sqrt(mean_squared_error(yhat, test_y))
    print('Test RMSE: %.3f' % rmse)
    scores = model.evaluate(test_X, test_y)
    rmse = math.sqrt(mean_squared_error(yhat, test_y))
    plt.plot(times, yhat, label='prediction')
    plt.plot(times, distance, label="ground_truth")
    plt.title('Comparison between truth and prediction', fontsize=18)
    plt.xlabel('Boot time (s)', fontsize=18)
    plt.ylabel('Distance travelled during single timestamp (m) ', fontsize=12)
    plt.legend()
    plt.show()
    min = min((distance - yhat), key=abs)
    max = max((distance - yhat), key=abs)
    avr = average(distance-yhat)
    print('Min:%f' % min)
    print('Max:%f' % max)
    print('average:%f' % avr)

使用其他epoch和batch_size訓(xùn)練

我令訓(xùn)練集和測(cè)試集分別取自不同的route,來看訓(xùn)練情況是否更好

  • 當(dāng)batch_size = 50 epoch  = 100時(shí),訓(xùn)練時(shí)loss在epoch = 50左右就不動(dòng)了 
測(cè)試集上的預(yù)測(cè)效果如下:重新挑選一個(gè)route進(jìn)行預(yù)測(cè),可以看出預(yù)測(cè)效果還是不錯(cuò)的,誤差絕對(duì)值的最大最小和平均值分別如下:
在這里插入圖片描述
  • 由于每一段數(shù)據(jù)基本都由1200個(gè)數(shù)據(jù)組成,所以我想令batch_size = 1200,這樣分段訓(xùn)練,每訓(xùn)練一個(gè)segment再調(diào)整梯度,于是我令 batch_size = 1200 epoch = 300,發(fā)現(xiàn)訓(xùn)練速度很快,誤差也比較理想。
說明batch_size = 1200  epoch = 300訓(xùn)練效果更好,用非測(cè)試集去做預(yù)測(cè)評(píng)估,大部分的誤差都不大
誤差的最大最小和平均值分別如下:
這可能是訓(xùn)練集太小導(dǎo)致的,訓(xùn)練集只有10分鐘,不足以包含所有情況。模型本身很好,但需要尋找更好的數(shù)據(jù)集來進(jìn)行訓(xùn)練。
完整代碼已上傳到Github,地址https://github.com/Juntu-hub/Prediction-based-GNSS-Spoofing-Attack-Detection-for-Autonomous-Vehicle.git
分享到:
 
反對(duì) 0 舉報(bào) 0 收藏 0 評(píng)論 0
滬ICP備11026917號(hào)-25