本章是利用keras实现MLP三种方式(序列模型、函数模型、子类模型),分别搭建回归神经网络,分类神经网络,以及宽深神经网络
Tensorflow2.2的安装教程可参考 https://www.jianshu.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)