├── .gitignore ├── Data ├── Text │ ├── dictionary │ ├── test.txt │ └── test_small.txt ├── cmnt.txt ├── cmnt_test.txt ├── post.txt ├── post_test.txt ├── preprocess.py ├── textData.m └── used │ ├── cmnt_index.txt │ ├── dictionary.txt │ └── post_index.txt ├── Layers ├── ConcatLayer.m ├── Data.m ├── EmbeddingLayer.m ├── InputLayer.m ├── LstmLayer.m ├── OperateLayer.m ├── RecurrentLayer.m ├── SGD.m ├── SelectLayer.m ├── SoftmaxLayer.m ├── setup.m ├── sigmoid.m ├── sigmoidPrime.m ├── tanhPrime.m ├── test_components.m └── test_gradient_components.m ├── Models ├── encoder_decoder.mat ├── setup.m ├── test_LSTM_autoencode.m ├── test_RNN_autoencode.m ├── test_encoder_decoder.m ├── test_video_seq_classification.m ├── train_encoder_decoder.m └── video_sample.mat └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | -------------------------------------------------------------------------------- /Data/Text/test_small.txt: -------------------------------------------------------------------------------- 1 | 153 14 10 37 280 51 9 31 64 766 10 243 172 356 12 32 36 13117 8 307 147 13 530 40 156 32 90 31 10 402 21 14 31 113 39 139 31 10 3589 21 14 31 616 27 15 399 6 311 36 31 2 | 16 8 19 52 872 2 98 871 3 2347 20 300 3 147 5 151 85 634 2 680 20 131 937 31 210 14 201 10 1675 6 449 3 577 598 3 425 7 1 904 5 29 354 9 7531 3 104 28 678 2 49 31 3 | 35 14 4 885 626 24 50 688 48 26 33 54 5 77 31 2 14 13 19 79 1100 5 117 6 311 1455 27 104 935 5 37 6 696 9 5 366 159 18 2 2207 5 2075 12 138 152 31 11 91 870 125 98 31 4 | 2 660 13 570 24 50 9865 5 6 86 760 3 480 114 5 2 48 9 983 19 54 5 2 66 930 3 6 50 5 347 2 130 660 503 3959 115 3 34 13 64 61 788 169 408 22 34 33 50 1 15 61 375 3 5 | 10 37 124 7 213 1400 3 5 37 51 18 1485 122 23 21 8 83 360 2 153 3 161 20 35 3 49 8 123 9 2 606 12 138 152 5 11 29 6 16 26 1632 138 152 3 10 396 12 270 15 6 181 1 3 6 | 64 392 3 646 1545 3 2255 10463 142 477 3 64 1516 74 424 3 3072 3049 180 584 883 2562 3 64 1 511 2246 3 566 1364 98 2041 69 236 180 30 2351 3 9 6 9116 5714 4 6 80 4782 3 469 196 3 173 1040 214 41 7 | 2 451 1353 40 192 158 5 818 1703 84 835 32 754 235 31 400 8 45 86 786 32 36 4 6328 26 17 47 46 6 19157 235 31 10 154 136 21 14 7 428 266 15 35 66 5 6 35 71 31 616 27 451 1353 206 523 31 8 | 1589 6 706 166 333 9 2 14 5 51 974 3 16 8 226 4 81 8 54 5 77 5 2 101 8 933 3 2 932 9 2 348 8 6 52 611 5 2 326 61 9 2 171 1368 2 779 3 11 47 154 36 65 76 3 2805 31 9 | 125 7 21 14 53 27 193 293 1139 66 3 2 40 630 74 15 157 88 6999 4 1638 42 434 46 158 5 158 76 3 217 6 188 564 7447 26 200 109 162 347 197 3 2 431 33 8644 31 415 15 2 2100 103 266 1792 2 177 31 10 | 150 73 21 14 8 139 24 55 1785 3 30 16 8 25 1255 103 4 790 619 2 147 3 222 2078 38 4218 695 78 513 3 19 1365 18 57 31 2 40 8 131 937 4 11 20 123 25 2 854 3 67 173 36 25 2 1255 103 31 11 | 51 65 15 2 1 2127 31 110 9 8 1999 5 42 29 32 16 492 194 2501 31 305 1102 26 31 225 171 12 2 3159 10 29 6 843 619 168 1336 32 1162 29 962 38 2125 7 2927 31 10 8 45 2178 31 42 154 318 516 66 31 12 | 10 29 10 311 36 18 2 1540 5008 14 3 10 127 9 560 346 22 22712 8 34 7 2650 59 24 6 1015 5 6 2536 73 6 5108 1611 26 8 380 5 1056 31 3 2 16 8 77 5 32 36 9 475 8 35 3 1019 46 98 3 13 | 51 38 513 78 2863 78 4731 23 513 78 3324 78 4731 3 2 40 8 70 3 5 48 201 50 233 3 35 49 151 205 7 138 152 5 1419 644 3 5 1683 234 3 174 35 570 1 770 25 4483 5 802 3 27 37 7 110 56 3 14 | 45 11 394 11 47 1228 6 120 334 3 3897 667 550 84 778 27 21 13 2 805 14 83 2 230 3 66 4887 2 48 245 515 5 34 9763 24 88 120 3829 31 112 6 14 25 55 283 5 6 813 10032 1312 2434 25 2 94 283 3 15 | 11 51 34 15 160 135 5 265 17 6 231 3 49 31 3 49 31 3 49 31 3 17 117 2 153 49 9 727 12 206 523 184 3 2 302 13 79 878 4 2 388 13 2962 310 5 2 48 33 12514 3 2 40 13 19 579 3 16 | 127 6 16 24 6 1308 101 15 73 80 1003 2788 3 440 570 15 2 49 31 163 14 48 9 21 85 33 134 100 80 3 8072 4 1308 101 22 28 45 287 5 34 13 6 715 9 2 101 3 35 15 1191 7 1458 114 229 133 3 17 | 51 15 167 24 734 3 276 516 66 10 24734 46 4473 1423 2568 38 1129 9 1274 3 839 2 11908 42 274 1997 2 5814 62 519 84 6 19 155 367 3 3936 24 2 3289 23 456 466 3 1002 516 66 1595 3 10 24734 182 36 65 76 31 18 | 30 190 18 2 332 5 1456 8 55 10 173 193 7 190 3 38 2 71 11 1300 7 110 23 9 11 29 297 22 746 66 3 2 1129 26 1738 2 846 5470 20 1002 3 2 68 476 26 8 52 7 59 8 21253 1 3 228 8 307 3 19 | 3047 25 2 646 31 45 118 31 139 292 15 334 4 309 9 561 186 85 4 482 86 40 4 150 8 1576 4 10 396 415 15 100 3 53 10 232 1376 224 7 324 7 114 229 4 10 91 37 64 2082 9 653 24 15017 464 435 76 3 20 | 35 145 5 35 49 3 6 120 170 12 6 2269 411 9 5 56 1728 2 230 3 2 115 13 93 31 53 27 33 67 9 2 1092 85 15 6 90 69 45 21 14 117 150 3 42 391 15 219 3 2 95 87 281 84 9 19 733 3 21 | -------------------------------------------------------------------------------- /Data/cmnt_test.txt: -------------------------------------------------------------------------------- 1 | 你 流 泪 了 。 2 | 嗯 , 这 剧 我 百 白 不 厌 啊 。 3 | 好 想 领 一 只 回 家 ! 4 | 郭 德 纲 徒 弟 。 5 | 大 早 晨 就 吃 一 堆 凉 咸 菜 能 舒 服 么 。 6 | 这 个 我 雷 可 以 一 争 。 7 | 这 张 图 很 强 大 。 8 | 拿 剪 刀 吧 。 9 | 生 死 之 恋 ! 10 | 慕 尼 黑 。 11 | 这 个 可 以 有 。 12 | 必 须 欢 迎 。 13 | 这 个 , 好 狠 。 14 | 挺 精 致 , 人 偶 。 15 | 酒 蒙 子 。 16 | 还 有 杭 州 女 神 探 判 了 吗 。 17 | 为 什 么 不 能 选 择 性 失 忆 。 18 | 你 什 么 专 业 啊 。 19 | 伟 大 的 对 手 ! 20 | 好 恶 心 啊 。 21 | 真 是 张 壮 阳 的 好 图 。 22 | 怎 么 看 怎 么 像 精 灵 球 。 23 | 对 错 焦 了 ? 24 | 去 年 尤 文 对 帕 尔 马 的 吧 。 25 | 有 点 的 风 格 。 26 | 哪 里 卖 的 ? 27 | 先 转 走 , 有 空 再 学 。 28 | 幸 福 健 康 啊 。 29 | 应 该 把 它 抱 走 , 看 还 睡 。 30 | 会 这 样 哦 , 宝 宝 想 出 来 。 31 | 哈 哈 , 那 必 须 的 哦 ! 32 | 喝 碗 羊 汤 解 解 骚 。 33 | 小 心 被 雷 霹 。 34 | 你 还 好 吗 。 35 | 竹 , 翠 绿 , 似 玉 。 36 | 哇 赛 赛 这 个 好 方 便 啊 。 37 | 你 的 墨 镜 是 啥 牌 子 的 ? 38 | 肥 仔 我 爱 死 你 了 。 39 | 递 归 , 迭 代 。 40 | 当 前 状 态 的 写 照 。 41 | 回 我 回 我 回 我 回 我 回 我 回 我 回 我 。 42 | 有 意 思 吗 ? 43 | 只 有 浙 江 还 是 其 他 地 方 也 是 。 44 | 很 好 , 加 油 。 45 | 没 看 出 有 多 好 。 46 | 你 的 意 思 是 正 常 过 咯 ? 47 | 广 州 还 是 很 多 灰 尘 。 48 | 哈 哈 不 行 了 。 49 | 这 才 是 基 石 啊 ! 50 | 平 安 夜 快 乐 ! 51 | 呵 呵 , 好 食 吗 。 52 | 潘 总 , 想 长 寿 就 离 开 北 京 吧 。 53 | 挺 好 的 。 54 | 这 个 是 相 机 开 机 ? 55 | 信 不 信 看 你 的 心 里 正 义 感 多 少 。 56 | 乐 队 挺 带 劲 ! 57 | 找 到 萧 敬 腾 了 。 58 | 就 一 个 人 。 59 | 这 营 销 策 划 牛 逼 。 60 | 喝 习 酒 强 身 健 体 又 升 官 。 61 | 好 牛 的 妹 子 。 62 | 小 心 走 路 哦 , 乡 间 路 滑 。 63 | 很 实 用 。 64 | 明 显 是 用 格 尺 量 就 好 了 。 65 | 据 说 喝 白 酒 能 让 变 小 。 66 | 希 望 人 人 都 能 自 觉 遵 守 交 通 规 则 。 67 | 生 活 因 你 而 美 丽 。 68 | 中 国 台 湾 是 个 地 区 吧 。 69 | 赶 紧 拉 直 。 70 | 有 过 迷 茫 , 走 过 荒 凉 。 71 | 简 直 就 系 正 啦 ! 72 | 没 那 么 粗 脖 子 的 黑 人 ! 73 | 到 底 是 哪 一 个 。 74 | 我 特 胖 了 , 转 着 转 着 摔 到 了 。 75 | 好 可 爱 。 76 | 这 不 哈 利 波 特 嘛 。 77 | 真 的 挺 强 迫 的 呢 ! 78 | 但 愿 您 能 说 对 一 次 ! 79 | 刘 总 , 内 涵 ! 80 | 你 给 了 多 少 钱 。 81 | 李 易 不 是 个 好 同 志 啊 。 82 | 师 父 多 穿 点 。 83 | 这 个 必 须 要 学 了 , 加 油 。 84 | 明 年 的 申 花 是 啥 样 ? 85 | 它 也 应 该 睡 睡 蜡 烛 包 。 86 | 可 以 先 去 北 大 借 读 嘛 。 87 | 老 师 买 一 赠 一 , 哈 哈 。 88 | 这 社 会 啊 。 89 | 美 景 如 画 心 之 向 往 。 90 | 其 它 的 都 弱 爆 了 。 91 | 这 小 白 猫 到 底 是 被 虐 成 怎 样 了 。 92 | 您 这 不 惹 祸 吗 。 93 | 对 必 须 的 ! 94 | 不 愧 是 我 的 女 帝 , 生 日 快 乐 。 95 | 哟 , 发 改 委 又 出 山 了 。 96 | 你 不 仅 是 真 是 奇 迹 。 97 | 阿 白 姐 姐 今 晚 去 要 不 要 来 呢 。 98 | 小 心 打 雷 。 99 | 真 实 写 照 啊 。 100 | 怎 么 还 没 做 好 ? 101 | -------------------------------------------------------------------------------- /Data/post_test.txt: -------------------------------------------------------------------------------- 1 | 秋 雨 沥 沥 一 夜 , 好 似 泪 水 不 绝 。 2 | 女 人 帮 之 七 年 前 。 3 | 如 意 和 她 的 五 个 宝 宝 。 4 | 让 人 抓 狂 的 熊 孩 子 ! 5 | 韩 国 全 州 韩 屋 村 的 早 餐 。 6 | 恨 他 , 就 快 快 把 他 签 下 来 吧 。 7 | 骨 骼 系 统 常 用 英 文 单 词 。 8 | 碰 到 调 戏 少 女 的 露 阴 癖 怎 么 破 ? 9 | 请 帮 这 张 照 片 配 一 下 文 字 。 10 | 中 的 , 飞 机 中 的 战 斗 机 ! 11 | 非 常 隐 蔽 的 柜 子 设 计 ! 12 | 亚 洲 最 大 的 交 通 枢 纽 郑 州 到 了 。 13 | 以 后 再 也 不 微 信 摇 一 摇 了 。 14 | 时 装 插 画 你 是 哪 个 范 儿 。 15 | 又 醉 了 , 明 个 儿 见 , 亲 人 们 。 16 | 忽 然 想 起 , 禽 流 感 怎 么 样 了 ? 17 | 我 想 爱 情 里 最 伤 人 的 就 是 记 忆 。 18 | 博 士 也 要 洗 衣 服 啊 有 木 有 。 19 | 向 老 将 们 致 敬 , 向 致 敬 。 20 | 食 物 链 最 顶 端 的 男 人 ! 21 | 压 着 双 黄 线 , 威 武 壮 观 。 22 | 世 界 知 名 球 体 , 你 认 识 几 个 ? 23 | 和 春 天 有 个 约 会 。 24 | 尤 文 式 中 场 , 请 问 是 哪 名 球 员 呢 ? 25 | 大 家 喜 欢 这 个 界 面 不 ? 26 | 大 瓶 子 装 的 豆 , 见 过 没 ? 27 | 平 底 锅 也 可 以 做 出 美 味 的 披 萨 哦 。 28 | 老 妈 生 日 , 我 爱 你 , 哈 哈 。 29 | 懒 成 这 模 样 , 丫 够 牛 逼 。 30 | 宝 宝 好 强 大 , 为 天 下 母 亲 转 ! 31 | 青 岛 , 一 个 不 错 的 城 市 ! 32 | 等 会 儿 必 须 吃 碗 卤 煮 解 解 腻 ! 33 | 帮 我 诊 断 一 下 这 个 酒 多 少 玛 尼 ? 34 | 据 说 这 是 泰 国 的 排 队 方 式 。 35 | 好 竹 千 竿 翠 , 新 泉 一 勺 水 。 36 | 激 光 键 盘 , 好 有 未 来 感 哦 ! 37 | 哈 哈 , 今 天 就 这 样 开 工 了 。 38 | 炎 炎 夏 日 我 想 一 直 这 么 泡 着 。 39 | 请 用 计 算 机 术 语 解 释 这 幅 图 ! 40 | 看 不 到 未 来 , 回 不 到 过 去 。 41 | 多 关 注 新 电 影 致 命 闪 玩 。 42 | 在 等 神 舟 十 号 发 射 直 播 ! 43 | 新 浪 微 博 的 系 统 又 抽 了 ? 44 | 另 外 一 位 同 事 的 摄 影 佳 作 。 45 | 明 唐 寅 行 书 “ 落 花 诗 册 ” 46 | 这 个 国 家 还 会 正 常 吗 ? 47 | 开 敞 篷 车 的 季 节 到 了 。 48 | 方 舟 子 你 够 了 啊 喂 ! 49 | 艾 玛 这 张 图 太 有 赶 脚 了 ! 50 | 送 给 你 一 个 童 话 般 的 圣 诞 节 “ 转 ” 51 | 今 晚 最 后 一 项 , 吃 完 睡 觉 。 52 | 太 阳 刚 刚 升 起 时 的 北 京 。 53 | 清 新 的 飘 窗 餐 厅 。 54 | 人 类 的 美 瞳 简 直 弱 暴 啦 ! 55 | 他 只 贪 污 了 六 千 万 , 你 相 信 吗 ? 56 | “ 春 晚 精 彩 照 片 , 刘 欢 “ 大 爱 ” 57 | 很 怪 的 云 , 苏 州 桥 西 北 。 58 | 这 条 路 , 你 想 和 谁 一 起 走 过 ? 59 | 一 个 案 例 一 个 链 接 。 60 | 难 怪 都 说 喝 白 酒 对 身 体 有 害 呢 。 61 | 不 要 以 为 任 何 妹 纸 好 欺 负 ! 62 | 走 在 越 南 乡 间 的 小 路 上 。 63 | 教 你 轻 松 取 下 芒 果 果 肉 ! 64 | 又 见 逆 天 小 学 题 。 65 | 据 说 喝 咖 啡 会 让 胸 变 小 。 66 | 终 于 找 到 交 通 混 乱 的 原 因 了 呵 。 67 | 留 点 时 间 去 感 受 生 活 的 美 好 。 68 | 最 值 得 游 览 的 十 个 国 家 。 69 | 阿 妹 戴 上 眼 镜 框 , 立 马 变 小 互 了 ! 70 | 没 有 迷 惘 的 青 春 , 是 荒 凉 的 。 71 | 撒 一 片 晚 霞 , 网 一 段 时 光 。 72 | 一 种 黄 立 行 和 黑 人 讲 相 声 的 感 觉 。 73 | 补 个 图 , 锤 子 图 标 。 74 | 适 当 的 放 弃 , 是 人 生 优 雅 的 转 身 。 75 | 我 是 一 只 橘 子 味 的 蜗 牛 “ 转 ” 76 | 哈 佛 大 学 的 食 堂 是 这 样 的 ! 77 | 一 只 患 有 强 迫 症 的 猫 咪 。 78 | 中 国 股 市 的 明 天 会 更 好 。 79 | 路 边 的 野 花 啊 , 你 总 是 那 么 美 ! 80 | 林 志 玲 做 了 形 象 代 表 。 81 | 李 易 , 小 米 不 是 好 榜 样 。 82 | 哇 我 们 这 里 现 在 就 开 始 下 大 雪 。 83 | “ 创 意 手 绘 ” 强 大 的 手 绘 ! 84 | 整 支 队 消 失 , 一 个 人 早 饭 。 85 | 睡 得 那 叫 一 个 香 啊 。 86 | 难 熬 的 两 周 要 开 始 了 。 87 | 这 样 的 老 师 最 可 爱 了 。 88 | 上 网 人 群 的 阶 级 分 析 “ 转 贴 ” 89 | 艳 丽 的 色 彩 , 舒 服 视 角 的 展 示 。 90 | 告 诉 你 们 人 类 神 马 叫 。 91 | 一 旦 死 了 心 , 再 怎 么 舔 也 没 用 了 。 92 | 原 来 许 仙 才 是 王 派 快 板 掌 门 人 。 93 | 法 治 社 会 , 程 序 正 义 是 必 须 的 。 94 | 小 生 日 快 乐 永 远 美 丽 。 95 | 相 知 多 年 , 值 得 信 赖 。 96 | 准 备 挑 战 下 自 己 , 今 晚 全 部 看 完 。 97 | 还 有 谁 没 看 泰 坦 尼 克 ? 98 | 在 山 里 发 现 一 条 新 路 , 跑 去 ! 99 | 男 人 和 女 人 逛 淘 宝 的 区 别 “ 转 ” 100 | 一 句 话 演 财 务 经 理 , 看 谁 演 得 像 ! 101 | -------------------------------------------------------------------------------- /Data/preprocess.py: -------------------------------------------------------------------------------- 1 | 2 | cmnt_read = open('cmnt_test.txt','r'); 3 | post_read = open('post_test.txt','r'); 4 | 5 | dictionary_file = open('./used/dictionary.txt','w'); 6 | cmnt_index = open('./used/cmnt_index.txt','w'); 7 | post_index = open('./used/post_index.txt','w'); 8 | 9 | dictionary = list(); 10 | dictionary.append(''); 11 | dictionary.append(''); 12 | dictionary.append(''); 13 | 14 | i = 0; 15 | while True: 16 | line = cmnt_read.readline(); 17 | if not line: 18 | print "total ",i,"sentences"; 19 | print "touch the end of file"; 20 | break; 21 | i += 1; 22 | lline = line.split('\t'); 23 | line = ' '.join(lline); 24 | lline = line.split(' '); 25 | del lline[-1]; 26 | lline = [x for x in lline if x is not '']; 27 | temp = list(); 28 | for x in lline: 29 | if x not in dictionary: 30 | dictionary.append(x); 31 | temp.append(str(dictionary.index(x) + 1)); 32 | temp.append(str(dictionary.index(''))); 33 | temp.append('\n'); 34 | cmnt_index.write(' '.join(temp)); 35 | 36 | i = 0; 37 | while True: 38 | line = post_read.readline(); 39 | if not line: 40 | print "total ",i,"sentences"; 41 | print "touch the end of file"; 42 | break; 43 | i += 1; 44 | lline = line.split('\t'); 45 | line = ' '.join(lline); 46 | lline = line.split(' '); 47 | del lline[-1]; 48 | lline = [x for x in lline if x is not '']; 49 | temp = list(); 50 | for x in lline: 51 | if x not in dictionary: 52 | dictionary.append(x); 53 | temp.append(str(dictionary.index(x) + 1)); 54 | temp.append(str(dictionary.index(''))); 55 | temp.append('\n'); 56 | post_index.write(' '.join(temp)); 57 | 58 | for i in xrange(len(dictionary)): 59 | dictionary_file.write(dictionary[i] + '\n'); 60 | 61 | post_index.close() 62 | cmnt_index.close(); 63 | dictionary_file.close(); 64 | 65 | -------------------------------------------------------------------------------- /Data/textData.m: -------------------------------------------------------------------------------- 1 | classdef textData < handle 2 | properties 3 | dictionary = '../Data/Text/dictionary' 4 | txtfile = '../Data/Text/test.txt' 5 | data = []; 6 | index = []; 7 | end 8 | methods 9 | function obj = textData(txtfile,dictionary) 10 | if nargin == 0 11 | if exist(obj.txtfile,'file') 12 | obj.data = textread(obj.txtfile); 13 | end 14 | 15 | if exist(obj.dictionary,'file') 16 | obj.index = textread(obj.dictionary,'%s'); 17 | end 18 | else if nargin >= 1 19 | if exist(txtfile,'file') 20 | obj.data = textread(txtfile); 21 | obj.txtfile = txtfile; 22 | end 23 | if nargin >= 2 24 | if exist(dictionary,'file') 25 | obj.dictionary = dictionary; 26 | obj.index = textread(obj.dictionary,'%s'); 27 | end 28 | end 29 | end 30 | end 31 | end 32 | end 33 | end -------------------------------------------------------------------------------- /Data/used/cmnt_index.txt: -------------------------------------------------------------------------------- 1 | 4 5 6 7 8 2 2 | 9 10 11 12 13 14 15 16 17 18 8 2 3 | 19 20 21 22 23 24 25 26 2 4 | 27 28 29 30 31 8 2 5 | 32 33 34 35 36 22 37 38 39 40 41 42 43 44 8 2 6 | 11 45 13 46 47 48 22 49 8 2 7 | 11 50 51 52 53 32 8 2 8 | 54 55 56 57 8 2 9 | 58 59 60 61 26 2 10 | 62 63 64 8 2 11 | 11 45 47 48 65 8 2 12 | 66 67 68 69 8 2 13 | 11 45 10 19 70 8 2 14 | 71 72 73 10 74 75 8 2 15 | 76 77 78 8 2 16 | 79 65 80 81 82 83 84 85 7 86 8 2 17 | 87 88 44 16 41 89 90 91 92 93 8 2 18 | 4 88 44 94 95 18 8 2 19 | 96 32 97 98 99 26 2 20 | 19 100 101 18 8 2 21 | 102 103 50 104 105 97 19 51 8 2 22 | 106 44 107 106 44 108 72 109 110 8 2 23 | 98 111 112 7 113 2 24 | 114 115 116 117 98 118 119 120 97 57 8 2 25 | 65 121 97 122 123 8 2 26 | 124 125 126 97 113 2 27 | 127 128 129 10 65 130 131 132 8 2 28 | 133 134 135 136 18 8 2 29 | 137 138 139 140 141 129 10 107 79 142 8 2 30 | 143 11 144 145 10 146 146 20 147 148 8 2 31 | 149 149 10 150 66 67 97 145 26 2 32 | 151 152 153 154 155 155 156 8 2 33 | 157 101 158 46 159 8 2 34 | 4 79 19 86 8 2 35 | 160 10 161 162 10 163 164 8 2 36 | 165 166 166 11 45 19 167 168 18 8 2 37 | 4 97 169 170 103 171 172 78 97 113 2 38 | 173 174 13 175 59 4 7 8 2 39 | 176 177 10 178 179 8 2 40 | 180 181 182 183 97 184 185 8 2 41 | 24 13 24 13 24 13 24 13 24 13 24 13 24 13 8 2 42 | 65 186 187 86 113 2 43 | 23 65 188 189 79 103 190 191 192 167 193 103 8 2 44 | 52 19 10 194 195 8 2 45 | 196 107 147 65 197 19 8 2 46 | 4 97 186 187 103 198 199 200 201 113 2 47 | 202 81 79 103 52 197 203 204 8 2 48 | 149 149 16 205 7 8 2 49 | 11 206 103 207 208 18 26 2 50 | 209 210 211 212 213 26 2 51 | 214 214 10 19 215 86 8 2 52 | 216 217 10 20 218 219 35 220 221 222 223 57 8 2 53 | 71 19 97 8 2 54 | 11 45 103 224 225 221 225 113 2 55 | 226 16 226 107 4 97 101 125 198 227 228 197 229 8 2 56 | 213 230 71 231 232 26 2 57 | 233 234 235 236 237 7 8 2 58 | 35 22 45 74 8 2 59 | 11 238 239 240 241 242 243 8 2 60 | 151 244 76 53 245 135 246 247 248 249 8 2 61 | 19 242 97 250 78 8 2 62 | 157 101 129 251 145 10 252 253 251 254 8 2 63 | 52 255 256 8 2 64 | 257 258 103 256 123 259 260 35 19 7 8 2 65 | 261 262 151 15 76 41 263 264 157 8 2 66 | 265 266 74 74 267 41 268 269 270 271 272 273 274 275 8 2 67 | 58 276 277 4 278 279 280 8 2 68 | 281 282 283 284 103 45 192 285 57 8 2 69 | 286 287 288 289 8 2 70 | 65 200 290 291 10 129 200 292 38 8 2 71 | 293 289 35 294 198 295 26 2 72 | 196 150 44 296 297 78 97 64 74 26 2 73 | 234 298 103 124 22 45 8 2 74 | 13 299 300 7 10 128 301 128 301 302 234 7 8 2 75 | 19 47 175 8 2 76 | 11 16 149 303 304 299 305 8 2 77 | 102 97 71 53 306 97 307 26 2 78 | 308 309 310 41 262 98 22 311 26 2 79 | 312 217 10 313 314 26 2 80 | 4 315 7 197 229 316 8 2 81 | 317 318 16 103 45 19 319 320 18 8 2 82 | 321 322 197 323 121 8 2 83 | 11 45 66 67 324 132 7 10 194 195 8 2 84 | 257 115 97 325 326 103 171 144 113 2 85 | 140 193 137 138 142 142 327 328 329 8 2 86 | 47 48 127 114 222 32 330 331 305 8 2 87 | 332 321 333 22 334 22 10 149 149 8 2 88 | 11 335 143 18 8 2 89 | 279 336 337 338 101 60 339 340 8 2 90 | 190 140 97 267 341 342 7 8 2 91 | 11 157 15 343 234 298 103 158 344 345 106 144 7 8 2 92 | 310 11 16 346 347 86 8 2 93 | 98 66 67 97 26 2 94 | 16 348 103 13 97 82 349 10 58 350 212 213 8 2 95 | 351 10 352 353 354 247 147 355 7 8 2 96 | 4 16 356 103 102 103 357 358 8 2 97 | 359 15 360 360 361 362 114 324 16 324 148 307 8 2 98 | 157 101 363 46 8 2 99 | 102 255 184 185 18 8 2 100 | 106 44 79 196 364 19 113 2 101 | -------------------------------------------------------------------------------- /Data/used/dictionary.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 你 5 | 流 6 | 泪 7 | 了 8 | 。 9 | 嗯 10 | , 11 | 这 12 | 剧 13 | 我 14 | 百 15 | 白 16 | 不 17 | 厌 18 | 啊 19 | 好 20 | 想 21 | 领 22 | 一 23 | 只 24 | 回 25 | 家 26 | ! 27 | 郭 28 | 德 29 | 纲 30 | 徒 31 | 弟 32 | 大 33 | 早 34 | 晨 35 | 就 36 | 吃 37 | 堆 38 | 凉 39 | 咸 40 | 菜 41 | 能 42 | 舒 43 | 服 44 | 么 45 | 个 46 | 雷 47 | 可 48 | 以 49 | 争 50 | 张 51 | 图 52 | 很 53 | 强 54 | 拿 55 | 剪 56 | 刀 57 | 吧 58 | 生 59 | 死 60 | 之 61 | 恋 62 | 慕 63 | 尼 64 | 黑 65 | 有 66 | 必 67 | 须 68 | 欢 69 | 迎 70 | 狠 71 | 挺 72 | 精 73 | 致 74 | 人 75 | 偶 76 | 酒 77 | 蒙 78 | 子 79 | 还 80 | 杭 81 | 州 82 | 女 83 | 神 84 | 探 85 | 判 86 | 吗 87 | 为 88 | 什 89 | 选 90 | 择 91 | 性 92 | 失 93 | 忆 94 | 专 95 | 业 96 | 伟 97 | 的 98 | 对 99 | 手 100 | 恶 101 | 心 102 | 真 103 | 是 104 | 壮 105 | 阳 106 | 怎 107 | 看 108 | 像 109 | 灵 110 | 球 111 | 错 112 | 焦 113 | ? 114 | 去 115 | 年 116 | 尤 117 | 文 118 | 帕 119 | 尔 120 | 马 121 | 点 122 | 风 123 | 格 124 | 哪 125 | 里 126 | 卖 127 | 先 128 | 转 129 | 走 130 | 空 131 | 再 132 | 学 133 | 幸 134 | 福 135 | 健 136 | 康 137 | 应 138 | 该 139 | 把 140 | 它 141 | 抱 142 | 睡 143 | 会 144 | 样 145 | 哦 146 | 宝 147 | 出 148 | 来 149 | 哈 150 | 那 151 | 喝 152 | 碗 153 | 羊 154 | 汤 155 | 解 156 | 骚 157 | 小 158 | 被 159 | 霹 160 | 竹 161 | 翠 162 | 绿 163 | 似 164 | 玉 165 | 哇 166 | 赛 167 | 方 168 | 便 169 | 墨 170 | 镜 171 | 啥 172 | 牌 173 | 肥 174 | 仔 175 | 爱 176 | 递 177 | 归 178 | 迭 179 | 代 180 | 当 181 | 前 182 | 状 183 | 态 184 | 写 185 | 照 186 | 意 187 | 思 188 | 浙 189 | 江 190 | 其 191 | 他 192 | 地 193 | 也 194 | 加 195 | 油 196 | 没 197 | 多 198 | 正 199 | 常 200 | 过 201 | 咯 202 | 广 203 | 灰 204 | 尘 205 | 行 206 | 才 207 | 基 208 | 石 209 | 平 210 | 安 211 | 夜 212 | 快 213 | 乐 214 | 呵 215 | 食 216 | 潘 217 | 总 218 | 长 219 | 寿 220 | 离 221 | 开 222 | 北 223 | 京 224 | 相 225 | 机 226 | 信 227 | 义 228 | 感 229 | 少 230 | 队 231 | 带 232 | 劲 233 | 找 234 | 到 235 | 萧 236 | 敬 237 | 腾 238 | 营 239 | 销 240 | 策 241 | 划 242 | 牛 243 | 逼 244 | 习 245 | 身 246 | 体 247 | 又 248 | 升 249 | 官 250 | 妹 251 | 路 252 | 乡 253 | 间 254 | 滑 255 | 实 256 | 用 257 | 明 258 | 显 259 | 尺 260 | 量 261 | 据 262 | 说 263 | 让 264 | 变 265 | 希 266 | 望 267 | 都 268 | 自 269 | 觉 270 | 遵 271 | 守 272 | 交 273 | 通 274 | 规 275 | 则 276 | 活 277 | 因 278 | 而 279 | 美 280 | 丽 281 | 中 282 | 国 283 | 台 284 | 湾 285 | 区 286 | 赶 287 | 紧 288 | 拉 289 | 直 290 | 迷 291 | 茫 292 | 荒 293 | 简 294 | 系 295 | 啦 296 | 粗 297 | 脖 298 | 底 299 | 特 300 | 胖 301 | 着 302 | 摔 303 | 利 304 | 波 305 | 嘛 306 | 迫 307 | 呢 308 | 但 309 | 愿 310 | 您 311 | 次 312 | 刘 313 | 内 314 | 涵 315 | 给 316 | 钱 317 | 李 318 | 易 319 | 同 320 | 志 321 | 师 322 | 父 323 | 穿 324 | 要 325 | 申 326 | 花 327 | 蜡 328 | 烛 329 | 包 330 | 借 331 | 读 332 | 老 333 | 买 334 | 赠 335 | 社 336 | 景 337 | 如 338 | 画 339 | 向 340 | 往 341 | 弱 342 | 爆 343 | 猫 344 | 虐 345 | 成 346 | 惹 347 | 祸 348 | 愧 349 | 帝 350 | 日 351 | 哟 352 | 发 353 | 改 354 | 委 355 | 山 356 | 仅 357 | 奇 358 | 迹 359 | 阿 360 | 姐 361 | 今 362 | 晚 363 | 打 364 | 做 365 | 秋 366 | 雨 367 | 沥 368 | 水 369 | 绝 370 | 帮 371 | 七 372 | 和 373 | 她 374 | 五 375 | 抓 376 | 狂 377 | 熊 378 | 孩 379 | 韩 380 | 全 381 | 屋 382 | 村 383 | 餐 384 | 恨 385 | 签 386 | 下 387 | 骨 388 | 骼 389 | 统 390 | 英 391 | 单 392 | 词 393 | 碰 394 | 调 395 | 戏 396 | 露 397 | 阴 398 | 癖 399 | 破 400 | 请 401 | 片 402 | 配 403 | 字 404 | 飞 405 | 战 406 | 斗 407 | 非 408 | 隐 409 | 蔽 410 | 柜 411 | 设 412 | 计 413 | 亚 414 | 洲 415 | 最 416 | 枢 417 | 纽 418 | 郑 419 | 后 420 | 微 421 | 摇 422 | 时 423 | 装 424 | 插 425 | 范 426 | 儿 427 | 醉 428 | 见 429 | 亲 430 | 们 431 | 忽 432 | 然 433 | 起 434 | 禽 435 | 情 436 | 伤 437 | 记 438 | 博 439 | 士 440 | 洗 441 | 衣 442 | 木 443 | 将 444 | 物 445 | 链 446 | 顶 447 | 端 448 | 男 449 | 压 450 | 双 451 | 黄 452 | 线 453 | 威 454 | 武 455 | 观 456 | 世 457 | 界 458 | 知 459 | 名 460 | 认 461 | 识 462 | 几 463 | 春 464 | 天 465 | 约 466 | 式 467 | 场 468 | 问 469 | 员 470 | 喜 471 | 面 472 | 瓶 473 | 豆 474 | , 475 | 锅 476 | 味 477 | 披 478 | 萨 479 | 妈 480 | 懒 481 | 模 482 | 丫 483 | 够 484 | 母 485 | 青 486 | 岛 487 | 城 488 | 市 489 | 等 490 | 卤 491 | 煮 492 | 腻 493 | 诊 494 | 断 495 | 玛 496 | 泰 497 | 排 498 | 千 499 | 竿 500 | 新 501 | 泉 502 | 勺 503 | 激 504 | 光 505 | 键 506 | 盘 507 | 未 508 | 工 509 | 炎 510 | 夏 511 | 泡 512 | 算 513 | 术 514 | 语 515 | 释 516 | 幅 517 | 关 518 | 注 519 | 电 520 | 影 521 | 命 522 | 闪 523 | 玩 524 | 在 525 | 舟 526 | 十 527 | 号 528 | 射 529 | 播 530 | 浪 531 | 抽 532 | 另 533 | 外 534 | 位 535 | 事 536 | 摄 537 | 佳 538 | 作 539 | 唐 540 | 寅 541 | 书 542 | “ 543 | 落 544 | 诗 545 | 册 546 | ” 547 | 敞 548 | 篷 549 | 车 550 | 季 551 | 节 552 | 喂 553 | 艾 554 | 太 555 | 脚 556 | 送 557 | 童 558 | 话 559 | 般 560 | 圣 561 | 诞 562 | 项 563 | 完 564 | 刚 565 | 清 566 | 飘 567 | 窗 568 | 厅 569 | 类 570 | 瞳 571 | 暴 572 | 贪 573 | 污 574 | 六 575 | 万 576 | 彩 577 | 怪 578 | 云 579 | 苏 580 | 桥 581 | 西 582 | 条 583 | 谁 584 | 案 585 | 例 586 | 接 587 | 难 588 | 害 589 | 任 590 | 何 591 | 纸 592 | 欺 593 | 负 594 | 越 595 | 南 596 | 上 597 | 教 598 | 轻 599 | 松 600 | 取 601 | 芒 602 | 果 603 | 肉 604 | 逆 605 | 题 606 | 咖 607 | 啡 608 | 胸 609 | 终 610 | 于 611 | 混 612 | 乱 613 | 原 614 | 留 615 | 受 616 | 值 617 | 得 618 | 游 619 | 览 620 | 戴 621 | 眼 622 | 框 623 | 立 624 | 互 625 | 惘 626 | 撒 627 | 霞 628 | 网 629 | 段 630 | 种 631 | 讲 632 | 声 633 | 补 634 | 锤 635 | 标 636 | 适 637 | 放 638 | 弃 639 | 优 640 | 雅 641 | 橘 642 | 蜗 643 | 佛 644 | 堂 645 | 患 646 | 症 647 | 咪 648 | 股 649 | 更 650 | 边 651 | 野 652 | 林 653 | 玲 654 | 形 655 | 象 656 | 表 657 | 米 658 | 榜 659 | 现 660 | 始 661 | 雪 662 | 创 663 | 绘 664 | 整 665 | 支 666 | 消 667 | 饭 668 | 叫 669 | 香 670 | 熬 671 | 两 672 | 周 673 | 群 674 | 阶 675 | 级 676 | 分 677 | 析 678 | 贴 679 | 艳 680 | 色 681 | 视 682 | 角 683 | 展 684 | 示 685 | 告 686 | 诉 687 | 旦 688 | 舔 689 | 许 690 | 仙 691 | 王 692 | 派 693 | 板 694 | 掌 695 | 门 696 | 法 697 | 治 698 | 程 699 | 序 700 | 永 701 | 远 702 | 赖 703 | 准 704 | 备 705 | 挑 706 | 己 707 | 部 708 | 坦 709 | 克 710 | 跑 711 | 逛 712 | 淘 713 | 别 714 | 句 715 | 演 716 | 财 717 | 务 718 | 经 719 | 理 720 | -------------------------------------------------------------------------------- /Data/used/post_index.txt: -------------------------------------------------------------------------------- 1 | 365 366 367 367 22 211 10 19 163 6 368 16 369 8 2 2 | 82 74 370 60 371 115 181 8 2 3 | 337 186 372 373 97 374 45 146 146 8 2 4 | 263 74 375 376 97 377 378 78 26 2 5 | 379 282 380 81 379 381 382 97 33 383 8 2 6 | 384 191 10 35 212 212 139 191 385 386 148 57 8 2 7 | 387 388 294 389 199 256 390 117 391 392 8 2 8 | 393 234 394 395 229 82 97 396 397 398 106 44 399 113 2 9 | 400 370 11 50 185 401 402 22 386 117 403 8 2 10 | 281 97 10 404 225 281 97 405 406 225 26 2 11 | 407 199 408 409 97 410 78 411 412 26 2 12 | 413 414 415 32 97 272 273 416 417 418 81 234 7 8 2 13 | 48 419 131 193 16 420 226 421 22 421 7 8 2 14 | 422 423 424 338 4 103 124 45 425 426 8 2 15 | 247 427 7 10 257 45 426 428 10 429 74 430 8 2 16 | 431 432 20 433 10 434 5 228 106 44 144 7 113 2 17 | 13 20 175 435 125 415 436 74 97 35 103 437 93 8 2 18 | 438 439 193 324 440 441 43 18 65 442 65 8 2 19 | 339 332 443 430 73 236 10 339 73 236 8 2 20 | 215 444 445 415 446 447 97 448 74 26 2 21 | 449 301 450 451 452 10 453 454 104 455 8 2 22 | 456 457 458 459 110 246 10 4 460 461 462 45 113 2 23 | 372 463 464 65 45 465 143 8 2 24 | 116 117 466 281 467 10 400 468 103 124 459 110 469 307 113 2 25 | 32 25 470 68 11 45 457 471 16 113 2 26 | 32 472 78 423 97 473 474 428 200 196 113 2 27 | 209 298 475 193 47 48 364 147 279 476 97 477 478 145 8 2 28 | 332 479 58 350 10 13 175 4 10 149 149 8 2 29 | 480 345 11 481 144 10 482 483 242 243 8 2 30 | 146 146 19 53 32 10 87 464 386 484 429 128 26 2 31 | 485 486 10 22 45 16 111 97 487 488 26 2 32 | 489 143 426 66 67 36 152 490 491 155 155 492 26 2 33 | 370 13 493 494 22 386 11 45 76 197 229 495 63 113 2 34 | 261 262 11 103 496 282 97 497 230 167 466 8 2 35 | 19 160 498 499 161 10 500 501 22 502 368 8 2 36 | 503 504 505 506 10 19 65 507 148 228 145 26 2 37 | 149 149 10 361 464 35 11 144 221 508 7 8 2 38 | 509 509 510 350 13 20 22 289 11 44 511 301 8 2 39 | 400 256 412 512 225 513 514 155 515 11 516 51 26 2 40 | 107 16 234 507 148 10 24 16 234 200 114 8 2 41 | 197 517 518 500 519 520 73 521 522 523 8 2 42 | 524 489 83 525 526 527 352 528 289 529 26 2 43 | 500 530 420 438 97 294 389 247 531 7 113 2 44 | 532 533 22 534 319 535 97 536 520 537 538 8 2 45 | 257 539 540 205 541 542 543 326 544 545 546 2 46 | 11 45 282 25 79 143 198 199 86 113 2 47 | 221 547 548 549 97 550 551 234 7 8 2 48 | 167 525 78 4 483 7 18 552 26 2 49 | 553 495 11 50 51 554 65 286 555 7 26 2 50 | 556 315 4 22 45 557 558 559 97 560 561 551 542 128 546 2 51 | 361 362 415 419 22 562 10 36 563 142 269 8 2 52 | 554 105 564 564 248 433 422 97 222 223 8 2 53 | 565 500 97 566 567 383 568 8 2 54 | 74 569 97 279 570 293 289 341 571 295 26 2 55 | 191 23 572 573 7 574 498 575 10 4 224 226 86 113 2 56 | 542 463 362 72 576 185 401 10 312 68 542 32 175 546 2 57 | 52 577 97 578 10 579 81 580 581 222 8 2 58 | 11 582 251 10 4 20 372 583 22 433 129 200 113 2 59 | 22 45 584 585 22 45 445 586 8 2 60 | 587 577 267 262 151 15 76 98 245 246 65 588 307 8 2 61 | 16 324 48 87 589 590 250 591 19 592 593 26 2 62 | 129 524 594 595 252 253 97 157 251 596 8 2 63 | 597 4 598 599 600 386 601 602 602 603 26 2 64 | 247 428 604 464 157 132 605 8 2 65 | 261 262 151 606 607 143 263 608 264 157 8 2 66 | 609 610 233 234 272 273 611 612 97 613 277 7 214 8 2 67 | 614 121 422 253 114 228 615 58 276 97 279 19 8 2 68 | 415 616 617 618 619 97 526 45 282 25 8 2 69 | 359 250 620 596 621 170 622 10 623 120 264 157 624 7 26 2 70 | 196 65 290 625 97 485 463 10 103 292 38 97 8 2 71 | 626 22 401 362 627 10 628 22 629 422 504 8 2 72 | 22 630 451 623 205 372 64 74 631 224 632 97 228 269 8 2 73 | 633 45 51 10 634 78 51 635 8 2 74 | 636 180 97 637 638 10 103 74 58 639 640 97 128 245 8 2 75 | 13 103 22 23 641 78 476 97 642 242 542 128 546 2 76 | 149 643 32 132 97 215 644 103 11 144 97 26 2 77 | 22 23 645 65 53 306 646 97 343 647 8 2 78 | 281 282 648 488 97 257 464 143 649 19 8 2 79 | 251 650 97 651 326 18 10 4 217 103 150 44 279 26 2 80 | 652 320 653 364 7 654 655 179 656 8 2 81 | 317 318 10 157 657 16 103 19 658 144 8 2 82 | 165 13 430 11 125 659 524 35 221 660 386 32 661 8 2 83 | 542 662 186 99 663 546 53 32 97 99 663 26 2 84 | 664 665 230 666 92 10 22 45 74 33 667 8 2 85 | 142 617 150 668 22 45 669 18 8 2 86 | 587 670 97 671 672 324 221 660 7 8 2 87 | 11 144 97 332 321 415 47 175 7 8 2 88 | 596 628 74 673 97 674 675 676 677 542 128 678 546 2 89 | 679 280 97 680 576 10 42 43 681 682 97 683 684 8 2 90 | 685 686 4 430 74 569 83 120 668 8 2 91 | 22 687 59 7 101 10 131 106 44 688 193 196 256 7 8 2 92 | 613 148 689 690 206 103 691 692 212 693 694 695 74 8 2 93 | 696 697 335 143 10 698 699 198 227 103 66 67 97 8 2 94 | 157 58 350 212 213 700 701 279 280 8 2 95 | 224 458 197 115 10 616 617 226 702 8 2 96 | 703 704 705 405 386 268 706 10 361 362 380 707 107 563 8 2 97 | 79 65 583 196 107 496 708 63 709 113 2 98 | 524 355 125 352 659 22 582 500 251 10 710 114 26 2 99 | 448 74 372 82 74 711 712 146 97 285 713 542 128 546 2 100 | 22 714 558 715 716 717 718 719 10 107 583 715 617 108 26 2 101 | -------------------------------------------------------------------------------- /Layers/ConcatLayer.m: -------------------------------------------------------------------------------- 1 | classdef ConcatLayer < OperateLayer 2 | properties 3 | input_index 4 | end 5 | methods 6 | function obj = ConcatLayer(option) 7 | if nargin == 0 8 | super_args{1} = struct(); 9 | else if nargin == 1 10 | super_args{1} = option; 11 | end 12 | end 13 | obj = obj@OperateLayer(super_args{:}); 14 | end 15 | 16 | function output = fprop(obj,input,length) 17 | obj.length = length; 18 | obj.input = input; 19 | obj.input_index = zeros([size(input,1) + 1,1]); 20 | obj.batch_size = size(obj.input{1,1},2); 21 | obj.input_index(1,1) = 1; 22 | for j = 1 : size(input,1) 23 | obj.input_index(j + 1,1) = obj.input_index(j,1) + size(input{j,1},1); 24 | end 25 | for i = 1 : obj.length 26 | if isempty(obj.output) 27 | obj.output = cell([1,obj.length]); 28 | end 29 | if isempty(obj.output{1,i}) 30 | obj.init.setDataSize([obj.input_index(end,1) - 1,obj.batch_size]); 31 | obj.init.setZeros(); 32 | obj.output{1,i} = obj.init.context; 33 | obj.init.clearData(); 34 | end 35 | end 36 | for i = 1 : obj.length 37 | temp = obj.output{1,i}; 38 | for j = 1 : size(obj.input,1) 39 | temp(obj.input_index(j,1) : obj.input_index(j + 1,1) - 1,: ) = obj.input{j,i}; 40 | end 41 | obj.output{1,i} = temp; 42 | end 43 | output = obj.output; 44 | end 45 | 46 | function grad_input = bprop(obj,grad_output,length) 47 | if nargin >= 3 48 | obj.length = length; 49 | end 50 | for i = obj.length : -1 : 1 51 | obj.grad_output{1,i} = grad_output{1,i}; 52 | for j = 1 : size(obj.input_index,1) - 1 53 | obj.grad_input{j,i} = obj.grad_output{1,i}(obj.input_index(j,1) : obj.input_index(j + 1,1) - 1,:); 54 | end 55 | end 56 | grad_input = obj.grad_input; 57 | end 58 | end 59 | end -------------------------------------------------------------------------------- /Layers/Data.m: -------------------------------------------------------------------------------- 1 | classdef Data < handle 2 | properties 3 | context 4 | dataSize 5 | rangeData = 0.1; 6 | useGPU = false; 7 | dataType = 'double'; 8 | seed = 123 9 | debug = false; 10 | end 11 | 12 | methods 13 | function obj = Data(option) 14 | if nargin >= 1 15 | obj.initialOption(option); 16 | end 17 | end 18 | 19 | function initialOption(obj,option) 20 | if isfield(option,'useGPU') 21 | obj.setGPU(option.useGPU); 22 | end 23 | 24 | if isfield(option,'dataType') 25 | obj.setDataType(option.dataType); 26 | end 27 | 28 | if isfield(option,'dataSize') 29 | obj.setDataSize(option.dataSize); 30 | end 31 | 32 | if isfield(option,'rangeData') 33 | obj.setRange(option.rangeData); 34 | end 35 | 36 | if isfield(option,'debug') 37 | obj.setDebug(option.debug); 38 | end 39 | 40 | if isfield(option,'seed') 41 | obj.setSeed(option.seed); 42 | end 43 | 44 | if isfield(option,'globalOpt') 45 | obj.initialOption(option.globalOpt); 46 | end 47 | end 48 | 49 | function context = dataConvert(obj,context) 50 | if obj.debug 51 | if nargin <= 1 52 | error('you should input something to convert!'); 53 | end 54 | end 55 | if obj.useGPU 56 | if ~isa(class(context),'gpuArray') 57 | context = gpuArray(context); 58 | end 59 | else 60 | if ~isa(class(context),obj.dataType) 61 | eval(['context = ',obj.dataType,'(context);']); 62 | end 63 | end 64 | end 65 | 66 | function setData(obj,context) 67 | if obj.debug 68 | if nargin <= 1 69 | error('you should input something to set the Data!'); 70 | end 71 | if obj.useGPU 72 | if ~isa(context,'gpuArray') 73 | error('you must ensure the input context has the same dataType'); 74 | end 75 | else 76 | if isa(context,'gpuArray') 77 | error('you must ensure the input context has the same dataType'); 78 | end 79 | end 80 | end 81 | obj.context = context; 82 | end 83 | 84 | function initial(obj) 85 | if obj.debug 86 | if isempty(obj.dataSize) 87 | error('you should define the dataSize first'); 88 | end 89 | end 90 | rng(obj.seed); 91 | if obj.useGPU 92 | obj.setData(2 * obj.rangeData * (rand(obj.dataSize,'gpuArray') - 0.5)); 93 | else 94 | obj.setData(2 * obj.rangeData * (rand(obj.dataSize,obj.dataType) - 0.5)); 95 | end 96 | end 97 | 98 | function setZeros(obj) 99 | if obj.debug 100 | if isempty(obj.dataSize) 101 | error('you should define the dataSize first'); 102 | end 103 | end 104 | 105 | if obj.useGPU 106 | obj.setData(zeros(obj.dataSize, 'gpuArray')); 107 | else 108 | obj.setData(zeros(obj.dataSize,obj.dataType)); 109 | end 110 | end 111 | 112 | function setOnes(obj) 113 | if obj.debug 114 | if isempty(obj.dataSize) 115 | error('you should define the dataSize first'); 116 | end 117 | end 118 | 119 | if obj.useGPU 120 | obj.setData(ones(obj.dataSize,'gpuArray')); 121 | else 122 | obj.setData(ones(obj.dataSize,obj.dataType)); 123 | end 124 | end 125 | 126 | function clearData(obj) 127 | if obj.debug 128 | if isempty(obj.context) 129 | error('cannot clear because it is empty'); 130 | end 131 | end 132 | obj.context = []; 133 | obj.dataSize = []; 134 | end 135 | 136 | function setDataSize(obj,dataSize) 137 | if isempty(obj.context) 138 | obj.dataSize = dataSize; 139 | else 140 | if sum(size(obj.context) ~= dataSize) ~= 0 141 | error('context already exist,unable to change its size'); 142 | end 143 | end 144 | end 145 | 146 | function dataSize = getDataSize(obj) 147 | obj.dataSize = size(obj.context); 148 | dataSize = obj.dataSize; 149 | end 150 | 151 | function setRange(obj,rangeData) 152 | if isnumeric(rangeData) 153 | obj.rangeData = rangeData; 154 | else 155 | error('unknown rangeData type,must be a numeric'); 156 | end 157 | end 158 | 159 | function setDataType(obj,dataType) 160 | if strcmp(dataType,'single') || strcmp(dataType,'double') 161 | obj.dataType = dataType; 162 | else 163 | error('unkonw dataType'); 164 | end 165 | end 166 | 167 | function setGPU(obj,useGPU) 168 | if useGPU == true || useGPU == false 169 | obj.useGPU = useGPU; 170 | else 171 | error('unknown useGPU'); 172 | end 173 | end 174 | 175 | function setDebug(obj,debug) 176 | if debug == true || debug == false 177 | obj.debug = debug; 178 | else 179 | error('unkown debug type'); 180 | end 181 | end 182 | 183 | function setSeed(obj,seed) 184 | if isnumeric(seed) 185 | obj.seed = seed; 186 | else 187 | error('unknown seed type,must be a numeric'); 188 | end 189 | end 190 | end 191 | end -------------------------------------------------------------------------------- /Layers/EmbeddingLayer.m: -------------------------------------------------------------------------------- 1 | classdef EmbeddingLayer < OperateLayer 2 | methods 3 | function obj = EmbeddingLayer(option) 4 | if nargin == 0 5 | super_args{1} = struct(); 6 | else if nargin == 1 7 | super_args{1} = option; 8 | end 9 | end 10 | obj = obj@OperateLayer(super_args{:}); 11 | obj.initialOption(super_args{:}); 12 | obj.initial(); 13 | end 14 | 15 | function [output,length] = fprop(obj,input,length) 16 | obj.length = length; 17 | obj.batch_size = size(input{1,1},2); 18 | for i = 1 : obj.length 19 | obj.input{1,i} = input{1,i}; 20 | obj.output{1,i} = obj.W.context(:,obj.input{1,i}); 21 | end 22 | output = obj.output; 23 | if obj.debug 24 | display(['EmbeddingLayer | W | mean : ',num2str(mean(obj.W.context(:))),' | std : ',num2str(std(obj.W.context(:)))]); 25 | end 26 | end 27 | 28 | function output = fprop_step(obj,input,i) 29 | obj.length = i; 30 | obj.batch_size = size(input{1,1},2); 31 | obj.input{1,i} = input{1,1}; 32 | obj.output{1,i} = obj.W.context(:,input{1,1}); 33 | output{1,1} = obj.output{1,i}; 34 | end 35 | 36 | function bprop(obj,grad_output,length) 37 | if nargin >= 3 38 | obj.length = length; 39 | end 40 | for i = 1 : obj.length 41 | temp = grad_output{1,i}; 42 | index = obj.input{1,i}; 43 | for j = 1 : obj.batch_size 44 | obj.grad_W.context(:,index(1,j)) = obj.grad_W.context(:,index(1,j)) + temp(:,j) ./ obj.batch_size; 45 | end 46 | end 47 | if obj.debug 48 | display(['EmbeddingLayer | grad_W | mean : ',num2str(mean(obj.grad_W.context(:))),' | std : ',num2str(std(obj.grad_W.context(:)))]); 49 | end 50 | end 51 | 52 | function update(obj,apply,option) 53 | if nargin <= 2 54 | option = struct(); 55 | end 56 | obj.W.context = apply(obj.W.context,obj.grad_W.context,option); 57 | obj.grad_W.setZeros(); 58 | end 59 | 60 | function object = saveObj(obj) 61 | if obj.W.useGPU 62 | object.W = gather(obj.W.context); 63 | object.B = gather(obj.B.context); 64 | else 65 | object.W = obj.W.context; 66 | object.B = obj.B.context; 67 | end 68 | 69 | object.activation = obj.activation; 70 | object.diff_activ = obj.diff_activ; 71 | end 72 | 73 | function loadObj(obj,object) 74 | obj.W.context = obj.init.dataConvert(object.W); 75 | obj.B.context = obj.init.dataConvert(object.B); 76 | obj.activation = object.activation; 77 | obj.diff_activ = object.diff_activ; 78 | end 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /Layers/InputLayer.m: -------------------------------------------------------------------------------- 1 | classdef InputLayer < handle 2 | properties 3 | txt = textData('../Data/Text/test_small.txt','../Data/Text/dictionary'); 4 | output 5 | base_point = 1 6 | permute = false 7 | batchSize 8 | convert = Data(); 9 | vocabSize 10 | vocab 11 | used_index 12 | permutation 13 | end 14 | methods 15 | function obj = InputLayer(option) 16 | if nargin >= 1 17 | obj.initialOption(option); 18 | obj.convert = Data(option); 19 | end 20 | obj.vocab = obj.txt.index; 21 | obj.vocabSize = length(obj.vocab); 22 | end 23 | 24 | function getFile(obj,txtfile,dictionary) 25 | if ~exist(txtfile,'file') 26 | error([txtfile,'do not found !']); 27 | end 28 | 29 | if ~exist(dictionary,'file') 30 | error([dictionary,'do not found']); 31 | end 32 | obj.txt = textData(txtfile,dictionary); 33 | obj.vocab = obj.txt.index; 34 | obj.vocabSize = length(obj.vocab); 35 | end 36 | 37 | function [output,length] = fprop(obj,option) 38 | if nargin <= 1 39 | option = struct(); 40 | end 41 | 42 | if ~isfield(option,'reverse') 43 | option.reverse = false; 44 | end 45 | 46 | if ~isfield(option,'fprop') 47 | option.fprop = true; 48 | end 49 | 50 | if ~isfield(option,'rightAlig') 51 | option.rightAlig = false; 52 | end 53 | 54 | 55 | if isempty(obj.txt.data) 56 | error('you should appoint the txtfile of txt first'); 57 | end 58 | 59 | if isempty(obj.batchSize) 60 | obj.batchSize = size(obj.txt.data,1); 61 | end 62 | 63 | index = obj.base_point : obj.base_point + obj.batchSize - 1; 64 | obj.used_index = mod(index - 1,size(obj.txt.data,1)) + 1; 65 | if obj.permute 66 | if isempty(obj.permutation) 67 | error('you should specify the permutation first !'); 68 | end 69 | obj.used_index = obj.permutation(obj.used_index); 70 | end 71 | prune_data = obj.txt.data(obj.used_index,:); 72 | mark = sum(prune_data,1) > 0; 73 | prune_data = prune_data(:,1 : sum(mark)); 74 | 75 | if option.reverse 76 | prune_data = prune_data(:,end : -1 : 1); 77 | end 78 | 79 | if option.rightAlig 80 | new_data = zeros(size(prune_data)); 81 | for i = 1 : size(prune_data,1) 82 | text = prune_data(i,:); 83 | zeros_index = find(text == 0); 84 | if isempty(zeros_index) 85 | new_data(i,:) = text; 86 | continue; 87 | end 88 | offset = size(text,2) - zeros_index(1,1) + 2; 89 | new_data(i,offset : end) = text(1,1 : zeros_index(1,1) - 1); 90 | end 91 | prune_data = new_data; 92 | end 93 | 94 | prune_data(prune_data == 0) = 1; 95 | 96 | obj.output = cell(1,size(prune_data,2)); 97 | for i = 1 : size(prune_data,2) 98 | obj.output{1,i} = obj.convert.dataConvert(prune_data(:,i)'); 99 | end 100 | 101 | if option.fprop 102 | obj.base_point = mod(obj.base_point + obj.batchSize - 1,size(obj.txt.data,1)) + 1; 103 | end 104 | 105 | output = obj.output; 106 | length = size(output,2); 107 | end 108 | 109 | function initialOption(obj,option) 110 | if isfield(option,'batchSize') 111 | obj.batchSize = option.batchSize; 112 | end 113 | 114 | if isfield(option,'base_point') 115 | obj.base_point = option.base_point; 116 | end 117 | 118 | if isfield(option,'permute') 119 | obj.permute = option.permute; 120 | end 121 | end 122 | end 123 | end -------------------------------------------------------------------------------- /Layers/LstmLayer.m: -------------------------------------------------------------------------------- 1 | classdef LstmLayer < OperateLayer 2 | %this layer is an implemention of lstm unit mentioned in paper ,page 38 4 | properties 5 | W_il = Data(); 6 | W_hl = Data(); 7 | W_cl = Data(); 8 | W_cf = Data(); 9 | W_hf = Data(); 10 | W_if = Data(); 11 | W_hc = Data(); 12 | W_ic = Data(); 13 | W_cw = Data(); 14 | W_hw = Data(); 15 | W_iw = Data(); 16 | B_l = Data(); 17 | B_f = Data(); 18 | B_c = Data(); 19 | B_w = Data(); 20 | grad_W_il = Data(); 21 | grad_W_hl = Data(); 22 | grad_W_cl = Data(); 23 | grad_W_cf = Data(); 24 | grad_W_hf = Data(); 25 | grad_W_if = Data(); 26 | grad_W_hc = Data(); 27 | grad_W_ic = Data(); 28 | grad_W_cw = Data(); 29 | grad_W_hw = Data(); 30 | grad_W_iw = Data(); 31 | grad_B_l = Data(); 32 | grad_B_f = Data(); 33 | grad_B_c = Data(); 34 | grad_B_w = Data(); 35 | gate_activation = @sigmoid 36 | gate_diff_activ = @sigmoidPrime 37 | cell_activation = @tanh 38 | cell_diff_activ = @tanhPrime 39 | cells 40 | states 41 | input_gates 42 | forget_gates 43 | output_gates 44 | grad_cells 45 | grad_states 46 | grad_input_gates 47 | grad_forget_gates 48 | grad_output_gates 49 | init_output 50 | init_state 51 | grad_init_output 52 | grad_init_state 53 | output_state 54 | grad_output_state 55 | end 56 | methods 57 | function obj = LstmLayer(option) 58 | if nargin == 0 59 | super_args{1} = struct(); 60 | else if nargin == 1 61 | super_args{1} = option; 62 | end 63 | end 64 | obj = obj@OperateLayer(super_args{:}); 65 | obj.initialOption(super_args{:}); 66 | obj.W_il = Data(super_args{:}); 67 | obj.W_hl = Data(super_args{:}); 68 | obj.W_cl = Data(super_args{:}); 69 | obj.W_cf = Data(super_args{:}); 70 | obj.W_hf = Data(super_args{:}); 71 | obj.W_if = Data(super_args{:}); 72 | obj.W_hc = Data(super_args{:}); 73 | obj.W_ic = Data(super_args{:}); 74 | obj.W_cw = Data(super_args{:}); 75 | obj.W_hw = Data(super_args{:}); 76 | obj.W_iw = Data(super_args{:}); 77 | obj.B_l = Data(super_args{:}); 78 | obj.B_f = Data(super_args{:}); 79 | obj.B_c = Data(super_args{:}); 80 | obj.B_w = Data(super_args{:}); 81 | obj.grad_W_il = Data(super_args{:}); 82 | obj.grad_W_hl = Data(super_args{:}); 83 | obj.grad_W_cl = Data(super_args{:}); 84 | obj.grad_W_cf = Data(super_args{:}); 85 | obj.grad_W_hf = Data(super_args{:}); 86 | obj.grad_W_if = Data(super_args{:}); 87 | obj.grad_W_hc = Data(super_args{:}); 88 | obj.grad_W_ic = Data(super_args{:}); 89 | obj.grad_W_cw = Data(super_args{:}); 90 | obj.grad_W_hw = Data(super_args{:}); 91 | obj.grad_W_iw = Data(super_args{:}); 92 | obj.grad_B_l = Data(super_args{:}); 93 | obj.grad_B_f = Data(super_args{:}); 94 | obj.grad_B_c = Data(super_args{:}); 95 | obj.grad_B_w = Data(super_args{:}); 96 | obj.initial(); 97 | end 98 | 99 | function initial(obj) 100 | obj.W_il.setDataSize([obj.hidden_dim,obj.input_dim]); 101 | obj.W_il.initial(); 102 | obj.W_hl.setDataSize([obj.hidden_dim,obj.hidden_dim]); 103 | obj.W_hl.initial(); 104 | obj.W_cl.setDataSize([obj.hidden_dim,obj.hidden_dim]); 105 | obj.W_cl.initial(); 106 | obj.W_cf.setDataSize([obj.hidden_dim,obj.hidden_dim]); 107 | obj.W_cf.initial(); 108 | obj.W_hf.setDataSize([obj.hidden_dim,obj.hidden_dim]); 109 | obj.W_hf.initial(); 110 | obj.W_if.setDataSize([obj.hidden_dim,obj.input_dim]); 111 | obj.W_if.initial(); 112 | obj.W_hc.setDataSize([obj.hidden_dim,obj.hidden_dim]); 113 | obj.W_hc.initial(); 114 | obj.W_ic.setDataSize([obj.hidden_dim,obj.input_dim]); 115 | obj.W_ic.initial(); 116 | obj.W_cw.setDataSize([obj.hidden_dim,obj.hidden_dim]); 117 | obj.W_cw.initial(); 118 | obj.W_hw.setDataSize([obj.hidden_dim,obj.hidden_dim]); 119 | obj.W_hw.initial(); 120 | obj.W_iw.setDataSize([obj.hidden_dim,obj.input_dim]); 121 | obj.W_iw.initial(); 122 | obj.B_l.setDataSize([obj.hidden_dim,1]); 123 | obj.B_l.initial(); 124 | obj.B_f.setDataSize([obj.hidden_dim,1]); 125 | obj.B_f.initial(); 126 | obj.B_c.setDataSize([obj.hidden_dim,1]); 127 | obj.B_c.initial(); 128 | obj.B_w.setDataSize([obj.hidden_dim,1]); 129 | obj.B_w.initial(); 130 | if obj.backward 131 | obj.grad_W_il.setDataSize([obj.hidden_dim,obj.input_dim]); 132 | obj.grad_W_il.setZeros(); 133 | obj.grad_W_hl.setDataSize([obj.hidden_dim,obj.hidden_dim]); 134 | obj.grad_W_hl.setZeros(); 135 | obj.grad_W_cl.setDataSize([obj.hidden_dim,obj.hidden_dim]); 136 | obj.grad_W_cl.setZeros(); 137 | obj.grad_W_cf.setDataSize([obj.hidden_dim,obj.hidden_dim]); 138 | obj.grad_W_cf.setZeros(); 139 | obj.grad_W_hf.setDataSize([obj.hidden_dim,obj.hidden_dim]); 140 | obj.grad_W_hf.setZeros(); 141 | obj.grad_W_if.setDataSize([obj.hidden_dim,obj.input_dim]); 142 | obj.grad_W_if.setZeros(); 143 | obj.grad_W_hc.setDataSize([obj.hidden_dim,obj.hidden_dim]); 144 | obj.grad_W_hc.setZeros(); 145 | obj.grad_W_ic.setDataSize([obj.hidden_dim,obj.input_dim]); 146 | obj.grad_W_ic.setZeros(); 147 | obj.grad_W_cw.setDataSize([obj.hidden_dim,obj.hidden_dim]); 148 | obj.grad_W_cw.setZeros(); 149 | obj.grad_W_hw.setDataSize([obj.hidden_dim,obj.hidden_dim]); 150 | obj.grad_W_hw.setZeros(); 151 | obj.grad_W_iw.setDataSize([obj.hidden_dim,obj.input_dim]); 152 | obj.grad_W_iw.setZeros(); 153 | obj.grad_B_l.setDataSize([obj.hidden_dim,1]); 154 | obj.grad_B_l.setZeros(); 155 | obj.grad_B_f.setDataSize([obj.hidden_dim,1]); 156 | obj.grad_B_f.setZeros(); 157 | obj.grad_B_c.setDataSize([obj.hidden_dim,1]); 158 | obj.grad_B_c.setZeros(); 159 | obj.grad_B_w.setDataSize([obj.hidden_dim,1]); 160 | obj.grad_B_w.setZeros(); 161 | end 162 | end 163 | 164 | function [output,length] = fprop(obj,input,length) 165 | if obj.debug 166 | if isempty(obj.W_il.context) || isempty(obj.W_hl.context) || isempty(obj.W_cl.context) || ... 167 | isempty(obj.W_cf.context) || isempty(obj.W_hf.context) || isempty(obj.W_if.context) || ... 168 | isempty(obj.W_hc.context) || isempty(obj.W_ic.context) || isempty(obj.W_cw.context) || ... 169 | isempty(obj.W_hw.context) || isempty(obj.W_iw.context) || isempty(obj.B_l.context) || ... 170 | isempty(obj.B_f.context) || isempty(obj.B_c.context) || isempty(obj.B_w.context) 171 | error('not all the context are initialized yet,and can not do the fprop operation!'); 172 | end 173 | end 174 | obj.length = length; 175 | obj.batch_size = size(input{1,1},2); 176 | 177 | if isempty(obj.init_output) 178 | obj.init.setDataSize([obj.hidden_dim,obj.batch_size]); 179 | obj.init.setZeros(); 180 | obj.init_output{1,1} = obj.init.context; 181 | obj.init.clearData(); 182 | end 183 | if isempty(obj.init_state) 184 | obj.init.setDataSize([obj.hidden_dim,obj.batch_size]); 185 | obj.init.setZeros(); 186 | obj.init_state{1,1} = obj.init.context; 187 | obj.init.clearData(); 188 | end 189 | 190 | for i = 1 : obj.length 191 | obj.input{1,i} = input{1,i}; 192 | if i == 1 193 | obj.input_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_il.context * obj.input{1,i} + obj.W_hl.context * obj.init_output{1,1} ... 194 | + obj.W_cl.context * obj.init_state{1,1},obj.B_l.context)); 195 | obj.forget_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_if.context * obj.input{1,i} + obj.W_hf.context * obj.init_output{1,1} ... 196 | + obj.W_cf.context * obj.init_state{1,1},obj.B_f.context)); 197 | obj.cells{1,i} =obj.cell_activation(bsxfun(@plus,obj.W_ic.context * obj.input{1,i} + obj.W_hc.context * ... 198 | obj.init_output{1,1},obj.B_c.context)); 199 | obj.states{1,i} = obj.forget_gates{1,i} .* obj.init_state{1,1} + obj.input_gates{1,i} .* obj.cells{1,i}; 200 | obj.output_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_iw.context * obj.input{1,i} + obj.W_hw.context * obj.init_output{1,1} ... 201 | + obj.W_cw.context * obj.states{1,i},obj.B_w.context)); 202 | else 203 | obj.input_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_il.context * obj.input{1,i} + ... 204 | obj.W_hl.context * obj.output{1,i - 1} + obj.W_cl.context * obj.states{1,i - 1},obj.B_l.context)); 205 | obj.forget_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_if.context * obj.input{1,i} + ... 206 | obj.W_hf.context * obj.output{1,i - 1} + obj.W_cf.context * obj.states{1,i - 1},obj.B_f.context)); 207 | obj.cells{1,i} = obj.cell_activation(bsxfun(@plus,obj.W_ic.context * obj.input{1,i} + obj.W_hc.context * obj.output{1,i - 1},obj.B_c.context)); 208 | obj.states{1,i} = obj.forget_gates{1,i} .* obj.states{1,i - 1} + obj.input_gates{1,i} .* obj.cells{1,i}; 209 | obj.output_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_iw.context * obj.input{1,i} + ... 210 | obj.W_hw.context * obj.output{1,i - 1} + obj.W_cw.context * obj.states{1,i},obj.B_w.context)); 211 | end 212 | obj.output{1,i} = obj.output_gates{1,i} .* obj.activation(obj.states{1,i}); 213 | end 214 | obj.output_state{1,1} = obj.states{1,obj.length}; 215 | output = obj.output; 216 | if obj.debug 217 | display(['LstmLayer | W_il | mean : ',num2str(mean(obj.W_il.context(:))),' | std : ',num2str(std(obj.W_il.context(:)))]); 218 | display(['LstmLayer | W_hl | mean : ',num2str(mean(obj.W_hl.context(:))),' | std : ',num2str(std(obj.W_hl.context(:)))]); 219 | display(['LstmLayer | W_cl | mean : ',num2str(mean(obj.W_cl.context(:))),' | std : ',num2str(std(obj.W_cl.context(:)))]); 220 | display(['LstmLayer | W_cf | mean : ',num2str(mean(obj.W_cf.context(:))),' | std : ',num2str(std(obj.W_cf.context(:)))]); 221 | display(['LstmLayer | W_hf | mean : ',num2str(mean(obj.W_hf.context(:))),' | std : ',num2str(std(obj.W_hf.context(:)))]); 222 | display(['LstmLayer | W_if | mean : ',num2str(mean(obj.W_if.context(:))),' | std : ',num2str(std(obj.W_if.context(:)))]); 223 | display(['LstmLayer | W_hc | mean : ',num2str(mean(obj.W_hc.context(:))),' | std : ',num2str(std(obj.W_hc.context(:)))]); 224 | display(['LstmLayer | W_ic | mean : ',num2str(mean(obj.W_ic.context(:))),' | std : ',num2str(std(obj.W_ic.context(:)))]); 225 | display(['LstmLayer | W_cw | mean : ',num2str(mean(obj.W_cw.context(:))),' | std : ',num2str(std(obj.W_cw.context(:)))]); 226 | display(['LstmLayer | W_hw | mean : ',num2str(mean(obj.W_hw.context(:))),' | std : ',num2str(std(obj.W_hw.context(:)))]); 227 | display(['LstmLayer | W_iw | mean : ',num2str(mean(obj.W_iw.context(:))),' | std : ',num2str(std(obj.W_iw.context(:)))]); 228 | end 229 | end 230 | 231 | function output = fprop_step(obj,input,i) 232 | if obj.debug 233 | if isempty(obj.W_il.context) || isempty(obj.W_hl.context) || isempty(obj.W_cl.context) || ... 234 | isempty(obj.W_cf.context) || isempty(obj.W_hf.context) || isempty(obj.W_if.context) || ... 235 | isempty(obj.W_hc.context) || isempty(obj.W_ic.context) || isempty(obj.W_cw.context) || ... 236 | isempty(obj.W_hw.context) || isempty(obj.W_iw.context) || isempty(obj.B_l.context) || ... 237 | isempty(obj.B_f.context) || isempty(obj.B_c.context) || isempty(obj.B_w.context) 238 | error('not all the context are initialized yet,and can not do the fprop operation!'); 239 | end 240 | end 241 | 242 | obj.length = i; 243 | obj.batch_size = size(input{1,1},2); 244 | 245 | if isempty(obj.init_output) 246 | obj.init.setDataSize([obj.hidden_dim,obj.batch_size]); 247 | obj.init.setZeros(); 248 | obj.init_output{1,1} = obj.init.context; 249 | obj.init.clearData(); 250 | end 251 | if isempty(obj.init_state) 252 | obj.init.setDataSize([obj.hidden_dim,obj.batch_size]); 253 | obj.init.setZeros(); 254 | obj.init_state{1,1} = obj.init.context; 255 | obj.init.clearData(); 256 | end 257 | 258 | obj.input{1,i} = input{1,1}; 259 | if i == 1 260 | obj.input_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_il.context * obj.input{1,i} + obj.W_hl.context * obj.init_output{1,1} ... 261 | + obj.W_cl.context * obj.init_state{1,1},obj.B_l.context)); 262 | obj.forget_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_if.context * obj.input{1,i} + obj.W_hf.context * obj.init_output{1,1} ... 263 | + obj.W_cf.context * obj.init_state{1,1},obj.B_f.context)); 264 | obj.cells{1,i} =obj.cell_activation(bsxfun(@plus,obj.W_ic.context * obj.input{1,i} + obj.W_hc.context * ... 265 | obj.init_output{1,1},obj.B_c.context)); 266 | obj.states{1,i} = obj.forget_gates{1,i} .* obj.init_state{1,1} + obj.input_gates{1,i} .* obj.cells{1,i}; 267 | obj.output_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_iw.context * obj.input{1,i} + obj.W_hw.context * obj.init_output{1,1} ... 268 | + obj.W_cw.context * obj.states{1,i},obj.B_w.context)); 269 | else 270 | obj.input_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_il.context * obj.input{1,i} + ... 271 | obj.W_hl.context * obj.output{1,i - 1} + obj.W_cl.context * obj.states{1,i - 1},obj.B_l.context)); 272 | obj.forget_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_if.context * obj.input{1,i} + ... 273 | obj.W_hf.context * obj.output{1,i - 1} + obj.W_cf.context * obj.states{1,i - 1},obj.B_f.context)); 274 | obj.cells{1,i} = obj.cell_activation(bsxfun(@plus,obj.W_ic.context * obj.input{1,i} + obj.W_hc.context * obj.output{1,i - 1},obj.B_c.context)); 275 | obj.states{1,i} = obj.forget_gates{1,i} .* obj.states{1,i - 1} + obj.input_gates{1,i} .* obj.cells{1,i}; 276 | obj.output_gates{1,i} = obj.gate_activation(bsxfun(@plus,obj.W_iw.context * obj.input{1,i} + ... 277 | obj.W_hw.context * obj.output{1,i - 1} + obj.W_cw.context * obj.states{1,i},obj.B_w.context)); 278 | end 279 | obj.output_state{1,1} = obj.states{1,obj.length}; 280 | obj.output{1,i} = obj.output_gates{1,i} .* obj.activation(obj.states{1,i}); 281 | 282 | output{1,1} = obj.output{1,i}; 283 | end 284 | 285 | function grad_input = bprop(obj,grad_output,length) 286 | if nargin >= 3 287 | obj.length = length; 288 | end 289 | if isempty(obj.grad_output_state) 290 | obj.init.setDataSize([obj.hidden_dim,obj.batch_size]); 291 | obj.init.setZeros(); 292 | obj.grad_output_state{1,1} = obj.init.context; 293 | end 294 | for i = obj.length : -1 : 1 295 | obj.grad_output{1,i} = grad_output{1,i}; 296 | if i == obj.length 297 | obj.grad_output_gates{1,i} = obj.gate_diff_activ(obj.output_gates{1,i}) .* obj.activation(obj.states{1,i}) .* obj.grad_output{1,i}; 298 | obj.grad_states{1,i} = obj.grad_output_state{1,1} + obj.output_gates{1,i} .* obj.diff_activ(obj.activation(obj.states{1,i})) .* ... 299 | obj.grad_output{1,i} + obj.W_cw.context' * obj.grad_output_gates{1,i};% obj.grad_states{1,i} + 300 | obj.grad_cells{1,i} = obj.input_gates{1,i} .* obj.cell_diff_activ(obj.cells{1,i}) .* obj.grad_states{1,i}; 301 | obj.grad_forget_gates{1,i} = obj.gate_diff_activ(obj.forget_gates{1,i}) .* obj.states{1,i - 1} .* obj.grad_states{1,i}; 302 | obj.grad_input_gates{1,i} = obj.gate_diff_activ(obj.input_gates{1,i}) .* obj.cells{1,i} .* obj.grad_states{1,i}; 303 | obj.grad_input{1,i} = obj.W_il.context' * obj.grad_input_gates{1,i} + obj.W_if.context' * obj.grad_forget_gates{1,i} + ... 304 | obj.W_ic.context' * obj.grad_cells{1,i} + obj.W_iw.context' * obj.grad_output_gates{1,i}; 305 | else 306 | obj.grad_output{1,i} = obj.grad_output{1,i} + obj.W_hl.context' * obj.grad_input_gates{1,i + 1} + ... 307 | obj.W_hf.context' * obj.grad_forget_gates{1,i + 1} ... 308 | + obj.W_hc.context' * obj.grad_cells{1,i + 1} + obj.W_hw.context' * obj.grad_output_gates{1,i + 1}; 309 | obj.grad_output_gates{1,i} = obj.gate_diff_activ(obj.output_gates{1,i}) .* obj.activation(obj.states{1,i}) .* obj.grad_output{1,i}; 310 | obj.grad_states{1,i} = obj.output_gates{1,i} .* obj.diff_activ(obj.activation(obj.states{1,i})) .* obj.grad_output{1,i} + ... 311 | obj.W_cw.context' * obj.grad_output_gates{1,i} + obj.forget_gates{1,i + 1} .* obj.grad_states{1,i + 1} + ... 312 | obj.W_cf.context' * obj.grad_forget_gates{1,i + 1} ... 313 | + obj.W_cl.context' * obj.grad_input_gates{1,i + 1};%obj.grad_states{1,i} + 314 | obj.grad_cells{1,i} = obj.input_gates{1,i} .* obj.cell_diff_activ(obj.cells{1,i}) .* obj.grad_states{1,i}; 315 | obj.grad_input_gates{1,i} = obj.gate_diff_activ(obj.input_gates{1,i}) .* obj.cells{1,i} .* obj.grad_states{1,i}; 316 | if i > 1 317 | obj.grad_forget_gates{1,i} = obj.gate_diff_activ(obj.forget_gates{1,i}) .* obj.states{1,i - 1} .* obj.grad_states{1,i}; 318 | obj.grad_input{1,i} = obj.W_il.context' * obj.grad_input_gates{1,i} + obj.W_if.context' * obj.grad_forget_gates{1,i} + ... 319 | obj.W_ic.context' * obj.grad_cells{1,i} + obj.W_iw.context' * obj.grad_output_gates{1,i}; 320 | else 321 | obj.grad_forget_gates{1,i} = obj.gate_diff_activ(obj.forget_gates{1,i}) .* obj.init_state{1,1} .* obj.grad_states{1,i}; 322 | obj.grad_input{1,i} = obj.W_il.context' * obj.grad_input_gates{1,i} + obj.W_if.context' * obj.grad_forget_gates{1,i} + ... 323 | obj.W_ic.context' * obj.grad_cells{1,i} + obj.W_iw.context' * obj.grad_output_gates{1,i}; 324 | end 325 | end 326 | end 327 | grad_input = obj.grad_input; 328 | for i = 1 : obj.length 329 | obj.grad_B_l.context = obj.grad_B_l.context + sum(obj.grad_input_gates{1,i},2) ./ obj.batch_size; 330 | obj.grad_B_c.context = obj.grad_B_c.context + sum(obj.grad_cells{1,i},2) ./ obj.batch_size; 331 | obj.grad_B_w.context = obj.grad_B_w.context + sum(obj.grad_output_gates{1,i},2) ./ obj.batch_size; 332 | obj.grad_B_f.context = obj.grad_B_f.context + sum(obj.grad_forget_gates{1,i},2) ./ obj.batch_size; 333 | obj.grad_W_il.context = obj.grad_W_il.context + obj.grad_input_gates{1,i} * (obj.input{1,i})' ./ obj.batch_size; 334 | obj.grad_W_ic.context = obj.grad_W_ic.context + obj.grad_cells{1,i} * (obj.input{1,i})' ./ obj.batch_size; 335 | obj.grad_W_iw.context = obj.grad_W_iw.context + obj.grad_output_gates{1,i} * (obj.input{1,i})' ./ obj.batch_size; 336 | obj.grad_W_cw.context = obj.grad_W_cw.context + obj.grad_output_gates{1,i} * (obj.states{1,i})' ./ obj.batch_size; 337 | obj.grad_W_if.context = obj.grad_W_if.context + obj.grad_forget_gates{1,i} * (obj.input{1,i})' ./ obj.batch_size; 338 | if i > 1 339 | obj.grad_W_hl.context = obj.grad_W_hl.context + obj.grad_input_gates{1,i} * (obj.output{1,i - 1})' ./ obj.batch_size; 340 | obj.grad_W_cl.context = obj.grad_W_cl.context + obj.grad_input_gates{1,i} * (obj.states{1,i - 1})' ./ obj.batch_size; 341 | obj.grad_W_hf.context = obj.grad_W_hf.context + obj.grad_forget_gates{1,i} * (obj.output{1,i - 1})' ./ obj.batch_size; 342 | obj.grad_W_cf.context = obj.grad_W_cf.context + obj.grad_forget_gates{1,i} * (obj.states{1,i - 1})' ./ obj.batch_size; 343 | obj.grad_W_hc.context = obj.grad_W_hc.context + obj.grad_cells{1,i} * (obj.output{1,i - 1})' ./ obj.batch_size; 344 | obj.grad_W_hw.context = obj.grad_W_hw.context + obj.grad_output_gates{1,i} * (obj.output{1,i - 1})' ./ obj.batch_size; 345 | else 346 | obj.grad_W_hl.context = obj.grad_W_hl.context + obj.grad_input_gates{1,i} * (obj.init_output{1,1})' ./ obj.batch_size; 347 | obj.grad_W_cl.context = obj.grad_W_cl.context + obj.grad_input_gates{1,i} * (obj.init_state{1,1})' ./ obj.batch_size; 348 | obj.grad_W_hf.context = obj.grad_W_hf.context + obj.grad_forget_gates{1,i} * (obj.init_output{1,1})' ./ obj.batch_size; 349 | obj.grad_W_cf.context = obj.grad_W_cf.context + obj.grad_forget_gates{1,i} * (obj.init_state{1,1})' ./ obj.batch_size; 350 | obj.grad_W_hc.context = obj.grad_W_hc.context + obj.grad_cells{1,i} * (obj.init_output{1,1})' ./ obj.batch_size; 351 | obj.grad_W_hw.context = obj.grad_W_hw.context + obj.grad_output_gates{1,i} * (obj.init_output{1,1})' ./ obj.batch_size; 352 | end 353 | end 354 | obj.grad_init_output{1,1} = obj.W_hl.context' * obj.grad_input_gates{1,1} + ... 355 | obj.W_hf.context' * obj.grad_forget_gates{1,1} + obj.W_hc.context' * obj.grad_cells{1,1} + ... 356 | obj.W_hw.context' * obj.grad_output_gates{1,1}; 357 | obj.grad_init_state{1,1} = obj.W_cl.context' * obj.grad_input_gates{1,1} + ... 358 | obj.W_cf.context' * obj.grad_forget_gates{1,1} + obj.forget_gates{1,1} .* obj.grad_states{1,1}; 359 | 360 | if obj.debug 361 | display(['LstmLayer | grad_W_il | mean : ',num2str(mean(obj.grad_W_il.context(:))),' | std : ',num2str(std(obj.grad_W_il.context(:)))]); 362 | display(['LstmLayer | grad_W_hl | mean : ',num2str(mean(obj.grad_W_hl.context(:))),' | std : ',num2str(std(obj.grad_W_hl.context(:)))]); 363 | display(['LstmLayer | grad_W_cl | mean : ',num2str(mean(obj.grad_W_cl.context(:))),' | std : ',num2str(std(obj.grad_W_cl.context(:)))]); 364 | display(['LstmLayer | grad_W_cf | mean : ',num2str(mean(obj.grad_W_cf.context(:))),' | std : ',num2str(std(obj.grad_W_cf.context(:)))]); 365 | display(['LstmLayer | grad_W_hf | mean : ',num2str(mean(obj.grad_W_hf.context(:))),' | std : ',num2str(std(obj.grad_W_hf.context(:)))]); 366 | display(['LstmLayer | grad_W_if | mean : ',num2str(mean(obj.grad_W_if.context(:))),' | std : ',num2str(std(obj.grad_W_if.context(:)))]); 367 | display(['LstmLayer | grad_W_hc | mean : ',num2str(mean(obj.grad_W_hc.context(:))),' | std : ',num2str(std(obj.grad_W_hc.context(:)))]); 368 | display(['LstmLayer | grad_W_ic | mean : ',num2str(mean(obj.grad_W_ic.context(:))),' | std : ',num2str(std(obj.grad_W_ic.context(:)))]); 369 | display(['LstmLayer | grad_W_cw | mean : ',num2str(mean(obj.grad_W_cw.context(:))),' | std : ',num2str(std(obj.grad_W_cw.context(:)))]); 370 | display(['LstmLayer | grad_W_hw | mean : ',num2str(mean(obj.grad_W_hw.context(:))),' | std : ',num2str(std(obj.grad_W_hw.context(:)))]); 371 | display(['LstmLayer | grad_W_iw | mean : ',num2str(mean(obj.grad_W_iw.context(:))),' | std : ',num2str(std(obj.grad_W_iw.context(:)))]); 372 | end 373 | end 374 | 375 | function initialOption(obj,option) 376 | initialOption@OperateLayer(obj,option) 377 | 378 | if isfield(option,'gate_activation') 379 | obj.gate_activation = option.gate_activation; 380 | end 381 | 382 | if isfield(option,'gate_diff_activ') 383 | obj.gate_diff_activ = option.gate_diff_activ; 384 | end 385 | 386 | if isfield(option,'cell_activation') 387 | obj.cell_activation = option.cell_activation; 388 | end 389 | 390 | if isfield(option,'cell_diff_activ') 391 | obj.cell_diff_activ = option.cell_diff_activ; 392 | end 393 | end 394 | 395 | function update(obj,apply,option) 396 | if nargin <= 2 397 | option = struct(); 398 | end 399 | obj.W_il.context = apply(obj.W_il.context,obj.grad_W_il.context,option); 400 | obj.W_hl.context = apply(obj.W_hl.context,obj.grad_W_hl.context,option); 401 | obj.W_cl.context = apply(obj.W_cl.context,obj.grad_W_cl.context,option); 402 | obj.W_cf.context = apply(obj.W_cf.context,obj.grad_W_cf.context,option); 403 | obj.W_hf.context = apply(obj.W_hf.context,obj.grad_W_hf.context,option); 404 | obj.W_if.context = apply(obj.W_if.context,obj.grad_W_if.context,option); 405 | obj.W_hc.context = apply(obj.W_hc.context,obj.grad_W_hc.context,option); 406 | obj.W_ic.context = apply(obj.W_ic.context,obj.grad_W_ic.context,option); 407 | obj.W_cw.context = apply(obj.W_cw.context,obj.grad_W_cw.context,option); 408 | obj.W_hw.context = apply(obj.W_hw.context,obj.grad_W_hw.context,option); 409 | obj.W_iw.context = apply(obj.W_iw.context,obj.grad_W_iw.context,option); 410 | obj.B_l.context = apply(obj.B_l.context,obj.grad_B_l.context,option); 411 | obj.B_f.context = apply(obj.B_f.context,obj.grad_B_f.context,option); 412 | obj.B_c.context = apply(obj.B_c.context,obj.grad_B_c.context,option); 413 | obj.B_w.context = apply(obj.B_w.context,obj.grad_B_w.context,option); 414 | obj.grad_W_il.setZeros(); 415 | obj.grad_W_hl.setZeros(); 416 | obj.grad_W_cl.setZeros(); 417 | obj.grad_W_cf.setZeros(); 418 | obj.grad_W_hf.setZeros(); 419 | obj.grad_W_if.setZeros(); 420 | obj.grad_W_hc.setZeros(); 421 | obj.grad_W_ic.setZeros(); 422 | obj.grad_W_cw.setZeros(); 423 | obj.grad_W_hw.setZeros(); 424 | obj.grad_W_iw.setZeros(); 425 | obj.grad_B_l.setZeros(); 426 | obj.grad_B_f.setZeros(); 427 | obj.grad_B_c.setZeros(); 428 | obj.grad_B_w.setZeros(); 429 | end 430 | 431 | function object = saveObj(obj) 432 | object = struct(); 433 | if obj.W_il.useGPU 434 | object.W_il = gather(obj.W_il.context); 435 | object.W_hl = gather(obj.W_hl.context); 436 | object.W_cl = gather(obj.W_cl.context); 437 | object.W_cf = gather(obj.W_cf.context); 438 | object.W_hf = gather(obj.W_hf.context); 439 | object.W_if = gather(obj.W_if.context); 440 | object.W_hc = gather(obj.W_hc.context); 441 | object.W_ic = gather(obj.W_ic.context); 442 | object.W_cw = gather(obj.W_cw.context); 443 | object.W_hw = gather(obj.W_hw.context); 444 | object.W_iw = gather(obj.W_iw.context); 445 | object.B_l = gather(obj.B_l.context); 446 | object.B_f = gather(obj.B_f.context); 447 | object.B_c = gather(obj.B_c.context); 448 | object.B_w = gather(obj.B_w.context); 449 | else 450 | object.W_il = obj.W_il.context; 451 | object.W_hl = obj.W_hl.context; 452 | object.W_cl = obj.W_cl.context; 453 | object.W_cf = obj.W_cf.context; 454 | object.W_hf = obj.W_hf.context; 455 | object.W_if = obj.W_if.context; 456 | object.W_hc = obj.W_hc.context; 457 | object.W_ic = obj.W_ic.context; 458 | object.W_cw = obj.W_cw.context; 459 | object.W_hw = obj.W_hw.context; 460 | object.W_iw = obj.W_iw.context; 461 | object.B_l = obj.B_l.context; 462 | object.B_f = obj.B_f.context; 463 | object.B_c = obj.B_c.context; 464 | object.B_w = obj.B_w.context; 465 | end 466 | object.gate_activation = obj.gate_activation; 467 | object.gate_diff_activ = obj.gate_diff_activ; 468 | object.cell_activation = obj.cell_activation; 469 | object.cell_diff_activ = obj.cell_diff_activ; 470 | object.activation = obj.activation; 471 | object.diff_activ = obj.diff_activ; 472 | end 473 | 474 | function loadObj(obj,object) 475 | obj.W_il.context = obj.init.dataConvert(object.W_il); 476 | obj.W_hl.context = obj.init.dataConvert(object.W_hl); 477 | obj.W_cl.context = obj.init.dataConvert(object.W_cl); 478 | obj.W_cf.context = obj.init.dataConvert(object.W_cf); 479 | obj.W_hf.context = obj.init.dataConvert(object.W_hf); 480 | obj.W_if.context = obj.init.dataConvert(object.W_if); 481 | obj.W_hc.context = obj.init.dataConvert(object.W_hc); 482 | obj.W_ic.context = obj.init.dataConvert(object.W_ic); 483 | obj.W_cw.context = obj.init.dataConvert(object.W_cw); 484 | obj.W_hw.context = obj.init.dataConvert(object.W_hw); 485 | obj.W_iw.context = obj.init.dataConvert(object.W_iw); 486 | obj.B_l.context = obj.init.dataConvert(object.B_l); 487 | obj.B_f.context = obj.init.dataConvert(object.B_f); 488 | obj.B_c.context = obj.init.dataConvert(object.B_c); 489 | obj.B_w.context = obj.init.dataConvert(object.B_w); 490 | 491 | obj.gate_activation = object.gate_activation; 492 | obj.gate_diff_activ = object.gate_diff_activ; 493 | obj.cell_activation = object.cell_activation; 494 | obj.cell_diff_activ = object.cell_diff_activ; 495 | obj.activation = object.activation; 496 | obj.diff_activ = object.diff_activ; 497 | end 498 | %% the functions below this line are used in the above functions or some functions are just defined for the gradient check; 499 | function checkGrad(obj) 500 | % prepare the data 501 | seqLen = 20; 502 | batchSize = 20; 503 | input = cell([1,seqLen]); 504 | target = cell([1,seqLen]); 505 | for i = 1 : seqLen 506 | input{1,i} = randn([obj.input_dim,batchSize]); 507 | target{1,i} = randn([obj.hidden_dim,batchSize]); 508 | end 509 | epislon = 10 ^ (-7); 510 | 511 | W_il = obj.W_il.context; 512 | W_hl = obj.W_hl.context; 513 | W_cl = obj.W_cl.context; 514 | W_cf = obj.W_cf.context; 515 | W_hf = obj.W_hf.context; 516 | W_if = obj.W_if.context; 517 | W_hc = obj.W_hc.context; 518 | W_ic = obj.W_ic.context; 519 | W_cw = obj.W_cw.context; 520 | W_hw = obj.W_hw.context; 521 | W_iw = obj.W_iw.context; 522 | B_l = obj.B_l.context; 523 | B_f = obj.B_f.context; 524 | B_c = obj.B_c.context; 525 | B_w = obj.B_w.context; 526 | 527 | obj.fprop(input,size(input,2)); 528 | grad_output = cell([1,size(obj.output,2)]); 529 | for i = 1 : size(obj.output,2) 530 | grad_output{1,i} = 2 * (obj.output{1,i} - target{1,i}); 531 | end 532 | obj.bprop(grad_output); 533 | 534 | grad_W_il = obj.grad_W_il.context; 535 | numeric_grad_W_il = zeros(size(W_il)); 536 | 537 | grad_W_hl = obj.grad_W_hl.context; 538 | numeric_grad_W_hl = zeros(size(W_hl)); 539 | 540 | grad_W_cl = obj.grad_W_cl.context; 541 | numeric_grad_W_cl = zeros(size(W_cl)); 542 | 543 | grad_W_cf = obj.grad_W_cf.context; 544 | numeric_grad_W_cf = zeros(size(W_cf)); 545 | 546 | grad_W_hf = obj.grad_W_hf.context; 547 | numeric_grad_W_hf = zeros(size(W_hf)); 548 | 549 | grad_W_if = obj.grad_W_if.context; 550 | numeric_grad_W_if = zeros(size(W_if)); 551 | 552 | grad_W_hc = obj.grad_W_hc.context; 553 | numeric_grad_W_hc = zeros(size(W_hc)); 554 | 555 | grad_W_ic = obj.grad_W_ic.context; 556 | numeric_grad_W_ic = zeros(size(W_ic)); 557 | 558 | grad_W_cw = obj.grad_W_cw.context; 559 | numeric_grad_W_cw = zeros(size(W_cw)); 560 | 561 | grad_W_hw = obj.grad_W_hw.context; 562 | numeric_grad_W_hw = zeros(size(W_hw)); 563 | 564 | grad_W_iw = obj.grad_W_iw.context; 565 | numeric_grad_W_iw = zeros(size(W_iw)); 566 | 567 | grad_B_l = obj.grad_B_l.context; 568 | numeric_grad_B_l = zeros(size(B_l)); 569 | 570 | grad_B_f = obj.grad_B_f.context; 571 | numeric_grad_B_f = zeros(size(B_f)); 572 | 573 | grad_B_c = obj.grad_B_c.context; 574 | numeric_grad_B_c = zeros(size(B_c)); 575 | 576 | grad_B_w = obj.grad_B_w.context; 577 | numeric_grad_B_w = zeros(size(B_w)); 578 | 579 | init_output = obj.init_output{1,1}; 580 | grad_init_output = obj.grad_init_output{1,1}; 581 | 582 | init_state = obj.init_state{1,1}; 583 | grad_init_state = obj.grad_init_state{1,1}; 584 | 585 | grad_input = obj.grad_input; 586 | numeric_grad_input = cell(size(grad_input)); 587 | for i = 1 : size(numeric_grad_input,2) 588 | numeric_grad_input{1,i} = zeros(size(grad_input{1,i})); 589 | end 590 | %% the W_il parameter check 591 | for n = 1 : size(W_il,1) 592 | for m = 1 : size(W_il,2) 593 | obj.W_il.context = W_il; 594 | obj.W_il.context(n,m) = obj.W_il.context(n,m) + epislon; 595 | obj.fprop(input,size(input,2)); 596 | cost_1 = getCost(target,obj.output); 597 | 598 | obj.W_il.context = W_il; 599 | obj.W_il.context(n,m) = obj.W_il.context(n,m) - epislon; 600 | obj.fprop(input,size(input,2)); 601 | cost_2 = getCost(target,obj.output); 602 | 603 | numeric_grad_W_il(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 604 | end 605 | end 606 | norm_diff = norm(numeric_grad_W_il(:) - grad_W_il(:)) ./ norm(numeric_grad_W_il(:) + grad_W_il(:)); 607 | if obj.debug 608 | disp([numeric_grad_W_il(:),obj.grad_W_il.context(:)]); 609 | end 610 | disp(['the W_il parameter check is ' , num2str(norm_diff)]) 611 | %% the W_hl parameter check 612 | for n = 1 : size(W_hl,1) 613 | for m = 1 : size(W_hl,2) 614 | obj.W_hl.context = W_hl; 615 | obj.W_hl.context(n,m) = obj.W_hl.context(n,m) + epislon; 616 | obj.fprop(input,size(input,2)); 617 | cost_1 = getCost(target,obj.output); 618 | 619 | obj.W_hl.context = W_hl; 620 | obj.W_hl.context(n,m) = obj.W_hl.context(n,m) - epislon; 621 | obj.fprop(input,size(input,2)); 622 | cost_2 = getCost(target,obj.output); 623 | 624 | numeric_grad_W_hl(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 625 | end 626 | end 627 | norm_diff = norm(numeric_grad_W_hl(:) - grad_W_hl(:)) ./ norm(numeric_grad_W_hl(:) + grad_W_hl(:)); 628 | if obj.debug 629 | disp([numeric_grad_W_hl(:),obj.grad_W_hl.context(:)]); 630 | end 631 | disp(['the W_hl parameter check is ' , num2str(norm_diff)]) 632 | %% the W_cl parameter check 633 | for n = 1 : size(W_cl,1) 634 | for m = 1 : size(W_cl,2) 635 | obj.W_cl.context = W_cl; 636 | obj.W_cl.context(n,m) = obj.W_cl.context(n,m) + epislon; 637 | obj.fprop(input,size(input,2)); 638 | cost_1 = getCost(target,obj.output); 639 | 640 | obj.W_cl.context = W_cl; 641 | obj.W_cl.context(n,m) = obj.W_cl.context(n,m) - epislon; 642 | obj.fprop(input,size(input,2)); 643 | cost_2 = getCost(target,obj.output); 644 | 645 | numeric_grad_W_cl(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 646 | end 647 | end 648 | norm_diff = norm(numeric_grad_W_cl(:) - grad_W_cl(:)) ./ norm(numeric_grad_W_cl(:) + grad_W_cl(:)); 649 | if obj.debug 650 | disp([numeric_grad_W_cl(:),obj.grad_W_cl.context(:)]); 651 | end 652 | disp(['the W_cl parameter check is ' , num2str(norm_diff)]) 653 | %% the W_cf parameter check 654 | for n = 1 : size(W_cf,1) 655 | for m = 1 : size(W_cf,2) 656 | obj.W_cf.context = W_cf; 657 | obj.W_cf.context(n,m) = obj.W_cf.context(n,m) + epislon; 658 | obj.fprop(input,size(input,2)); 659 | cost_1 = getCost(target,obj.output); 660 | 661 | obj.W_cf.context = W_cf; 662 | obj.W_cf.context(n,m) = obj.W_cf.context(n,m) - epislon; 663 | obj.fprop(input,size(input,2)); 664 | cost_2 = getCost(target,obj.output); 665 | 666 | numeric_grad_W_cf(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 667 | end 668 | end 669 | norm_diff = norm(numeric_grad_W_cf(:) - grad_W_cf(:)) ./ norm(numeric_grad_W_cf(:) + grad_W_cf(:)); 670 | if obj.debug 671 | disp([numeric_grad_W_cf(:),obj.grad_W_cf.context(:)]); 672 | end 673 | disp(['the W_cf parameter check is ' , num2str(norm_diff)]) 674 | %% the W_hf parameter check 675 | for n = 1 : size(W_hf,1) 676 | for m = 1 : size(W_hf,2) 677 | obj.W_hf.context = W_hf; 678 | obj.W_hf.context(n,m) = obj.W_hf.context(n,m) + epislon; 679 | obj.fprop(input,size(input,2)); 680 | cost_1 = getCost(target,obj.output); 681 | 682 | obj.W_hf.context = W_hf; 683 | obj.W_hf.context(n,m) = obj.W_hf.context(n,m) - epislon; 684 | obj.fprop(input,size(input,2)); 685 | cost_2 = getCost(target,obj.output); 686 | 687 | numeric_grad_W_hf(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 688 | end 689 | end 690 | norm_diff = norm(numeric_grad_W_hf(:) - grad_W_hf(:)) ./ norm(numeric_grad_W_hf(:) + grad_W_hf(:)); 691 | if obj.debug 692 | disp([numeric_grad_W_hf(:),obj.grad_W_hf.context(:)]); 693 | end 694 | disp(['the W_hf parameter check is ' , num2str(norm_diff)]) 695 | %% the W_if parameter check 696 | for n = 1 : size(W_if,1) 697 | for m = 1 : size(W_if,2) 698 | obj.W_if.context = W_if; 699 | obj.W_if.context(n,m) = obj.W_if.context(n,m) + epislon; 700 | obj.fprop(input,size(input,2)); 701 | cost_1 = getCost(target,obj.output); 702 | 703 | obj.W_if.context = W_if; 704 | obj.W_if.context(n,m) = obj.W_if.context(n,m) - epislon; 705 | obj.fprop(input,size(input,2)); 706 | cost_2 = getCost(target,obj.output); 707 | 708 | numeric_grad_W_if(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 709 | end 710 | end 711 | norm_diff = norm(numeric_grad_W_if(:) - grad_W_if(:)) ./ norm(numeric_grad_W_if(:) + grad_W_if(:)); 712 | if obj.debug 713 | disp([numeric_grad_W_if(:),obj.grad_W_if.context(:)]); 714 | end 715 | disp(['the W_if parameter check is ' , num2str(norm_diff)]) 716 | %% the W_hc parameter check 717 | for n = 1 : size(W_hc,1) 718 | for m = 1 : size(W_hc,2) 719 | obj.W_hc.context = W_hc; 720 | obj.W_hc.context(n,m) = obj.W_hc.context(n,m) + epislon; 721 | obj.fprop(input,size(input,2)); 722 | cost_1 = getCost(target,obj.output); 723 | 724 | obj.W_hc.context = W_hc; 725 | obj.W_hc.context(n,m) = obj.W_hc.context(n,m) - epislon; 726 | obj.fprop(input,size(input,2)); 727 | cost_2 = getCost(target,obj.output); 728 | 729 | numeric_grad_W_hc(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 730 | end 731 | end 732 | norm_diff = norm(numeric_grad_W_hc(:) - grad_W_hc(:)) ./ norm(numeric_grad_W_hc(:) + grad_W_hc(:)); 733 | if obj.debug 734 | disp([numeric_grad_W_hc(:),obj.grad_W_hc.context(:)]); 735 | end 736 | disp(['the W_hc parameter check is ' , num2str(norm_diff)]) 737 | %% the W_ic parameter check 738 | for n = 1 : size(W_ic,1) 739 | for m = 1 : size(W_ic,2) 740 | obj.W_ic.context = W_ic; 741 | obj.W_ic.context(n,m) = obj.W_ic.context(n,m) + epislon; 742 | obj.fprop(input,size(input,2)); 743 | cost_1 = getCost(target,obj.output); 744 | 745 | obj.W_ic.context = W_ic; 746 | obj.W_ic.context(n,m) = obj.W_ic.context(n,m) - epislon; 747 | obj.fprop(input,size(input,2)); 748 | cost_2 = getCost(target,obj.output); 749 | 750 | numeric_grad_W_ic(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 751 | end 752 | end 753 | norm_diff = norm(numeric_grad_W_ic(:) - grad_W_ic(:)) ./ norm(numeric_grad_W_ic(:) + grad_W_ic(:)); 754 | if obj.debug 755 | disp([numeric_grad_W_ic(:),obj.grad_W_ic.context(:)]); 756 | end 757 | disp(['the W_ic parameter check is ' , num2str(norm_diff)]) 758 | %% the W_cw parameter check 759 | for n = 1 : size(W_cw,1) 760 | for m = 1 : size(W_cw,2) 761 | obj.W_cw.context = W_cw; 762 | obj.W_cw.context(n,m) = obj.W_cw.context(n,m) + epislon; 763 | obj.fprop(input,size(input,2)); 764 | cost_1 = getCost(target,obj.output); 765 | 766 | obj.W_cw.context = W_cw; 767 | obj.W_cw.context(n,m) = obj.W_cw.context(n,m) - epislon; 768 | obj.fprop(input,size(input,2)); 769 | cost_2 = getCost(target,obj.output); 770 | 771 | numeric_grad_W_cw(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 772 | end 773 | end 774 | norm_diff = norm(numeric_grad_W_cw(:) - grad_W_cw(:)) ./ norm(numeric_grad_W_cw(:) + grad_W_cw(:)); 775 | if obj.debug 776 | disp([numeric_grad_W_cw(:),obj.grad_W_cw.context(:)]); 777 | end 778 | disp(['the W_cw parameter check is ' , num2str(norm_diff)]) 779 | %% the W_hw parameter check 780 | for n = 1 : size(W_hw,1) 781 | for m = 1 : size(W_hw,2) 782 | obj.W_hw.context = W_hw; 783 | obj.W_hw.context(n,m) = obj.W_hw.context(n,m) + epislon; 784 | obj.fprop(input,size(input,2)); 785 | cost_1 = getCost(target,obj.output); 786 | 787 | obj.W_hw.context = W_hw; 788 | obj.W_hw.context(n,m) = obj.W_hw.context(n,m) - epislon; 789 | obj.fprop(input,size(input,2)); 790 | cost_2 = getCost(target,obj.output); 791 | 792 | numeric_grad_W_hw(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 793 | end 794 | end 795 | norm_diff = norm(numeric_grad_W_hw(:) - grad_W_hw(:)) ./ norm(numeric_grad_W_hw(:) + grad_W_hw(:)); 796 | if obj.debug 797 | disp([numeric_grad_W_hw(:),obj.grad_W_hw.context(:)]); 798 | end 799 | disp(['the W_hw parameter check is ' , num2str(norm_diff)]) 800 | %% the W_iw parameter check 801 | for n = 1 : size(W_iw,1) 802 | for m = 1 : size(W_iw,2) 803 | obj.W_iw.context = W_iw; 804 | obj.W_iw.context(n,m) = obj.W_iw.context(n,m) + epislon; 805 | obj.fprop(input,size(input,2)); 806 | cost_1 = getCost(target,obj.output); 807 | 808 | obj.W_iw.context = W_iw; 809 | obj.W_iw.context(n,m) = obj.W_iw.context(n,m) - epislon; 810 | obj.fprop(input,size(input,2)); 811 | cost_2 = getCost(target,obj.output); 812 | 813 | numeric_grad_W_iw(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 814 | end 815 | end 816 | norm_diff = norm(numeric_grad_W_iw(:) - grad_W_iw(:)) ./ norm(numeric_grad_W_iw(:) + grad_W_iw(:)); 817 | if obj.debug 818 | disp([numeric_grad_W_iw(:),obj.grad_W_iw.context(:)]); 819 | end 820 | disp(['the W_iw parameter check is ' , num2str(norm_diff)]) 821 | %% the B_l parameter check 822 | for n = 1 : size(B_l,1) 823 | for m = 1 : size(B_l,2) 824 | obj.B_l.context = B_l; 825 | obj.B_l.context(n,m) = obj.B_l.context(n,m) + epislon; 826 | obj.fprop(input,size(input,2)); 827 | cost_1 = getCost(target,obj.output); 828 | 829 | obj.B_l.context = B_l; 830 | obj.B_l.context(n,m) = obj.B_l.context(n,m) - epislon; 831 | obj.fprop(input,size(input,2)); 832 | cost_2 = getCost(target,obj.output); 833 | 834 | numeric_grad_B_l(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 835 | end 836 | end 837 | norm_diff = norm(numeric_grad_B_l(:) - grad_B_l(:)) ./ norm(numeric_grad_B_l(:) + grad_B_l(:)); 838 | if obj.debug 839 | disp([numeric_grad_B_l(:),obj.grad_B_l.context(:)]); 840 | end 841 | disp(['the B_l parameter check is ' , num2str(norm_diff)]) 842 | %% the B_f parameter check 843 | for n = 1 : size(B_f,1) 844 | for m = 1 : size(B_f,2) 845 | obj.B_f.context = B_f; 846 | obj.B_f.context(n,m) = obj.B_f.context(n,m) + epislon; 847 | obj.fprop(input,size(input,2)); 848 | cost_1 = getCost(target,obj.output); 849 | 850 | obj.B_f.context = B_f; 851 | obj.B_f.context(n,m) = obj.B_f.context(n,m) - epislon; 852 | obj.fprop(input,size(input,2)); 853 | cost_2 = getCost(target,obj.output); 854 | 855 | numeric_grad_B_f(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 856 | end 857 | end 858 | norm_diff = norm(numeric_grad_B_f(:) - grad_B_f(:)) ./ norm(numeric_grad_B_f(:) + grad_B_f(:)); 859 | if obj.debug 860 | disp([numeric_grad_B_f(:),obj.grad_B_f.context(:)]); 861 | end 862 | disp(['the B_f parameter check is ' , num2str(norm_diff)]) 863 | %% the B_c parameter check 864 | for n = 1 : size(B_c,1) 865 | for m = 1 : size(B_c,2) 866 | obj.B_c.context = B_c; 867 | obj.B_c.context(n,m) = obj.B_c.context(n,m) + epislon; 868 | obj.fprop(input,size(input,2)); 869 | cost_1 = getCost(target,obj.output); 870 | 871 | obj.B_c.context = B_c; 872 | obj.B_c.context(n,m) = obj.B_c.context(n,m) - epislon; 873 | obj.fprop(input,size(input,2)); 874 | cost_2 = getCost(target,obj.output); 875 | 876 | numeric_grad_B_c(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 877 | end 878 | end 879 | norm_diff = norm(numeric_grad_B_c(:) - grad_B_c(:)) ./ norm(numeric_grad_B_c(:) + grad_B_c(:)); 880 | if obj.debug 881 | disp([numeric_grad_B_c(:),obj.grad_B_c.context(:)]); 882 | end 883 | disp(['the B_c parameter check is ' , num2str(norm_diff)]) 884 | %% the B_w parameter check 885 | for n = 1 : size(B_w,1) 886 | for m = 1 : size(B_w,2) 887 | obj.B_w.context = B_w; 888 | obj.B_w.context(n,m) = obj.B_w.context(n,m) + epislon; 889 | obj.fprop(input,size(input,2)); 890 | cost_1 = getCost(target,obj.output); 891 | 892 | obj.B_w.context = B_w; 893 | obj.B_w.context(n,m) = obj.B_w.context(n,m) - epislon; 894 | obj.fprop(input,size(input,2)); 895 | cost_2 = getCost(target,obj.output); 896 | 897 | numeric_grad_B_w(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 898 | end 899 | end 900 | norm_diff = norm(numeric_grad_B_w(:) - grad_B_w(:)) ./ norm(numeric_grad_B_w(:) + grad_B_w(:)); 901 | if obj.debug 902 | disp([numeric_grad_B_w(:),obj.grad_B_w.context(:)]); 903 | end 904 | disp(['the B_w parameter check is ' , num2str(norm_diff)]) 905 | 906 | %% the init_output parameter check 907 | for n = 1 : size(init_output,1) 908 | for m = 1 : size(init_output,2) 909 | temp_init_output = init_output; 910 | temp_init_output(n,m) = temp_init_output(n,m) + epislon; 911 | obj.init_output{1,1} = temp_init_output; 912 | obj.fprop(input,size(input,2)); 913 | cost_1 = getCost(target,obj.output); 914 | 915 | temp_init_output = init_output; 916 | temp_init_output(n,m) = temp_init_output(n,m) - epislon; 917 | obj.init_output{1,1} = temp_init_output; 918 | obj.fprop(input,size(input,2)); 919 | cost_2 = getCost(target,obj.output); 920 | 921 | numeric_grad_init_output(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 922 | end 923 | end 924 | norm_diff = norm(numeric_grad_init_output(:) - grad_init_output(:)) ./ norm(numeric_grad_init_output(:) + grad_init_output(:)); 925 | if obj.debug 926 | disp([numeric_grad_init_output(:),grad_init_output(:)]); 927 | end 928 | disp(['the init_output parameter check is ' , num2str(norm_diff)]) 929 | 930 | %% the init_state parameter check 931 | for n = 1 : size(init_state,1) 932 | for m = 1 : size(init_state,2) 933 | temp_init_state = init_state; 934 | temp_init_state(n,m) = temp_init_state(n,m) + epislon; 935 | obj.init_state{1,1} = temp_init_state; 936 | obj.fprop(input,size(input,2)); 937 | cost_1 = getCost(target,obj.output); 938 | 939 | temp_init_state = init_state; 940 | temp_init_state(n,m) = temp_init_state(n,m) - epislon; 941 | obj.init_state{1,1} = temp_init_state; 942 | obj.fprop(input,size(input,2)); 943 | cost_2 = getCost(target,obj.output); 944 | 945 | numeric_grad_init_state(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 946 | end 947 | end 948 | norm_diff = norm(numeric_grad_init_state(:) - grad_init_state(:)) ./ norm(numeric_grad_init_state(:) + grad_init_state(:)); 949 | if obj.debug 950 | disp([numeric_grad_init_state(:),grad_init_state(:)]); 951 | end 952 | disp(['the init_state parameter check is ' , num2str(norm_diff)]) 953 | %% check the gradient of input data 954 | for t = 1 : seqLen 955 | temp = input{1,t}; 956 | for i = 1 : size(temp,1) 957 | for j = 1 : size(temp,2) 958 | temp_input = input; 959 | temp = temp_input{1,t}; 960 | temp(i,j) = temp(i,j) + epislon; 961 | temp_input{1,t} = temp; 962 | obj.fprop(temp_input,size(temp_input,2)); 963 | cost_1 = getCost(target,obj.output); 964 | 965 | temp_input = input; 966 | temp = temp_input{1,t}; 967 | temp(i,j) = temp(i,j) - epislon; 968 | temp_input{1,t} = temp; 969 | obj.fprop(temp_input,size(temp_input,2)); 970 | cost_2 = getCost(target,obj.output); 971 | numeric_grad_input{1,t}(i,j) = (cost_1 - cost_2) ./ (2 * epislon); 972 | end 973 | end 974 | norm_diff = norm(numeric_grad_input{1,t}(:) - grad_input{1,t}(:)) ./ norm(numeric_grad_input{1,t}(:) + grad_input{1,t}(:)); 975 | if obj.debug 976 | disp([numeric_grad_input{1,t}(:),grad_input{1,t}(:)]); 977 | end 978 | disp([num2str(t),' : the check of input gradient is ' , num2str(norm_diff)]) 979 | end 980 | end 981 | end 982 | end 983 | 984 | function cost = getCost(target,output) 985 | cost = 0; 986 | for m = 1 : size(target,2) 987 | temp = (target{1,m} - output{1,m}) .^ 2; 988 | cost = cost + sum(temp(:)) ./ size(temp,2); 989 | end 990 | end -------------------------------------------------------------------------------- /Layers/OperateLayer.m: -------------------------------------------------------------------------------- 1 | classdef OperateLayer < handle 2 | properties 3 | W = Data(); 4 | B = Data(); 5 | grad_W = Data(); 6 | grad_B = Data(); 7 | init = Data(); 8 | activation = @tanh; 9 | diff_activ = @tanhPrime; 10 | length 11 | batch_size 12 | input 13 | output 14 | grad_input 15 | grad_output 16 | end 17 | properties(SetAccess = private,GetAccess = public) 18 | hidden_dim 19 | input_dim 20 | mask = true; 21 | debug = false; 22 | backward = false; 23 | end 24 | methods 25 | function obj = OperateLayer(option) 26 | if nargin >= 1 27 | obj.W = Data(option); 28 | obj.B = Data(option); 29 | obj.grad_W = Data(option); 30 | obj.grad_B = Data(option); 31 | obj.init = Data(option); 32 | end 33 | end 34 | 35 | % function update(obj,apply,option) 36 | % if nargin <= 2 37 | % option = struct(); 38 | % end 39 | % obj.W.context = apply(obj.W.context,obj.grad_W.context,option); 40 | % obj.B.context = apply(obj.B.context,obj.grad_B.context,option); 41 | % obj.grad_W.setZeros(); 42 | % obj.grad_B.setZeros(); 43 | % end 44 | 45 | function initial(obj) 46 | if obj.debug 47 | if isempty(obj.hidden_dim) || isempty(obj.input_dim) 48 | error('the dimension should be initialized first'); 49 | end 50 | end 51 | 52 | obj.W.setDataSize([obj.hidden_dim,obj.input_dim]); 53 | obj.B.setDataSize([obj.hidden_dim,1]); 54 | obj.W.initial(); 55 | obj.B.initial(); 56 | if obj.backward 57 | obj.grad_W.setDataSize([obj.hidden_dim,obj.input_dim]); 58 | obj.grad_B.setDataSize([obj.hidden_dim,1]); 59 | obj.grad_W.setZeros(); 60 | obj.grad_B.setZeros(); 61 | end 62 | end 63 | 64 | function initialOption(obj,option) 65 | if isfield(option,'hidden_dim') 66 | obj.hidden_dim = option.hidden_dim; 67 | end 68 | 69 | if isfield(option,'input_dim') 70 | obj.input_dim = option.input_dim; 71 | end 72 | 73 | if isfield(option,'debug') 74 | obj.setDebug(option.debug); 75 | end 76 | 77 | if isfield(option,'activation') 78 | obj.activation = option.activation; 79 | end 80 | 81 | if isfield(option,'diff_avtiv') 82 | obj.diff_activ = option.diff_activ; 83 | end 84 | 85 | if isfield(option,'backward') 86 | obj.backward = option.backward; 87 | end 88 | end 89 | 90 | function setDebug(obj,debug) 91 | if debug == true || debug == false 92 | obj.debug = debug; 93 | else 94 | error('unkown debug type'); 95 | end 96 | end 97 | end 98 | end -------------------------------------------------------------------------------- /Layers/RecurrentLayer.m: -------------------------------------------------------------------------------- 1 | classdef RecurrentLayer < OperateLayer 2 | properties 3 | W_T = Data(); 4 | grad_W_T = Data(); 5 | init_output 6 | grad_init_output 7 | end 8 | methods 9 | function obj = RecurrentLayer(option) 10 | if nargin == 0 11 | super_args{1} = struct(); 12 | else if nargin == 1 13 | super_args{1} = option; 14 | end 15 | end 16 | obj = obj@OperateLayer(super_args{:}); 17 | obj.initialOption(super_args{:}); 18 | obj.W_T = Data(super_args{:}); 19 | obj.grad_W_T = Data(super_args{:}); 20 | obj.initial(); 21 | end 22 | 23 | function initial(obj) 24 | initial@OperateLayer(obj); 25 | obj.W_T.setDataSize([obj.hidden_dim,obj.hidden_dim]); 26 | obj.W_T.initial(); 27 | if obj.backward 28 | obj.grad_W_T.setDataSize([obj.hidden_dim,obj.hidden_dim]); 29 | obj.grad_W_T.setZeros(); 30 | end 31 | end 32 | 33 | function [output,length] = fprop(obj,input,length) 34 | if obj.debug 35 | if isempty(obj.W.context) || isempty(obj.W_T.context) || isempty(obj.B.context) 36 | error('not all the context are initialized yet,and can not do the fprop operation!'); 37 | end 38 | end 39 | obj.length = length; 40 | obj.batch_size = size(input{1,1},2); 41 | if isempty(obj.init_output) 42 | obj.init.setDataSize([obj.hidden_dim,obj.batch_size]); 43 | obj.init.setZeros(); 44 | obj.init_output{1,1} = obj.init.context; 45 | obj.init.clearData(); 46 | end 47 | for i = 1 : size(input,2) 48 | obj.input{1,i} = input{1,i}; 49 | if i == 1 50 | obj.output{1,i} = obj.activation(bsxfun(@plus,obj.W.context * obj.input{1,i} + obj.W_T.context * obj.init_output{1,1},obj.B.context)); 51 | else 52 | obj.output{1,i} = obj.activation(bsxfun(@plus,obj.W.context * obj.input{1,i} + obj.W_T.context * obj.output{1,i - 1},obj.B.context)); 53 | end 54 | end 55 | output = obj.output; 56 | end 57 | 58 | function output = fprop_step(obj,input,i) 59 | if obj.debug 60 | if isempty(obj.W.context) || isempty(obj.W_T.context) || isempty(obj.B.context) 61 | error('not all the context are initialized yet,and can not do the fprop operation!'); 62 | end 63 | end 64 | obj.length = i; 65 | obj.batch_size = size(input{1,1},2); 66 | if isempty(obj.init_output) 67 | obj.init.setDataSize([obj.hidden_dim,obj.batch_size]); 68 | obj.init.setZeros(); 69 | obj.init_output{1,1} = obj.init.context; 70 | obj.init.clearData(); 71 | end 72 | if i == 1 73 | obj.output{1,i} = obj.activation(bsxfun(@plus,obj.W.context * input{1,1} + obj.W_T.context * obj.init_output{1,1},obj.B.context)); 74 | else 75 | obj.output{1,i} = obj.activation(bsxfun(@plus,obj.W.context * input{1,1} + obj.W_T.context * obj.output{1,i - 1},obj.B.context)); 76 | end 77 | output{1,1} = obj.output{1,i}; 78 | end 79 | 80 | function initialOption(obj,option) 81 | initialOption@OperateLayer(obj,option); 82 | end 83 | 84 | function grad_input = bprop(obj,grad_output) 85 | for i = obj.length : -1 : 1 86 | obj.grad_output{1,i} = grad_output{1,i}; 87 | if i == size(obj.grad_output,2) 88 | obj.grad_input{1,i} = obj.grad_output{1,i} .* obj.diff_activ(obj.output{1,i}); 89 | else 90 | obj.grad_input{1,i} = (obj.grad_output{1,i} + obj.W_T.context' * obj.grad_input{1,i + 1}) .* obj.diff_activ(obj.output{1,i}); 91 | end 92 | if i > 1 93 | obj.grad_W_T.context = obj.grad_W_T.context + obj.grad_input{1,i} * (obj.output{1,i - 1})' ./ obj.batch_size; 94 | else 95 | obj.grad_W_T.context = obj.grad_W_T.context + obj.grad_input{1,i} * (obj.init_output{1,1})' ./ obj.batch_size; 96 | end 97 | end 98 | obj.grad_init_output{1,1} = obj.W_T.context' * obj.grad_input{1,1}; 99 | for i = 1 : size(obj.grad_input,2) 100 | obj.grad_B.context = obj.grad_B.context + sum(obj.grad_input{1,i},2) ./ obj.batch_size; 101 | obj.grad_W.context = obj.grad_W.context + obj.grad_input{1,i} * (obj.input{1,i})' ./ obj.batch_size; 102 | obj.grad_input{1,i} = obj.W.context' * obj.grad_input{1,i}; 103 | end 104 | grad_input = obj.grad_input; 105 | end 106 | 107 | function update(obj,apply,option) 108 | if nargin <= 2 109 | option = struct(); 110 | end 111 | obj.W.context = apply(obj.W.context,obj.grad_W.context,option); 112 | obj.W_T.context = apply(obj.W_T.context,obj.grad_W_T.context,option); 113 | obj.B.context = apply(obj.B.context,obj.grad_B.context,option); 114 | 115 | obj.grad_W.setZeros(); 116 | obj.grad_W_T.setZeros(); 117 | obj.grad_B.setZeros(); 118 | end 119 | 120 | function object = saveObj(obj) 121 | if obj.W.useGPU 122 | object.W = gather(obj.W.context); 123 | object.W_T = gather(obj.W_T.context); 124 | object.B = gather(obj.B.context); 125 | else 126 | object.W = obj.W.context; 127 | object.W_T = obj.W_T.context; 128 | object.B = obj.B.context; 129 | end 130 | 131 | object.activation = obj.activation; 132 | object.diff_activ = obj.diff_activ; 133 | end 134 | 135 | function loadObj(obj,object) 136 | obj.W.context = obj.init.dataConvert(object.W); 137 | obj.B.context = obj.init.dataConvert(object.B); 138 | obj.W_T.context = obj.init.dataConvert(object.W_T); 139 | obj.activation = object.activaiton; 140 | obj.diff_activ = object.diff_activ; 141 | end 142 | %% the functions below this line are used in the above ones or some are just defined for the gradient check; 143 | function checkGrad(obj) 144 | seqLen = 10; 145 | batchSize = 20; 146 | input = cell([1,seqLen]); 147 | target = cell([1,seqLen]); 148 | for i = 1 : seqLen 149 | input{1,i} = randn([obj.input_dim,batchSize]); 150 | target{1,i} = randn([obj.hidden_dim,batchSize]); 151 | end 152 | epislon = 10 ^ (-6); 153 | 154 | W = obj.W.context; 155 | W_T = obj.W_T.context; 156 | B = obj.B.context; 157 | 158 | obj.fprop(input,size(input,2)); 159 | grad_output = cell([1,size(obj.output,2)]); 160 | for i = 1 : size(obj.output,2) 161 | grad_output{1,i} = 2 * (obj.output{1,i} - target{1,i}); 162 | end 163 | obj.bprop(grad_output); 164 | 165 | grad_input = obj.grad_input; 166 | grad_W = obj.grad_W.context; 167 | grad_W_T = obj.grad_W_T.context; 168 | grad_B = obj.grad_B.context; 169 | init_output = obj.init_output{1,1}; 170 | grad_init_output = obj.grad_init_output{1,1}; 171 | numeric_grad_W = zeros(size(W)); 172 | numeric_grad_W_T = zeros(size(W_T)); 173 | numeric_grad_B = zeros(size(grad_B)); 174 | numeric_grad_input = cell(size(grad_input)); 175 | numeric_grad_init_output = zeros(size(grad_init_output)); 176 | for i = 1 : size(numeric_grad_input,2) 177 | numeric_grad_input{1,i} = zeros(size(grad_input{1,i})); 178 | end 179 | %% the W parameter check 180 | for n = 1 : size(W,1) 181 | for m = 1 : size(W,2) 182 | obj.W.context = W; 183 | obj.W.context(n,m) = obj.W.context(n,m) + epislon; 184 | obj.fprop(input,size(input,2)); 185 | cost_1 = getCost(target,obj.output); 186 | 187 | obj.W.context = W; 188 | obj.W.context(n,m) = obj.W.context(n,m) - epislon; 189 | obj.fprop(input,size(input,2)); 190 | cost_2 = getCost(target,obj.output); 191 | 192 | numeric_grad_W(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 193 | end 194 | end 195 | norm_diff = norm(numeric_grad_W(:) - grad_W(:)) ./ norm(numeric_grad_W(:) + grad_W(:)); 196 | if obj.debug 197 | disp([numeric_grad_W(:),obj.grad_W.context(:)]); 198 | end 199 | disp(['the W parameter check is ' , num2str(norm_diff)]) 200 | 201 | %% the W_T parameter check 202 | for n = 1 : size(W_T,1) 203 | for m = 1 : size(W_T,2) 204 | obj.W_T.context = W_T; 205 | obj.W_T.context(n,m) = obj.W_T.context(n,m) + epislon; 206 | obj.fprop(input,size(input,2)); 207 | cost_1 = getCost(target,obj.output); 208 | 209 | obj.W_T.context = W_T; 210 | obj.W_T.context(n,m) = obj.W_T.context(n,m) - epislon; 211 | obj.fprop(input,size(input,2)); 212 | cost_2 = getCost(target,obj.output); 213 | 214 | numeric_grad_W_T(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 215 | end 216 | end 217 | norm_diff = norm(numeric_grad_W_T(:) - grad_W_T(:)) ./ norm(numeric_grad_W_T(:) + grad_W_T(:)); 218 | if obj.debug 219 | disp([numeric_grad_W_T(:),grad_W_T(:)]); 220 | end 221 | disp(['the W_T parameter check is ' , num2str(norm_diff)]) 222 | 223 | %% the B parameter check 224 | for n = 1 : size(B,1) 225 | for m = 1 : size(B,2) 226 | obj.B.context = B; 227 | obj.B.context(n,m) = obj.B.context(n,m) + epislon; 228 | obj.fprop(input,size(input,2)); 229 | cost_1 = getCost(target,obj.output); 230 | 231 | obj.B.context = B; 232 | obj.B.context(n,m) = obj.B.context(n,m) - epislon; 233 | obj.fprop(input,size(input,2)); 234 | cost_2 = getCost(target,obj.output); 235 | 236 | numeric_grad_B(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 237 | end 238 | end 239 | norm_diff = norm(numeric_grad_B(:) - grad_B(:)) ./ norm(numeric_grad_B(:) + grad_B(:)); 240 | if obj.debug 241 | disp([numeric_grad_B(:),grad_B(:)]); 242 | end 243 | disp(['the B parameter check is ' , num2str(norm_diff)]) 244 | 245 | %% the init_output parameter check 246 | for n = 1 : size(init_output,1) 247 | for m = 1 : size(init_output,2) 248 | temp = init_output; 249 | temp(n,m) = temp(n,m) + epislon; 250 | obj.init_output{1,1} = temp; 251 | obj.fprop(input,size(input,2)); 252 | cost_1 = getCost(target,obj.output); 253 | 254 | temp = init_output; 255 | temp(n,m) = temp(n,m) - epislon; 256 | obj.init_output{1,1} = temp; 257 | obj.fprop(input,size(input,2)); 258 | cost_2 = getCost(target,obj.output); 259 | 260 | numeric_grad_init_output(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 261 | end 262 | end 263 | norm_diff = norm(numeric_grad_init_output(:) - grad_init_output(:) ./ batchSize) ./ norm(numeric_grad_init_output(:) + grad_init_output(:) ./ batchSize); 264 | if obj.debug 265 | disp([numeric_grad_init_output(:),grad_init_output(:)]); 266 | end 267 | disp(['the init_output parameter check is ' , num2str(norm_diff)]) 268 | %% check the gradient of input data 269 | for t = 1 : seqLen 270 | temp = input{1,t}; 271 | for i = 1 : size(temp,1) 272 | for j = 1 : size(temp,2) 273 | temp_input = input; 274 | temp = temp_input{1,t}; 275 | temp(i,j) = temp(i,j) + epislon; 276 | temp_input{1,t} = temp; 277 | obj.fprop(temp_input,size(temp_input,2)); 278 | cost_1 = getCost(target,obj.output); 279 | 280 | temp_input = input; 281 | temp = temp_input{1,t}; 282 | temp(i,j) = temp(i,j) - epislon; 283 | temp_input{1,t} = temp; 284 | obj.fprop(temp_input,size(temp_input,2)); 285 | cost_2 = getCost(target,obj.output); 286 | numeric_grad_input{1,t}(i,j) = (cost_1 - cost_2) ./ (2 * epislon); 287 | end 288 | end 289 | norm_diff = norm(numeric_grad_input{1,t}(:) - grad_input{1,t}(:) ./ batchSize) ./ norm(numeric_grad_input{1,t}(:) + grad_input{1,t}(:) ./ batchSize); 290 | if obj.debug 291 | disp([numeric_grad_input{1,t}(:),grad_input{1,t}(:)]); 292 | end 293 | disp([num2str(t),' : the check of input gradient is ' , num2str(norm_diff)]) 294 | end 295 | end 296 | end 297 | end 298 | 299 | function cost = getCost(target,output) 300 | cost = 0; 301 | for m = 1 : size(target,2) 302 | temp = (target{1,m} - output{1,m}) .^ 2; 303 | cost = cost + sum(temp(:)) ./ size(temp,2); 304 | end 305 | end -------------------------------------------------------------------------------- /Layers/SGD.m: -------------------------------------------------------------------------------- 1 | function W = SGD(W,grad_W,option) 2 | if nargin <= 2 3 | option = struct(); 4 | end 5 | 6 | if ~isfield(option,'learningRate') 7 | option.learningRate = 0.001; 8 | end 9 | 10 | W = W - option.learningRate .* grad_W; 11 | end -------------------------------------------------------------------------------- /Layers/SelectLayer.m: -------------------------------------------------------------------------------- 1 | classdef SelectLayer < handle 2 | properties 3 | init = Data(); 4 | index 5 | output 6 | input 7 | end 8 | methods 9 | function obj = SelectLayer(option) 10 | if nargin >= 1 11 | obj.init = Data(option); 12 | end 13 | end 14 | 15 | function output = fprop(obj,input,index) 16 | if nargin <= 2 17 | index = size(input,2); 18 | end 19 | obj.index = index; 20 | obj.output = cell([2,size(index,2)]); 21 | obj.input = input; 22 | obj.init.setDataSize(size(input{1,1})); 23 | obj.init.setZeros(); 24 | for i = 1 : size(index,2) 25 | obj.output{1,i} = input{1,index(1,i)}; 26 | obj.output{2,i} = input{2,index(1,i)}; 27 | end 28 | output = obj.output; 29 | end 30 | 31 | function grad_input = bprop(obj,grad_output) 32 | obj.grad_input = cell([1,size(obj.input,2)]); 33 | for i = 1 : size(obj.grad_input,2) 34 | for j = 1 : size(obj.index,2) 35 | if i ~= obj.index(1,j) 36 | obj.grad_input{1,i} = obj.init.context; 37 | else 38 | obj.grad_input{1,i} = grad_output{1,j}; 39 | end 40 | end 41 | end 42 | grad_input = obj.grad_input; 43 | end 44 | 45 | % function update(obj,apply) 46 | % end 47 | end 48 | end -------------------------------------------------------------------------------- /Layers/SoftmaxLayer.m: -------------------------------------------------------------------------------- 1 | classdef SoftmaxLayer < OperateLayer 2 | methods 3 | function obj = SoftmaxLayer(option) 4 | if nargin == 0 5 | super_args{1} = struct(); 6 | else if nargin == 1 7 | super_args{1} = option; 8 | end 9 | end 10 | obj = obj@OperateLayer(super_args{:}); 11 | obj.initialOption(super_args{:}); 12 | obj.initial(); 13 | end 14 | 15 | function [output,length] = fprop(obj,input,length) 16 | obj.length = length; 17 | for i = 1 : obj.length 18 | obj.input{1,i} = input{1,i}; 19 | obj.output{1,i} = bsxfun(@plus,obj.W.context * obj.input{1,i},obj.B.context); 20 | obj.output{1,i} = exp(bsxfun(@minus,obj.output{1,i},max(obj.output{1,i},[],1))); 21 | obj.output{1,i} = bsxfun(@rdivide,obj.output{1,i},sum(obj.output{1,i},1)); 22 | end 23 | output = obj.output; 24 | if obj.debug 25 | display(['SoftmaxLayer | W | mean : ',num2str(mean(obj.W.context(:))),' | std : ',num2str(std(obj.W.context(:)))]); 26 | end 27 | end 28 | 29 | function output = fprop_step(obj,input,i) 30 | obj.length = i; 31 | obj.input{1,i} = input{1,1}; 32 | obj.output{1,i} = bsxfun(@plus,obj.W.context * obj.input{1,i},obj.B.context); 33 | obj.output{1,i} = exp(bsxfun(@minus,obj.output{1,i},max(obj.output{1,i},[],1))); 34 | obj.output{1,i} = bsxfun(@rdivide,obj.output{1,i},sum(obj.output{1,i},1)); 35 | output{1,1} = obj.output{1,i}; 36 | end 37 | 38 | function cost = getCost(obj,target) 39 | cost = 0; 40 | for i = 1 : obj.length 41 | temp_target = target{1,i}; 42 | temp_output = 1 : size(obj.output{1,i},2); 43 | cost_index = sub2ind(size(obj.output{1,i}),temp_target,temp_output); 44 | cost = cost + sum((- log(obj.output{1,i}(cost_index)))) ./ length(temp_output); 45 | end 46 | end 47 | 48 | function accuracy = getAccuracy(obj,target) 49 | temp_accuracy = zeros(1,obj.length); 50 | if obj.W.useGPU 51 | temp_accuracy = gpuArray(temp_accuracy); 52 | end 53 | for i = 1 : obj.length 54 | temp_output = obj.output{1,i}; 55 | [~,max_index] = max(temp_output,[],1); 56 | temp_accuracy(1,i) = sum(max_index == target{1,i}) ./ size(temp_output,2); 57 | end 58 | accuracy = mean(temp_accuracy); 59 | end 60 | 61 | function grad_input = bprop(obj,target) 62 | for i = 1 : obj.length 63 | temp_target = target{1,i}; 64 | temp_output = 1 : size(obj.output{1,i},2); 65 | cost_index = sub2ind(size(obj.output{1,i}),temp_target,temp_output); 66 | obj.grad_output{1,i} = obj.output{1,i}; 67 | obj.grad_output{1,i}(cost_index) = obj.grad_output{1,i}(cost_index) - 1; 68 | obj.grad_input{1,i} = obj.W.context' * obj.grad_output{1,i}; 69 | obj.grad_W.context = obj.grad_W.context + obj.grad_output{1,i} * (obj.input{1,i})' ./ size(obj.input{1,i},2); 70 | obj.grad_B.context = obj.grad_B.context + mean(obj.grad_output{1,i},2); 71 | end 72 | grad_input = obj.grad_input; 73 | if obj.debug 74 | display(['SoftmaxLayer | grad_W | mean : ',num2str(mean(obj.grad_W.context(:))),' | std : ',num2str(std(obj.grad_W.context(:)))]); 75 | end 76 | end 77 | 78 | function update(obj,apply,option) 79 | if nargin <= 2 80 | option = struct(); 81 | end 82 | obj.W.context = apply(obj.W.context,obj.grad_W.context,option); 83 | obj.B.context = apply(obj.B.context,obj.grad_B.context,option); 84 | obj.grad_W.setZeros(); 85 | obj.grad_B.setZeros(); 86 | end 87 | 88 | function object = saveObj(obj) 89 | if obj.W.useGPU 90 | object.W = gather(obj.W.context); 91 | object.B = gather(obj.B.context); 92 | else 93 | object.W = obj.W.context; 94 | object.B = obj.B.context; 95 | end 96 | 97 | object.activation = obj.activation; 98 | object.diff_activ = obj.diff_activ; 99 | end 100 | 101 | function loadObj(obj,object) 102 | obj.W.context = obj.init.dataConvert(object.W); 103 | obj.B.context = obj.init.dataConvert(object.B); 104 | obj.activation = object.activation; 105 | obj.diff_activ = object.diff_activ; 106 | end 107 | 108 | %% the functions below this line are used in the above functions or some functions are just defined for the gradient check; 109 | function checkGrad(obj) 110 | seqLen = 20; 111 | batchSize = 10; 112 | input = cell([1,seqLen]); 113 | target = cell([1,seqLen]); 114 | for i = 1 : seqLen 115 | input{1,i} = randn([obj.input_dim,batchSize]); 116 | target{1,i} = randi(obj.hidden_dim,1,batchSize); 117 | end 118 | epislon = 10 ^ (-7); 119 | 120 | W = obj.W.context; 121 | B = obj.B.context; 122 | obj.fprop(input,size(input,2)); 123 | obj.bprop(target); 124 | grad_input = obj.grad_input; 125 | grad_W = obj.grad_W.context; 126 | grad_B = obj.grad_B.context; 127 | numeric_grad_W = zeros(size(W)); 128 | numeric_grad_B = zeros(size(grad_B)); 129 | numeric_grad_input = cell(size(grad_input)); 130 | for i = 1 : size(numeric_grad_input,2) 131 | numeric_grad_input{1,i} = zeros(size(grad_input{1,i})); 132 | end 133 | %% the W parameter check 134 | for n = 1 : size(W,1) 135 | for m = 1 : size(W,2) 136 | obj.W.context = W; 137 | obj.W.context(n,m) = obj.W.context(n,m) + epislon; 138 | obj.fprop(input,size(input,2)); 139 | cost_1 = obj.getCost(target); 140 | 141 | obj.W.context = W; 142 | obj.W.context(n,m) = obj.W.context(n,m) - epislon; 143 | obj.fprop(input,size(input,2)); 144 | cost_2 = obj.getCost(target); 145 | 146 | numeric_grad_W(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 147 | end 148 | end 149 | norm_diff = norm(numeric_grad_W(:) - grad_W(:)) ./ norm(numeric_grad_W(:) + grad_W(:)); 150 | if obj.debug 151 | disp([numeric_grad_W(:),grad_W(:)]); 152 | end 153 | disp(['the W parameter check is ' , num2str(norm_diff)]) 154 | %% the B parameter check 155 | for n = 1 : size(B,1) 156 | for m = 1 : size(B,2) 157 | obj.B.context = B; 158 | obj.B.context(n,m) = obj.B.context(n,m) + epislon; 159 | obj.fprop(input,size(input,2)); 160 | cost_1 = obj.getCost(target); 161 | 162 | obj.B.context = B; 163 | obj.B.context(n,m) = obj.B.context(n,m) - epislon; 164 | obj.fprop(input,size(input,2)); 165 | cost_2 = obj.getCost(target); 166 | 167 | numeric_grad_B(n,m) = (cost_1 - cost_2) ./ (2 * epislon); 168 | end 169 | end 170 | norm_diff = norm(numeric_grad_B(:) - grad_B(:)) ./ norm(numeric_grad_B(:) + grad_B(:)); 171 | if obj.debug 172 | disp([numeric_grad_B(:),grad_B(:)]); 173 | end 174 | disp(['the B parameter check is ' , num2str(norm_diff)]) 175 | %% check the gradient of input data 176 | for t = 1 : seqLen 177 | temp = input{1,t}; 178 | for i = 1 : size(temp,1) 179 | for j = 1 : size(temp,2) 180 | temp_input = input; 181 | temp = temp_input{1,t}; 182 | temp(i,j) = temp(i,j) + epislon; 183 | temp_input{1,t} = temp; 184 | obj.fprop(temp_input,size(temp_input,2)); 185 | cost_1 = obj.getCost(target); 186 | 187 | temp_input = input; 188 | temp = temp_input{1,t}; 189 | temp(i,j) = temp(i,j) - epislon; 190 | temp_input{1,t} = temp; 191 | obj.fprop(temp_input,size(temp_input,2)); 192 | cost_2 = obj.getCost(target); 193 | numeric_grad_input{1,t}(i,j) = (cost_1 - cost_2) ./ (2 * epislon); 194 | end 195 | end 196 | norm_diff = norm(numeric_grad_input{1,t}(:) - grad_input{1,t}(:) ./ batchSize) ./ norm(numeric_grad_input{1,t}(:) + grad_input{1,t}(:) ./ batchSize); 197 | if obj.debug 198 | disp([numeric_grad_input{1,t}(:),grad_input{1,t}(:)]); 199 | end 200 | disp([num2str(t),' : the check of input gradient is ' , num2str(norm_diff)]) 201 | end 202 | end 203 | end 204 | end 205 | -------------------------------------------------------------------------------- /Layers/setup.m: -------------------------------------------------------------------------------- 1 | function setup() 2 | addpath(genpath('../.')); 3 | addpath(genpath('../../common/')) 4 | end -------------------------------------------------------------------------------- /Layers/sigmoid.m: -------------------------------------------------------------------------------- 1 | function y = sigmoid(x) 2 | y = 1 ./ (1 + exp(-x)); 3 | end -------------------------------------------------------------------------------- /Layers/sigmoidPrime.m: -------------------------------------------------------------------------------- 1 | function y = sigmoidPrime(x) 2 | y = x .* ( 1 - x); 3 | end -------------------------------------------------------------------------------- /Layers/tanhPrime.m: -------------------------------------------------------------------------------- 1 | function [result] = tanhPrime(z) 2 | result = (1-z.^2); 3 | -------------------------------------------------------------------------------- /Layers/test_components.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | close all; 4 | % dbstop if error 5 | setup 6 | useGPU = false; 7 | dataType = 'single'; 8 | backward = true; 9 | tic; 10 | output1 = InputLayer(struct('batchSize',16,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 11 | output2 = EmbeddingLayer(struct('hidden_dim',1024,'input_dim',output1.vocabSize,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 12 | output3 = LstmLayer(struct('hidden_dim',1024,'input_dim',1024,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 13 | output4 = RecurrentLayer(struct('hidden_dim',1024,'input_dim',1024,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 14 | output5 = SoftmaxLayer(struct('hidden_dim',output1.vocabSize,'input_dim',1024,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 15 | % output4 = RecurrentLayer(struct('hidden_dim',4096,'input_dim',4096,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 16 | % output5 = RecurrentLayer(struct('hidden_dim',4096,'input_dim',4096,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 17 | % output6= RecurrentLayer(struct('hidden_dim',4096,'input_dim',4096,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 18 | toc; 19 | 20 | tic; 21 | output5.fprop(output4.fprop(output3.fprop(output2.fprop(output1.fprop())))); 22 | toc; 23 | 24 | target = cell(size(output1.output)); 25 | for i = 1 : size(target,2) 26 | target{1,i} = randi(output1.vocabSize,1,size(output1.output{1,i},2)); 27 | target{2,i} = output1.output{2,i}; 28 | end 29 | 30 | output5.getCost(target); -------------------------------------------------------------------------------- /Layers/test_gradient_components.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | close all; 4 | dbstop if error 5 | 6 | %% check the gradient of RecurrentLayer 7 | display('check the gradient of RecurrentLayer') 8 | input_dim = 8; 9 | hidden_dim = 5; 10 | option = struct('hidden_dim',hidden_dim,'input_dim',input_dim,'useGPU',false,'dataType','double','backward',true); 11 | check = RecurrentLayer(option); 12 | check.checkGrad(); 13 | 14 | %% check the gradient of LstmLayer 15 | display('check the gradient of LstmLayer') 16 | input_dim = 8; 17 | hidden_dim = 5; 18 | option = struct('hidden_dim',hidden_dim,'input_dim',input_dim,'useGPU',false,'dataType','double','backward',true); 19 | check = LstmLayer(option); 20 | check.checkGrad(); 21 | 22 | %% check the gradient of SoftmaxLayer 23 | display('check the gradient of SoftmaxLayer') 24 | input_dim = 8; 25 | hidden_dim = 5; 26 | option = struct('hidden_dim',hidden_dim,'input_dim',input_dim,'useGPU',false,'dataType','double','backward',true); 27 | check = SoftmaxLayer(option); 28 | check.checkGrad(); -------------------------------------------------------------------------------- /Models/encoder_decoder.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JianboTang/RNN_MATLAB/e8ba401c9a40f27f8db3e37a355c19c98357de79/Models/encoder_decoder.mat -------------------------------------------------------------------------------- /Models/setup.m: -------------------------------------------------------------------------------- 1 | function setup() 2 | addpath(genpath('../.')); 3 | % addpath(genpath('../../common/')) 4 | end -------------------------------------------------------------------------------- /Models/test_LSTM_autoencode.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | close all; 4 | setup; 5 | dbstop if error 6 | %% LSTM autoencoder 7 | 8 | % layers definition 9 | useGPU = true; 10 | dataType = 'single'; 11 | backward = true; 12 | debug = true; 13 | 14 | input = InputLayer(struct('batchSize',5,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug)); 15 | embedd1 = EmbeddingLayer(struct('hidden_dim',512,'input_dim',input.vocabSize,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug)); 16 | rec1 = LstmLayer(struct('hidden_dim',512,'input_dim',512,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug)); 17 | rec2 = LstmLayer(struct('hidden_dim',512,'input_dim',512,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug)); 18 | loss = SoftmaxLayer(struct('hidden_dim',input.vocabSize,'input_dim',512,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug)); 19 | 20 | % train 21 | MaxIter = 10000; 22 | history_cost = zeros(1,MaxIter); 23 | for i = 1 : MaxIter 24 | tic; 25 | target = input.fprop(struct('reverse',false,'fprop',true)); 26 | loss.fprop(rec2.fprop(rec1.fprop(embedd1.fprop(target,size(target,2)),size(target,2)),size(target,2)),size(target,2)); 27 | history_cost(1,i) = gather(loss.getCost(target)); 28 | display(['cost of this ',num2str(i),'th iteration is ',num2str(history_cost(1,i))]); 29 | 30 | embedd1.bprop(rec1.bprop(rec2.bprop(loss.bprop(target)))); 31 | loss.update(@SGD); 32 | rec2.update(@SGD); 33 | rec1.update(@SGD); 34 | embedd1.update(@SGD); 35 | toc; 36 | end -------------------------------------------------------------------------------- /Models/test_RNN_autoencode.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | close all; 4 | setup; 5 | dbstop if error 6 | %% RNN autoencoder 7 | 8 | % layers definition 9 | useGPU = true; 10 | dataType = 'single'; 11 | backward = true; 12 | 13 | input = InputLayer(struct('batchSize',5,'useGPU',useGPU,'dataType',dataType,'backward',backward,'reverse',true)); 14 | embedd1 = EmbeddingLayer(struct('hidden_dim',512,'input_dim',input.vocabSize,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 15 | rec1 = RecurrentLayer(struct('hidden_dim',512,'input_dim',512,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 16 | rec2 = RecurrentLayer(struct('hidden_dim',512,'input_dim',512,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 17 | loss = SoftmaxLayer(struct('hidden_dim',input.vocabSize,'input_dim',512,'useGPU',useGPU,'dataType',dataType,'backward',backward)); 18 | 19 | % train 20 | MaxIter = 10000; 21 | history_cost = zeros(1,MaxIter); 22 | for i = 1 : MaxIter 23 | tic; 24 | target = input.fprop(struct('reverse',false,'fprop',true)); 25 | loss.fprop(rec2.fprop(rec1.fprop(embedd1.fprop(target,size(target,2)),size(target,2)),size(target,2)),size(target,2)); 26 | history_cost(1,i) = gather(loss.getCost(target)); 27 | display(history_cost(1,i)); 28 | 29 | embedd1.bprop(rec1.bprop(rec2.bprop(loss.bprop(target)))); 30 | loss.update(@SGD); 31 | rec2.update(@SGD); 32 | rec1.update(@SGD); 33 | embedd1.update(@SGD); 34 | toc; 35 | end -------------------------------------------------------------------------------- /Models/test_encoder_decoder.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | close all; 4 | % dbstop if error; 5 | addpath(genpath('../../toolbox')); 6 | %% setting definition 7 | 8 | gpuDevice(3) 9 | 10 | useGPU = true; 11 | dataType = 'single'; 12 | backward = true; 13 | debug = false; 14 | batchSize = 1; 15 | beamSearch = 10; 16 | permute = false; 17 | convert = Data(struct('useGPU',useGPU,'dataType',dataType)); 18 | 19 | %% layer definition 20 | post = InputLayer(struct('batchSize',batchSize,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug,'permute',permute)); 21 | post.getFile('../data/used/post_index.txt','../data/used/dictionary.txt'); 22 | 23 | cmnt = InputLayer(struct('batchSize',batchSize,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug,'permute',permute)); 24 | cmnt.getFile('../data/used/cmnt_index.txt','../data/used/dictionary.txt'); 25 | 26 | embedd1 = EmbeddingLayer(struct('hidden_dim',620,'input_dim',post.vocabSize,'useGPU',useGPU,'dataType',dataType, ... 27 | 'backward',backward,'debug',debug)); 28 | encoder = LstmLayer(struct('hidden_dim',500,'input_dim',620,'useGPU',useGPU,'dataType',dataType, ... 29 | 'backward',backward,'debug',debug)); 30 | decoder = LstmLayer(struct('hidden_dim',500,'input_dim',620,'useGPU',useGPU,'dataType',dataType, ... 31 | 'backward',backward,'debug',debug)); 32 | loss = SoftmaxLayer(struct('hidden_dim',post.vocabSize,'input_dim',500,'useGPU',useGPU,'dataType',dataType, ... 33 | 'backward',backward,'debug',debug)); 34 | 35 | if exist('encoder_decoder.mat','file') 36 | load('encoder_decoder.mat'); 37 | embedd1.loadObj(layers{1,1}); 38 | encoder.loadObj(layers{1,2}); 39 | decoder.loadObj(layers{1,3}); 40 | loss.loadObj(layers{1,4}); 41 | end 42 | %% test 43 | MaxIter = size(post.txt.data,1); 44 | history_cost = zeros(1,MaxIter); 45 | context = cell([1,1]); 46 | 47 | front_add = cell([1,1]); 48 | front_add{1,1} = convert.dataConvert(3 * ones(1,beamSearch)); 49 | trans_file = fopen('trans.txt','w+'); 50 | 51 | convert.setDataSize([encoder.hidden_dim,batchSize]); 52 | convert.setZeros(); 53 | 54 | layers = cell(1); 55 | 56 | for i = 1 : MaxIter 57 | tic; 58 | %% forward 59 | % encode 60 | input = post.fprop(struct('reverse',true)); 61 | display(['encode input start : ',num2str(post.used_index(1,1)),' end : ',num2str(post.used_index(1,end))]); 62 | embedd1.fprop(input,size(input,2)); 63 | encoder.fprop(embedd1.output,size(input,2)); 64 | 65 | % decode 66 | previous_index = cell(1); 67 | previous_index{1,1} = zeros(1,beamSearch); 68 | current_index = cell(1); 69 | current_index{1,1} = 3 * ones(1,beamSearch); 70 | sum_prob = cell(1); 71 | sum_prob{1,1} = zeros(1,beamSearch); 72 | 73 | decoder.init_output{1,1} = repmat(encoder.output{1,size(input,2)},[1,beamSearch]); 74 | decoder.init_state{1,1} = repmat(encoder.states{1,size(input,2)},[1,beamSearch]); 75 | temp_step = front_add; 76 | for j = 1 : 40 %2 * size(input,2) 77 | if j == 1 78 | temp_step = embedd1.fprop_step(temp_step,j); 79 | temp_step = decoder.fprop_step(temp_step,j); 80 | temp_step = loss.fprop_step(temp_step,j); 81 | total_prob = bsxfun(@plus,gather(temp_step{1,1}),sum_prob{1,end}); 82 | [max_value,max_pos] = sort(total_prob(:)); 83 | sum_prob{1,end + 1} = (max_value(end - beamSearch * beamSearch + 1 : beamSearch : end,1))'; 84 | previous_index{1,end + 1} = (floor((max_pos(end - beamSearch * beamSearch + 1 : beamSearch : end) - 1) / size(total_prob,1)) + 1)'; 85 | current_index{1,end + 1} = (mod(max_pos(end - beamSearch * beamSearch + 1 : beamSearch : end) - 1,size(total_prob,1)) + 1)'; 86 | temp_step{1,1} = convert.dataConvert(current_index{1,end}); 87 | else 88 | temp_step = embedd1.fprop_step(temp_step,j); 89 | temp_step = decoder.fprop_step(temp_step,j); 90 | temp_step = loss.fprop_step(temp_step,j); 91 | total_prob = bsxfun(@plus,gather(temp_step{1,1}),sum_prob{1,end}); 92 | [max_value,max_pos] = sort(total_prob(:)); 93 | sum_prob{1,end + 1} = (max_value(end - beamSearch + 1 : end,1))'; 94 | previous_index{1,end + 1} = (floor((max_pos(end - beamSearch + 1 : end) - 1) / size(total_prob,1)) + 1)'; 95 | current_index{1,end + 1} = (mod(max_pos(end - beamSearch + 1 : end) - 1,size(total_prob,1)) + 1)'; 96 | temp_step{1,1} = convert.dataConvert(current_index{1,end}); 97 | end 98 | end_mark = current_index{1,end}; 99 | %if sum(end_mark == 1,1) >= 0.5 * size(end_mark,2) 100 | % break; 101 | %end 102 | end 103 | trans = zeros(beamSearch,size(sum_prob,2)); 104 | temp = sum_prob{1,j} .* (end_mark == 1); 105 | [~,candidate_index] = sort(temp); 106 | for m = 1 : size(candidate_index,2) 107 | index = candidate_index(1,m); 108 | trans(m,end) = current_index{1,end}(1,index); 109 | for j = size(sum_prob,2) - 1 : -1 : 1 110 | trans(m,j) = current_index{1,j}(previous_index{1,j + 1}(index)); 111 | index = previous_index{1,j}(previous_index{1,j + 1}(index)); 112 | end 113 | display(['index ',num2str(m),'th candidate']); 114 | display((post.vocab(trans(m,:)))'); 115 | for j = 1 : size(trans,2) 116 | fprintf(trans_file,post.vocab{trans(m,j)}); 117 | end 118 | fprintf(trans_file,' | '); 119 | end 120 | fprintf(trans_file,'\n'); 121 | toc; 122 | end 123 | -------------------------------------------------------------------------------- /Models/test_video_seq_classification.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | close all; 4 | setup; 5 | addpath(genpath('./')) 6 | % dbstop if error 7 | load video_sample 8 | %% data Convert 9 | useGPU = false; 10 | dataType = 'single'; 11 | backward = true; 12 | % debug = false; 13 | 14 | option = struct('useGPU',useGPU,'dataType',dataType); 15 | convert = Data(option); 16 | 17 | temp = traindata{1,1}; 18 | temp_label = trainlabel{1,1}; 19 | TrainData = cell([1,size(temp,2)]); 20 | TrainLabel = cell([1,size(temp_label,2)]); 21 | for i = 1 : size(temp,2) 22 | % ????? 23 | TrainData{1,i} = convert.dataConvert(temp(:,i)); 24 | end 25 | TrainLabel{1,1} = convert.dataConvert(trainlabel{1,1}); 26 | 27 | %% ??? 28 | rec1 = LstmLayer(struct('hidden_dim',300,'input_dim',600,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug)); 29 | rec2 = LstmLayer(struct('hidden_dim',50,'input_dim',300,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug)); 30 | loss = SoftmaxLayer(struct('hidden_dim',7,'input_dim',50,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug)); 31 | 32 | MaxIter = 10000; 33 | history_cost = zeros(1,MaxIter); 34 | lstm_output = cell([1,1]); 35 | for i = 1 : MaxIter 36 | tic; 37 | % ???? 38 | rec1.fprop(TrainData,size(TrainData,2)); 39 | rec2.fprop(rec1.output,size(TrainData,2)); 40 | lstm_output{1,1} = rec2.output{1,size(TrainData,2)}; 41 | loss.fprop(lstm_output,size(lstm_output,2)); 42 | history_cost(1,i) = gather(loss.getCost(TrainLabel)); 43 | display(' == == == == == == == == == == == == == == == '); 44 | display(['iteration : ',num2str(i)]); 45 | display(['cost : ',num2str(history_cost(1,i))]); 46 | loss.bprop(TrainLabel);%???? 47 | grad_output = cell([1,size(TrainData,2)]); 48 | convert.setDataSize(size(loss.grad_input{1,1})) 49 | convert.setZeros(); 50 | for j = 1 : size(TrainData,2) 51 | grad_output{1,j} = convert.context; 52 | end 53 | grad_output{1,size(TrainData,2)} = loss.grad_input{1,1}; 54 | rec1.bprop(rec2.bprop(grad_output)); 55 | loss.update(@SGD); 56 | rec2.update(@SGD); 57 | rec1.update(@SGD); 58 | toc; 59 | end 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Models/train_encoder_decoder.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | close all; 4 | dbstop if error; 5 | setup; 6 | %% setting definition 7 | 8 | gpuDevice(1); 9 | 10 | useGPU = true; 11 | dataType = 'single'; 12 | backward = true; 13 | debug = false; 14 | batchSize = 100; 15 | permute = true; 16 | convert = Data(struct('useGPU',useGPU,'dataType',dataType)); 17 | 18 | %% layer definition 19 | post = InputLayer(struct('batchSize',batchSize,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug,'permute',permute)); 20 | post.getFile('../Data/used/post_index.txt','../Data/used/dictionary.txt'); 21 | 22 | cmnt = InputLayer(struct('batchSize',batchSize,'useGPU',useGPU,'dataType',dataType,'backward',backward,'debug',debug,'permute',permute)); 23 | cmnt.getFile('../Data/used/cmnt_index.txt','../Data/used/dictionary.txt'); 24 | 25 | embedd1 = EmbeddingLayer(struct('hidden_dim',620,'input_dim',post.vocabSize,'useGPU',useGPU,'dataType',dataType, ... 26 | 'backward',backward,'debug',debug)); 27 | encoder = LstmLayer(struct('hidden_dim',500,'input_dim',620,'useGPU',useGPU,'dataType',dataType, ... 28 | 'backward',backward,'debug',debug)); 29 | decoder = LstmLayer(struct('hidden_dim',500,'input_dim',620,'useGPU',useGPU,'dataType',dataType, ... 30 | 'backward',backward,'debug',debug)); 31 | loss = SoftmaxLayer(struct('hidden_dim',post.vocabSize,'input_dim',500,'useGPU',useGPU,'dataType',dataType, ... 32 | 'backward',backward,'debug',debug)); 33 | 34 | %% load parameter 35 | if exist('encoder_decoder.mat','file') 36 | load('encoder_decoder.mat'); 37 | embedd1.loadObj(layers{1,1}); 38 | encoder.loadObj(layers{1,2}); 39 | decoder.loadObj(layers{1,3}); 40 | loss.loadObj(layers{1,4}); 41 | end 42 | 43 | %% train 44 | MaxIter = 100000; 45 | history_cost = zeros(1,MaxIter,dataType); 46 | history_accuracy = zeros(1,MaxIter,dataType); 47 | context = cell([1,1]); 48 | 49 | front_add = cell([1,1]); 50 | front_add{1,1} = convert.dataConvert(3 * ones(1,batchSize)); 51 | backe_add = cell([1,1]); 52 | encode_grad_output = cell(1); 53 | convert.setDataSize([encoder.hidden_dim,batchSize]); 54 | convert.setZeros(); 55 | layers = cell(1); 56 | for i = 1 : MaxIter 57 | tic; 58 | %% forward 59 | temp = post.base_point + post.batchSize; 60 | if (temp > size(post.txt.data,1)) || isempty(post.permutation) 61 | post.permutation = randperm(size(post.txt.data,1)); 62 | cmnt.permutation = post.permutation; 63 | end 64 | % encode 65 | display(' == == == == == == train == == == == == == '); 66 | input = post.fprop(struct('reverse',true)); 67 | display(['encode input start : ',num2str(post.used_index(1,1)),' end : ',num2str(post.used_index(1,end))]); 68 | display(['the length of encode input : ',num2str(size(input,2))]); 69 | embedd1.fprop(input,size(input,2)); 70 | encoder.fprop(embedd1.output,size(input,2)); 71 | display(['the length of encode output : ',num2str(size(encoder.output,2))]); 72 | 73 | % decode 74 | decoder.init_output{1,1} = encoder.output{1,size(input,2)}; 75 | decoder.init_state{1,1} = encoder.states{1,size(input,2)}; 76 | decode_raw = cmnt.fprop(); 77 | display(['decode input start : ',num2str(cmnt.used_index(1,1)),' end : ',num2str(cmnt.used_index(1,end))]); 78 | display(['the length of decode input : ',num2str(size(decode_raw,2) + 1)]); 79 | for j = 2 : size(decode_raw,2) + 1 80 | front_add{1,j} = decode_raw{1,j - 1}; 81 | end 82 | for j = 1 : size(decode_raw,2) 83 | backe_add{1,j} = decode_raw{1,j}; 84 | end 85 | backe_add{1,size(decode_raw,2) + 1} = convert.dataConvert(ones([1,batchSize])); 86 | embedd1.fprop(front_add,size(front_add,2)); 87 | decoder.fprop(embedd1.output,size(front_add,2)); 88 | loss.fprop(decoder.output,size(front_add,2)); 89 | display(['the length of decode output : ',num2str(size(loss.output,2))]); 90 | history_cost(1,i) = gather(loss.getCost(backe_add)); 91 | if useGPU 92 | history_accuracy(1,i) = gather(loss.getAccuracy(backe_add)); 93 | else 94 | history_accuracy(1,i) = loss.getAccuracy(backe_add); 95 | end 96 | % show cost 97 | display(['iteration : ',num2str(i)]); 98 | display(['cost : ',num2str(history_cost(1,i))]); 99 | display(['accuracy : ',num2str(history_accuracy(1,i))]); 100 | 101 | %% backward 102 | % decode 103 | loss.bprop(backe_add); 104 | decoder.bprop(loss.grad_input); 105 | for j = 1 : size(input,2) 106 | encode_grad_output{1,j} = convert.context; 107 | end 108 | encode_grad_output{1,size(input,2)} = decoder.grad_init_output{1,1}; 109 | encoder.grad_output_state{1,1} = decoder.grad_init_state{1,1}; 110 | 111 | encoder.bprop(encode_grad_output); 112 | embedd1.bprop(encoder.grad_input,size(encoder.grad_input,2)); 113 | embedd1.bprop(decoder.grad_input,size(decoder.grad_input,2)); 114 | embedd1.update(@SGD); 115 | encoder.update(@SGD); 116 | decoder.update(@SGD); 117 | loss.update(@SGD); 118 | toc; 119 | 120 | %% save parameter 121 | if mod(i,100) == 1 122 | display(' ## ## ## ## ## ## ## ## '); 123 | layers{1,1} = embedd1.saveObj(); 124 | layers{2,1} = 'EmbeddingLayer'; 125 | layers{1,2} = encoder.saveObj(); 126 | layers{2,2} = 'LstmLayer'; 127 | layers{1,3} = decoder.saveObj(); 128 | layers{2,3} = 'LstmLayer'; 129 | layers{1,4} = loss.saveObj(); 130 | layers{2,4} = 'SoftmaxLayer'; 131 | save('encoder_decoder.mat','layers'); 132 | display(' ## ## ## ## ## ## ## ## '); 133 | end 134 | end 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /Models/video_sample.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JianboTang/RNN_MATLAB/e8ba401c9a40f27f8db3e37a355c19c98357de79/Models/video_sample.mat -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RNN_MATLAB 2 | this is a new implemention of stacked RNNs autoencoder based on matlab, object-oriented.it's more flexible than the old version. 3 | Feel free to email me, if you encounter any problems,and my email is tangyao3669508@qq.com. enjoy yourself! 4 | all rights reserved. 5 | --------------------------------------------------------------------------------