这里以MNIST数据集来介绍Keras创建人工神经网络模型的四种方法
1、将参数传递给tf.keras.Sequential
import tensorflow as tf
from tensorflow.keras.layers import Dropout, Dense, Flatten
mnist=tf.keras.datasets.mnist
(train_x,train_y),(test_x,test_y)=mnist.load_data()
epochs=10#epochs变量存储将数据输入给模型的次数
batch_size=32
#将所有数据点归一化为0~1范围的浮点值,数据类型为float32,标签y需要转换为int64
train_x,test_x=tf.cast(train_x/255.0,tf.float32),tf.cast(test_x/255.0,tf.float32)
train_y,test_y=tf.cast(train_y,tf.int64),tf.cast(test_y,tf.int64)
模型定义如下(注意观察祝贺在模型定义中进行层列表的传递):
- Flatten接收28*28(即2D)像素的图像输入,并生成一个784(即1D)的向量(下一个Dense层为一维)
- Dense是一个全连接层,表示在两个网络层中任意一堆神经元都存在连接关系。下例有512个神经元,其输入通过ReLU(非线性)激活函数传递。
- Dropout会随机关闭上一层的一小部分神经元(本例随机概率设为0.2).这样做是为了防止任何特定的神经元变得过于强大,而导致模型与数据过拟合,从而影响模型对测试数据度量的准确性。
- 最后的Dense层包含一个softmax激活函数,该函数为每一个可能的输出(10个神经元)分配概率。
#模型定义
model1=tf.keras.models.Sequential([
Flatten(),
Dense(512,activation=tf.nn.relu),
Dropout(0.2),
Dense(10,activation=tf.nn.softmax)
])
#编译模型
optimiser=tf.keras.optimizers.Adam()
model1.compile(optimiser=optimiser,loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
#训练模型
model1.fit(train_x,train_y,batch_size=batch_size,epochs=epochs)
Train on 60000 samples Epoch 1/10 60000/60000 [==============================] - 6s 100us/sample - loss: 0.2228 - accuracy: 0.9347 Epoch 2/10 60000/60000 [==============================] - 5s 82us/sample - loss: 0.1102 - accuracy: 0.9678 Epoch 3/10 60000/60000 [==============================] - 5s 82us/sample - loss: 0.0857 - accuracy: 0.9760 Epoch 4/10 60000/60000 [==============================] - 5s 84us/sample - loss: 0.0741 - accuracy: 0.9800 Epoch 5/10 60000/60000 [==============================] - 5s 83us/sample - loss: 0.0628 - accuracy: 0.9838 Epoch 6/10 60000/60000 [==============================] - 5s 82us/sample - loss: 0.0553 - accuracy: 0.9852 Epoch 7/10 60000/60000 [==============================] - 5s 83us/sample - loss: 0.0493 - accuracy: 0.9873 Epoch 8/10 60000/60000 [==============================] - 5s 85us/sample - loss: 0.0456 - accuracy: 0.9883 Epoch 9/10 60000/60000 [==============================] - 5s 83us/sample - loss: 0.0408 - accuracy: 0.9894 Epoch 10/10 60000/60000 [==============================] - 5s 84us/sample - loss: 0.0384 - accuracy: 0.9899
Out[8]:
<tensorflow.python.keras.callbacks.History at 0x2e500325448>
#模型评估
model1.evaluate(test_x,test_y)
查看模型结构
# 查看模型结构
model1.summary()
数字401920的计算方法为
$$ (28\times 28)\times 512(dense\_2层)=784\times 512=401408 $$
401408+512(每个dense_2层神经元的偏置单元)=401920
5130的计算方法为:
$$ 512 \times10+10=5130 $$
2、用tf.keras.Sequential的.add
方法
model2 = tf.keras.models.Sequential();
model2.add(tf.keras.layers.Flatten())
model2.add(tf.keras.layers.Dense(512, activation='relu'))
model2.add(tf.keras.layers.Dropout(0.2))
model2.add(tf.keras.layers.Dense(10,activation=tf.nn.softmax))
optimiser = tf.keras.optimizers.Adam()
model2.compile (optimizer= optimiser, loss='sparse_categorical_crossentropy', metrics = ['accuracy'])
model2.fit(train_x, train_y, batch_size = batch_size, epochs=epochs)
model2.evaluate(test_x, test_y)
3、使用Keras函数式API
import tensorflow as tf
mnist=tf.keras.datasets.mnist
(train_x,train_y),(test_x,test_y)=mnist.load_data()
train_x,test_x=train_x/255.0,test_x/255.0
epochs=10
#模型定义
inputs=tf.keras.Input(shape=(28,28))#返回一个占位符张量
x=tf.keras.layers.Flatten()(inputs)
x=tf.keras.layers.Dense(512,activation='relu',name='d1')(x)
x=tf.keras.layers.Dropout(0.2)(x)
predictions=tf.keras.layers.Dense(10,activation=tf.nn.softmax,name='d2')(x)
model3=tf.keras.Model(inputs=inputs,outputs=predictions)
#编译模型
optimiser=tf.keras.optimizers.Adam()
model3.compile(optimiser=optimiser,loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
#训练模型
model3.fit(train_x,train_y,batch_size=32,epochs=epochs)
#评估模型
loss,accuracy=model3.evaluate(test_x,test_y)
print('loss:',loss)
print('accuracy:',accuracy)
4、子类化tf.keras.Model对象
首先,使用构造函数(.__init__())
分别对神经层进行声明和命名
然后,在call()
方法中以函数形式将神经层连接在一起。该方法封装了前向传播:
import tensorflow as tf
class MyModel(tf.keras.Model):
def __init__(self,num_class=10):
super(MyModel,self).__init__()
#定义神经层
inputs=tf.keras.Input(shape=(28,28))#返回一个占位符张量
self.x0=tf.keras.layers.Flatten()
self.x1=tf.keras.layers.Dense(512,activation='relu',name='d1')
self.x2=tf.keras.layers.Dropout(0.2)
self.predictions=tf.keras.layers.Dense(10,activation=tf.nn.softmax,name='d2')
def call(self,inputs):
#定义前向传播
#使用先前在__init__中定义的神经层
x=self.x0(inputs)
x=self.x1(x)
x=self.x2(x)
return self.predictions(x)
model4=MyModel()
mnist=tf.keras.datasets.mnist
(train_x,train_y),(test_x,test_y)=mnist.load_data()
train_x, test_x = train_x/255.0, test_x/255.0
epochs=10
batch_size=32
steps_per_epoch=len(train_x)//batch_size
print(steps_per_epoch)
epochs=10
#编译模型
model4.compile(optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy'])
#训练模型
model4.fit(train_x,train_y,batch_size=batch_size,epochs=epochs)
#查看模型摘要
model4.summary()
#模型评估
loss,accuracy=model4.evaluate(test_x,test_y)
print('loss:',loss)
print('accuracy:',accuracy)