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

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

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