From 71582494d5f3bbf31cac4006d79da2279f7d2a10 Mon Sep 17 00:00:00 2001 From: teddylee777 Date: Sun, 13 Sep 2020 12:47:52 +0900 Subject: [PATCH] update tf2 tutorial files --- 04-TensorFlow2.0/09-LSTM/LSTM Layer.ipynb | 781 ++++++++++++++++++++++ CAM.ipynb => 08-XAI/CAM.ipynb | 0 2 files changed, 781 insertions(+) create mode 100644 04-TensorFlow2.0/09-LSTM/LSTM Layer.ipynb rename CAM.ipynb => 08-XAI/CAM.ipynb (100%) diff --git a/04-TensorFlow2.0/09-LSTM/LSTM Layer.ipynb b/04-TensorFlow2.0/09-LSTM/LSTM Layer.ipynb new file mode 100644 index 0000000..3fe928f --- /dev/null +++ b/04-TensorFlow2.0/09-LSTM/LSTM Layer.ipynb @@ -0,0 +1,781 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## LSTM Layer 파헤치기" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Sequence 혹은 Time Series (시계열) 데이터**를 다룰 때, `LSTM` layer를 어떻게 활용하여 접근하면 되는지 이해하기 위한 튜토리얼 코드입니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "필요한 모듈을 import 합니다." + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "metadata": {}, + "outputs": [], + "source": [ + "import tensorflow as tf\n", + "\n", + "from tensorflow.keras.layers import Dense, Conv1D, LSTM, Input, TimeDistributed\n", + "from tensorflow.keras.models import Model" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 0. Hyper Parameter 설명\n", + "\n", + "출처: keras.io\n", + "\n", + "- `units`: 양의 정수, 아웃풋 공간의 차원입니다.\n", + "- `activation`: 사용할 활성화 함수 (활성화를 참조하십시오). 디폴트: 쌍곡 탄젠트 (tanh). None을 전달하는 경우, 활성화가 적용되지 않습니다 (다시 말해, \"선형적\" 활성화: a(x) = x).\n", + "- `recurrent_activation`: 순환 단계에 사용할 활성화 함수 (활성화를 참조하십시오). 디폴트 값: 하드 시그모이드 (hard_sigmoid). None을 전달하는 경우, 활성화가 적용되지 않습니다 (다시 말해, \"선형적\" 활성화: a(x) = x).\n", + "- `use_bias`: 불리언, 레이어가 편향 벡터를 사용하는지 여부.\n", + "- `kernel_initializer`: kernel 가중치 행렬의 초기값 설정기. 인풋의 선형적 변형에 사용됩니다 ( 초기값 설정기를 참조하십시오).\n", + "- `recurrent_initializer`: recurrent_kernel 가중치 행렬의 초기값 설정기. 순환 상태의 선형적 변형에 사용됩니다 ( 초기값 설정기를 참조하십시오).\n", + "- `bias_initializer`: 편향 벡터의 초기값 설정기 ( 초기값 설정기를 참조하십시오).\n", + "- `unit_forget_bias`: 불리언. 참일 경우, 초기값 설정 시 망각 회로에 1을 더합니다. 참으로 설정 시 강제적으로 bias_initializer=\"zeros\"가 됩니다. 이는 [Jozefowicz et al. (2015)] 에서 권장됩니다. (http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf).\n", + "- `kernel_regularizer`: kernel 가중치 행렬에 적용되는 정규화 함수 (정규화를 참조하십시오).\n", + "- `recurrent_regularizer`: recurrent_kernel 가중치 행렬에 적용되는 정규화 함수 (정규화를 참조하십시오).\n", + "- `bias_regularizer`: 편향 벡터에 적용되는 정규화 함수 (정규화를 참조하십시오).\n", + "- `activity_regularizer`: 레이어의 아웃풋(레이어의 “활성화”)에 적용되는 정규화 함수 (정규화를 참조하십시오).\n", + "- `kernel_constraint`: kernel 가중치 행렬에 적용되는 제약 함수 (제약을 참조하십시오).\n", + "- `recurrent_constraint`: recurrent_kernel 가중치 행렬에 적용되는 제약 함수 (제약을 참조하십시오).\n", + "- `bias_constraint`: 편향 벡터에 적용하는 제약 함수 (제약을 참조하십시오).\n", + "- `dropout`: 0과 1사이 부동소수점. 인풋의 선형적 변형을 실행하는데 드롭시킬(고려하지 않을) 유닛의 비율.\n", + "- `recurrent_dropout`: 0과 1사이 부동소수점. 순환 상태의 선형적 변형을 실행하는데 드롭시킬(고려하지 않을) 유닛의 비율.\n", + "- `implementation`: 실행 모드, 1 혹은 2. 모드 1은 비교적 많은 수의 소규모의 점곱과 덧셈을 이용해 연산을 구성하는데 반해, 모드 2는 이를 소수의 대규모 연산으로 묶습니다. 이 두 모드는, 하드웨어나 어플리케이션에 따라서 성능의 차이를 보입니다.\n", + "- `return_sequences`: 불리언. 아웃풋 시퀀스의 마지막 아웃풋을 반환할지, 혹은 시퀀스 전체를 반환할지 여부.\n", + "- `return_state`: 불리언. 아웃풋에 더해 마지막 상태도 반환할지 여부. 상태 리스트의 반환된 성분은 각각 은닉 성분과 셀 상태입니다.\n", + "- `go_backwards`: 불리언 (디폴트 값은 거짓). 참인 경우, 인풋 시퀀스를 거꾸로 처리하여 뒤집힌 시퀀스를 반환합니다.\n", + "- `stateful`: 불리언 (디폴트 값은 거짓). 참인 경우, 배치 내 색인 i의 각 샘플의 마지막 상태가 다음 배치의 색인 i 샘플의 초기 상태로 사용됩니다.\n", + "- `unroll`: 불리언 (디폴트 값은 거짓). 참인 경우, 신경망을 펼쳐서 사용하고 그렇지 않은 경우 심볼릭 루프가 사용됩니다. 신경망을 펼쳐 순환 신경망의 속도를 높일 수 있지만, 메모리 소모가 큰 경향이 있습니다. 신경망 펼치기는 짧은 시퀀스에만 적합합니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. LSTM Layer와 input_shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "주요 hyper parameter는 다음과 같습니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- `batch`: 32\n", + "- `time_step`: 3\n", + "- `window_size`: 25" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### sample data 생성" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "아래와 같이 샘플 데이터를 생성합니다." + ] + }, + { + "cell_type": "code", + "execution_count": 150, + "metadata": {}, + "outputs": [], + "source": [ + "x = tf.random.uniform(shape=(32, 25, 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 151, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 25, 1])" + ] + }, + "execution_count": 151, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "32는 `batch`의 크기, 25는 `time_step`의 크기, 1은 `feature`의 갯수를 나타냅니다.\n", + "\n", + "여기서 batch는 얼마만큼 `batch`로 묶어 주느냐에 따라 달라지는 hyper parameter이므로 크게 걱정할 이유가 없습니다.\n", + "\n", + "25는 `window_size`를 나타내며, 일자로 예를 들자면, 25일치의 `time_step`을 input으로 공급하겠다는 겁니다.\n", + "\n", + "1은 `feature_size`이며, 주가 데이터를 예로 들자면, **종가** 데이터 한 개만 본다면 1로 설정합니다.\n", + "\n", + "만약에, [종가, 시가, 고가] 3가지 feature를 모두 본다면, 3이 될 것 입니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1-1. return_sequences=False 인 경우" + ] + }, + { + "cell_type": "code", + "execution_count": 152, + "metadata": {}, + "outputs": [], + "source": [ + "lstm = LSTM(20)" + ] + }, + { + "cell_type": "code", + "execution_count": 153, + "metadata": {}, + "outputs": [], + "source": [ + "output_a = lstm(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 154, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 154, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "output_a[:5]" + ] + }, + { + "cell_type": "code", + "execution_count": 155, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 20])" + ] + }, + "execution_count": 155, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "output_a.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**결과 해석**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1. `output_a`의 shape이 `(32, 20)`으로 출력됌을 확인할 수 있습니다.\n", + "2. shape가 (32, 20)의 32는 `batch`의 갯수, 20은 LSTM에서 지정한 unit 수입니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1-2. return_sequences=True 인 경우" + ] + }, + { + "cell_type": "code", + "execution_count": 156, + "metadata": {}, + "outputs": [], + "source": [ + "lstm = LSTM(20, return_sequences=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 157, + "metadata": {}, + "outputs": [], + "source": [ + "output_b = lstm(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 158, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 158, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "output_b[:5]" + ] + }, + { + "cell_type": "code", + "execution_count": 159, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 25, 20])" + ] + }, + "execution_count": 159, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "output_b.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**결과 해석**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "1. `output_b`의 shape이 `(32, 25, 20)`으로 출력됌을 확인할 수 있습니다.\n", + "2. shape가 (32, 25, 20)의 32는 `batch`의 갯수, (25, 20)은 LSTM에서 지정한 unit 수입니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. LSTM layer의 결과 값을 Dense로 넘겨줄 경우" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "아래와 같이 `output_a`는 return_sequence=False 에 대한 결과 값이며, \n", + "\n", + "`output_b`는 return_sequences=True 에 대한 결과 값입니다." + ] + }, + { + "cell_type": "code", + "execution_count": 160, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(TensorShape([32, 20]), TensorShape([32, 25, 20]))" + ] + }, + "execution_count": 160, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "output_a.shape, output_b.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**shape가 다름**을 확인할 수 있습니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2-1. return_sequence=False 를 Dense에 넘겨줄 경우" + ] + }, + { + "cell_type": "code", + "execution_count": 162, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 20])" + ] + }, + "execution_count": 162, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "output_a.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 163, + "metadata": {}, + "outputs": [], + "source": [ + "dense = Dense(10)" + ] + }, + { + "cell_type": "code", + "execution_count": 165, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 10])" + ] + }, + "execution_count": 165, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dense(output_a).shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "위의 결과에서도 나타나듯이, LSTM으로부터 **넘겨 받은 20개의 unit**이 **Dense를 거쳐 10**개로 변환됩니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2-2. return_sequence=True 를 Dense에 넘겨줄 경우" + ] + }, + { + "cell_type": "code", + "execution_count": 166, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 25, 20])" + ] + }, + "execution_count": 166, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "output_b.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 167, + "metadata": {}, + "outputs": [], + "source": [ + "dense = Dense(10)" + ] + }, + { + "cell_type": "code", + "execution_count": 168, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 25, 10])" + ] + }, + "execution_count": 168, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dense(output_b).shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "이번에도 마찬가지로, LSTM으로부터 **넘겨 받은 20개의 unit**이 **Dense를 거쳐 10**개로 변환됩니다.\n", + "\n", + "단, shape는 이전 케이스와는 다르게 모든 sequence에 대한 유닛 20개를 10개로 변환된 것을 확인할 수 있습니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2-3. TimeDistributed layer 활용 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "TimeDistributed layer는 `return_sequences=True` 인 경우, sequence로 받은 데이터에 대하여 처리할 수 있지만, 사실상 Dense를 써주면 동작은 동일하게 나타납니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "유의해야할 점은, `return_sequences=False`로 받은 값은 **2차원이기 때문에 TimeDistributed에 넘겨줄 수 없습니다.**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Dense를 사용한 경우**" + ] + }, + { + "cell_type": "code", + "execution_count": 180, + "metadata": {}, + "outputs": [], + "source": [ + "dense = Dense(10)" + ] + }, + { + "cell_type": "code", + "execution_count": 181, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 25, 10])" + ] + }, + "execution_count": 181, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dense(output_b).shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**TimeDistributed를 사용한 경우**" + ] + }, + { + "cell_type": "code", + "execution_count": 182, + "metadata": {}, + "outputs": [], + "source": [ + "time = TimeDistributed(Dense(10))" + ] + }, + { + "cell_type": "code", + "execution_count": 183, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 25, 10])" + ] + }, + "execution_count": 183, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "time(output_b).shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3. cell state와 hidden layer" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "LSTM layer에서 결과 값에 대한 **hidden layer 값**과, **cell state**를 받아볼 수 있습니다." + ] + }, + { + "cell_type": "code", + "execution_count": 205, + "metadata": {}, + "outputs": [], + "source": [ + "lstm = LSTM(20, return_sequences=True, return_state=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 208, + "metadata": {}, + "outputs": [], + "source": [ + "output_c, _hidden, _state = lstm(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 211, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 25, 20])" + ] + }, + "execution_count": 211, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "output_c.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 212, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 20])" + ] + }, + "execution_count": 212, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "_hidden.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 213, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "TensorShape([32, 20])" + ] + }, + "execution_count": 213, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "_state.shape" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Environment (conda_tensorflow2_p36)", + "language": "python", + "name": "conda_tensorflow2_p36" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/CAM.ipynb b/08-XAI/CAM.ipynb similarity index 100% rename from CAM.ipynb rename to 08-XAI/CAM.ipynb