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)  |