You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_batchnorm.py 14 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. # -*- coding: utf-8 -*-
  2. # MegEngine is Licensed under the Apache License, Version 2.0 (the "License")
  3. #
  4. # Copyright (c) 2014-2020 Megvii Inc. All rights reserved.
  5. #
  6. # Unless required by applicable law or agreed to in writing,
  7. # software distributed under the License is distributed on an
  8. # "AS IS" BASIS, WITHOUT ARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. import multiprocessing as mp
  10. import platform
  11. import numpy as np
  12. import pytest
  13. import megengine as mge
  14. import megengine.distributed as dist
  15. from megengine.core import tensor
  16. from megengine.module import BatchNorm1d, BatchNorm2d, SyncBatchNorm
  17. from megengine.test import assertTensorClose
  18. @pytest.mark.skipif(
  19. platform.system() == "Darwin", reason="do not imp GPU mode at macos now"
  20. )
  21. @pytest.mark.isolated_distributed
  22. def test_syncbn():
  23. nr_chan = 8
  24. data_shape = (3, nr_chan, 4, 16)
  25. momentum = 0.9
  26. eps = 1e-5
  27. running_mean = np.zeros((1, nr_chan, 1, 1), dtype=np.float32)
  28. running_var = np.ones((1, nr_chan, 1, 1), dtype=np.float32)
  29. steps = 4
  30. nr_ranks = 2
  31. def worker(rank, data, yv_expect, running_mean, running_var):
  32. if mge.get_device_count("gpu") < nr_ranks:
  33. return
  34. dist.init_process_group("localhost", 2333, nr_ranks, rank, rank)
  35. bn = SyncBatchNorm(nr_chan, momentum=momentum, eps=eps)
  36. data_tensor = tensor()
  37. for i in range(steps):
  38. data_tensor.set_value(data[i])
  39. yv = bn(data_tensor)
  40. assertTensorClose(yv_expect, yv.numpy(), max_err=5e-6)
  41. assertTensorClose(running_mean, bn.running_mean.numpy(), max_err=5e-6)
  42. assertTensorClose(running_var, bn.running_var.numpy(), max_err=5e-6)
  43. xv = []
  44. for i in range(steps):
  45. xv.append(np.random.normal(loc=2.3, size=data_shape).astype(np.float32))
  46. xv_transposed = np.transpose(xv[i], [0, 2, 3, 1]).reshape(
  47. (data_shape[0] * data_shape[2] * data_shape[3], nr_chan)
  48. )
  49. mean = np.mean(xv_transposed, axis=0).reshape(1, nr_chan, 1, 1)
  50. var_biased = np.var(xv_transposed, axis=0).reshape((1, nr_chan, 1, 1))
  51. sd = np.sqrt(var_biased + eps)
  52. var_unbiased = np.var(xv_transposed, axis=0, ddof=1).reshape((1, nr_chan, 1, 1))
  53. running_mean = running_mean * momentum + mean * (1 - momentum)
  54. running_var = running_var * momentum + var_unbiased * (1 - momentum)
  55. yv_expect = (xv[i] - mean) / sd
  56. data = []
  57. for i in range(nr_ranks):
  58. data.append([])
  59. for j in range(steps):
  60. data[i].append(xv[j][:, :, :, i * 8 : i * 8 + 8])
  61. procs = []
  62. for rank in range(nr_ranks):
  63. p = mp.Process(
  64. target=worker,
  65. args=(
  66. rank,
  67. data[rank],
  68. yv_expect[:, :, :, rank * 8 : rank * 8 + 8],
  69. running_mean,
  70. running_var,
  71. ),
  72. )
  73. p.start()
  74. procs.append(p)
  75. for p in procs:
  76. p.join(10)
  77. assert p.exitcode == 0
  78. def test_batchnorm():
  79. nr_chan = 8
  80. data_shape = (3, nr_chan, 4)
  81. momentum = 0.9
  82. bn = BatchNorm1d(nr_chan, momentum=momentum)
  83. running_mean = np.zeros((1, nr_chan, 1), dtype=np.float32)
  84. running_var = np.ones((1, nr_chan, 1), dtype=np.float32)
  85. data = tensor()
  86. for i in range(3):
  87. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  88. mean = np.mean(np.mean(xv, axis=0, keepdims=True), axis=2, keepdims=True)
  89. xv_transposed = np.transpose(xv, [0, 2, 1]).reshape(
  90. (data_shape[0] * data_shape[2], nr_chan)
  91. )
  92. var_biased = np.var(xv_transposed, axis=0).reshape((1, nr_chan, 1))
  93. sd = np.sqrt(var_biased + bn.eps)
  94. var_unbiased = np.var(xv_transposed, axis=0, ddof=1).reshape((1, nr_chan, 1))
  95. running_mean = running_mean * momentum + mean * (1 - momentum)
  96. running_var = running_var * momentum + var_unbiased * (1 - momentum)
  97. data.set_value(xv)
  98. yv = bn(data)
  99. yv_expect = (xv - mean) / sd
  100. assertTensorClose(yv_expect, yv.numpy(), max_err=5e-6)
  101. assertTensorClose(
  102. running_mean.reshape(-1), bn.running_mean.numpy().reshape(-1), max_err=5e-6
  103. )
  104. assertTensorClose(
  105. running_var.reshape(-1), bn.running_var.numpy().reshape(-1), max_err=5e-6
  106. )
  107. # test set 'training' flag to False
  108. mean_backup = bn.running_mean.numpy()
  109. var_backup = bn.running_var.numpy()
  110. bn.training = False
  111. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  112. data.set_value(xv)
  113. yv1 = bn(data)
  114. yv2 = bn(data)
  115. assertTensorClose(yv1.numpy(), yv2.numpy(), max_err=0)
  116. assertTensorClose(mean_backup, bn.running_mean.numpy(), max_err=0)
  117. assertTensorClose(var_backup, bn.running_var.numpy(), max_err=0)
  118. yv_expect = (xv - running_mean) / np.sqrt(running_var + bn.eps)
  119. assertTensorClose(yv_expect, yv1.numpy(), max_err=5e-6)
  120. @pytest.mark.skipif(
  121. platform.system() == "Darwin", reason="do not imp GPU mode at macos now"
  122. )
  123. def test_syncbn1d():
  124. nr_chan = 8
  125. data_shape = (3, nr_chan, 4)
  126. momentum = 0.9
  127. bn = SyncBatchNorm(nr_chan, momentum=momentum)
  128. running_mean = np.zeros((1, nr_chan, 1), dtype=np.float32)
  129. running_var = np.ones((1, nr_chan, 1), dtype=np.float32)
  130. data = tensor()
  131. for i in range(3):
  132. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  133. mean = np.mean(np.mean(xv, axis=0, keepdims=True), axis=2, keepdims=True)
  134. xv_transposed = np.transpose(xv, [0, 2, 1]).reshape(
  135. (data_shape[0] * data_shape[2], nr_chan)
  136. )
  137. var_biased = np.var(xv_transposed, axis=0).reshape((1, nr_chan, 1))
  138. sd = np.sqrt(var_biased + bn.eps)
  139. var_unbiased = np.var(xv_transposed, axis=0, ddof=1).reshape((1, nr_chan, 1))
  140. running_mean = running_mean * momentum + mean * (1 - momentum)
  141. running_var = running_var * momentum + var_unbiased * (1 - momentum)
  142. data.set_value(xv)
  143. yv = bn(data)
  144. yv_expect = (xv - mean) / sd
  145. assertTensorClose(yv_expect, yv.numpy(), max_err=5e-6)
  146. assertTensorClose(
  147. running_mean.reshape(-1), bn.running_mean.numpy().reshape(-1), max_err=5e-6
  148. )
  149. assertTensorClose(
  150. running_var.reshape(-1), bn.running_var.numpy().reshape(-1), max_err=5e-6
  151. )
  152. # test set 'training' flag to False
  153. mean_backup = bn.running_mean.numpy()
  154. var_backup = bn.running_var.numpy()
  155. bn.training = False
  156. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  157. data.set_value(xv)
  158. yv1 = bn(data)
  159. yv2 = bn(data)
  160. assertTensorClose(yv1.numpy(), yv2.numpy(), max_err=0)
  161. assertTensorClose(mean_backup, bn.running_mean.numpy(), max_err=0)
  162. assertTensorClose(var_backup, bn.running_var.numpy(), max_err=0)
  163. yv_expect = (xv - running_mean) / np.sqrt(running_var + bn.eps)
  164. assertTensorClose(yv_expect, yv1.numpy(), max_err=5e-6)
  165. def test_batchnorm2d():
  166. nr_chan = 8
  167. data_shape = (3, nr_chan, 16, 16)
  168. momentum = 0.9
  169. bn = BatchNorm2d(nr_chan, momentum=momentum)
  170. running_mean = np.zeros((1, nr_chan, 1, 1), dtype=np.float32)
  171. running_var = np.ones((1, nr_chan, 1, 1), dtype=np.float32)
  172. data = tensor()
  173. for i in range(3):
  174. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  175. xv_transposed = np.transpose(xv, [0, 2, 3, 1]).reshape(
  176. (data_shape[0] * data_shape[2] * data_shape[3], nr_chan)
  177. )
  178. mean = np.mean(xv_transposed, axis=0).reshape(1, nr_chan, 1, 1)
  179. var_biased = np.var(xv_transposed, axis=0).reshape((1, nr_chan, 1, 1))
  180. sd = np.sqrt(var_biased + bn.eps)
  181. var_unbiased = np.var(xv_transposed, axis=0, ddof=1).reshape((1, nr_chan, 1, 1))
  182. running_mean = running_mean * momentum + mean * (1 - momentum)
  183. running_var = running_var * momentum + var_unbiased * (1 - momentum)
  184. data.set_value(xv)
  185. yv = bn(data)
  186. yv_expect = (xv - mean) / sd
  187. assertTensorClose(yv_expect, yv.numpy(), max_err=5e-6)
  188. assertTensorClose(running_mean, bn.running_mean.numpy(), max_err=5e-6)
  189. assertTensorClose(running_var, bn.running_var.numpy(), max_err=5e-6)
  190. # test set 'training' flag to False
  191. mean_backup = bn.running_mean.numpy()
  192. var_backup = bn.running_var.numpy()
  193. bn.training = False
  194. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  195. data.set_value(xv)
  196. yv1 = bn(data)
  197. yv2 = bn(data)
  198. assertTensorClose(yv1.numpy(), yv2.numpy(), max_err=0)
  199. assertTensorClose(mean_backup, bn.running_mean.numpy(), max_err=0)
  200. assertTensorClose(var_backup, bn.running_var.numpy(), max_err=0)
  201. yv_expect = (xv - running_mean) / np.sqrt(running_var + bn.eps)
  202. assertTensorClose(yv_expect, yv1.numpy(), max_err=5e-6)
  203. @pytest.mark.skipif(
  204. platform.system() == "Darwin", reason="do not imp GPU mode at macos now"
  205. )
  206. def test_syncbn2d():
  207. nr_chan = 8
  208. data_shape = (3, nr_chan, 16, 16)
  209. momentum = 0.9
  210. bn = SyncBatchNorm(nr_chan, momentum=momentum)
  211. running_mean = np.zeros((1, nr_chan, 1, 1), dtype=np.float32)
  212. running_var = np.ones((1, nr_chan, 1, 1), dtype=np.float32)
  213. data = tensor()
  214. for i in range(3):
  215. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  216. xv_transposed = np.transpose(xv, [0, 2, 3, 1]).reshape(
  217. (data_shape[0] * data_shape[2] * data_shape[3], nr_chan)
  218. )
  219. mean = np.mean(xv_transposed, axis=0).reshape(1, nr_chan, 1, 1)
  220. var_biased = np.var(xv_transposed, axis=0).reshape((1, nr_chan, 1, 1))
  221. sd = np.sqrt(var_biased + bn.eps)
  222. var_unbiased = np.var(xv_transposed, axis=0, ddof=1).reshape((1, nr_chan, 1, 1))
  223. running_mean = running_mean * momentum + mean * (1 - momentum)
  224. running_var = running_var * momentum + var_unbiased * (1 - momentum)
  225. data.set_value(xv)
  226. yv = bn(data)
  227. yv_expect = (xv - mean) / sd
  228. assertTensorClose(yv_expect, yv.numpy(), max_err=5e-6)
  229. assertTensorClose(running_mean, bn.running_mean.numpy(), max_err=5e-6)
  230. assertTensorClose(running_var, bn.running_var.numpy(), max_err=5e-6)
  231. # test set 'training' flag to False
  232. mean_backup = bn.running_mean.numpy()
  233. var_backup = bn.running_var.numpy()
  234. bn.training = False
  235. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  236. data.set_value(xv)
  237. yv1 = bn(data)
  238. yv2 = bn(data)
  239. assertTensorClose(yv1.numpy(), yv2.numpy(), max_err=0)
  240. assertTensorClose(mean_backup, bn.running_mean.numpy(), max_err=0)
  241. assertTensorClose(var_backup, bn.running_var.numpy(), max_err=0)
  242. yv_expect = (xv - running_mean) / np.sqrt(running_var + bn.eps)
  243. assertTensorClose(yv_expect, yv1.numpy(), max_err=5e-6)
  244. def test_batchnorm_no_stats():
  245. nr_chan = 8
  246. data_shape = (3, nr_chan, 4)
  247. bn = BatchNorm1d(8, track_running_stats=False)
  248. data = tensor()
  249. for i in range(4):
  250. if i == 2:
  251. bn.training = False
  252. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  253. mean = np.mean(np.mean(xv, axis=0, keepdims=True), axis=2, keepdims=True)
  254. var = np.var(
  255. np.transpose(xv, [0, 2, 1]).reshape(
  256. (data_shape[0] * data_shape[2], nr_chan)
  257. ),
  258. axis=0,
  259. ).reshape((1, nr_chan, 1))
  260. sd = np.sqrt(var + bn.eps)
  261. data.set_value(xv)
  262. yv = bn(data)
  263. yv_expect = (xv - mean) / sd
  264. assertTensorClose(yv_expect, yv.numpy(), max_err=5e-6)
  265. @pytest.mark.skipif(
  266. platform.system() == "Darwin", reason="do not imp GPU mode at macos now"
  267. )
  268. def test_syncbn_no_stats():
  269. nr_chan = 8
  270. data_shape = (3, nr_chan, 4)
  271. bn = SyncBatchNorm(8, track_running_stats=False)
  272. data = tensor()
  273. for i in range(4):
  274. if i == 2:
  275. bn.training = False
  276. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  277. mean = np.mean(np.mean(xv, axis=0, keepdims=True), axis=2, keepdims=True)
  278. var = np.var(
  279. np.transpose(xv, [0, 2, 1]).reshape(
  280. (data_shape[0] * data_shape[2], nr_chan)
  281. ),
  282. axis=0,
  283. ).reshape((1, nr_chan, 1))
  284. sd = np.sqrt(var + bn.eps)
  285. data.set_value(xv)
  286. yv = bn(data)
  287. yv_expect = (xv - mean) / sd
  288. assertTensorClose(yv_expect, yv.numpy(), max_err=5e-6)
  289. def test_batchnorm2d_no_stats():
  290. nr_chan = 8
  291. data_shape = (3, nr_chan, 16, 16)
  292. bn = BatchNorm2d(8, track_running_stats=False)
  293. data = tensor()
  294. for i in range(4):
  295. if i == 2:
  296. bn.training = False
  297. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  298. xv_transposed = np.transpose(xv, [0, 2, 3, 1]).reshape(
  299. (data_shape[0] * data_shape[2] * data_shape[3], nr_chan)
  300. )
  301. mean = np.mean(xv_transposed, axis=0).reshape(1, nr_chan, 1, 1)
  302. var = np.var(xv_transposed, axis=0).reshape((1, nr_chan, 1, 1))
  303. sd = np.sqrt(var + bn.eps)
  304. data.set_value(xv)
  305. yv = bn(data)
  306. yv_expect = (xv - mean) / sd
  307. assertTensorClose(yv_expect, yv.numpy(), max_err=5e-6)
  308. @pytest.mark.skipif(
  309. platform.system() == "Darwin", reason="do not imp GPU mode at macos now"
  310. )
  311. def test_syncbn2d_no_stats():
  312. nr_chan = 8
  313. data_shape = (3, nr_chan, 16, 16)
  314. bn = SyncBatchNorm(8, track_running_stats=False)
  315. data = tensor()
  316. for i in range(4):
  317. if i == 2:
  318. bn.training = False
  319. xv = np.random.normal(loc=2.3, size=data_shape).astype(np.float32)
  320. xv_transposed = np.transpose(xv, [0, 2, 3, 1]).reshape(
  321. (data_shape[0] * data_shape[2] * data_shape[3], nr_chan)
  322. )
  323. mean = np.mean(xv_transposed, axis=0).reshape(1, nr_chan, 1, 1)
  324. var = np.var(xv_transposed, axis=0).reshape((1, nr_chan, 1, 1))
  325. sd = np.sqrt(var + bn.eps)
  326. data.set_value(xv)
  327. yv = bn(data)
  328. yv_expect = (xv - mean) / sd
  329. assertTensorClose(yv_expect, yv.numpy(), max_err=5e-6)

MegEngine 安装包中集成了使用 GPU 运行代码所需的 CUDA 环境,不用区分 CPU 和 GPU 版。 如果想要运行 GPU 程序,请确保机器本身配有 GPU 硬件设备并安装好驱动。 如果你想体验在云端 GPU 算力平台进行深度学习开发的感觉,欢迎访问 MegStudio 平台