{"cells":[{"metadata":{},"cell_type":"markdown","source":"코드 설명\n\n1. 먼저 자료를 가지고 와서 256*256 matrix 형태로 만들어서 그려진 부분을 1로 놓고 나머지는 0으로 놓습니다.\n\n2. CNN 모델을 만듭니다.\n\n3. 분류할 내용이 340개나 되기 때문에 이를 몇 집단으로 쪼개서 학습한 후 test자료에서는 확률이 가장 높은 것 3개를 택합니다."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport math\nimport random\nimport tensorflow as tf\nimport keras\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten\nfrom keras.layers.convolutional import Conv2D, MaxPooling2D\nfrom keras.utils import np_utils\nfrom keras.callbacks import EarlyStopping\nimport os\nimport cv2\nimport ast\n%matplotlib inline\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"path_dir = \"../input/quickdraw-doodle-recognition/train_simplified\"\nfile_list = os.listdir(path_dir)\n\nfile_list = [word.replace('.csv', '') for word in file_list]\n\nfile_list","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"submission 자료를 갖고 와서 좀 수정해줍니다."},{"metadata":{"trusted":true},"cell_type":"code","source":"path_csv3 = '../input/quickdraw-doodle-recognition/test_simplified.csv'\n\ndata3 = pd.read_csv(path_csv3)\n\ndata3['listed'] = \"a\"\ndata3['probability'] = 0.0001\ndata3['listed2'] = \"a\"\ndata3['probability2'] = 0.0001\ndata3['listed3'] = \"a\"\ndata3['probability3'] = 0.0001","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"다음은 matrix를 만드는 함수입니다."},{"metadata":{"trusted":true},"cell_type":"code","source":"def draw_matrix(list_raw):\n    A = np.zeros((256, 256))\n    xx = []\n    yy = []\n    for list1 in list_raw:\n        xx = xx + list1[0]\n        yy = yy + list1[1]\n    minx = min(xx)\n    maxx = max(xx)\n    miny = min(yy)\n    maxy = max(yy)\n\n    midx = round(127-(maxx-minx)/2)\n    midy = round(127-(maxy-miny)/2)\n    \n    for i in range(len(list_raw)):\n        length1 = len(list_raw[i][0])\n        length2 = len(list_raw[i][1])\n        list_raw[i][0] = [min(list_raw[i][0][j]+midx, 255) for j in range(length1)]\n        list_raw[i][1] = [min(list_raw[i][1][j]+midy, 255) for j in range(length2)]\n        \n    for list1 in list_raw:\n        for i in range(1,len(list1[0])):\n            x2 = list1[0][i]\n            y2 = list1[1][i]\n            x1 = list1[0][i-1]\n            y1 = list1[1][i-1]\n            \n            decide = max(abs(x2-x1), abs(y2-y1))\n            if decide == abs(x2- x1) and decide > 0:\n                slope = (y2-y1)/(x2-x1)\n                if x1 < x2:\n                    for j in range(x1, x2+1):\n                        x = j\n                        y = y1+slope*(j-x1)\n                        y = round(y)\n                        A[x, y] = 1\n                else:\n                    for j in range(x2, x1+1):\n                        x = j\n                        y = y1+slope*(j-x1)\n                        y = round(y)\n                        A[x, y] = 1\n            elif decide == abs(y2-y1) and decide > 0:\n                slope = (x2-x1)/(y2-y1)\n                if y1 < y2:\n                    for j in range(y1, y2+1):\n                        y = j\n                        x = x1+slope*(j-y1)\n                        x = round(x)\n                        A[x, y] = 1                   \n                else:\n                    for j in range(y2, y1+1):\n                        y = j\n                        x = x1+slope*(j-y1)\n                        x = round(x)\n                        A[x, y] = 1           \n            elif x1 == x2:\n                if y1 < y2:\n                    for j in range(y1, y2+1):\n                        A[x1, j] = 1\n                else:\n                    for j in range(y2, y1+1):\n                        A[x1, j] = 1\n            elif y1 == y2:\n                if x1 < x2:\n                    for j in range(x1, x2+1):\n                        A[j, y1] = 1\n                else:\n                    for j in range(x2, x1+1):\n                        A[j, y1] = 1\n                        \n    return A\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"이게 잘 맞는지 예를 들어 확인해봅니다."},{"metadata":{"trusted":true},"cell_type":"code","source":"data_example = pd.read_csv(path_csv3)\nlist_raw = data_example['drawing'][100]\nlist_raw = ast.literal_eval(list_raw)\nA = draw_matrix(list_raw)\nplt.matshow(A)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"CNN 모델을 만들어줍니다."},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\nmodel.add(Conv2D(100, kernel_size=(5, 5), strides=(1, 1), padding='same',\n                 activation='relu',\n                 input_shape=(256, 256,1)))\n\nmodel.add(MaxPooling2D(pool_size=(4, 4), strides=(4, 4)))\nmodel.add(Conv2D(64, (4, 4), activation='relu', padding='same'))\nmodel.add(MaxPooling2D(pool_size=(4, 4)))\nmodel.add(Dropout(0.25))\nmodel.add(Flatten())\nmodel.add(Dense(1000, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(17, activation='softmax'))\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"학습하고 test 한 뒤 결과를 제출합니다."},{"metadata":{"trusted":true},"cell_type":"code","source":"file_list = random.sample(file_list, 340)\n\ntrain_N = 600\ntest_N = 200\n\n\nfor epoch in range(20):\n    A = np.zeros((17*train_N, 256, 256, 1))\n    B = np.zeros((17*test_N, 256, 256, 1))\n    A1 = [i for i in range(17*train_N)]\n    sampling2 = random.sample(A1, 17*train_N)\n    B1 = [i for i in range(17*test_N)]\n    sampling3 = random.sample(B1, 17*test_N)\n\n    y_train = [0 for i in range(17*train_N)]\n    y_test = [0 for i in range(17*test_N)]\n    l_train = 0\n    l_test = 0\n    l = 0\n    \n    file_list2 = file_list[(17*epoch):(17*epoch+17)]\n    for download in file_list2:\n        path_csv = '../input/quickdraw-doodle-recognition/train_simplified/'\n        path_csv2 = path_csv + download + '.csv'\n        data = pd.read_csv(path_csv2)\n        select = [i for i in range(len(data['drawing']))]\n        sampling = random.sample(select, train_N+test_N)\n        for i in range(train_N):\n            key = sampling[i]\n            list_raw = data['drawing'][key]\n            list_raw = ast.literal_eval(list_raw)\n            A[sampling2[l_train], :, :, 0] = draw_matrix(list_raw)\n            y_train[sampling2[l_train]] = l\n            l_train += 1\n        \n        \n        for i in range(train_N, test_N):\n            key = sampling[i]\n            list_raw = data['drawing'][key]\n            list_raw = ast.literal_eval(list_raw)\n            B[sampling3[l_test], :, :, 0] = draw_matrix(list_raw)\n            y_test[sampling3[l_test]] = l\n            l_test += 1\n        l += 1\n    y_train = np_utils.to_categorical(y_train, 17)\n    y_test = np_utils.to_categorical(y_test, 17)\n    \n    \n    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])\n    batch_size = 50\n    epochs = 5\n    x_train = A\n    x_test = B\n    \n    hist = model.fit(x_train, y_train, validation_data = (x_test, y_test),\n                 batch_size=batch_size,\n                 epochs=epochs,\n                 verbose=1)\n    \n    \n    for testing in range(len(data3)):\n        K = np.zeros((256, 256))\n        list_raw = data3['drawing'][testing]\n        list_raw = ast.literal_eval(list_raw)\n        K = np.zeros((1, 256, 256, 1))\n        K[0, :, :,0] = draw_matrix(list_raw)\n        \n        predicted_result = model.predict(K)\n        key = np.where(predicted_result[0] == max(predicted_result[0]))\n        key2 = list(key[0])[0]\n        name = file_list2[key2]\n        probs = max(predicted_result[0])\n        if probs > data3['probability'][testing]:\n            if data3['probability2'][testing] == 0.0001:\n                data3['listed2'][testing] = name\n                data3['probability2'][testing] = probs\n            elif data3['probability3'][testing] == 0.0001:\n                data3['listed3'][testing] = name\n                data3['probability3'][testing] = probs\n            else:\n                data3['listed'][testing] = name\n                data3['probability'][testing] = probs\n        elif probs >data3['probability2'][testing]:\n            data3['listed2'][testing] = name\n            data3['probability2'][testing] = probs\n        elif probs >data3['probability3'][testing]:\n            data3['listed3'][testing] = name\n            data3['probability3'][testing] = probs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_final = pd.read_csv('../input/quickdraw-doodle-recognition/sample_submission.csv')\n\nfor i in range(len(data3)):\n    data3['listed'][i] = data3['listed'][i].replace(\" \", \"_\")\n    data3['listed2'][i] = data3['listed2'][i].replace(\" \", \"_\")\n    data3['listed3'][i] = data3['listed3'][i].replace(\" \", \"_\")\n    data_final['word'][i] = data3['listed'][i] + \" \" + data3['listed2'][i] + \" \" + data3['listed3'][i]\n    if i % 1000 == 0:\n        print(i//1000)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_final.to_csv('submission_final.csv', index = False)","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}