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

369 lines
11 KiB

  1. {
  2. "cells": [
  3. {
  4. "cell_type": "code",
  5. "execution_count": null,
  6. "metadata": {},
  7. "outputs": [],
  8. "source": [
  9. "from google.colab import drive\n",
  10. "\n",
  11. "drive.mount('/content/drive', force_remount=True)\n",
  12. "\n",
  13. "# 输入daseCV所在的路径\n",
  14. "# 'daseCV' 文件夹包括 '.py', 'classifiers' 和'datasets'文件夹\n",
  15. "# 例如 'CV/assignments/assignment1/daseCV/'\n",
  16. "FOLDERNAME = None\n",
  17. "\n",
  18. "assert FOLDERNAME is not None, \"[!] Enter the foldername.\"\n",
  19. "\n",
  20. "%cd drive/My\\ Drive\n",
  21. "%cp -r $FOLDERNAME ../../\n",
  22. "%cd ../../\n",
  23. "%cd daseCV/datasets/\n",
  24. "!bash get_datasets.sh\n",
  25. "%cd ../../"
  26. ]
  27. },
  28. {
  29. "cell_type": "markdown",
  30. "metadata": {
  31. "tags": [
  32. "pdf-title"
  33. ]
  34. },
  35. "source": [
  36. "# Dropout\n",
  37. "Dropout [1] 是一种通过在正向传播中将一些输出随机设置为零,神经网络正则化的方法。在这个练习中,你将实现一个dropout层,并修改你的全连接网络使其可选择的使用dropout\n",
  38. "\n",
  39. "[1] [Geoffrey E. Hinton et al, \"Improving neural networks by preventing co-adaptation of feature detectors\", arXiv 2012](https://arxiv.org/abs/1207.0580)"
  40. ]
  41. },
  42. {
  43. "cell_type": "code",
  44. "execution_count": null,
  45. "metadata": {
  46. "tags": [
  47. "pdf-ignore"
  48. ]
  49. },
  50. "outputs": [],
  51. "source": [
  52. "# As usual, a bit of setup\n",
  53. "from __future__ import print_function\n",
  54. "import time\n",
  55. "import numpy as np\n",
  56. "import matplotlib.pyplot as plt\n",
  57. "from daseCV.classifiers.fc_net import *\n",
  58. "from daseCV.data_utils import get_CIFAR10_data\n",
  59. "from daseCV.gradient_check import eval_numerical_gradient, eval_numerical_gradient_array\n",
  60. "from daseCV.solver import Solver\n",
  61. "\n",
  62. "%matplotlib inline\n",
  63. "plt.rcParams['figure.figsize'] = (10.0, 8.0) # set default size of plots\n",
  64. "plt.rcParams['image.interpolation'] = 'nearest'\n",
  65. "plt.rcParams['image.cmap'] = 'gray'\n",
  66. "\n",
  67. "# for auto-reloading external modules\n",
  68. "# see http://stackoverflow.com/questions/1907993/autoreload-of-modules-in-ipython\n",
  69. "%load_ext autoreload\n",
  70. "%autoreload 2\n",
  71. "\n",
  72. "\n",
  73. "def rel_error(x, y):\n",
  74. " \"\"\" returns relative error \"\"\"\n",
  75. " return np.max(np.abs(x - y) / (np.maximum(1e-8, np.abs(x) + np.abs(y))))\n"
  76. ]
  77. },
  78. {
  79. "cell_type": "code",
  80. "execution_count": null,
  81. "metadata": {
  82. "tags": [
  83. "pdf-ignore"
  84. ]
  85. },
  86. "outputs": [],
  87. "source": [
  88. "# Load the (preprocessed) CIFAR10 data.\n",
  89. "\n",
  90. "data = get_CIFAR10_data()\n",
  91. "for k, v in data.items():\n",
  92. " print('%s: ' % k, v.shape)"
  93. ]
  94. },
  95. {
  96. "cell_type": "markdown",
  97. "metadata": {},
  98. "source": [
  99. "# Dropout 正向传播\n",
  100. "在文件 `daseCV/layers.py` 中完成dropout的正向传播过程。由于dropout在训练和测试期间的行为是不同的,因此请确保两种模式下都实现完成。\n",
  101. "\n",
  102. "完成此操作后,运行下面的cell以测试你的代码。"
  103. ]
  104. },
  105. {
  106. "cell_type": "code",
  107. "execution_count": null,
  108. "metadata": {},
  109. "outputs": [],
  110. "source": [
  111. "np.random.seed(231)\n",
  112. "x = np.random.randn(500, 500) + 10\n",
  113. "\n",
  114. "for p in [0.25, 0.4, 0.7]:\n",
  115. " out, _ = dropout_forward(x, {'mode': 'train', 'p': p})\n",
  116. " out_test, _ = dropout_forward(x, {'mode': 'test', 'p': p})\n",
  117. "\n",
  118. " print('Running tests with p = ', p)\n",
  119. " print('Mean of input: ', x.mean())\n",
  120. " print('Mean of train-time output: ', out.mean())\n",
  121. " print('Mean of test-time output: ', out_test.mean())\n",
  122. " print('Fraction of train-time output set to zero: ', (out == 0).mean())\n",
  123. " print('Fraction of test-time output set to zero: ', (out_test == 0).mean())\n",
  124. " print()"
  125. ]
  126. },
  127. {
  128. "cell_type": "markdown",
  129. "metadata": {},
  130. "source": [
  131. "# Dropout 反向传播\n",
  132. "在文件 `daseCV/layers.py` 中完成dropout的反向传播。完成之后运行以下cell以对你的实现代码进行梯度检查。"
  133. ]
  134. },
  135. {
  136. "cell_type": "code",
  137. "execution_count": null,
  138. "metadata": {},
  139. "outputs": [],
  140. "source": [
  141. "np.random.seed(231)\n",
  142. "x = np.random.randn(10, 10) + 10\n",
  143. "dout = np.random.randn(*x.shape)\n",
  144. "\n",
  145. "dropout_param = {'mode': 'train', 'p': 0.2, 'seed': 123}\n",
  146. "out, cache = dropout_forward(x, dropout_param)\n",
  147. "dx = dropout_backward(dout, cache)\n",
  148. "dx_num = eval_numerical_gradient_array(lambda xx: dropout_forward(xx, dropout_param)[0], x, dout)\n",
  149. "\n",
  150. "# Error should be around e-10 or less\n",
  151. "print('dx relative error: ', rel_error(dx, dx_num))"
  152. ]
  153. },
  154. {
  155. "cell_type": "markdown",
  156. "metadata": {
  157. "tags": [
  158. "pdf-inline"
  159. ]
  160. },
  161. "source": [
  162. "## 问题 1:\n",
  163. "如果我们不利用inverted dropout,在训练的时候直接将dropout后的值除以 `p`,会发生什么?为什么会这样呢?\n",
  164. "\n",
  165. "\n",
  166. "\n",
  167. "## 回答:\n",
  168. "[FILL THIS IN]\n"
  169. ]
  170. },
  171. {
  172. "cell_type": "markdown",
  173. "metadata": {},
  174. "source": [
  175. "# 全连接网络的Dropout\n",
  176. "\n",
  177. "修改`daseCV/classifiers/fc_net.py`文件完成使用dropout的部分。具体来说,如果网络的构造函数收到的`dropout`参数值不为1,则应在每个ReLU之后添加一个dropout层。完成之后,运行以下命令以对你的代码进行梯度检查。"
  178. ]
  179. },
  180. {
  181. "cell_type": "code",
  182. "execution_count": null,
  183. "metadata": {},
  184. "outputs": [],
  185. "source": [
  186. "np.random.seed(231)\n",
  187. "N, D, H1, H2, C = 2, 15, 20, 30, 10\n",
  188. "X = np.random.randn(N, D)\n",
  189. "y = np.random.randint(C, size=(N,))\n",
  190. "\n",
  191. "for dropout in [1, 0.75, 0.5]:\n",
  192. " print('Running check with dropout = ', dropout)\n",
  193. " model = FullyConnectedNet([H1, H2], input_dim=D, num_classes=C,\n",
  194. " weight_scale=5e-2, dtype=np.float64,\n",
  195. " dropout=dropout, seed=123)\n",
  196. "\n",
  197. " loss, grads = model.loss(X, y)\n",
  198. " print('Initial loss: ', loss)\n",
  199. " \n",
  200. " # Relative errors should be around e-6 or less; Note that it's fine\n",
  201. " # if for dropout=1 you have W2 error be on the order of e-5.\n",
  202. " for name in sorted(grads):\n",
  203. " f = lambda _: model.loss(X, y)[0]\n",
  204. " grad_num = eval_numerical_gradient(f, model.params[name], verbose=False, h=1e-5)\n",
  205. " print('%s relative error: %.2e' % (name, rel_error(grad_num, grads[name])))\n",
  206. " print()"
  207. ]
  208. },
  209. {
  210. "cell_type": "markdown",
  211. "metadata": {},
  212. "source": [
  213. "# 正则化实验\n",
  214. "作为实验,我们将在500个样本上训练一对双层网络:一个不使用dropout,另一个使用概率为0.25的dropout。之后,我们将可视化这两个网络训练和验证的准确度。"
  215. ]
  216. },
  217. {
  218. "cell_type": "code",
  219. "execution_count": null,
  220. "metadata": {
  221. "scrolled": false
  222. },
  223. "outputs": [],
  224. "source": [
  225. "# Train two identical nets, one with dropout and one without\n",
  226. "np.random.seed(231)\n",
  227. "num_train = 500\n",
  228. "small_data = {\n",
  229. " 'X_train': data['X_train'][:num_train],\n",
  230. " 'y_train': data['y_train'][:num_train],\n",
  231. " 'X_val': data['X_val'],\n",
  232. " 'y_val': data['y_val'],\n",
  233. "}\n",
  234. "\n",
  235. "solvers = {}\n",
  236. "dropout_choices = [1, 0.25]\n",
  237. "for dropout in dropout_choices:\n",
  238. " model = FullyConnectedNet([500], dropout=dropout)\n",
  239. " print(dropout)\n",
  240. "\n",
  241. " solver = Solver(model, small_data,\n",
  242. " num_epochs=25, batch_size=100,\n",
  243. " update_rule='adam',\n",
  244. " optim_config={\n",
  245. " 'learning_rate': 5e-4,\n",
  246. " },\n",
  247. " verbose=True, print_every=100)\n",
  248. " solver.train()\n",
  249. " solvers[dropout] = solver\n",
  250. " print()"
  251. ]
  252. },
  253. {
  254. "cell_type": "code",
  255. "execution_count": null,
  256. "metadata": {},
  257. "outputs": [],
  258. "source": [
  259. "# Plot train and validation accuracies of the two models\n",
  260. "\n",
  261. "train_accs = []\n",
  262. "val_accs = []\n",
  263. "for dropout in dropout_choices:\n",
  264. " solver = solvers[dropout]\n",
  265. " train_accs.append(solver.train_acc_history[-1])\n",
  266. " val_accs.append(solver.val_acc_history[-1])\n",
  267. "\n",
  268. "plt.subplot(3, 1, 1)\n",
  269. "for dropout in dropout_choices:\n",
  270. " plt.plot(solvers[dropout].train_acc_history, 'o', label='%.2f dropout' % dropout)\n",
  271. "plt.title('Train accuracy')\n",
  272. "plt.xlabel('Epoch')\n",
  273. "plt.ylabel('Accuracy')\n",
  274. "plt.legend(ncol=2, loc='lower right')\n",
  275. " \n",
  276. "plt.subplot(3, 1, 2)\n",
  277. "for dropout in dropout_choices:\n",
  278. " plt.plot(solvers[dropout].val_acc_history, 'o', label='%.2f dropout' % dropout)\n",
  279. "plt.title('Val accuracy')\n",
  280. "plt.xlabel('Epoch')\n",
  281. "plt.ylabel('Accuracy')\n",
  282. "plt.legend(ncol=2, loc='lower right')\n",
  283. "\n",
  284. "plt.gcf().set_size_inches(15, 15)\n",
  285. "plt.show()"
  286. ]
  287. },
  288. {
  289. "cell_type": "markdown",
  290. "metadata": {
  291. "tags": [
  292. "pdf-inline"
  293. ]
  294. },
  295. "source": [
  296. "## 问题 2:\n",
  297. "对比有无dropout的验证和训练的精度,你对使用dropout作为正则化有何建议?\n",
  298. "\n",
  299. "## 回答:\n",
  300. "[FILL THIS IN]\n"
  301. ]
  302. },
  303. {
  304. "cell_type": "markdown",
  305. "metadata": {
  306. "tags": [
  307. "pdf-inline"
  308. ]
  309. },
  310. "source": [
  311. "## 问题三 3:\n",
  312. "假设我们正在训练一个深层的全连接网络用以进行图像分类,并隐层之后dropout(通过使用概率p进行参数化)。如果我们担心过度拟合而决定减小隐层的大小(即每层中的节点数)时,应该如何修改p(如果有的话)?\n",
  313. "\n",
  314. "## 回答:\n",
  315. "[FILL THIS IN]\n"
  316. ]
  317. },
  318. {
  319. "cell_type": "markdown",
  320. "metadata": {},
  321. "source": [
  322. "---\n",
  323. "# 重要\n",
  324. "\n",
  325. "这里是作业的结尾处,请执行以下步骤:\n",
  326. "\n",
  327. "1. 点击`File -> Save`或者用`control+s`组合键,确保你最新的的notebook的作业已经保存到谷歌云。\n",
  328. "2. 执行以下代码确保 `.py` 文件保存回你的谷歌云。"
  329. ]
  330. },
  331. {
  332. "cell_type": "code",
  333. "execution_count": null,
  334. "metadata": {},
  335. "outputs": [],
  336. "source": [
  337. "import os\n",
  338. "\n",
  339. "FOLDER_TO_SAVE = os.path.join('drive/My Drive/', FOLDERNAME)\n",
  340. "FILES_TO_SAVE = ['daseCV/classifiers/cnn.py', 'daseCV/classifiers/fc_net.py']\n",
  341. "\n",
  342. "for files in FILES_TO_SAVE:\n",
  343. " with open(os.path.join(FOLDER_TO_SAVE, '/'.join(files.split('/')[1:])), 'w') as f:\n",
  344. " f.write(''.join(open(files).readlines()))"
  345. ]
  346. }
  347. ],
  348. "metadata": {
  349. "kernelspec": {
  350. "display_name": "Python 3",
  351. "language": "python",
  352. "name": "python3"
  353. },
  354. "language_info": {
  355. "codemirror_mode": {
  356. "name": "ipython",
  357. "version": 3
  358. },
  359. "file_extension": ".py",
  360. "mimetype": "text/x-python",
  361. "name": "python",
  362. "nbconvert_exporter": "python",
  363. "pygments_lexer": "ipython3",
  364. "version": "3.7.0"
  365. }
  366. },
  367. "nbformat": 4,
  368. "nbformat_minor": 2
  369. }