zl程序教程

您现在的位置是:首页 >  后端

当前栏目

keras建模的3种方式——序列模型、函数模型、子类模型

建模序列 函数 方式 模型 Keras 子类
2023-09-11 14:20:52 时间

1 前言

keras是Google公司于2016年发布的以tensorflow为后端的用于深度学习网络训练的高阶API,因接口设计非常人性化,深受程序员的喜爱。

keras建模有3种实现方式——序列模型函数模型子类模型。本文以MNIST手写数字为例,用3种建模方式实现。

关于MNIST数据集的说明,见使用TensorFlow实现MNIST数据集分类

笔者工作空间如下:

2 序列模型

sequential.py

from tensorflow.examples.tutorials.mnist import input_data
from keras.models import Sequential
from keras.models import load_model
from keras.layers import Dense

#载入数据
def read_data(path):
    mnist=input_data.read_data_sets(path,one_hot=True)
    train_x,train_y=mnist.train.images,mnist.train.labels,
    valid_x,valid_y=mnist.validation.images,mnist.validation.labels,
    test_x,test_y=mnist.test.images,mnist.test.labels
    return train_x,train_y,valid_x,valid_y,test_x,test_y

#序列模型
def DNN(train_x,train_y,valid_x,valid_y):
    #创建模型
    model=Sequential()
    model.add(Dense(64,input_dim=784,activation='relu'))
    model.add(Dense(128,activation='relu'))
    model.add(Dense(10,activation='softmax'))
    #查看网络结构
    model.summary()
    #编译模型
    model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])
    #训练模型
    model.fit(train_x,train_y,batch_size=500,nb_epoch=100,verbose=2,validation_data=(valid_x,valid_y))
    #保存模型
    model.save('sequential.h5')
   
train_x,train_y,valid_x,valid_y,test_x,test_y=read_data('MNIST_data')
DNN(train_x,train_y,valid_x,valid_y)

model=load_model('sequential.h5')  #下载模型
pre=model.evaluate(test_x,test_y,batch_size=500,verbose=2)  #评估模型
print('test_loss:',pre[0],'- test_acc:',pre[1])

运行结果

Epoch 98/100
 - 1s - loss: 4.8694e-04 - acc: 1.0000 - val_loss: 0.1331 - val_acc: 0.9776
Epoch 99/100
 - 1s - loss: 4.7432e-04 - acc: 1.0000 - val_loss: 0.1336 - val_acc: 0.9778
Epoch 100/100
 - 1s - loss: 4.6462e-04 - acc: 1.0000 - val_loss: 0.1343 - val_acc: 0.9774
test_loss: 0.13972217990085484 - test_acc: 0.9768999993801117

 

3 函数模型

fun_model.py

from tensorflow.examples.tutorials.mnist import input_data
from keras.models import Model
from keras.models import load_model
from keras.layers import Input,Dense

#载入数据
def read_data(path):
    mnist=input_data.read_data_sets(path,one_hot=True)
    train_x,train_y=mnist.train.images,mnist.train.labels,
    valid_x,valid_y=mnist.validation.images,mnist.validation.labels,
    test_x,test_y=mnist.test.images,mnist.test.labels
    return train_x,train_y,valid_x,valid_y,test_x,test_y

#函数模型
def DNN(train_x,train_y,valid_x,valid_y):
    #创建模型
    inputs=Input(shape=(784,))
    x=Dense(64,activation='relu')(inputs)
    x=Dense(128,activation='relu')(x)
    output=Dense(10,activation='softmax')(x)
    model=Model(input=inputs,output=output)
    #查看网络结构
    model.summary()
    #编译模型
    model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])
    #训练模型
    model.fit(train_x,train_y,batch_size=500,nb_epoch=100,verbose=2,validation_data=(valid_x,valid_y))
    #保存模型
    model.save('fun_model.h5')
   
train_x,train_y,valid_x,valid_y,test_x,test_y=read_data('MNIST_data')
DNN(train_x,train_y,valid_x,valid_y)

model=load_model('fun_model.h5')  #下载模型
pre=model.evaluate(test_x,test_y,batch_size=500,verbose=2)  #评估模型
print('test_loss:',pre[0],'- test_acc:',pre[1])

4 子类模型

class_model.py

from tensorflow.examples.tutorials.mnist import input_data
from keras.models import Model
from keras.layers import Dense

#载入数据
def read_data(path):
    mnist=input_data.read_data_sets(path,one_hot=True)
    train_x,train_y=mnist.train.images,mnist.train.labels,
    valid_x,valid_y=mnist.validation.images,mnist.validation.labels,
    test_x,test_y=mnist.test.images,mnist.test.labels
    return train_x,train_y,valid_x,valid_y,test_x,test_y

#子类模型
class DNN(Model):
    def __init__(self):
        super(DNN,self).__init__()
        #初始化网络结构
        self.dense1=Dense(64,input_dim=784,activation='relu')
        self.dense2=Dense(128,activation='relu')
        self.dense3=Dense(10,activation='softmax')
        
    def call(self,inputs):  #回调顺序
        x=self.dense1(inputs)
        x=self.dense2(x)
        x=self.dense3(x)
        return x
   
train_x,train_y,valid_x,valid_y,test_x,test_y=read_data('MNIST_data')
model=DNN()
#编译模型
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])
#训练模型
model.fit(train_x,train_y,batch_size=500,nb_epoch=100,verbose=2,validation_data=(valid_x,valid_y))
#查看网络结构
model.summary()

pre=model.evaluate(test_x,test_y,batch_size=500,verbose=2)  #评估模型
print('test_loss:',pre[0],'- test_acc:',pre[1])

5 注意事项

(1)只有序列模型函数模型能够保存模型,子类模型不能保存模型,即不能调用 model.save()

(2)子类模型中,model.summary() 得放在 model.fit() 之后,否则会报错

ValueError: This model has not yet been built. Build the model first by calling build() or calling fit() with some data. Or specify input_shape or batch_input_shape in the first layer for automatic build. 

(3)若想自定义学习率,可以引入优化器对象,如下:

from keras.optimizers import Adam
....
model.compile(optimizer=Adam(lr=0.001),loss='categorical_crossentropy',metrics=['accuracy'])

(4)常用损失函数

mse  #均方差(回归)
mae  #绝对误差(回归)
binary_crossentropy  #二值交叉熵(二分类,逻辑回归)
categorical_crossentropy  #交叉熵(多分类)

(5)model.fit( ) 和 model.evaluate( ) 中,属性 verbose 表示打印训练或评估信息是否详细

  • 0:不打印进度和结果
  • 1:打印进度和结果
Epoch 100/100
55000/55000 [==============================] - 1s 9us/step - loss: 6.0211e-05 - acc: 1.0000 - val_loss: 0.1405 - val_acc: 0.9766
10000/10000 [==============================] - 0s 26us/step
  • 2:只打印结果
Epoch 100/100
 - 1s - loss: 4.6462e-04 - acc: 1.0000 - val_loss: 0.1343 - val_acc: 0.9774