基於飛槳實現高光譜反演:經過遙感數據獲取土壤某物質含量

飛槳開發者說】馬雲飛,棗莊學院地理信息科學專業在讀,計算機視覺技術愛好者,研究方向爲神經網絡在遙感領域的應用等。php

 

高光譜反演是什麼?git

高光譜反演是使用遙感衛星拍攝的高光譜數據以及實地採樣化驗的某物質含量數據來創建一個反演模型。簡單來講就是:有模型之後衛星一拍,就能得知土壤中某物質的含量,不用實地採樣化驗了。

高光譜遙感可應用在礦物精細識別(好比油氣資源及災害探測)、地質環境信息反演(好比植被重金屬污染探測)、行星地質探測(好比中國行星探測工程 天問一號)等。github

目前有許多模型可用於高光譜反演,如線性模型、天然對數模型、包絡線去除模型、簡化Hapke模型,人工神經網絡模型等,本文選擇線性模型進行研究。算法

下載安裝命令

## CPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

準備數據集緩存

本次使用的數據集是前段時間跟一位博士師哥學習時使用的數據,是師哥辛辛苦苦從各地採樣帶回實驗室化驗以及處理遙感圖像得來的。咱們經常使用的遙感衛星有高分一號、高分二號、Landsat7 、Landsat8等。以Lansat8爲例,其OLI陸地成像儀包括9個波段,空間分辨率爲30米,其中包括一個15米的全色波段,成像寬幅爲185x185km。熱紅外傳感器TIRS包括2個單獨的熱紅外波段,分辨率100米。如下是各波段的常見用途。

本次使用的數據集格式以下:網絡

切割數據的比例要考慮到兩個因素:更多的訓練數據會下降參數估計的方差,從而獲得更可信的模型;而更多的測試數據會下降測試偏差的方差,從而獲得更可信的測試偏差。咱們這個例子中設置的分割比例爲8:2。數據結構

如下代碼可直接在百度AI Studio 上fork個人項目來運行:app

https://aistudio.baidu.com/aistudio/projectdetail/693750/框架

dataset = pd.read_csv('data/data48548/data.csv')#讀取數據集  
# df轉array  
values = dataset.values  
# 原始數據標準化,爲了加速收斂  
scaler = MinMaxScaler(feature_range=(01))  
scaled = scaler.fit_transform(values)  
data = scaled  

ratio = 0.8 # 訓練集和驗證集的劃分比例  
offset = int(data.shape[0]*ratio)  
train_data = data[:offset]  
test_data = data[offset:]  

def reader_creator(train_data):    
    def reader():    
        for d in train_data:    
            yield d[:-1], d[-1:]    
    return reader  

BUF_SIZE=50  
BATCH_SIZE=20  

#用於訓練的數據提供器,每次從緩存中隨機讀取批次大小的數據  
train_reader = paddle.batch(  
    paddle.reader.shuffle(reader_creator(train_data),   
                          buf_size=BUF_SIZE),                      
    batch_size=BATCH_SIZE)     
#用於測試的數據提供器,每次從緩存中隨機讀取批次大小的數據  
test_reader = paddle.batch(  
    paddle.reader.shuffle(reader_creator(test_data),  
                          buf_size=BUF_SIZE),  
    batch_size=BATCH_SIZE)   

配置訓練程序函數

 

下面咱們開始配置訓練程序,目的是定義一個訓練模型的網絡結構。

對於線性迴歸來說,它就是一個從輸入到輸出的簡單的全鏈接層。訓練程序必須返回 平均損失做爲第一個返回值,由於它會被後面反向傳播算法所用到。

優化器選擇的是 SGD(隨機梯度降低)optimizer,其中 learning_rate 是學習率,與網絡的訓練收斂速度有關係。代碼以下:

#定義張量變量x,表示14維的特徵值
x = fluid.layers.data(name='x', shape=[14], dtype='float32')
#定義張量y,表示1維的目標值
y = fluid.layers.data(name='y', shape=[1], dtype='float32')
#定義一個簡單的線性網絡,鏈接輸入和輸出的全鏈接層
#input:輸入tensor;
#size:該層輸出單元的數目
#act:激活函數
y_predict=fluid.layers.fc(input=x,size=1,act=None)

cost = fluid.layers.square_error_cost(input=y_predict, label=y) #求一個batch的損失值
avg_cost = fluid.layers.mean(cost)  

optimizer = fluid.optimizer.SGDOptimizer(learning_rate=0.001)
opts = optimizer.minimize(avg_cost)

開始訓練

請使用以下代碼開始訓練,其中EPOCH_NUM爲模型的訓練輪數,這個數量要適中,不然可能發生過擬合等問題

model_save_dir:模型的保存目錄,保存下來,下次就能夠繼續訓練或者直接推理了。

for pass_id in range(EPOCH_NUM):                                  #訓練EPOCH_NUM輪
    # 開始訓練並輸出最後一個batch的損失值
    train_cost = 0
    for batch_id, data in enumerate(train_reader()):              #遍歷train_reader迭代器
        train_cost = exe.run(program=fluid.default_main_program(),#運行主程序
                             feed=feeder.feed(data),              #喂入一個batch的訓練數據,根據feed_list和data提供的信息,將輸入數據轉成一種特殊的數據結構
                             fetch_list=[avg_cost])    
        if batch_id % 40 == 0:
            print("Pass:%d, Cost:%0.5f" % (pass_id, train_cost[0][0]))    #打印最後一個batch的損失值
        iter=iter+BATCH_SIZE
        iters.append(iter)
        train_costs.append(train_cost[0][0])


    # 開始測試並輸出最後一個batch的損失值
    test_cost = 0
    for batch_id, data in enumerate(test_reader()):               #遍歷test_reader迭代器
        test_cost= exe.run(program=test_program, #運行測試cheng
                            feed=feeder.feed(data),               #喂入一個batch的測試數據
                            fetch_list=[avg_cost])                #fetch均方偏差
    print('Test:%d, Cost:%0.5f' % (pass_id, test_cost[0][0]))     #打印最後一個batch的損失值

訓練過程圖:

模型預測

須要構建一個使用訓練好的模型來進行預測的程序,訓練好的模型位置在 model_save_dir 。

with fluid.scope_guard(inference_scope):#修改全局/默認做用域(scope), 運行時中的全部變量都將分配給新的scope。
    #從指定目錄中加載 推理model(inference model)
    [inference_program,                             #推理的program
     feed_target_names,                             #須要在推理program中提供數據的變量名稱
     fetch_targets] = fluid.io.load_inference_model(#fetch_targets: 推斷結果
                                    model_save_dir, #model_save_dir:模型訓練路徑 
                                    infer_exe)      #infer_exe: 預測用executor
    #獲取預測數據
    infer_reader = paddle.batch(reader_creator(test_data),  #測試數據
                          batch_size=20)                #從測試數據中讀取一個大小爲20的batch數據
    #從test_reader中分割x
    test_data = next(infer_reader())
    test_x = np.array([data[0for data in test_data]).astype("float32")
    test_y= np.array([data[1for data in test_data]).astype("float32")
    results = infer_exe.run(inference_program,                #預測模型
    feed={feed_target_names[0]: np.array(test_x)},  #輸入光譜數據
    fetch_list=fetch_targets)            #獲得推測含量

將結果進行可視化,橫軸爲實際含量,縱軸爲根據光譜預測的含量,大部分得結果仍是比較接近得。至此,咱們得到了經過光譜看到土壤中某物質含量的火眼金睛啦!高光譜反演的用途還有許多,快快在AI Studio中fork項目展現出你的創意吧:

https://aistudio.baidu.com/aistudio/projectdetail/693750/

如在使用過程當中有問題,可加入飛槳官方QQ羣進行交流:1108045677。

下載安裝命令

## CPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安裝命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

>> 訪問 PaddlePaddle 官網瞭解更多相關內容

若是您想詳細瞭解更多飛槳的相關內容,請參閱如下文檔。

飛槳官網地址:

https://www.paddlepaddle.org.cn/

飛槳開源框架項目地址:

GitHub: 

https://github.com/PaddlePaddle/Paddle 

Gitee: 

https://gitee.com/paddlepaddle/Paddle

相關文章
相關標籤/搜索