TensorFlow与PyTorch的区别在网上有很多的分析,主要可以总结为以下几点:
动态与静态
PyTorch是一个动态的框架,而TensorFlow是一个静态的框架。使用TensorFlow时,必须先搭建好网络的结构,然后使用预先留出的几个占位符作为样本输入和label输入,这就像是通过开了几个洞的木板进行交互,中途无法对计算的流程进行更改。
TensorFlow必须运行会话才能得到运行的结果,而且网络必须努力构造以确保每个张量具有正确的维度,否则就会出现这样的错误:
与之不同的是,PyTorch遵循动态的图像计算方法,不需要考虑张量尺寸的问题。另外,PyTorch能够自动求变量的导数,易于在编程中理解网络底层的原理。
模型可视化
在模型可视化方面,TensorFlow因为具有模型可视化工具TensorBoard而具有绝对的优势。TensorBoard能够在训练中对数据进行实时分析,而PyTorch完全缺乏这一功能,当然,为了实现模型可视化,也可以将TensorBoardX应用到PyTorch中。
模型部署
对于小规模的部署,TensorFlow与PyTorch都可以使用Flask框架。但是对于大规模的部署,使用TensorFlow Serving是一个更好的选择。
函数习惯的区别
1. 常量与变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 常量 x = torch.tensor([1, 2, 3, 4]) # pytorch常量 x = tf.constant([1, 2, 3, 4]) # tensorflow常量 # 变量 from torch.autograd import Variable x = Variable(torch.randn(N, D).type(dtype), requires_grad=False) # pytorch变量 x = tf.Variable(tf.truncated_normal([5, 5, 1, 32], stddev=0.1)) # tensorflow变量 x = tf.get_variable(name='w_c1',shape=[N, D]) # tensorflow另一种使用变量的方式 # 占位符 # pytorch没有占位符 x = tf.placeholder(tf.float32, [None, 784]) # tensorflow的占位符 |
2. 获取张量的维度
1 2 3 4 5 6 7 |
# tensorflow sess.run(tf.shape(x)) x.shape # pytorch x.size() |
3. reshape操作
1 2 3 4 5 6 7 |
# tensorflow x = tf.reshape(x, [2, 2]) # pytorch x = x.view([2, 2]) x = x.reshape([2, 2]) |
4. 卷积操作
1 2 3 4 5 6 7 8 |
# tensorflow w_c1 = tf.Variable(tf.truncated_normal([5, 5, 1, 32], stddev=0.1), name='w_c1') # 5×5核,1通道输入,32通道输出 conv1 = tf.nn.conv2d(x, w_c1, strides=[1, 1, 1, 1], padding='SAME', name='conv1') # pytorch import torch.nn as nn conv1 = nn.Conv2d(1, 32, 5) # 5×5核,1通道输入,32通道输出,步长默认为1 |
5. 池化操作
1 2 3 4 5 6 7 |
# tensorflow conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME', name='pool1') # pytorch import torch.nn.functional as F x = F.max_pool2d(conv1, (2, 2)) |
6. 全连接层
1 2 3 4 5 6 7 8 9 |
# tensorflow w_d = tf.Variable(tf.truncated_normal([7 * 7 * 64, 1024], stddev=0.1), name='w_d') b_d = tf.Variable(tf.constant(0.1, shape=[1024]), name='b_d') fc1 = tf.matmul(x, w_d) fc1 = fc1 + b_d # pytorch fc1 = nn.Linear(7 * 7 * 64, 1024) |
7. 激活函数
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# tensorflow tf.sigmoid() tf.tanh() tf.nn.relu() tf.nn.softmax() # pytorch import torch.nn.functional as F F.sigmoid() F.tanh() F.relu() F.softmax() |
8. 优化器
1 2 3 4 5 6 7 8 9 |
# tensorflow loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y)) optimizer = tf.train.AdamOptimizer(1e-4).minimize(loss) # pytorch import torch.optim as optim output = model(data) optimizer = optim.adam(model.parameters(), lr=0.01, momentum=0.5) |
9. 训练过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# tensorflow with tf.Session() as sess: for i in range(100): sess.run(optimizer, feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5}) # pytorch for i in range(100): output = model(data) loss = F.nll_loss(output, target) # 应该是相当于softmax_cross_entropy_with_logits optimizer.zero_grad() # 所有参数的梯度清零 loss.backward() # 即反向传播求梯度 optimizer.step() # 调用optimizer进行梯度下降更新参数 |
10. dropout
1 2 3 4 5 6 7 |
# tensorflow keep_prob = tf.placeholder(tf.float32) dense = tf.nn.dropout(dense, keep_prob) # pytorch torch.nn.Dropout(0.5) |