Last active
March 3, 2023 02:29
-
-
Save iiSeymour/85a5285e00cbed60537241da7c3b8525 to your computer and use it in GitHub Desktop.
Compare 1D Separable Convolutions in PyTorch and Tensorflow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import os | |
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' | |
import sys | |
import torch | |
import numpy as np | |
import tensorflow as tf | |
from time import perf_counter | |
from torch.nn import Module, Conv1d | |
from tensorflow.keras import Model, Input | |
from tensorflow.keras.layers import SeparableConv1D | |
tf.compat.v1.disable_eager_execution() | |
class TCSConv1d(Module): | |
def __init__(self, filters, kernel_size): | |
super(TCSConv1d, self).__init__() | |
self.depthwise = Conv1d(filters, filters, kernel_size=kernel_size, groups=filters) | |
self.pointwise = Conv1d(filters, filters, kernel_size=1) | |
def forward(self, x): | |
x = self.depthwise(x) | |
x = self.pointwise(x) | |
return x | |
def pytorch_model(N, C, W, K): | |
model = TCSConv1d(C, K) | |
model.to('cuda') | |
data = torch.ones((N, C, W), dtype=torch.float32) | |
return model, data | |
def tensorflow_model(N, C, W, K): | |
inputs = Input(batch_shape=(N, C, W)) | |
x = SeparableConv1D(C, K, data_format='channels_first')(inputs) | |
model = Model(inputs=inputs, outputs=x) | |
model.compile(loss='mean_squared_error', optimizer='adam') | |
data = np.ones((N, C, W), dtype=np.float32) | |
return model, data | |
def benchmark(N=100, W=2000): | |
test_sizes = [ | |
(256, 33), | |
(256, 39), | |
(512, 51), | |
(512, 63), | |
(512, 75), | |
(512, 86), | |
] | |
for C, K in test_sizes: | |
model, data = tensorflow_model(N, C, W, K) | |
model.predict(data) | |
t0 = perf_counter() | |
model.predict(data) | |
tftime = perf_counter() - t0 | |
model, data = pytorch_model(N, C, W, K) | |
t0 = perf_counter() | |
model(data.to('cuda')).to('cpu') | |
torch.cuda.synchronize('cuda') | |
pttime = perf_counter() - t0 | |
print("Filters:", C, "Kernel Size:", K) | |
print("PyTorch %.4f" % pttime) | |
print("Tensorflow %.4f" % tftime) | |
if __name__ == "__main__": | |
benchmark() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
On a GV100 comparing PyTorch 1.3.1 and Tensorflow 2.0 (cuda 10.1), I make PyTorch up to twice as fast in some cases.