學習筆記TF010:softmax分類


回答多選項問題,使用softmax函數,對數幾率回歸在多個可能不同值上的推廣。函數返回值是C個分量的概率向量,每個分量對應一個輸出類別概率。分量為概率,C個分量和始終為1。每個樣本必須屬於某個輸出類別,所有可能樣本均被覆蓋。分量和小於1,存在隱藏類別;分量和大於1,每個樣本可能同時屬於多個類別。類別數量為2,輸出概率與對數幾率回歸模型輸出相同。

變量初始化,需要C個不同權值組,每個組對應一個可能輸出,使用權值矩陣。每行與輸入特征對應,每列與輸出類別對應。

鳶尾花數據集Iris,包含4個數據特征、3類可能輸出,權值矩陣4X3。

訓練樣本每個輸出類別損失相加。訓練樣本期望類別為1,其他為0。只有一個損失值被計入,度量模型為真實類別預測的概率可信度。每個訓練樣本損失相加,得到訓練集總損失值。TensorFlow的softmax交叉熵函數,sparse_softmax_cross_entropy_with_logits版本針對訓練集每個樣本只對應單個類別優化,softmax_cross_entropy_with_logits版本可使用包含每個樣本屬於每個類別的概率信息的訓練集。模型最終輸出是單個類別值。

不需要每個類別都轉換獨立變量,需要把值轉換為0~2整數(總類別數3)。tf.stack創建張量,tf.equal把文件輸入與每個可能值比較。tf.argmax找到張量值為真的位置。

推斷過程計算測試樣本屬於每個類別概率。tf. argmax函數選擇預測輸出值最大概率類別。tf.equal與期望類別比較。tf.reduce_meen計算准確率。

 

import tensorflow as tf#導入TensorFlow庫
import os#導入OS庫
W = tf.Variable(tf.zeros([4, 3]), name="weights")#變量權值,矩陣,每個特征權值列對應一個輸出類別
b = tf.Variable(tf.zeros([3], name="bias"))#模型偏置,每個偏置對應一個輸出類別
def combine_inputs(X):#輸入值合並
print "function: combine_inputs"
return tf.matmul(X, W) + b
def inference(X):#計算返回推斷模型輸出(數據X)
print "function: inference"
return tf.nn.softmax(combine_inputs(X))#調用softmax分類函數
def loss(X, Y):#計算損失(訓練數據X及期望輸出Y)
print "function: loss"
return tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=combine_inputs(X), labels=Y))#求平均值,針對每個樣本只對應單個類別優化
def read_csv(batch_size, file_name, record_defaults):#從csv文件讀取數據,加載解析,創建批次讀取張量多行數據
filename_queue = tf.train.string_input_producer([os.path.join(os.getcwd(), file_name)])
reader = tf.TextLineReader(skip_header_lines=1)
key, value = reader.read(filename_queue)
decoded = tf.decode_csv(value, record_defaults=record_defaults)#字符串(文本行)轉換到指定默認值張量列元組,為每列設置數據類型
return tf.train.shuffle_batch(decoded, batch_size=batch_size, capacity=batch_size * 50, min_after_dequeue=batch_size)#讀取文件,加載張量batch_size行
def inputs():#讀取或生成訓練數據X及期望輸出Y
print "function: inputs"
#數據來源:https://archive.ics.uci.edu/ml/datasets/Iris
#iris.data改為iris.csv,增加sepal_length, sepal_width, petal_length, petal_width, label字段行首行
sepal_length, sepal_width, petal_length, petal_width, label =\
read_csv(100, "iris.csv", [[0.0], [0.0], [0.0], [0.0], [""]])
#轉換屬性數據
label_number = tf.to_int32(tf.argmax(tf.to_int32(tf.stack([
tf.equal(label, ["Iris-setosa"]),
tf.equal(label, ["Iris-versicolor"]),
tf.equal(label, ["Iris-virginica"])
])), 0))#將類名稱轉抽象為從0開始的類別索引
features = tf.transpose(tf.stack([sepal_length, sepal_width, petal_length, petal_width]))#特征裝入矩陣,轉置,每行一樣本,每列一特征
return features, label_number
def train(total_loss):#訓練或調整模型參數(計算總損失)
print "function: train"
learning_rate = 0.01
return tf.train.GradientDescentOptimizer(learning_rate).minimize(total_loss)
def evaluate(sess, X, Y):#評估訓練模型
print "function: evaluate"
predicted = tf.cast(tf.arg_max(inference(X), 1), tf.int32)#選擇預測輸出值最大概率類別
print sess.run(tf.reduce_mean(tf.cast(tf.equal(predicted, Y), tf.float32)))#統計所有正確預測樣本數,除以批次樣本總數,得到正確預測百分比
with tf.Session() as sess:#會話對象啟動數據流圖,搭建流程
print "Session: start"
tf.global_variables_initializer().run()
X, Y = inputs()
total_loss = loss(X, Y)
train_op = train(total_loss)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
training_steps = 1000#實際訓練迭代次數
for step in range(training_steps):#實際訓練閉環
sess.run([train_op])
if step % 10 == 0:#查看訓練過程損失遞減
print str(step)+ " loss: ", sess.run([total_loss])
print str(training_steps) + " final loss: ", sess.run([total_loss])
evaluate(sess, X, Y)#模型評估
coord.request_stop()
coord.join(threads)
sess.close()

 


參考資料:
《面向機器智能的TensorFlow實踐》

歡迎加我微信交流:qingxingfengzi
我的微信公眾號:qingxingfengzigz
我老婆張幸清的微信公眾號:qingqingfeifangz


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM