{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Важные и не очень интуитивные моменты про LSTM и CNN в торче\n\nПо умолчанию LSTM принимает данные с такой размерностью:\n```python\n(seq_len, batch, input_size)\n```\nСделано это с целью оптимизации на более низком уровне.  \nМы оперируем такими объектами:\n```python\n(batch, seq_len, input_size)\n```\nЧтобы LSTM у нас заработала правильно, мы можем либо передать параметр ```batch_first=True``` во время инициализации слоя,\nлибо транспонировать (поменять) первую и вторую размерность у нашего x перед подачей в слой.  \n[Подробнее про LSTM](https://pytorch.org/docs/stable/nn.html#lstm)\n\n- 128 - размер батча\n- 64 - количество слов\n- 1024 - эмбеддинг слова"},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = torch.rand(128, 64, 1024)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# первый способ\nlstm = torch.nn.LSTM(1024, 512, batch_first=True)\n\npred, mem = lstm(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# эмбеддинг последнего слова\n# обратите внимание, что в случае с bidirectional моделью размер эмбеддинга после LSTM будет не 512, а 1024\n# то есть конкатенация прохода LSTM слева направо и наоборот\n# это будут две разные LSTM\npred[:, -1, :].shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# второй способ использования LSTM\nlstm = torch.nn.LSTM(1024, 512)\n\n# меняем размерность batch и seq_len местами\nx_transposed = x.transpose(0, 1)\npred_transposed, mem = lstm(x_transposed)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# у нас все еще осталась размерность (seq_len, batch, input_size)\npred_transposed.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# просто транспонируем еще раз\npred = pred_transposed.transpose(0, 1)\npred.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Conv1d & MaxPool1d\nПримерно такая же ситуация происходит со сверточными слоями и пулингами.  \n1d реализация как раз для текстов, в ней матрица-фильтр ходит только по одной размерности.  \n[Подробнее про CNN](https://pytorch.org/docs/stable/nn.html#conv1d)  \n[Подробнее про пулинг](https://pytorch.org/docs/stable/nn.html#maxpool1d)  \nОжидается такая размерность:\n```python\n(batch, input_size, seq_len)\n```\nМы все еще хоти подавать такую размерность:\n```python\n(batch, seq_len, input_size)\n```\nВ случае со свертками и пулингами у нас есть вариант только транспонировать x перед подачей и транспонировать полученный результат. Обратите внимание, что транспонируем мы первую и вторую размерность (индексация с нуля)."},{"metadata":{"trusted":true},"cell_type":"code","source":"x.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"- 128 - размер батча\n- 64 - количество слов\n- 1024 - эмбеддинг слова"},{"metadata":{"trusted":true},"cell_type":"code","source":"# in_channels - размер входных эмбеддингов\n# out_channels - количество/какой размер эмбеддингов мы хотим получить\n# kernel_size - размер окна/н-граммы\ncnn = torch.nn.Conv1d(in_channels=1024, out_channels=512, kernel_size=3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# выпадет ошибка, посмотрите какая\n# pred = cnn(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_transposed = x.transpose(1, 2)\nx_transposed.shape\n# перевели в (batch, input_size, seq_len)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_transposed = cnn(x_transposed)\npred_transposed.shape\n# осталась размерность (batch, output_size, seq_len)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# переведем обратно в (batch, seq_len, input_size)\npred = pred_transposed.transpose(1, 2)\npred.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Еще важный момент про LSTM\n\nThe input can also be a packed variable length sequence. See [torch.nn.utils.rnn.pack_padded_sequence()](https://pytorch.org/docs/stable/nn.html#torch.nn.utils.rnn.pack_padded_sequence) or [torch.nn.utils.rnn.pack_sequence()](https://pytorch.org/docs/stable/nn.html#torch.nn.utils.rnn.pack_sequence) for details.\n\nЭто внутренняя конструкция торча, которая позволяет не читать токен ```PAD```, но все еще работать с батчами. То есть внутри батча мы можем передать лстмке, что у нас данные переменной длины. Не забудьте что на выход отдается [torch.nn.utils.rnn.PackedSequence](https://pytorch.org/docs/stable/nn.html#torch.nn.utils.rnn.PackedSequence)."},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","collapsed":true,"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":false},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}