本章是利用keras實現MLP三種方式(序列模型、函數模型、子類模型),分別搭建回歸神經網絡,分類神經網絡,以及寬深神經網絡
Tensorflow2.2的安裝教程可參考 http://www.lxweimin.com/p/293ba064d1cb
1、使用順序模型創建分類神經網絡
1.1準備數據
import tensorflow as tf
from sklearn.model_selection import train_test_split
from tensorflow import keras
import pandas as pd
import matplotlib.pyplot as plt
(X_train_full, y_train_full),(X_test,y_test) = keras.datasets.fashion_mnist.load_data()
X_train, X_valid, y_train, y_valid = train_test_split(X_train_full, y_train_full, random_state=42, stratify=y_train_full)
X_train = X_train/255
X_valid = X_valid/255
X_test = X_test/255
#創建一個列表表示每類要處理的對象
class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat","Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]
查看數據表示
plt.figure(figsize=(10,5))
for index in range(10):
plt.subplot(2,5,index+1)
plt.imshow(X_train_full[index], cmap='binary')
plt.title(class_names[y_train_full[index]])
1.2構建模型
#第一行創建了一個Sequential,這是神經網絡中最簡單的keras模型,他僅有順序單層堆疊而成
model = keras.models.Sequential()
#這一層作為輸入層,也可以使用keras.layers.InputLayer
model.add(keras.layers.Flatten(input_shape = X_train.shape[1:]))
model.add(keras.layers.Dense(300, activation='relu'))
#層與層之間應該越來越小,因為越往上面層提取的有效信息越大
model.add(keras.layers.Dense(100, activation='relu'))
#輸出層
model.add(keras.layers.Dense(10,activation='softmax'))
同樣也可以使用這種方式:
model = keras.models.Sequential([
keras.layers.Flatten(input_shape = X_train.shape[1:]),
keras.layers.Dense(300, activation='relu'),
keras.layers.Dense(100, activation='relu'),
keras.layers.Dense(10,activation='softmax')
])
1.3了解 Dense參數
需要注意Dense中activation激活函數可以用以下幾種
import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def relu(z):
return np.maximum(0, z)
plt.figure(figsize=(10,5))
z= np.linspace(-5,5,1000)
plt.plot(z, sigmoid(z), 'r-', label='sigmoid')
plt.plot(z, np.sign(z), 'g--', label ='step')
plt.plot(z, np.tanh(z), 'b-.', label='tanh')
plt.plot(z, relu(z), 'm-', label='relu')
plt.legend()
plt.gca()
plt.grid(True)
plt.axis([-5, 5, -1.2, 1.2])
最常用的是relu
1.4 設置compile參數()指定優化器,計算損失函數的方法
創建模型后調用compile
model.compile(loss=keras.losses.sparse_categorical_crossentropy, optimizer = 'sgd', metrics = 'accuracy')
此代碼需要一些解釋。首先,我們使用"sparse_categorical_crossentropy"損失,因為我們具有稀疏標簽(即對于每個實例,只有一個目標類索引,在這種情況下為0到9),并且這些類是互斥的。相反,如果每個實例的每個類都有一個目標概率(例如獨熱向量,[0.,0.,0.,1.,0.,0.,0.,0.,0.,0]代表類3),則我們需要使用"categorical_crossentropy"損失。如果我們正在執行二進制分類(帶有一個或多個二進制標簽),則在輸出層中使用"sigmoid"(即邏輯)激活函數,而不是"softmax"激活函數,并且使用"binary_crossentropy"損失。
如果要將稀疏標簽(即類索引)轉換為獨熱向量標簽,使用keras.utils.to_categorical()函數。反之則使用np.argmax()函數和axis=1。關于優化器,"sgd"表示我們使用簡單的隨機梯度下降來訓練模型。換句話說,Keras將執行先前所述的反向傳播算法(即反向模式自動微分加梯度下降)。我們將在第11章中討論更有效的優化器(它們改進梯度下降部分,而不是自動微分)。
使用SGD優化器時,調整學習率很重要。因此通常需要使用optimizer=keras.optimizers.SGD(lr=浮點數)來設置學習率,而不是使用optimizer="sgd"(默認值為lr=0.01)來設置學習率。最后,由于這是一個分類器,因此在訓練和評估過程中測量其"accuracy"很有用。
1.5 訓練模型
現在該模型已準備好進行訓練。為此我們只需要調用其fit()方法即可:
history = model.fit(X_train, y_train, epochs=20, validation_split=.2)
1.6評估泛化能力
model.evaluate(X_test, y_test)
第一個分類模型
2、使用順序模型創建回歸神經網絡
2.1數據準備
from sklearn.datasets import fetch_california_housing
from sklearn.preprocessing import StandardScaler
housing = fetch_california_housing()
X_train,X_test, y_train,y_test = train_test_split(housing.data, housing.target)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
2.2模型構建
model = keras.models.Sequential([
keras.layers.Dense(30,activation='relu', input_shape=X_train.shape[1:]),
keras.layers.Dense(1)
])
2.3 設置優化器,損失函數
model.compile(loss=keras.losses.mean_squared_error, optimizer = 'sgd')
2.4訓練
history = model.fit(X_train,y_train, epochs=10, validation_split=.2)
3、使用函數模型創建寬深神經網絡(一個輸入,一個輸出)
我們要創建的寬深神經網絡圖如下
3.1 構建模型
input_ = keras.layers.Input(shape=X_train.shape[1:])
hidden1 = keras.layers.Dense(30, activation='relu')(input_)
hidden2 = keras.layers.Dense(30, activation='relu')(hidden1)
concat = keras.layers.Concatenate()([input_, hidden2])
output = keras.layers.Dense(1)(concat)
model = keras.Model(inputs = [input_],outputs=[output])
3.2設置損失函數和優化器
model.compile(loss=keras.losses.mean_squared_error, optimizer = 'sgd')
3.3訓練模型
history = model.fit(X_train,y_train, epochs=10, validation_split=.2)
4、使用函數模型創建寬深神經網絡(二個輸入,一個輸出)
創建的寬深神經網絡如下圖:
4.1 構建模型
input_A = keras.layers.Input(shape=[5])
input_B = keras.layers.Input(shape=[6])
hidden1 = keras.layers.Dense(30, activation='relu')(input_B)
hidden2 = keras.layers.Dense(30, activation='relu')(hidden1)
concat = keras.layers.Concatenate()([input_A, hidden2])
output = keras.layers.Dense(1)(concat)
model = keras.Model(inputs =[input_A, input_B], outputs= [output])
4.2設置損失后漢書和優化器
model.compile(loss=keras.losses.mean_squared_error, optimizer = 'sgd')
4.3訓練模型
history = model.fit((X_train[:,:5],X_train[:,2:]),y_train, epochs=10, validation_split=.2)
5、使用函數模型創建寬深神經網絡(二個輸入,二個輸出)
創建的寬深神經網絡如下圖:
5.1 構建模型
input_A = keras.layers.Input(shape=[5])
input_B = keras.layers.Input(shape=[6])
hidden1 = keras.layers.Dense(30, activation='relu')(input_B)
hidden2 = keras.layers.Dense(30, activation='relu')(hidden1)
aux_output = keras.layers.Dense(1, name='aux')(hidden2)
concat = keras.layers.Concatenate()([input_A, hidden2])
main_output = keras.layers.Dense(1, name='main')(concat)
model = keras.Model(inputs =[input_A, input_B], outputs= [main_output,aux_output])
5.2設置損失后漢書和優化器
model.compile(loss=[keras.losses.mean_squared_error, keras.losses.mean_squared_error], loss_weights=[.9,.1] ,optimizer = 'sgd')
5.3訓練模型
history = model.fit((X_train[:,:5],X_train[:,2:]),[y_train, y_train], epochs=10, validation_split=.2)
6、子類模型創建寬深神經網絡
創建的神經網絡如下圖:
6.1、創建子類
class WideAndDeepModel(keras.Model):
def __init__(self, units=30, activation="relu", **kwargs):
super().__init__(**kwargs)
self.hidden1 = keras.layers.Dense(units, activation=activation)
self.hidden2 = keras.layers.Dense(units, activation=activation)
self.main_output = keras.layers.Dense(1)
self.aux_output = keras.layers.Dense(1)
def call(self, inputs):
input_A , input_B = inputs
hidden1 = self.hidden1(input_B)
hidden2 = self.hidden2(hidden1)
concat = keras.layers.concatenate([input_A, hidden2])
main_output = self.main_output()(concat)
aux_output = self.aux_output()(hidden2)
return main_outputi, aux_output
6.2 創建子類模型
model = WideAnDeepModel(30, activation='relu')
model.compile(loss=['mse'], loss_weights=[.9,.1] ,optimizer = 'sgd')
6.3 訓練模型
history = model.fit([X_train[:,:5],X_train[:,2:]],[y_train, y_train], epochs=10, validation_split=.2)