Tensorflow迴歸和分類示例代碼

1. 使用tensorflow訓練一個三分類問題。

分類是一個雙曲線分成的三部分。藍色部分對應的是x<=-(y^2+1)^(1/2),其向量爲[1,0,0],黃色部分對應的是x>=(y^2+1)^(1/2),其向量爲[0,0,1],其餘部分爲x^2<y^2+1,對應向量爲[0,1,0]

# coding: utf-8
import tensorflow as tf
from tensorflow.keras import layers
import math

print(tf.__version__)
print(tf.keras.__version__)

if __name__ == '__main__':
    model = tf.keras.Sequential()
    model.add(layers.Dense(32, activation='relu'))
    model.add(layers.Dense(32, activation='relu'))
    model.add(layers.Dense(3, activation='softmax'))
    model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
                  loss=tf.keras.losses.categorical_crossentropy,
                  metrics=[tf.keras.metrics.categorical_accuracy])
    train_x = [[x, y] for x in range(-10, 10) for y in range(-10, 10)]
    train_y = map(lambda v: [1, 0, 0] if v[0] <= -math.sqrt(v[1] * v[1] + 1) else (
        [0, 0, 1] if v[0] >= math.sqrt(v[1] * v[1] + 1) else [0, 1, 0]), train_x)
    print train_x
    print train_y

    model.fit(train_x, train_y, batch_size=1, epochs=200,
              validation_data=([[0, 0], [10, 0]], [[0, 1, 0], [0, 0, 1]]))
    result = model.predict([[0, 0], [1000, 100]], batch_size=1)
    print '################'
    print(result)

2. 迴歸問題

f(x,y)=x*y

通過這兩個模型的構建參數,足以見得我對模型構建一竅不通。

# coding: utf-8
import tensorflow as tf
from tensorflow.keras import layers

print(tf.__version__)
print(tf.keras.__version__)

if __name__ == '__main__':
    model = tf.keras.models.load_model('./regression')
    result = model.predict([[0.4, 0], [10, 10]], batch_size=1)
    print '################'
    print(result)
    # exit(0)

    model = tf.keras.Sequential()
    model.add(layers.Dense(32, activation='relu'))
    model.add(layers.Dense(32, activation='relu'))
    model.add(layers.Dense(1))
    model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
                  loss=tf.keras.losses.mse,
                  metrics=['mae', 'mse'])
    train_x = [[1.0 * x, 1.0 * y] for x in range(-10, 10) for y in range(-10, 10)]
    train_y = [[e[0] * e[1]] for e in train_x]
    print train_x
    print train_y

    model.fit(train_x, train_y, batch_size=1, epochs=200,
              validation_data=([[0, 0], [10, 0]], [[0], [0]]))
    result = model.predict([[0, 0], [1000, 100]], batch_size=1)
    model.save('./regression')
    print '################'
    print(result)

---------------------------------------------------

損失函數:

經過一天的折騰,終於明白了tensorflow.keras.losses.BinaryCrossEntropy和tensorflow.keras.losses.CategoricalCrossentropy的區別,也明白了爲什麼是這樣的。

對於:

y_true=[[0,2,1],[1,0,0]]

y_pred=[[0.1, 0.7, 0.7], [0.2, 0, 0]]

如果是BinaryCrossEntropy,對於每一項都會根據0/1計算交叉熵,對於第一個樣本,會計算三個交叉熵,即

bce1=1/N*Σ ( yi*ln pi + (1-yi)*ln(1-pi) ) = -0.00952922 # yi,pi分別是y_true和y_pred中對應的項
bce2=1/N*Σ ( yi*ln pi + (1-yi)*ln(1-pi) ) = 0.5364791 

#可以使用tf.keras.losses.binary_crossentropy(y_true, y_pred),這個方法會計算每個樣本的交叉熵,而不是最後的彙總結果

如果是CategoricalCrossentropy,每個樣本會計算一個交叉熵,計算之前會先對y_pred進行正規化,具體的方法不是採用softmax函數,而是直接根據比例重新劃分,在上例中,正規化後的結果爲

y_pred=[[1/15, 7/15, 7/15], [1, 0, 0]]

然後在正規化的結果上計算交叉熵

cce1= Σ ( yi*ln pi) = 2.2864201 # yi,pi分別是y_true和y_pred中對應的項
cce2= Σ ( yi*ln pi) = 1.1920929e-07

#可以使用tf.keras.losses.categorical_crossentropy(y_true, y_pred),這個方法會計算每個樣本的交叉熵,而不是最後的彙總結果

這兩種計算方式的不同是可以理解的。對於二分類問題,輸出的每個點代表一個類,回答的問題是是否屬於這個類,一個輸入,可以同屬於多個類,因此,應該認爲每個分類是獨立的。但是對於多分類問題,一般認爲,一個輸出判斷的是屬於哪一個類的問題,因此y_pred預測的是哪一個類。因此對於一個y_true=[0,1,1],說明的是這個分類不屬於第一類,但是屬於第二、三類。但是對於一個多分類問題,這個輸出一般認爲是無意義的,一個多分類問題的向量中只應該有一個值爲1,對應的屬於的類。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章