1 功能
在读tensorflow代码时经常看到使用Model定义模型,这与在Pytorch中经常使用的使用继承模型有区别,所以这里就记录一下。
在Keras中有两种深度学习的模型:序列模型(Sequential)和通用模型(Model)。差异在于不同的拓扑结构。
在序列模型中,就如同Pytorch中的用法一样,看下面代码:
from keras.models import Sequential
from keras.layers import Dense, Activation
layers = [Dense(32, input_shape = (784,)),
Activation('relu'),
Dense(10),
Activation('softmax')]
model = Sequential(layers)
# 或者逐层添加网络结构,代码如下:
from keras.models import Sequential
from keras.layers import Dense, Activation
model = Sequential()
model.add(Dense(32, input_shape = (784,)))
model.add(Activation('relu'))
model.add(Dense(10))
model.add(Activation('softmax'))
如果我们像实现一些更为复杂的网络,比如多输入多输出的模型就需要使用到keras.models.Model()来构建网络。如下代码同时输出最后卷积层Flatten后提取的特征层,以及分类结构。
流程使用keras.Input定义输入张量shape, 创建网络层;定义每层的输入和输出张量;keras.models.Model确定输入张量和输出层,keras可以根据每一层的输入输出关系完成整个网络图的创建。
个人理解,Model模块其实就是调用之前定义的函数层,主要就是注意的就是Model函数中的Input和outputs的输入,这个地方要注意理解。
import tensorflow as tf
from tensorflow.keras import layers, models, Input
input_tensor = Input(shape=(32, 32, 3))
x = layers.Conv2D(32, (3, 3), activation='relu')(input_tensor)
x = layers.MaxPooling2D((2, 2))(x)
x = layers.Conv2D(64, (3, 3), activation='relu')(x)
x = layers.MaxPooling2D((2, 2))(x)
x = layers.Conv2D(64, (3, 3), activation='relu')(x)
output_tensor1=layers.Flatten()(x)
x = layers.Dense(64, activation='relu')(output_tensor1)
output_tensor2 = layers.Dense(10, activation='softmax')(x)
model = models.Model(inputs=input_tensor, outputs=[output_tensor1, output_tensor2])
model.summary()
继承类:这个跟Pytorch的使用方法一致,call函数相当于forward。
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Model
class MyNet(Model):
def __init__(self):
super(MyNet, self).__init__()
self.conv1 = layers.Conv2D(32, (3, 3), activation='relu')
self.pool1 = layers.MaxPooling2D((2, 2))
self.conv2 = layers.Conv2D(64, (3, 3), activation='relu')
self.pool2 = layers.MaxPooling2D((2, 2))
self.conv3 = layers.Conv2D(64, (3, 3), activation='relu')
self.flatten = layers.Flatten()
self.fc1 = layers.Dense(64, activation='relu')
self.fc2 = layers.Dense(10, activation='softmax')
def call(self, inputs):
out = self.conv1(inputs)
out = self.pool1(out)
out = self.conv2(out)
out = self.pool2(out)
out = self.conv3(out)
out = self.flatten(out)
out = self.fc1(out)
out = self.fc2(out)
return out
def main():
model = MyNet()
model.build(input_shape=(None,32, 32,3))
model.summary()
if __name__ == '__main__':
main()
2 参考文献
[1]Keras中的两种模型:Sequential和Model用法
[2]Tensorflow 2.0 keras.models.Sequential() Model() 创建网络的若干方式 及共享权重问题