多層神經網絡非常好理解,就是在輸入和輸出中間多加一些層,每一層可以加多個神經元。下面的例子是通過加入一個隱藏層后對異或數據進行分類。
一 異或數據集
所謂的"異或數據"是來源於異或操作,可以繪制在直角坐標系中,如下圖所示:
我們可以看到這張圖很難通過一個直線把這兩類數據風格開來,但是我們可以通過類似支持向量機中核函數一樣的函數把數據映射到高維空間,然后通過線性分類的方法把數據分類。在輸入層和輸出層之間加一層隱藏層,就是起到核函數的作用。
生成數據集的代碼如下:
''' 生成模擬數據集 ''' train_x = np.array([[0,0],[0,1],[1,0],[1,1]],dtype=np.float32) #非one_hot編碼 #train_y = np.array([[0],[1],[1],[0]],dtype = np.float32) #輸出層節點個數 #n_label = 1 #one_hot編碼 train_y = np.array([[1, 0], [0, 1], [0, 1], [1, 0]],dtype = np.float32) #輸出層節點個數 n_label = 2
二 定義參數
''' 定義變量 ''' #學習率 learning_rate = 1e-4 #輸入層節點個數 n_input = 2 #隱藏層節點個數 n_hidden = 2 input_x = tf.placeholder(tf.float32,[None,n_input]) input_y = tf.placeholder(tf.float32,[None,n_label]) ''' 定義學習參數 h1 代表隱藏層 h2 代表輸出層 ''' weights = { 'h1':tf.Variable(tf.truncated_normal(shape=[n_input,n_hidden],stddev = 0.01)), #方差0.01 'h2':tf.Variable(tf.truncated_normal(shape=[n_hidden,n_label],stddev=0.01)) } biases = { 'h1':tf.Variable(tf.zeros([n_hidden])), 'h2':tf.Variable(tf.zeros([n_label])) }
三 定義網絡結構
''' 定義網絡模型 ''' #隱藏層 layer_1 = tf.nn.relu(tf.add(tf.matmul(input_x,weights['h1']),biases['h1'])) #1 softmax 方法 y_pred = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['h2']),biases['h2'])) loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits( labels=input_y,logits=y_pred)) #2 tanh方法+平方差#輸出層 #y_pred = tf.nn.tanh(tf.add(tf.matmul(layer_1,weights['h2']),biases['h2'])) #定義代價函數 二次代價函數 #loss = tf.reduce_mean((y_pred - input_y)**2) train = tf.train.AdamOptimizer(learning_rate).minimize(loss)
四 開始訓練
''' 開始訓練 ''' training_epochs = 100000 sess = tf.InteractiveSession() #初始化 sess.run(tf.global_variables_initializer()) for epoch in range(training_epochs): _,lo = sess.run([train,loss],feed_dict={input_x:train_x,input_y:train_y}) if epoch % 10000 == 0: print(lo) #計算預測值 print(sess.run(y_pred,feed_dict={input_x:train_x})) #查看隱藏層的輸出 print(sess.run(layer_1,feed_dict={input_x:train_x}))
運行結果如下:
上面輸出了兩個數組,第一個數組是一個4行兩列的輸出,如果我們采用四舍五入取值,我們會發現,和我們的輸入train_y值完全吻合。
第二個數組也是一個4行2列的數組,我們可以看到這4個元素是線性可分的,也就是說隱藏層把輸入數據從輸入空間映射到了特征空間中,將非線性問題變換成了線性分類問題。
如果你運行的結果並不能正確分類,可能你需要調整你的學習率和迭代周期,因為在訓練過程中可能陷入局部最優。
全部代碼:

# -*- coding: utf-8 -*- """ Created on Wed Apr 25 20:41:45 2018 @author: zy """ ''' 非線性分類問題:就是用直線分不開的問題 我們可以使用隱藏層解決非線性問題 ''' ''' 使用帶隱藏層的神經網絡擬合異或操作 input1 input2 output 0 0 0 0 1 1 1 0 1 1 1 0 ''' import tensorflow as tf import numpy as np ''' 生成模擬數據集 ''' train_x = np.array([[0,0],[0,1],[1,0],[1,1]],dtype=np.float32) #非one_hot編碼 #train_y = np.array([[0],[1],[1],[0]],dtype = np.float32) #輸出層節點個數 #n_label = 1 #one_hot編碼 train_y = np.array([[1, 0], [0, 1], [0, 1], [1, 0]],dtype = np.float32) #輸出層節點個數 n_label = 2 ''' 定義變量 ''' #學習率 learning_rate = 1e-4 #輸入層節點個數 n_input = 2 #隱藏層節點個數 n_hidden = 2 input_x = tf.placeholder(tf.float32,[None,n_input]) input_y = tf.placeholder(tf.float32,[None,n_label]) ''' 定義學習參數 h1 代表隱藏層 h2 代表輸出層 ''' weights = { 'h1':tf.Variable(tf.truncated_normal(shape=[n_input,n_hidden],stddev = 0.01)), #方差0.1 'h2':tf.Variable(tf.truncated_normal(shape=[n_hidden,n_label],stddev=0.01)) } biases = { 'h1':tf.Variable(tf.zeros([n_hidden])), 'h2':tf.Variable(tf.zeros([n_label])) } ''' 定義網絡模型 ''' #隱藏層 layer_1 = tf.nn.relu(tf.add(tf.matmul(input_x,weights['h1']),biases['h1'])) #1 softmax 方法 y_pred = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['h2']),biases['h2'])) loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits( labels=input_y,logits=y_pred)) #2 tanh方法+平方差#輸出層 #y_pred = tf.nn.tanh(tf.add(tf.matmul(layer_1,weights['h2']),biases['h2'])) #定義代價函數 二次代價函數 #loss = tf.reduce_mean((y_pred - input_y)**2) train = tf.train.AdamOptimizer(learning_rate).minimize(loss) ''' 開始訓練 ''' training_epochs = 100000 sess = tf.InteractiveSession() #初始化 sess.run(tf.global_variables_initializer()) for epoch in range(training_epochs): _,lo = sess.run([train,loss],feed_dict={input_x:train_x,input_y:train_y}) if epoch % 10000 == 0: print(lo) #計算預測值 print(sess.run(y_pred,feed_dict={input_x:train_x})) #查看隱藏層的輸出 print(sess.run(layer_1,feed_dict={input_x:train_x}))