在上篇「沒有實作所以只好講幹話系列(四) :: 淺談Reinforcement Learning (RL)」的最後,我提到我想要使用loss的方法去更新模型,不是透過Reinforcement Learning
或是一般的訓練方式,我並沒有使用DQN
或是DDPG
(因為還沒看Orz...) 為此,對於「超級簡略的單股買賣模擬器」的環境必須要修改一下,以及如何定義我們的loss
(就是reward
的相反)。 在這篇,我並不會將state
回傳至模型更新,單純只有loss
,如果這樣的方法也是可行的話,那就 ~ WOW ~
!
強調,這並不一定會有結果,因為確實沒人這麼做過,但我卻非常好奇XD 總之,讓我們開始吧 !
之前有寫一篇「沒有實作所以只好講幹話系列(一) :: 從loss到梯度下降」提到最常使用的loss
有兩種 : mean squared error
和 cross entropy
其可以滿足大部分的模型訓練需求。
那為什麼還要自定義loss function ?
在許多不同的情況下,我們可能希望對loss處理,如online hard example
,一個對loss做「權重放大」的方法。 如果我們只有使用keras
內建的loss function,就不能達到這樣的效果。 那麼,怎麼自定義loss呢?
要自定義loss,首先要先了解訓練過程中,keras會丟什麼樣的資料給loss function
就這樣,沒了@@
所以如果我們想要自定義loss,只要有這麼一個格式就能建立最基本的「自定義loss function」囉 !
def myLoss_DerLa(y_true, y_pred):
...
...
...
return your_loss_der_la # <- 這邊必須回傳一個tensor
很簡單吧! 至於我上面說一定要回傳一個tensor我會在下方有解釋 ~
那麼我們再來進階一步XD
想要實作在keras
中的環境其實非常困難,尤其還要自定義loss中的環境。
tf.keras.backend
把你的環境全部改寫進自定義的loss function ...太麻煩了吧 喂 ~ 前者還要多摸一個套件,後者光簡單的環境都會寫到發癲...
當然麻煩,因為keras
中並沒有支援py_function
。
只要想辦法使用
py_function
就可以了嗎?
對,在「自定義loss」中,因為是用迭代運算,所以只能支援tensor
的運算方式。 在剛開始跑程式的時候,就會先丟一個「空」的y_true
和y_pred
進到「自定義loss」函數中,如果不是tensor
運算式,一開始的執行中,因為丟進來的是「空」,所以運算出錯。
那麼可以用
tf.py_function
將整個「自定義loss」包起來嗎? 在keras
之下
可以的,所以實作上就可以有很大個改變
py_function
使用loop
或是numpy
運算看到這樣的優點,當然要使用一下啦XD 缺點什麼得先放下吧,我們用不到 (笑
new_function = tf.py_function(your_function, [function input], Tout=<type output>)
input
,Tout
則是定義輸出的格式所以只要這樣包起來...
def myLoss_DerLa(y_true, y_pred):
...
...
...
return your_loss_der_la # <- 這邊必須回傳一個tensor
def myLoss(y_true, y_pred):
return tf.py_function(myLoss_DerLa, [y_true, y_pred], Tout=tf.float32)
就可囉~
在開頭,我想做的是一個很特別的事情,就是直接把env
輸出當作我的loss
這樣真的可以嗎?
我認為loss
就只是 一個數字專門打臉你的機器人「你預測的有多不準」 ,但這只是理論上,實際上到底可不可以,還必須要測試看看... 我們先對環境做升級吧 !
我所定義的環境的loss希望得到「當下的資產」減去「過去的資產」,但這其實會有問題,我們如果做「買」,當下資產其實是下降的,因為手續費是使用的狀態。 所以如果我們直接使用「資產差」當作loss的話,只會讓機器選擇do_nothing
而已。
這個應該是全部當中最困難的,我們要考慮很多面向。 如果將do_nothing
的loss
下降,勢必最後又會全部都是do_nothing
。
我們要鼓勵買,也鼓勵賣,同時又希望在特殊情況下實行
do_nothing
,這是很矛盾的,很容易就偏往某一邊...
我們必須要修改環境的loss
同時,要考慮例外情況。 所以我自己實測不少次,以下是我的測試進化史
可以發現,訓練出來的「買」並不是隨便亂買的! 低峰容易進場,代表這樣計算loss是可行的 !!
~ WOW ~
這樣也可以? 這樣的loss? 人類自定的loss?
其實我看到也是滿驚訝的 (雖然我改很~~~~~~多次),這是第一次嘗試,也驗證了我對loss
的直覺。 今天的程式碼只會放上主要程式,不會放上環境 (因為超級亂Orz..)。 今天的進度條就先這樣吧XD 明天把它改完...