【发布时间】:2020-02-10 21:02:16
【问题描述】:
我比较了 Mathematica 和 Python 之间的 mxnet 性能,观察到超过一个数量级的性能差异,并希望就如何在 Python 下提高性能提出建议。
My NN 是一个用于回归的 MLP,具有 3 个浮点输入,8、16、24、8 个神经元全连接层和 2 个浮点输出,除了输入和输出神经元外,Sigmoid 被用于任何地方。 Mathematica 中使用的优化器是 Adam,所以我在 Python 中也使用了相同的参数。训练数据集包含 4215 条记录,将 xyY 颜色映射到 Munsell Hue 和 Chroma。
Mathematica 是 2017 年发布的 11.2 版,Mathematica 在底层使用 mxnet 进行深度学习任务。在 Python 方面,我使用最新版本的 mxnet-mkl,并检查了 MKLDNN 是否已启用。
Mathematica 许可证可在装有 Windows 10、i7-7660U、2.5Ghz、2 核、4 超线程、AVX2 的 MS Surface Pro 笔记本电脑上运行。我在这台计算机上运行 Python 进行比较。
这里是学习循环 32768 个 epoch 的时间和
Batch Sizes: 128, 256, 512, 1024, 2048, 4096
Mathematica: 8m12s, 5m14s, 3m34s, 2m57s, 3m4s, 3m48s
PythonMxNet: 286m, 163m, 93m, 65m, 49m, 47m
我尝试了英特尔建议的 mxnet 环境变量优化技巧,但速度只慢了 120%。
我还将所有数组从 float64 切换到 float32,假设 MKL 可以使用 SIMD 寄存器在相同的时间内(当然不包括开销)处理 2 倍的操作,但没有发现任何轻微的改进。
我将 NN 工作从 Mathematica 切换到 Python 的原因是我想在不同且更强大的计算机上训练 NN。而且我也不喜欢把笔记本绑在神经网络学习任务上。
我应该如何解释这些结果?
造成这些性能差异的原因可能是什么?
我可以做些什么来在 Python 下获得一些性能?
或者这仅仅是 Python 解释器强加的不可避免的开销?
编辑:
生成神经网络的脚本:
def get_MunsellNet( Layers, NbInputs ):
net = nn.HybridSequential()
for l in range( len( Layers ) ):
if l == 0:
net.add( nn.Dense( Layers[ l ], activation = 'sigmoid', dtype = mu.DType, in_units = NbInputs ) )
else:
net.add( nn.Dense( Layers[ l ], activation = 'sigmoid', dtype = mu.DType ) )
net.add( nn.Dense( 2, dtype = mu.DType ) )
net.hybridize()
net.initialize( mx.init.Uniform(), ctx = ctx )
return net
NN 是这样创建的:
mu.DType = 'f8'
NbInputs = 3
Norm = 'None' # Possible normalizer are: 'None', 'Unit', 'RMS', 'RRMS', 'Std'
Train_Dataset = mnr.Build_HCTrainData( NbInputs, Norm, Datasets = [ 'all.dat', 'fill.dat' ] )
Test_Dataset1 = mnr.Build_HCTestData( 'real.dat', NbInputs )
Test_Dataset2 = mnr.Build_HCTestData( 'test.dat', NbInputs )
Layers = [ 8, 16, 24, 8 ]
Net = mnn.get_MunsellNet( Layers, NbInputs )
Loss_Fn = mx.gluon.loss.L2Loss()
Learning_Rate = 0.0005
Optimizer = 'Adam'
Batch_Size = 4096
Epochs = 500000
并接受了以下训练:
if __name__ == '__main__':
global Train_Data_Loader
Train_Data_Loader = mx.gluon.data.DataLoader( Train_Dataset, batch_size = Batch_Size, shuffle = True, num_workers = mnn.NbWorkers )
Trainer = mx.gluon.Trainer( Net.collect_params(), Optimizer, {'learning_rate': Learning_Rate} )
Estimator = estimator.Estimator( net = Net,
loss = Loss_Fn,
trainer = Trainer,
context = mnn.ctx )
LossRecordHandler = mnu.ProgressRecorder( Epochs, Test_Dataset1, Test_Dataset2, NbInputs, Net_Name, Epochs / 10 * 8 )
for n in range( 10 ):
LossRecordHandler.ResetStates()
Train_Metric = Estimator.prepare_loss_and_metrics()
Net.initialize( force_reinit = True )
# ignore warnings for nightly test on CI only
with warnings.catch_warnings():
warnings.simplefilter( "ignore" )
Estimator.fit( train_data = Train_Data_Loader,
epochs = Epochs,
event_handlers = [ LossRecordHandler ] )
如果您需要更多代码片段,请告诉我。
【问题讨论】:
-
我们首先需要确保这种比较是苹果对苹果的,但是虽然我对 mxnet 很了解,但不幸的是,我对 mathematica 的了解还不够,无法提供有关注意事项的建议。您能否解释一下如何确保比较设置是一致的(例如,他们使用相同的 mxnet 构建)?另外,您介意分享显示模型大小的 python 脚本吗?
-
我不确定你所说的显示模型大小的 python 脚本是什么意思。我有一个创建网络的函数并使用参数调用该函数。那是你要的吗?我也应该在 cmets 中发布此内容还是将其发布到“回答您自己的问题”中?
-
关于 Mathematica 使用 MxNet 的详细信息,恐怕这不是可用的信息。但我猜它使用的是相当旧的 MxNet,因为 Mathematica v11.2 于 2017 年发布,我从未更新过它。无论如何,肯定是比我在 Python 下使用的那个更旧的 MxNet 版本。
-
我刚刚在上面的问题中添加了一些代码片段。
-
谢谢。看起来我缺少一些模块才能运行它。您能在某处签入代码以便我可以运行吗?
标签: python wolfram-mathematica mxnet