同时搞定TensorFlow、PyTorch (一):梯度下降。同时搞定TensorFlow、PyTorch (二):模型定义。同时搞定TensorFlow、PyTorch (三) :资料前置处理。同时搞定TensorFlow、PyTorch (四):模型训练。
前言
上一篇谈到 TensorFlow/PyTorch 自动微分及梯度下降的作法,这次我们再来比较神经层及神经网路模型的实作。
图一. 神经网路学习路径
神经网路模型
TensorFlow、PyTorch 都提供两种网路模型,TensorFlow/Keras 称为顺序型模型(Sequential Model)、Functional API,可参见Keras官网,PyTorch 则无正式名称,只是分别放在不同的模组下torch.nn、torch.nn.functional,为方便说明,以下均使用TensorFlow/Keras定义。
顺序型模型
TensorFlow:
import tensorflow as tf# 建立模型model = tf.keras.models.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dropout(0.2), tf.keras.layers.Dense(10, activation='softmax')])
PyTorch:
import torch# 建立模型model = torch.nn.Sequential( torch.nn.Flatten(), torch.nn.Linear(28 * 28, 256), torch.nn.Dropout(0.2), torch.nn.Linear(256, 10), # 使用nn.CrossEntropyLoss()时,不需要将输出经过softmax层,否则计算的损失会有误 # torch.nn.Softmax(dim=1))
完全连接层(Full Connected Layer) 用法有些差异:
TensorFlow 称为 Dense,PyTorch 称为 Linear。除了第一层外,TensorFlow 只要设定输出神经元的个数,PyTorch 还须设定输入神经元的个数,TensorFlow 输入神经元的个数等于上一层的输出。Functional API
Functional API 可以实作较複杂的模型,允许多个Input或Output、分叉及合併。
TensorFlow:
import tensorflow as tffrom tensorflow.keras import layers# 建立模型# 建立第一层 InputTensorInputTensor = layers.Input(shape=(100,))# H1 接在 InputTensor 后面H1 = layers.Dense(10, activation='relu')(InputTensor)# H2 接在 H1 后面H2 = layers.Dense(20, activation='relu')(H1)# Output 接在 H2 后面Output = layers.Dense(1, activation='softmax')(H2)# 建立模型,必须指定 inputs / outputsmodel = tf.keras.Model(inputs=InputTensor, outputs=Output)
PyTorch:神经层串连与TensorFlow大同小异。
from torch import nnfrom torch.nn import functional as Finputs = torch.randn(100, 256)x = nn.Linear(256,20)(inputs)x = F.relu(x)x = nn.Linear(20, 10)(x)x = F.relu(x)x = F.softmax(x, dim=1)
PyTorch 要建构整个模型,通常会使用类别,即所谓的专家模式,在__init__定义神经层,在forward串连神经层。
class MyModel(nn.Module): def __init__(self): super(Net, self).__init__() self.fc1 = nn.Linear(784,256) self.fc2 = nn.Linear(256, 10) self.dropout1 = nn.Dropout(0.2) self.dropout2 = nn.Dropout(0.2) def forward(self, x): x = torch.flatten(x, 1) x = self.fc1(x) x = self.dropout1(x) x = self.fc2(x) x = self.dropout2(x) output = F.softmax(x, dim=1) return output model = MyModel()
TensorFlow 也支援专家模式,使用 call函数,与 PyTorch 的 forward 函数相对应。
class MyModel(tf.keras.Model): def __init__(self): super(MyModel, self).__init__() self.conv1 = Conv2D(32, 3, activation='relu') self.flatten = Flatten() self.d1 = Dense(128, activation='relu') self.d2 = Dense(10, activation='softmax') def call(self, x): x = self.conv1(x) x = self.flatten(x) x = self.d1(x) return self.d2(x)model = MyModel()
TensorFlow完整程式可参阅深度学习 -- 最佳入门迈向 AI 专题实战的src/04_05_ Sequential_model.ipynb、src/04_06_ Functional_API.ipynb。PyTorch可参阅开发者传授 PyTorch 秘笈 的src/04_09_Sequential_vs_Functional.ipynb。结论
TensorFlow/PyTorch 在建立模型的基本设计也是一致的,只是语法不同而已。不过,有些细节是存在差异的,例如PyTorch损失函数使用nn.CrossEntropyLoss时,不需要将输出经过softmax层,否则计算的损失会有误。
下一篇我们继续比较Dataset/Dataloader的实作。
以下为工商广告:)。
PyTorch:
开发者传授 PyTorch 秘笈
预计 2022/6/20 出版。
TensorFlow:
深度学习 -- 最佳入门迈向 AI 专题实战。