From 659f8ba0cf9514d3b0ac326836368fb6908db2ed Mon Sep 17 00:00:00 2001 From: revsic Date: Tue, 26 Jun 2018 02:03:06 +0900 Subject: [PATCH 1/6] Update Preprocess - Add method create_dataset --- preprocess.py | 153 ++++++++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 67 deletions(-) diff --git a/preprocess.py b/preprocess.py index 16c85e0..ed1aeb6 100644 --- a/preprocess.py +++ b/preprocess.py @@ -1,6 +1,8 @@ +import csv import numpy as np -SEOUL_MAP = [ # 9 by 8 matrix, 25 borough +# 9 x 8 matrix, 25 city +SEOUL_MAP = [ [0, 0, 0, 0, '도봉구', '노원구', 0, 0], [0, 0, 0, '강북구', '강북구', '노원구', '노원구', 0], [0, '은평구', '종로구', '성북구', '성북구', '성북구', '중랑구', 0], @@ -12,107 +14,124 @@ [0, '구로구', '금천구', '관악구', '서초구', 0, 0, 0] ] -def read_csv(name, location_cnt=39): - """Read the csv file and return the amount of fine dust for each region grouped by date. + +def read_csv(name, num_region=39): + """Read the csv file and return the pm10 data Args: - name: The name of the csv file to read. - + name: str, the name of the csv file. + num_region: int, the number of the region including city and road. + Returns: - Dictionary object mapping the amount of fine dust for each region by date. + dist, dust data grouped by date and city. {'20170506': {'강남구': 50, '강동구': 60, '강서구':70}, '20170507': {'강남구': } ...} Raises: - ValueError: If the number of the data per day in the csv file is not equal to LOCATION_CNT. - + ValueError: If the number of region in the csv file is not equal to `num_region`. """ - with open(name) as f: - raw_data = f.read().strip() + with open(name, encoding='utf-8') as f: + raw = csv.reader(f) + raw.__next__() - del_quote = raw_data.replace("\"", '') - data = list(map(lambda x: x.split(','), del_quote.split('\n')))[1:] # [1:] csv header + date = '' + group = [] + group_by_date = [] - splitted = [] + for i, line in enumerate(raw): + if i % num_region == 0: + group_by_date.append([]) + group = group_by_date[-1] - ptr = 0 - for i in range(len(data) // location_cnt): - splitted.append(data[ptr:ptr+location_cnt]) - ptr += location_cnt - - ## test case - for date_list in splitted: - date = date_list[0][0] # index 0:date - for local in date_list: - if date != local[0]: - raise ValueError(date + ' is not same as ' + 'local[0]') - - def filter_borough(dic): - return dict(filter(lambda t: '구' in t[0], dic.items())) #filter not road name only borough + date = line[0] - # index 0:date, 1:local name, 6:pms - pms = dict(map(lambda x: (x[0][0], dict(map(lambda t: (t[1], t[6]), x))), splitted)) - pms_filtered = dict(filter(lambda x: '' not in x[1].values(), pms.items())) # csv data contains spaces - pms_filtered2 = dict(map(lambda x: (x[0], filter_borough(x[1])), pms_filtered.items())) - - return pms_filtered2 + if date == line[0]: + group.append(line) + else: + raise ValueError(date + 'is not same as ' + line[0]) + + group_by_city = {} + for regions in group_by_date: + date = regions[0][0] + group_by_city[date] = {} + + group = group_by_city[date] + for region in regions: + date, name, no2, o3, co, so2, pm10, pm20 = region + if name.endswith('구'): + if pm10 != '': + group[name] = int(pm10) + else: + del group_by_city[date] + break + + return group_by_city -def geographical_mapping(pms_data): - """Map the amount of fine dust for each region to geographical map of Seoul. + +def geographical_mapping(dust_data, seoul_map=SEOUL_MAP): + """Map dust data to geographical map of Seoul. Args: - pms_data: Fine dust data pre-processed by read_csv. - Dictionary obejct mapping the amount of fine dust for each region by date. - {'20170506': {'강남구': 50, '강동구': 60, '강서구':70}, '20170507': {'강남구': } ...} + dust_data: dict, dust data grouped by date and city (from `read_csv`). + {'20170506': {'강남구': 50, '강동구': 60, '강서구': 70}, '20170507': {'강남구': } ...} + seoul_map: list of int, geographical map of Seoul. Returns: - Dictionary that map the amount of fine dust to the geographical map of Seoul. + dict, dust data mapped by the geographical map of Seoul, `seoul_map`. {'20170506': [[0, 0, 0, 0, 50, 60, 0, 0], [0, 0, 0, 40, ...]]} """ - def dict2seoul(p): - return list(map(lambda t: list(map(lambda x: int(p[x]) if x != 0 else 0, t)), seoul_map)) + mapped = {} + for date, data in dust_data.items(): + mapped[date] = [] + map_of_seoul = mapped[date] + + for line in seoul_map: + transformed = list(map(lambda x: data[x] if x != 0 else 0, line)) + map_of_seoul.append(transformed) - # map dict to seoul geographic map - pms_mapped = dict(map(lambda p: (p[0], dict2seoul(p[1])), pms_data.items())) - return pms_mapped + return mapped -def generate_dataset(data, weekly_batch=7): - """ Generate the daily average amount of the fine dust(pm10) bundled in 7 days. + +def generate_dataset(data, len_time=7): + """ Generate the dust dataset grouped by N days. Args: - data: Fine dust data pre-processed by read_csv - Dictionary object mapping the amount of fine dust for each region by date. - {'20170506': {'강남구': 50, '강동구': 60, '강서구':70}, '20170507': {'강남구': } ...} - + data: dict, dust data grouped by date and city (from `read_csv`) + {'20170506': {'강남구': 50, '강동구': 60, '강서구': 70}, '20170507': {'강남구': } ...} + len_time: int, length of the time step. dataset is grouped by `len_time` days. + Returns: - pms_sampled: the amount of fine dust bundled in 7 days. - pms_result: the amount of fine dust on the next 7 days. - + sampled: the amount of fine dust bundled in 7 days. + result: the amount of fine dust on the next 7 days. """ - pms_mapped = geographical_mapping(data) + mapped = geographical_mapping(data) # tie data to WEEKLY_BATCH(7) batches - pms_data = list(map(lambda x: x[1], sorted(pms_mapped.items()))) - pms_tied = list(map(lambda i: pms_data[i:i+weekly_batch], range(len(pms_data) - weekly_batch))) - - pms_sampled = pms_tied[:-1] - pms_result = pms_tied[1:] + data = list(map(lambda x: x[1], sorted(mapped.items()))) + tied = list(map(lambda i: data[i:i+len_time], range(len(data) - len_time))) + + sampled = tied[:-1] + result = tied[1:] - return pms_sampled, pms_result + return sampled, result + -def main(): - csv_name = 'MonthlyAverageAirPollutionInSeoul.csv' - pms_data = read_csv(csv_name) - pms_sampled, pms_result = generate_dataset(pms_data) +def create_dataset(csv_name='./MonthlyAverageAirPollutionInSeoul.csv', + len_time=7, + train_rate=0.7): + data = read_csv(csv_name) + sampled, result = generate_dataset(data, len_time) - data_set = list(zip(pms_sampled, pms_result)) + data_set = list(zip(sampled, result)) np.random.shuffle(data_set) - train_set = data_set[:TRAIN_SIZE] + train_size = int(len(data_set) * train_rate) + train_set = data_set[:train_size] train_sampled = list(map(lambda x: x[0], train_set)) train_result = list(map(lambda x: x[1], train_set)) - test_set = data_set[-TEST_SIZE:] + test_set = data_set[-train_size:] test_sampled = list(map(lambda x: x[0], test_set)) test_result = list(map(lambda x: x[1], test_set)) + return (train_sampled, train_result), (test_sampled, test_result) From 8b3a3136c10ea85a70abdc7579fd4b1017b7fed7 Mon Sep 17 00:00:00 2001 From: revsic Date: Tue, 26 Jun 2018 05:03:25 +0900 Subject: [PATCH 2/6] Remove ipynb - Alter notebook to raw python --- Fine-Dust-Forecaster.ipynb | 702 ------------------------------------- Fine-Dust-Prediction.ipynb | 648 ---------------------------------- 2 files changed, 1350 deletions(-) delete mode 100644 Fine-Dust-Forecaster.ipynb delete mode 100644 Fine-Dust-Prediction.ipynb diff --git a/Fine-Dust-Forecaster.ipynb b/Fine-Dust-Forecaster.ipynb deleted file mode 100644 index e65ae09..0000000 --- a/Fine-Dust-Forecaster.ipynb +++ /dev/null @@ -1,702 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, - "source": [ - "# Fine dust prediction (하루 평균 미세 먼지 수치 예측)\n", - "Training Convolutional LSTM network to predict fine-dust.\n", - "\n", - "pm10 단위의 하루 평균 미세 먼지 수치를 예측하기 위해 ConvLSTM 을 훈련시킵니다." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "import tensorflow as tf\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "LOCATION_CNT = 39\n", - "BOROUGH_CNT = 25\n", - "WEEKLY_BATCH = 7\n", - "\n", - "TEST_SIZE = 40\n", - "TRAIN_SIZE = 240\n", - "BATCH_SIZE = 40\n", - "\n", - "TRAIN_ITER = 50\n", - "BATCH_ITER = TRAIN_SIZE // BATCH_SIZE" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, - "source": [ - "## Pre-processing data\n", - "Pre-processing the daily average amount of the fine dust(pm10) to bundle it in 7 days.\n", - "\n", - "For the convolution layer, the amount of fine dust for each region is mapped to the geographical map of Seoul (seoul_map). \n", - "\n", - "The data was extracted from the csv file [Seoul Daily Average Air Pollution Degree Information](http://data.seoul.go.kr/openinf/sheetview.jsp?infId=OA-2218&tMenu=11) provided by the Seoul Open Data Plaza.\n", - "\n", - "하루 평균 미세 먼지 수치를 7일 단위로 전처리 합니다.\n", - "\n", - "convolution layer를 위해, 지역별 미세 먼지 수치는 실제 서울시 지도에 대응됩니다 (seoul_map).\n", - "\n", - "데이터는 서울 열린 데이터 광장에서 제공하는 [서울시 일별 평균 대기 오염도 정보](http://data.seoul.go.kr/openinf/sheetview.jsp?infId=OA-2218&tMenu=11) csv 파일에서 추출하였습니다. " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": true, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "csv_name = 'MonthlyAverageAirPollutionInSeoul.csv'\n", - "\n", - "seoul_map = [ # 9 by 8 matrix, 25 borough\n", - " [0, 0, 0, 0, '도봉구', '노원구', 0, 0],\n", - " [0, 0, 0, '강북구', '강북구', '노원구', '노원구', 0],\n", - " [0, '은평구', '종로구', '성북구', '성북구', '성북구', '중랑구', 0],\n", - " [0, '은평구', '서대문구', '종로구', '종로구', '동대문구', '중랑구', 0],\n", - " [0, '은평구', '서대문구', '서대문구', '중구', '성동구', '광진구', '강동구'],\n", - " [0, '마포구', '마포구', '마포구', '용산구', '강남구', '송파구', '강동구'],\n", - " ['강서구', '강서구', '영등포구', '동작구', '서초구', '강남구', '송파구', 0],\n", - " [0, '양천구', '영등포구', '관악구', '서초구', '강남구', '송파구', 0],\n", - " [0, '구로구', '금천구', '관악구', '서초구', 0, 0, 0]\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "def read_csv(name):\n", - " \"\"\"Read the csv file and return the amount of fine dust for each region grouped by date.\n", - " \n", - " Args:\n", - " name: The name of the csv file to read.\n", - " \n", - " Returns:\n", - " Dictionary object mapping the amount of fine dust for each region by date.\n", - " {'20170506': {'강남구': 50, '강동구': 60, '강서구':70}, '20170507': {'강남구': } ...}\n", - " \n", - " Raises:\n", - " ValueError: If the number of the data per day in the csv file is not equal to LOCATION_CNT.\n", - " \n", - " \"\"\"\n", - " with open(name) as f:\n", - " raw_data = f.read().strip()\n", - "\n", - " del_quote = raw_data.replace(\"\\\"\", '')\n", - " data = list(map(lambda x: x.split(','), del_quote.split('\\n')))[1:] # [1:] csv header\n", - "\n", - " splitted = []\n", - "\n", - " ptr = 0\n", - " for i in range(len(data) // LOCATION_CNT):\n", - " splitted.append(data[ptr:ptr+LOCATION_CNT])\n", - " ptr += LOCATION_CNT\n", - " \n", - " ## test case\n", - " for date_list in splitted:\n", - " date = date_list[0][0] # index 0:date\n", - " for local in date_list:\n", - " if date != local[0]:\n", - " raise ValueError(date + ' is not same as ' + 'local[0]')\n", - " \n", - " def filter_borough(dic):\n", - " return dict(filter(lambda t: '구' in t[0], dic.items())) #filter not road name only borough \n", - "\n", - " # index 0:date, 1:local name, 6:pms\n", - " pms = dict(map(lambda x: (x[0][0], dict(map(lambda t: (t[1], t[6]), x))), splitted))\n", - " pms_filtered = dict(filter(lambda x: '' not in x[1].values(), pms.items())) # csv data contains spaces\n", - " pms_filtered2 = dict(map(lambda x: (x[0], filter_borough(x[1])), pms_filtered.items()))\n", - " \n", - " return pms_filtered2" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "def geographical_mapping(pms_data):\n", - " \"\"\"Map the amount of fine dust for each region to geographical map of Seoul.\n", - " \n", - " Args:\n", - " pms_data: Fine dust data pre-processed by read_csv.\n", - " Dictionary obejct mapping the amount of fine dust for each region by date.\n", - " {'20170506': {'강남구': 50, '강동구': 60, '강서구':70}, '20170507': {'강남구': } ...}\n", - " \n", - " Returns:\n", - " Dictionary that map the amount of fine dust to the geographical map of Seoul.\n", - " {'20170506': [[0, 0, 0, 0, 50, 60, 0, 0], [0, 0, 0, 40, ...]]}\n", - " \n", - " \"\"\"\n", - " def dict2seoul(p):\n", - " return list(map(lambda t: list(map(lambda x: int(p[x]) if x != 0 else 0, t)), seoul_map))\n", - "\n", - " # map dict to seoul geographic map\n", - " pms_mapped = dict(map(lambda p: (p[0], dict2seoul(p[1])), pms_data.items())) \n", - " return pms_mapped" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": true, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "def generate_dataset(data):\n", - " \"\"\" Generate the daily average amount of the fine dust(pm10) bundled in 7 days.\n", - " \n", - " Args:\n", - " data: Fine dust data pre-processed by read_csv\n", - " Dictionary object mapping the amount of fine dust for each region by date.\n", - " {'20170506': {'강남구': 50, '강동구': 60, '강서구':70}, '20170507': {'강남구': } ...}\n", - " \n", - " Returns:\n", - " pms_sampled: the amount of fine dust bundled in 7 days.\n", - " pms_result: the amount of fine dust on the next 7 days.\n", - " \n", - " \"\"\"\n", - " pms_mapped = geographical_mapping(data)\n", - " \n", - " # tie data to WEEKLY_BATCH(7) batches\n", - " pms_data = list(map(lambda x: x[1], sorted(pms_mapped.items()))) \n", - " pms_tied = list(map(lambda i: pms_data[i:i+WEEKLY_BATCH], range(len(pms_data) - WEEKLY_BATCH)))\n", - " \n", - " pms_sampled = pms_tied[:-1]\n", - " pms_result = pms_tied[1:]\n", - " \n", - " return pms_sampled, pms_result" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "pms_data = read_csv(csv_name)\n", - "pms_sampled, pms_result = generate_dataset(pms_data)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "data_set = list(zip(pms_sampled, pms_result))\n", - "np.random.shuffle(data_set)\n", - "\n", - "train_set = data_set[:TRAIN_SIZE]\n", - "train_sampled = list(map(lambda x: x[0], train_set))\n", - "train_result = list(map(lambda x: x[1], train_set))\n", - "\n", - "test_set = data_set[-TEST_SIZE:]\n", - "test_sampled = list(map(lambda x: x[0], test_set))\n", - "test_result = list(map(lambda x: x[1], test_set))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, - "source": [ - "## Generate Model\n", - "Generate ConvLSTM Networks to predict fine-dust. The original paper is [Convolutional LSTM](https://arxiv.org/abs/1506.04214).\n", - "\n", - "미세 먼지 예측이 이용할 ConvLSTM 네트워크를 구축합니다. ConvLSTM 네트워크는 [Convlutional LSTM](https://arxiv.org/abs/1506.04214) 논문을 참고하였습니다." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "X = tf.placeholder(tf.float32, [None, WEEKLY_BATCH, 9, 8]) # matrix size [9, 8]\n", - "Y = tf.placeholder(tf.float32, [None, WEEKLY_BATCH, 9, 8])\n", - "\n", - "Xr = tf.reshape(X, [-1, WEEKLY_BATCH, 9, 8, 1])\n", - "Xt = tf.transpose(Xr, [1, 0, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "class ConvLSTMCell(tf.contrib.rnn.RNNCell):\n", - " \"\"\" Convolutional LSTM Model. \n", - " Similar as LSTM Cell, but it calculate hidden states with convolution.\n", - " \n", - " Attributes:\n", - " shape (tf.TensorShape): tensor shape of the output value\n", - " kernel (list): kernel shape [f_h, f_w]\n", - " depth (int): depth of the output\n", - " name (str): name of the variable scope\n", - " \"\"\"\n", - " def __init__(self, shape, kernel, depth, name='ConvLSTM_'):\n", - " \"\"\" Convolutional LSTM initializer. It creates some tensorflow variables.\n", - " \n", - " Args:\n", - " shape (tf.TensorShape): tensor shape of the output value\n", - " kernel (list): kernel shape [f_h, f_w]\n", - " depth (int): depth of the output\n", - " name (str): name of the variable scope\n", - " \"\"\"\n", - " self._shape = tf.TensorShape(shape + [depth])\n", - " self._kernel = kernel\n", - " self._depth = depth\n", - " self._name = name\n", - " \n", - " @property\n", - " def state_size(self):\n", - " return tf.contrib.rnn.LSTMStateTuple(self._shape, self._shape)\n", - " \n", - " @property\n", - " def output_size(self):\n", - " return self._shape\n", - " \n", - " def __call__(self, x, state):\n", - " \"\"\" Feed input tensor to the ConvLSTM and return hidden units and cells.\n", - " \n", - " Args:\n", - " x (tf.Tensor): Input value of the ConvLSTM. 5D tensor\n", - " [input dim, batch size, width, height, channel]\n", - " \n", - " Returns:\n", - " h (tf.Tensor): hidden units of the ConvLSTM\n", - " state (LSTMStateTuple): states of the ConvLSTM [cell, hidden]\n", - " \"\"\"\n", - " with tf.variable_scope(self._name):\n", - " c_prev, h_prev = state\n", - " \n", - " x = tf.concat([x, h_prev], axis=3)\n", - " in_dim = x.shape[-1].value\n", - " h_dim = 4 * self._depth\n", - " \n", - " w = tf.get_variable('w', self._kernel + [in_dim, h_dim],\n", - " initializer=tf.random_normal_initializer(stddev=0.02))\n", - " conv = tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')\n", - " hi, hf, hc, ho = tf.split(conv, 4, axis=3)\n", - " \n", - " Wci = tf.get_variable('wci', c_prev.shape[1:],\n", - " initializer=tf.random_normal_initializer(stddev=0.02))\n", - " Wcf = tf.get_variable('wcf', c_prev.shape[1:],\n", - " initializer=tf.random_normal_initializer(stddev=0.02))\n", - " Wco = tf.get_variable('wco', c_prev.shape[1:],\n", - " initializer=tf.random_normal_initializer(stddev=0.02))\n", - " \n", - " hi = tf.contrib.layers.layer_norm(hi + c_prev * Wci)\n", - " hf = tf.contrib.layers.layer_norm(hf + c_prev * Wcf)\n", - " ho = tf.contrib.layers.layer_norm(ho + c_prev * Wco)\n", - " hc = tf.contrib.layers.layer_norm(hc)\n", - " \n", - " hi = tf.nn.sigmoid(hi)\n", - " hf = tf.nn.sigmoid(hf)\n", - " ho = tf.nn.sigmoid(ho)\n", - " hc = tf.nn.tanh(hc)\n", - " \n", - " c = c_prev * hf + hc * hi\n", - " c = tf.contrib.layers.layer_norm(c)\n", - " \n", - " h = ho * tf.nn.tanh(c)\n", - " \n", - " state = tf.contrib.rnn.LSTMStateTuple(c, h)\n", - " \n", - " return h, state" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "cell1 = ConvLSTMCell([9, 8], [5, 5], 128, name='encoder1')\n", - "cell2 = ConvLSTMCell([9, 8], [5, 5], 64, name='encoder2')\n", - "cell3 = ConvLSTMCell([9, 8], [5, 5], 64, name='encoder3')\n", - "\n", - "# time_major option prevent `dynamic_rnn` from transposing the state tensor of ConvLSTM Cell.\n", - "h1, state1 = tf.nn.dynamic_rnn(cell1, Xt, dtype=tf.float32, time_major=True)\n", - "h2, state2 = tf.nn.dynamic_rnn(cell2, h1, dtype=tf.float32, time_major=True)\n", - "h3, state3 = tf.nn.dynamic_rnn(cell3, h2, dtype=tf.float32, time_major=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "# `sample` function prevent `dynamic_decode` from raising 'invalid tensor shape err'\n", - "def sample(time, outputs, name=None, **unused_kwargs):\n", - " return tf.zeros([BATCH_SIZE])\n", - "\n", - "init = tf.zeros_like(Xt)\n", - "helper1 = tf.contrib.seq2seq.TrainingHelper(init, [WEEKLY_BATCH]*BATCH_SIZE, time_major=True)\n", - "helper1.sample = sample\n", - "dcell1 = ConvLSTMCell([9, 8], [5, 5], 128, name='decoder1')\n", - "dec1 = tf.contrib.seq2seq.BasicDecoder(dcell1, helper1, state1)\n", - "(o1, _), _ = tf.contrib.seq2seq.dynamic_decode(dec1, output_time_major=True)\n", - "\n", - "helper2 = tf.contrib.seq2seq.TrainingHelper(o1, [WEEKLY_BATCH]*BATCH_SIZE, time_major=True)\n", - "helper2.sample = sample\n", - "dcell2 = ConvLSTMCell([9, 8], [5, 5], 64, name='decoder2')\n", - "dec2 = tf.contrib.seq2seq.BasicDecoder(dcell2, helper2, state2)\n", - "(o2, _), _ = tf.contrib.seq2seq.dynamic_decode(dec2, output_time_major=True)\n", - "\n", - "helper3 = tf.contrib.seq2seq.TrainingHelper(o2, [WEEKLY_BATCH]*BATCH_SIZE, time_major=True)\n", - "helper3.sample = sample\n", - "dcell3 = ConvLSTMCell([9, 8], [5, 5], 64, name='decoder3')\n", - "dec3 = tf.contrib.seq2seq.BasicDecoder(dcell3, helper3, state3)\n", - "(o3, _), _ = tf.contrib.seq2seq.dynamic_decode(dec3, output_time_major=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "# 1x1 convolution for flattening data\n", - "Wf = tf.get_variable('wf', shape=[1, 1, 256, 1],\n", - " initializer=tf.random_normal_initializer(stddev=0.02))\n", - "\n", - "out = tf.concat([o1, o2, o3], axis=-1)\n", - "out = tf.transpose(out, [1, 0, 2, 3, 4])\n", - "\n", - "conv = [tf.nn.conv2d(out[i], Wf, strides=[1, 1, 1, 1], padding='SAME') for i in range(BATCH_SIZE)]\n", - "pred = tf.reshape(conv, [BATCH_SIZE, -1, 9, 8])\n", - "\n", - "loss = tf.reduce_mean(tf.square(Y - pred)) # MSE loss\n", - "opt = tf.train.RMSPropOptimizer(1e-2, 0.9).minimize(loss)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, - "source": [ - "## Training\n", - "\n", - "Train ConvLSTM Networks with batch size 40, train iter 200.\n", - "\n", - "Record training and cross validation errors during training.\n", - "\n", - "ConvLSTM 네트워크를 학습시킵니다. batch 크기는 40개, 반복 횟수는 200번입니다.\n", - "\n", - "훈련 과정에서 training error 와 cross validation error 을 계산, 기록합니다." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "sess = tf.Session()\n", - "sess.run(tf.global_variables_initializer())" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true, - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.0 1223.32\n", - "0.1 491.715\n", - "0.2 319.438\n", - "0.3 302.707\n", - "0.4 263.217\n", - "0.5 346.334\n", - "0.6 213.806\n", - "0.7 222.326\n", - "0.8 169.622\n", - "0.9 139.064\n", - "1.0 120.662\n" - ] - } - ], - "source": [ - "train_loss = []\n", - "test_loss = []\n", - "\n", - "for i in range(TRAIN_ITER + 1):\n", - " ptr = 0\n", - " for _ in range(BATCH_ITER):\n", - " _, trainloss = sess.run([opt, loss], feed_dict={X: train_sampled[ptr:ptr+BATCH_SIZE], \n", - " Y: train_result[ptr:ptr+BATCH_SIZE]})\n", - " \n", - " testloss = sess.run(loss, feed_dict={X: test_sampled, Y: test_result})\n", - " \n", - " ptr += BATCH_SIZE\n", - "\n", - " train_loss.append(trainloss)\n", - " test_loss.append(testloss)\n", - " \n", - " if i % (TRAIN_ITER // 10) == 0:\n", - " print(i/TRAIN_ITER, testloss)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, - "source": [ - "## Visualization\n", - "\n", - "Visualize loss graph and actual value and estimates for the test set.\n", - "\n", - "loss graph 와 test set 에 대한 실제 값과 평가치를 시각화합니다." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.plot(train_loss, label='train')\n", - "plt.plot(test_loss, label='test')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "predict = sess.run(pred, feed_dict={X: test_sampled})\n", - "pred_gangnam = list(map(lambda x: x[6][5], predict[3]))\n", - "real_gangnam = list(map(lambda x: x[6][5], test_result[3]))\n", - "\n", - "plt.plot(pred_gangnam, label='predict')\n", - "plt.plot(real_gangnam, label='real')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "pred_dongdaemun = list(map(lambda x: x[3][5], predict[20]))\n", - "real_dongdaemun = list(map(lambda x: x[3][5], test_result[20]))\n", - "\n", - "plt.plot(pred_dongdaemun, label='predict')\n", - "plt.plot(real_dongdaemun, label='real')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "sess.close()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.0" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/Fine-Dust-Prediction.ipynb b/Fine-Dust-Prediction.ipynb deleted file mode 100644 index abbe16f..0000000 --- a/Fine-Dust-Prediction.ipynb +++ /dev/null @@ -1,648 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, - "source": [ - "# Fine dust prediction (하루 평균 미세 먼지 수치 예측)\n", - "Training Convolutional LSTM network to predict fine-dust.\n", - "\n", - "pm10 단위의 하루 평균 미세 먼지 수치를 예측하기 위해 ConvLSTM 을 훈련시킵니다." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "import tensorflow as tf\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "LOCATION_CNT = 39\n", - "BOROUGH_CNT = 25\n", - "WEEKLY_BATCH = 7\n", - "\n", - "TEST_SIZE = 40\n", - "TRAIN_SIZE = 240\n", - "BATCH_SIZE = 40\n", - "\n", - "TRAIN_ITER = 100\n", - "BATCH_ITER = TRAIN_SIZE // BATCH_SIZE" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, - "source": [ - "## Pre-processing data\n", - "Pre-processing the daily average amount of the fine dust(pm10) to bundle it in 7 days.\n", - "\n", - "For the convolution layer, the amount of fine dust for each region is mapped to the geographical map of Seoul (seoul_map). \n", - "\n", - "The data was extracted from the csv file [Seoul Daily Average Air Pollution Degree Information](http://data.seoul.go.kr/openinf/sheetview.jsp?infId=OA-2218&tMenu=11) provided by the Seoul Open Data Plaza.\n", - "\n", - "하루 평균 미세 먼지 수치를 7일 단위로 전처리 합니다.\n", - "\n", - "convolution layer를 위해, 지역별 미세 먼지 수치는 실제 서울시 지도에 대응됩니다 (seoul_map).\n", - "\n", - "데이터는 서울 열린 데이터 광장에서 제공하는 [서울시 일별 평균 대기 오염도 정보](http://data.seoul.go.kr/openinf/sheetview.jsp?infId=OA-2218&tMenu=11) csv 파일에서 추출하였습니다. " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": true, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "csv_name = 'MonthlyAverageAirPollutionInSeoul.csv'\n", - "\n", - "seoul_map = [ # 9 by 8 matrix, 25 borough\n", - " [0, 0, 0, 0, '도봉구', '노원구', 0, 0],\n", - " [0, 0, 0, '강북구', '강북구', '노원구', '노원구', 0],\n", - " [0, '은평구', '종로구', '성북구', '성북구', '성북구', '중랑구', 0],\n", - " [0, '은평구', '서대문구', '종로구', '종로구', '동대문구', '중랑구', 0],\n", - " [0, '은평구', '서대문구', '서대문구', '중구', '성동구', '광진구', '강동구'],\n", - " [0, '마포구', '마포구', '마포구', '용산구', '강남구', '송파구', '강동구'],\n", - " ['강서구', '강서구', '영등포구', '동작구', '서초구', '강남구', '송파구', 0],\n", - " [0, '양천구', '영등포구', '관악구', '서초구', '강남구', '송파구', 0],\n", - " [0, '구로구', '금천구', '관악구', '서초구', 0, 0, 0]\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "def read_csv(name):\n", - " \"\"\"Read the csv file and return the amount of fine dust for each region grouped by date.\n", - " \n", - " Args:\n", - " name: The name of the csv file to read.\n", - " \n", - " Returns:\n", - " Dictionary object mapping the amount of fine dust for each region by date.\n", - " {'20170506': {'강남구': 50, '강동구': 60, '강서구':70}, '20170507': {'강남구': } ...}\n", - " \n", - " Raises:\n", - " ValueError: If the number of the data per day in the csv file is not equal to LOCATION_CNT.\n", - " \n", - " \"\"\"\n", - " with open(name) as f:\n", - " raw_data = f.read().strip()\n", - "\n", - " del_quote = raw_data.replace(\"\\\"\", '')\n", - " data = list(map(lambda x: x.split(','), del_quote.split('\\n')))[1:] # [1:] csv header\n", - "\n", - " splitted = []\n", - "\n", - " ptr = 0\n", - " for i in range(len(data) // LOCATION_CNT):\n", - " splitted.append(data[ptr:ptr+LOCATION_CNT])\n", - " ptr += LOCATION_CNT\n", - " \n", - " ## test case\n", - " for date_list in splitted:\n", - " date = date_list[0][0] # index 0:date\n", - " for local in date_list:\n", - " if date != local[0]:\n", - " raise ValueError(date + ' is not same as ' + 'local[0]')\n", - " \n", - " def filter_borough(dic):\n", - " return dict(filter(lambda t: '구' in t[0], dic.items())) #filter not road name only borough \n", - "\n", - " # index 0:date, 1:local name, 6:pms\n", - " pms = dict(map(lambda x: (x[0][0], dict(map(lambda t: (t[1], t[6]), x))), splitted))\n", - " pms_filtered = dict(filter(lambda x: '' not in x[1].values(), pms.items())) # csv data contains spaces\n", - " pms_filtered2 = dict(map(lambda x: (x[0], filter_borough(x[1])), pms_filtered.items()))\n", - " \n", - " return pms_filtered2" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "def geographical_mapping(pms_data):\n", - " \"\"\"Map the amount of fine dust for each region to geographical map of Seoul.\n", - " \n", - " Args:\n", - " pms_data: Fine dust data pre-processed by read_csv.\n", - " Dictionary obejct mapping the amount of fine dust for each region by date.\n", - " {'20170506': {'강남구': 50, '강동구': 60, '강서구':70}, '20170507': {'강남구': } ...}\n", - " \n", - " Returns:\n", - " Dictionary that map the amount of fine dust to the geographical map of Seoul.\n", - " {'20170506': [[0, 0, 0, 0, 50, 60, 0, 0], [0, 0, 0, 40, ...]]}\n", - " \n", - " \"\"\"\n", - " def dict2seoul(p):\n", - " return list(map(lambda t: list(map(lambda x: int(p[x]) if x != 0 else 0, t)), seoul_map))\n", - "\n", - " # map dict to seoul geographic map\n", - " pms_mapped = dict(map(lambda p: (p[0], dict2seoul(p[1])), pms_data.items())) \n", - " return pms_mapped" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": true, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "def generate_dataset(data):\n", - " \"\"\" Generate the daily average amount of the fine dust(pm10) bundled in 7 days.\n", - " \n", - " Args:\n", - " data: Fine dust data pre-processed by read_csv\n", - " Dictionary object mapping the amount of fine dust for each region by date.\n", - " {'20170506': {'강남구': 50, '강동구': 60, '강서구':70}, '20170507': {'강남구': } ...}\n", - " \n", - " Returns:\n", - " pms_sampled: the amount of fine dust bundled in 7 days.\n", - " pms_result: the amount of fine dust on the next day.\n", - " \n", - " \"\"\"\n", - " pms_mapped = geographical_mapping(data)\n", - " \n", - " # tie data to WEEKLY_BATCH(7) batches\n", - " pms_data = list(map(lambda x: x[1], sorted(pms_mapped.items()))) \n", - " pms_sampled = list(map(lambda i: pms_data[i:i+WEEKLY_BATCH], range(len(pms_data) - WEEKLY_BATCH - 1)))\n", - " pms_result = pms_data[WEEKLY_BATCH:]\n", - " \n", - " return pms_sampled, pms_result" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "pms_data = read_csv(csv_name)\n", - "pms_sampled, pms_result = generate_dataset(pms_data)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "test_sampled = pms_sampled[-TEST_SIZE:]\n", - "test_result = pms_result[-TEST_SIZE:]\n", - "\n", - "train_set = list(zip(pms_sampled[:TRAIN_SIZE], pms_result[:TRAIN_SIZE]))\n", - "np.random.shuffle(train_set)\n", - "\n", - "train_sampled = list(map(lambda x: x[0], train_set))\n", - "train_result = list(map(lambda x: x[1], train_set))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, - "source": [ - "## Generate Model\n", - "Generate ConvLSTM Networks to predict fine-dust. The original paper is [Convolutional LSTM](https://arxiv.org/abs/1506.04214).\n", - "\n", - "미세 먼지 예측이 이용할 ConvLSTM 네트워크를 구축합니다. ConvLSTM 네트워크는 [Convlutional LSTM](https://arxiv.org/abs/1506.04214) 논문을 참고하였습니다." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "X = tf.placeholder(tf.float32, [None, WEEKLY_BATCH, 9, 8]) # matrix size [9, 8]\n", - "Y = tf.placeholder(tf.float32, [None, 9, 8])\n", - "\n", - "Xr = tf.reshape(X, [-1, WEEKLY_BATCH, 9, 8, 1])\n", - "Xt = tf.transpose(Xr, [1, 0, 2, 3, 4])" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "class ConvLSTMCell(tf.contrib.rnn.RNNCell):\n", - " \"\"\" Convolutional LSTM Model. \n", - " Similar as LSTM Cell, but it calculate hidden states with convolution.\n", - " \n", - " Attributes:\n", - " shape (tf.TensorShape): tensor shape of the output value\n", - " kernel (list): kernel shape [f_h, f_w]\n", - " depth (int): depth of the output\n", - " name (str): name of the variable scope\n", - " \"\"\"\n", - " def __init__(self, shape, kernel, depth, name='ConvLSTM_'):\n", - " \"\"\" Convolutional LSTM initializer. It creates some tensorflow variables.\n", - " \n", - " Args:\n", - " shape (tf.TensorShape): tensor shape of the output value\n", - " kernel (list): kernel shape [f_h, f_w]\n", - " depth (int): depth of the output\n", - " name (str): name of the variable scope\n", - " \"\"\"\n", - " self._shape = tf.TensorShape(shape + [depth])\n", - " self._kernel = kernel\n", - " self._depth = depth\n", - " self._name = name\n", - " \n", - " @property\n", - " def state_size(self):\n", - " return tf.contrib.rnn.LSTMStateTuple(self._shape, self._shape)\n", - " \n", - " @property\n", - " def output_size(self):\n", - " return self._shape\n", - " \n", - " def __call__(self, x, state):\n", - " \"\"\" Feed input tensor to the ConvLSTM and return hidden units and cells.\n", - " \n", - " Args:\n", - " x (tf.Tensor): Input value of the ConvLSTM. 5D tensor\n", - " [input dim, batch size, width, height, channel]\n", - " \n", - " Returns:\n", - " h (tf.Tensor): hidden units of the ConvLSTM\n", - " state (LSTMStateTuple): states of the ConvLSTM [cell, hidden]\n", - " \"\"\"\n", - " with tf.variable_scope(self._name):\n", - " c_prev, h_prev = state\n", - " \n", - " x = tf.concat([x, h_prev], axis=3)\n", - " in_dim = x.shape[-1].value\n", - " h_dim = 4 * self._depth\n", - " \n", - " w = tf.get_variable('w', self._kernel + [in_dim, h_dim],\n", - " initializer=tf.random_normal_initializer(stddev=0.02))\n", - " conv = tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')\n", - " hi, hf, hc, ho = tf.split(conv, 4, axis=3)\n", - " \n", - " hi = tf.nn.sigmoid(hi)\n", - " hf = tf.nn.sigmoid(hf)\n", - " ho = tf.nn.sigmoid(ho)\n", - " hc = tf.nn.tanh(hc)\n", - " \n", - " c = c_prev * hf + hc * hi\n", - " h = ho * tf.nn.tanh(c)\n", - " \n", - " state = tf.contrib.rnn.LSTMStateTuple(c, h)\n", - " \n", - " return h, state" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "encoder1 = ConvLSTMCell([9, 8], [5, 5], 128, name='encoder1')\n", - "encoder2 = ConvLSTMCell([9, 8], [5, 5], 64, name='encoder2')\n", - "encoder3 = ConvLSTMCell([9, 8], [5, 5], 64, name='encoder3')\n", - "\n", - "h1, state1 = tf.nn.dynamic_rnn(encoder1, Xt, dtype=tf.float32, time_major=True)\n", - "h2, state2 = tf.nn.dynamic_rnn(encoder2, h1, dtype=tf.float32, time_major=True)\n", - "h3, state3 = tf.nn.dynamic_rnn(encoder3, h2, dtype=tf.float32, time_major=True)\n", - "\n", - "hidden = tf.concat([h1[-1], h2[-1], h3[-1]], axis=3)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "# 1x1 convolution for flattening data\n", - "Wf = tf.get_variable('wf', shape=[1, 1, 256, 1],\n", - " initializer=tf.random_normal_initializer(stddev=0.02))\n", - "out = tf.nn.conv2d(hidden, Wf, strides=[1, 1, 1, 1], padding='SAME')\n", - "\n", - "pred = tf.reshape(out, [-1, 9, 8])\n", - "\n", - "loss = tf.reduce_mean(tf.square(Y - pred)) # MSE loss\n", - "opt = tf.train.RMSPropOptimizer(1e-3, 0.9).minimize(loss)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, - "source": [ - "## Training\n", - "\n", - "Train ConvLSTM Networks with batch size 40, train iter 200.\n", - "\n", - "Record training and cross validation errors during training.\n", - "\n", - "ConvLSTM 네트워크를 학습시킵니다. batch 크기는 40개, 반복 횟수는 200번입니다.\n", - "\n", - "훈련 과정에서 training error 와 cross validation error 을 계산, 기록합니다." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "sess = tf.Session()\n", - "sess.run(tf.global_variables_initializer())" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true, - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.0 2634.04\n", - "0.1 1438.95\n", - "0.2 873.191\n", - "0.3 501.78\n", - "0.4 404.776\n", - "0.5 380.151\n", - "0.6 355.992\n", - "0.7 378.235\n", - "0.8 401.75\n", - "0.9 406.401\n", - "1.0 426.977\n" - ] - } - ], - "source": [ - "train_loss = []\n", - "test_loss = []\n", - "\n", - "for i in range(TRAIN_ITER + 1):\n", - " ptr = 0\n", - " for _ in range(BATCH_ITER):\n", - " _, trainloss = sess.run([opt, loss], feed_dict={X: train_sampled[ptr:ptr+BATCH_SIZE], \n", - " Y: train_result[ptr:ptr+BATCH_SIZE]})\n", - " \n", - " testloss = sess.run(loss, feed_dict={X: test_sampled, Y: test_result})\n", - " \n", - " ptr += BATCH_SIZE\n", - "\n", - " train_loss.append(trainloss)\n", - " test_loss.append(testloss)\n", - " \n", - " if i % (TRAIN_ITER // 10) == 0:\n", - " print(i/TRAIN_ITER, testloss)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, - "source": [ - "## Visualization\n", - "\n", - "Visualize loss graph and actual value and estimates for the test set.\n", - "\n", - "loss graph 와 test set 에 대한 실제 값과 평가치를 시각화합니다." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\nQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.plot(train_loss, label='train')\n", - "plt.plot(test_loss, label='test')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "predict = sess.run(pred, feed_dict={X: test_sampled})\n", - "pred_gangnam = list(map(lambda x: x[6][5], predict[-15:]))\n", - "real_gangnam = list(map(lambda x: x[6][5], test_result[-15:]))\n", - "\n", - "plt.plot(pred_gangnam, label='predict')\n", - "plt.plot(real_gangnam, label='real')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n2MU/HQAAAABJRU5ErkJggg==\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "pred_dongdaemun = list(map(lambda x: x[3][5], predict[-15:]))\n", - "real_dongdaemun = list(map(lambda x: x[3][5], test_result[-15:]))\n", - "\n", - "plt.plot(pred_dongdaemun, label='predict')\n", - "plt.plot(real_dongdaemun, label='real')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "outputs": [], - "source": [ - "sess.close()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "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.5.2" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From 124bff7dec8c10ec10a0caa8af7bdebb68d07331 Mon Sep 17 00:00:00 2001 From: revsic Date: Tue, 26 Jun 2018 05:04:27 +0900 Subject: [PATCH 3/6] Update Preprocess - Fix data_set slicing --- preprocess.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/preprocess.py b/preprocess.py index ed1aeb6..b16ef75 100644 --- a/preprocess.py +++ b/preprocess.py @@ -127,11 +127,11 @@ def create_dataset(csv_name='./MonthlyAverageAirPollutionInSeoul.csv', train_size = int(len(data_set) * train_rate) train_set = data_set[:train_size] - train_sampled = list(map(lambda x: x[0], train_set)) - train_result = list(map(lambda x: x[1], train_set)) + train_x = list(map(lambda x: x[0], train_set)) + train_y = list(map(lambda x: x[1], train_set)) - test_set = data_set[-train_size:] - test_sampled = list(map(lambda x: x[0], test_set)) - test_result = list(map(lambda x: x[1], test_set)) + test_set = data_set[train_size:] + test_x = list(map(lambda x: x[0], test_set)) + test_y = list(map(lambda x: x[1], test_set)) - return (train_sampled, train_result), (test_sampled, test_result) + return (train_x, train_y), (test_x, test_y) From bedcb610cb6beb3a4951f496cdd6e25984bc0d08 Mon Sep 17 00:00:00 2001 From: revsic Date: Tue, 26 Jun 2018 05:06:53 +0900 Subject: [PATCH 4/6] Update Model - Fix model to runnable --- model.py | 64 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/model.py b/model.py index 8edd4ca..c361927 100644 --- a/model.py +++ b/model.py @@ -1,8 +1,9 @@ import json import tensorflow as tf + class ConvLSTMCell(tf.nn.rnn_cell.RNNCell): - '''Convolutional LSTM (Long short-term memory unit) recurrent network cell. + """Convolutional LSTM (Long short-term memory unit) recurrent network cell. The class uses optional peep-hole connections, optional cell-clipping, optional normalization layer, and an optional recurrent dropout layer. @@ -38,7 +39,7 @@ class ConvLSTMCell(tf.nn.rnn_cell.RNNCell): 'Recurrent Dropout without Memory Loss'. 2016. Normalization layer is applied before interal nonlinearities. - ''' + """ def __init__(self, shape, kernel, @@ -51,7 +52,7 @@ def __init__(self, normalize=None, dropout=None, reuse=None): - '''Initialize the parameters for a ConvLSTM Cell. + """Initialize the parameters for a ConvLSTM Cell. Args: shape: list of 2 integers, specifying the height and width @@ -71,7 +72,7 @@ def __init__(self, dropout: Float, if provided dropout is applied to inner states with keep probability in this value. reuse: Boolean, whether to reuse variables in an existing scope. - ''' + """ super(ConvLSTMCell, self).__init__(_reuse=reuse) tf_shape = tf.TensorShape(shape + [depth]) @@ -103,7 +104,7 @@ def output_size(self): return self._output_size def call(self, inputs, state): - '''Run one step of ConvLSTM. + """Run one step of ConvLSTM. Args: inputs: input Tensor, 4D, (batch, shape[0], shape[1], depth) @@ -119,7 +120,7 @@ def call(self, inputs, state): shape[0] and shape[1]. - Tensor(s) representing the new state of ConvLSTM after reading `inputs` when the previous state was `state`. Same type and shape(s) as `state`. - ''' + """ dtype = inputs.dtype input_size = inputs.get_shape().with_rank(4)[3] if input_size.value is None: @@ -178,7 +179,7 @@ def call(self, inputs, state): class Predicator(object): - ''' Predict daily average amount of fine dust. + """Predict daily average amount of fine dust. Attributes: matrix_shape: list of 2 integers, specifying the height and width of input matrix. @@ -195,9 +196,9 @@ class Predicator(object): metric: tf.Tensor, metric for evaluating model. optimize: tf.Tensor, optimize object. summary: tf.Tensor, tensor summary of the metric. - ''' + """ def __init__(self, matrix_shape, num_time, out_time, kernels, depths, learning_rate, beta1): - ''' Initializer + """Initializer Args: matrix_shape: list of 2 integers, specifying the height and width of input matrix. num_time: Integer, the number of time series as an input. @@ -206,7 +207,7 @@ def __init__(self, matrix_shape, num_time, out_time, kernels, depths, learning_r depths: list of n-integers, specifying the depth of the ConvLSTM Cells. learning_rate: Float, learning rate in Adam for optimizing loss function. beta1: Float, beta1 value in Adam for optimizing loss function. - ''' + """ self._matrix_shape = matrix_shape self._num_time = num_time self._out_time = out_time @@ -236,8 +237,8 @@ def train(self, sess, x, y): def inference(self, sess, obj, x, y): return sess.run(obj, feed_dict={self.plc_x: x, self.plc_y: y}) - def dump(self, sess, path): - self.ckpt.save(sess, path + '.ckpt') + def dump(self, sess, path, global_step=None): + self.ckpt.save(sess, path + '.ckpt', global_step) with open(path + '.json', 'w') as f: dump = json.dumps( @@ -255,7 +256,7 @@ def dump(self, sess, path): f.write(dump) @classmethod - def load(cls, sess, path): + def load(cls, sess, path, global_step=None): with open(path + '.json') as f: param = json.loads(f.read()) @@ -268,7 +269,11 @@ def load(cls, sess, path): param['learning_rate'], param['beta1'] ) - model.ckpt.restore(sess, path + '.ckpt') + + if global_step: + model.ckpt.restore(sess, '{}.ckpt-{}'.format(path, global_step)) + else: + model.ckpt.restore(sess, path + '.ckpt') return model @@ -276,16 +281,17 @@ def _get_model(self): assert len(self._kernels) == len(self._depths), 'Number of kernels and depths must be same.' # self.plc_x.shape == [BATCH_SIZE, self._num_time, self._matrix_shape[0], self._matrix_shape[1]] - shape = [-1, self._matrix_shape[0], self._matrix_shape[1], 1] - inputs = tf.transpose(tf.reshape(self.plc_x, shape), [1, 0, 2, 3, 4]) # time major + shape = [-1, self._num_time, self._matrix_shape[0], self._matrix_shape[1], 1] + inputs = tf.transpose(tf.reshape(self.plc_x, shape), [1, 0, 2, 3, 4]) states = [] hiddens = [inputs] # Stacked ConvLSTM Encoder - for kernel, depth in zip(self._kernels, self._depths): - cell = ConvLSTMCell(self._matrix_shape, kernel, depth) - h, s = tf.nn.dynamic_rnn(cell, hiddens[-1], self._num_time, time_major=True) + for i, (kernel, depth) in enumerate(zip(self._kernels, self._depths)): + with tf.variable_scope('{}th_enc'.format(i)): + cell = ConvLSTMCell(self._matrix_shape, kernel, depth) + h, s = tf.nn.dynamic_rnn(cell, hiddens[-1], dtype=tf.float32, time_major=True) states.append(s) hiddens.append(h) @@ -298,23 +304,27 @@ def _get_model(self): result = tf.reshape(flatten, [-1] + self._matrix_shape) else: # Forecast after `self._out_time` days - hiddens = [tf.zeros_like(inputs)] + initial_shape = tf.concat([[self._out_time], tf.shape(inputs)[1:]], axis=0) + hiddens = [tf.zeros(initial_shape)] # Stacked ConvLSTM Decoder - for kernel, depth, state in zip(self._kernels, self._depths, states): - cell = ConvLSTMCell(self._matrix_shape, kernel, depth) - h, _ = tf.nn.dynamic_rnn(cell, hiddens[-1], self._out_time, initial_state=state, time_major=True) + for i, (kernel, depth, state) in enumerate(zip(self._kernels, self._depths, states)): + with tf.variable_scope('{}th_dec'.format(i)): + cell = ConvLSTMCell(self._matrix_shape, kernel, depth) + h, _ = tf.nn.dynamic_rnn(cell, hiddens[-1], initial_state=state, time_major=True) hiddens.append(h) concat = tf.concat(hiddens[1:], axis=-1) - shape = tf.shape(concat) + concat_t = tf.transpose(concat, [1, 0, 2, 3, 4]) + + shape = concat_t.shape.as_list() + out_shape = [-1, self._out_time] + self._matrix_shape - reduced_shape = (tf.reduce_prod(shape[:2]), self._matrix_shape[0], self._matrix_shape[1], shape[-1]) - reshaped = tf.reshape(concat, reduced_shape) + reshaped = tf.reshape(concat_t, [-1] + shape[2:]) flatten = tf.layers.conv2d(reshaped, 1, (1, 1), (1, 1), padding='SAME') - recover = tf.reshape(flatten, shape[:-1]) + recover = tf.reshape(flatten, out_shape) result = recover From 66fc5209c4c71fe5a1b532edda90d9458d442a72 Mon Sep 17 00:00:00 2001 From: revsic Date: Tue, 26 Jun 2018 05:07:22 +0900 Subject: [PATCH 5/6] Update Train - Add training routine --- train.py | 45 +++++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/train.py b/train.py index cb3db3c..ae11a4f 100644 --- a/train.py +++ b/train.py @@ -1,39 +1,60 @@ import os import model +import preprocess import tensorflow as tf flags = tf.app.flags flags.DEFINE_float('learning_rate', 1e-4, 'Float, learning rate, default 1e-4.') flags.DEFINE_float('beta1', 0.9, 'Float, beta1 value in Adam, default 0.9.') -flags.DEFINE_integer('epoch', 20, 'Integer, number of epochs, default 20.') -flags.DEFINE_integer('batch_size', 128, 'Integer, size of batch, default 128.') +flags.DEFINE_integer('epoch', 100, 'Integer, number of epochs, default 20.') +flags.DEFINE_integer('batch_size', 55, 'Integer, size of batch, default 128.') flags.DEFINE_integer('ckpt_interval', 5, 'Integer, interval for writing checkpoint, default 5') flags.DEFINE_string('name', 'default', 'String, name of model, default `default`.') -flags.DEFINE_string('summary_dir', './summary', 'String, dir name for saving tensor summary, default `./summary`.') -flags.DEFINE_string('ckpt_dir', './ckpt', 'String, dir name for saving checkpoint, default `./ckpt_dir`.') +flags.DEFINE_string('summary_dir', 'summary', 'String, dir name for saving tensor summary, default `./summary`.') +flags.DEFINE_string('ckpt_dir', 'ckpt', 'String, dir name for saving checkpoint, default `./ckpt_dir`.') FLAGS = flags.FLAGS + def main(_): # total_x, total_y, x_dim, y_dim ckpt_path = os.path.join(FLAGS.ckpt_dir, FLAGS.name) + (train_x, train_y), (test_x, test_y) = preprocess.create_dataset() - batch = model.Batch(total_x, total_y, 128) + batch = model.Batch(train_x, train_y, FLAGS.epoch) + print('start session') with tf.Session() as sess: - basic_model = model.BasicModel(x_dim, y_dim, FLAGS.learning_rate, FLAGS.beta1) - writer = tf.summary.FileWriter(os.path.join(FLAGS.summary_dir, FLAGS.name), sess.graph) + predicator = model.Predicator(matrix_shape=[9, 8], + num_time=7, + out_time=7, + kernels=[[5, 5], [5, 5], [5, 5], [5, 5], [5, 5]], + depths=[256, 128, 128, 64, 32], + learning_rate=FLAGS.learning_rate, + beta1=FLAGS.beta1) + + train_path = os.path.join(FLAGS.summary_dir, FLAGS.name, 'train') + test_path = os.path.join(FLAGS.summary_dir, FLAGS.name, 'test') + + train_writer = tf.summary.FileWriter(train_path, sess.graph) + test_writer = tf.summary.FileWriter(test_path, sess.graph) + print('start training') sess.run(tf.global_variables_initializer()) for i in range(FLAGS.epoch): for n in range(batch.iter_per_epoch): batch_x, batch_y = batch() - basic_model.train(sess, batch_x, batch_y) + predicator.train(sess, batch_x, batch_y) - summary = basic_model.inference(sess, basic_model.summary, batch_x, batch_y) - writer.add_summary(summary) + print(i, 'th epoch') + summary = predicator.inference(sess, predicator.summary, batch_x, batch_y) + train_writer.add_summary(summary, global_step=i) + + summary = predicator.inference(sess, predicator.summary, test_x, test_y) + test_writer.add_summary(summary, global_step=i) if (i + 1) % FLAGS.ckpt_interval == 0: - basic_model.dump(sess, ckpt_path) + predicator.dump(sess, ckpt_path, i) + if __name__ == '__main__': - tf.app.run() \ No newline at end of file + tf.app.run() From 557bd4da1047f91de9efd17e489f53807cb21326 Mon Sep 17 00:00:00 2001 From: revsic Date: Tue, 26 Jun 2018 05:13:43 +0900 Subject: [PATCH 6/6] Update README - Fix ipynb to raw python --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1e310bc..94e3a59 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Fine-Dust-Prediction Prediction of daily average amount of fine dust by tensorflow. -## Pre-processing -Pre-processing daily average amount of fine dust(pm10), bundling it into 7 days. +## Preprocessing +Preprocessing daily average amount of fine dust(pm10), bundling it into 7 days. For the convolutional layer, the amount of fine dust for each region is mapped to the geographical map of Seoul, 9x8 matrix. @@ -16,9 +16,7 @@ The data was extracted from [Degree of Seoul Daily Average Air Pollution](http:/ Feed 5D Tensor (time_dim, batch_size, height, width, channel) to ConvLSTM Cell and it returns hidden unit and state. -There is [prediction](https://github.com/revsic/Fine-Dust-Prediction/blob/master/Fine-Dust-Prediction.ipynb) and [forecasting](https://github.com/revsic/Fine-Dust-Prediction/blob/master/Fine-Dust-Forecaster.ipynb) models. Prediction model flatten an output of the last ConvLSTM Cell by 1x1 convolution and calculate MSE loss with the next day's fine dust data. - -Forecasting model is the Stacked ConvLSTM Encoder-Decoder model. Stacked encoder summary the sequential data to the fixed-length vector and it is feeded to an initial state of the decoder model. Stacked decoder model generate stacked sequential data and it is flattened by 1x1 convolution. It produces 7 days prediction. +The `Predicator` model is the Stacked ConvLSTM Encoder-Decoder model. Stacked encoder summary the sequential data to the fixed-length vector and it is feeded to an initial state of the decoder model. Stacked decoder model generate sequential data and it is flattend by 1x1 convolution. It produces default 7 days prediction. ## Conclusion