{"cells":[{"cell_type":"code","execution_count":null,"metadata":{"collapsed":false},"outputs":[],"source":"# -*- coding: utf-8 -*-\n\nimport numpy as np\n\nimport os\nimport glob\nimport cv2\nimport math\nimport pickle\nimport datetime\nimport pandas as pd\n\nfrom sklearn.cross_validation import train_test_split\nfrom sklearn.cross_validation import KFold\nfrom keras.models import Sequential\nfrom keras.layers.core import Dense, Dropout, Flatten\nfrom keras.layers.convolutional import Convolution2D, MaxPooling2D, \\\n                                       ZeroPadding2D\n\n# from keras.layers.normalization import BatchNormalization\n# from keras.optimizers import Adam\nfrom keras.optimizers import SGD\nfrom keras.utils import np_utils\nfrom keras.models import model_from_json\n# from sklearn.metrics import log_loss\nfrom numpy.random import permutation\n\n\nnp.random.seed(2016)\nuse_cache = 1\n# color type: 1 - grey, 3 - rgb\ncolor_type_global = 3\n\n# color_type = 1 - gray\n# color_type = 3 - RGB\n\n\ndef get_im(path, img_rows, img_cols, color_type=1):\n    # Load as grayscale\n    if color_type == 1:\n        img = cv2.imread(path, 0)\n    elif color_type == 3:\n        img = cv2.imread(path)\n    # Reduce size\n    resized = cv2.resize(img, (img_cols, img_rows))\n    # mean_pixel = [103.939, 116.799, 123.68]\n    # resized = resized.astype(np.float32, copy=False)\n\n    # for c in range(3):\n    #    resized[:, :, c] = resized[:, :, c] - mean_pixel[c]\n    # resized = resized.transpose((2, 0, 1))\n    # resized = np.expand_dims(img, axis=0)\n    return resized\n\n\ndef get_driver_data():\n    dr = dict()\n    path = os.path.join('..', 'input', 'driver_imgs_list.csv')\n    print('Read drivers data')\n    f = open(path, 'r')\n    line = f.readline()\n    while (1):\n        line = f.readline()\n        if line == '':\n            break\n        arr = line.strip().split(',')\n        dr[arr[2]] = arr[0]\n    f.close()\n    return dr\n\n\ndef load_train(img_rows, img_cols, color_type=1):\n    X_train = []\n    y_train = []\n    driver_id = []\n\n    driver_data = get_driver_data()\n\n    print('Read train images')\n    for j in range(10):\n        print('Load folder c{}'.format(j))\n        path = os.path.join('..', 'input', 'imgs', 'train',\n                            'c' + str(j), '*.jpg')\n        files = glob.glob(path)\n        for fl in files:\n            flbase = os.path.basename(fl)\n            img = get_im(fl, img_rows, img_cols, color_type)\n            X_train.append(img)\n            y_train.append(j)\n            driver_id.append(driver_data[flbase])\n\n    unique_drivers = sorted(list(set(driver_id)))\n    print('Unique drivers: {}'.format(len(unique_drivers)))\n    print(unique_drivers)\n    return X_train, y_train, driver_id, unique_drivers\n\n\ndef load_test(img_rows, img_cols, color_type=1):\n    print('Read test images')\n    path = os.path.join('..', 'input', 'imgs', 'test', '*.jpg')\n    files = glob.glob(path)\n    X_test = []\n    X_test_id = []\n    total = 0\n    thr = math.floor(len(files)/10)\n    for fl in files:\n        flbase = os.path.basename(fl)\n        img = get_im(fl, img_rows, img_cols, color_type)\n        X_test.append(img)\n        X_test_id.append(flbase)\n        total += 1\n        if total % thr == 0:\n            print('Read {} images from {}'.format(total, len(files)))\n\n    return X_test, X_test_id\n\n\ndef cache_data(data, path):\n    if not os.path.isdir('cache'):\n        os.mkdir('cache')\n    if os.path.isdir(os.path.dirname(path)):\n        file = open(path, 'wb')\n        pickle.dump(data, file)\n        file.close()\n    else:\n        print('Directory doesnt exists')\n\n\ndef restore_data(path):\n    data = dict()\n    if os.path.isfile(path):\n        print('Restore data from pickle........')\n        file = open(path, 'rb')\n        data = pickle.load(file)\n    return data\n\n\ndef save_model(model, index, cross=''):\n    json_string = model.to_json()\n    if not os.path.isdir('cache'):\n        os.mkdir('cache')\n    json_name = 'architecture' + str(index) + cross + '.json'\n    weight_name = 'model_weights' + str(index) + cross + '.h5'\n    open(os.path.join('cache', json_name), 'w').write(json_string)\n    model.save_weights(os.path.join('cache', weight_name), overwrite=True)\n\n\ndef read_model(index, cross=''):\n    json_name = 'architecture' + str(index) + cross + '.json'\n    weight_name = 'model_weights' + str(index) + cross + '.h5'\n    model = model_from_json(open(os.path.join('cache', json_name)).read())\n    model.load_weights(os.path.join('cache', weight_name))\n    return model\n\n\ndef split_validation_set(train, target, test_size):\n    random_state = 51\n    X_train, X_test, y_train, y_test = \\\n        train_test_split(train, target,\n                         test_size=test_size,\n                         random_state=random_state)\n    return X_train, X_test, y_train, y_test\n\n\ndef create_submission(predictions, test_id, info):\n    result1 = pd.DataFrame(predictions, columns=['c0', 'c1', 'c2', 'c3',\n                                                 'c4', 'c5', 'c6', 'c7',\n                                                 'c8', 'c9'])\n    result1.loc[:, 'img'] = pd.Series(test_id, index=result1.index)\n    now = datetime.datetime.now()\n    if not os.path.isdir('subm'):\n        os.mkdir('subm')\n    suffix = info + '_' + str(now.strftime(\"%Y-%m-%d-%H-%M\"))\n    sub_file = os.path.join('subm', 'submission_' + suffix + '.csv')\n    result1.to_csv(sub_file, index=False)\n\n\ndef read_and_normalize_and_shuffle_train_data(img_rows, img_cols,\n                                              color_type=1):\n\n    cache_path = os.path.join('cache', 'train_r_' + str(img_rows) +\n                              '_c_' + str(img_cols) + '_t_' +\n                              str(color_type) + '.dat')\n\n    if not os.path.isfile(cache_path) or use_cache == 0:\n        train_data, train_target, driver_id, unique_drivers = \\\n            load_train(img_rows, img_cols, color_type)\n        cache_data((train_data, train_target, driver_id, unique_drivers),\n                   cache_path)\n    else:\n        print('Restore train from cache!')\n        (train_data, train_target, driver_id, unique_drivers) = \\\n            restore_data(cache_path)\n\n    train_data = np.array(train_data, dtype=np.uint8)\n    train_target = np.array(train_target, dtype=np.uint8)\n\n    if color_type == 1:\n        train_data = train_data.reshape(train_data.shape[0], color_type,\n                                        img_rows, img_cols)\n    else:\n        train_data = train_data.transpose((0, 3, 1, 2))\n\n    train_target = np_utils.to_categorical(train_target, 10)\n    train_data = train_data.astype('float32')\n    mean_pixel = [103.939, 116.779, 123.68]\n    for c in range(3):\n        train_data[:, c, :, :] = train_data[:, c, :, :] - mean_pixel[c]\n    # train_data /= 255\n    perm = permutation(len(train_target))\n    train_data = train_data[perm]\n    train_target = train_target[perm]\n    print('Train shape:', train_data.shape)\n    print(train_data.shape[0], 'train samples')\n    return train_data, train_target, driver_id, unique_drivers\n\n\ndef read_and_normalize_test_data(img_rows=224, img_cols=224, color_type=1):\n    cache_path = os.path.join('cache', 'test_r_' + str(img_rows) +\n                              '_c_' + str(img_cols) + '_t_' +\n                              str(color_type) + '.dat')\n    if not os.path.isfile(cache_path) or use_cache == 0:\n        test_data, test_id = load_test(img_rows, img_cols, color_type)\n        cache_data((test_data, test_id), cache_path)\n    else:\n        print('Restore test from cache!')\n        (test_data, test_id) = restore_data(cache_path)\n\n    test_data = np.array(test_data, dtype=np.uint8)\n\n    if color_type == 1:\n        test_data = test_data.reshape(test_data.shape[0], color_type,\n                                      img_rows, img_cols)\n    else:\n        test_data = test_data.transpose((0, 3, 1, 2))\n\n    test_data = test_data.astype('float32')\n    mean_pixel = [103.939, 116.779, 123.68]\n    for c in range(3):\n        test_data[:, c, :, :] = test_data[:, c, :, :] - mean_pixel[c]\n    # test_data /= 255\n    print('Test shape:', test_data.shape)\n    print(test_data.shape[0], 'test samples')\n    return test_data, test_id\n\n\ndef dict_to_list(d):\n    ret = []\n    for i in d.items():\n        ret.append(i[1])\n    return ret\n\n\ndef merge_several_folds_mean(data, nfolds):\n    a = np.array(data[0])\n    for i in range(1, nfolds):\n        a += np.array(data[i])\n    a /= nfolds\n    return a.tolist()\n\n\ndef merge_several_folds_geom(data, nfolds):\n    a = np.array(data[0])\n    for i in range(1, nfolds):\n        a *= np.array(data[i])\n    a = np.power(a, 1/nfolds)\n    return a.tolist()\n\n\ndef copy_selected_drivers(train_data, train_target, driver_id, driver_list):\n    data = []\n    target = []\n    index = []\n    for i in range(len(driver_id)):\n        if driver_id[i] in driver_list:\n            data.append(train_data[i])\n            target.append(train_target[i])\n            index.append(i)\n    data = np.array(data, dtype=np.float32)\n    target = np.array(target, dtype=np.float32)\n    index = np.array(index, dtype=np.uint32)\n    return data, target, index\n\n\ndef vgg_std16_model(img_rows, img_cols, color_type=1):\n    model = Sequential()\n    model.add(ZeroPadding2D((1, 1), input_shape=(color_type,\n                                                 img_rows, img_cols)))\n    model.add(Convolution2D(64, 3, 3, activation='relu'))\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(64, 3, 3, activation='relu'))\n    model.add(MaxPooling2D((2, 2), strides=(2, 2)))\n\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(128, 3, 3, activation='relu'))\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(128, 3, 3, activation='relu'))\n    model.add(MaxPooling2D((2, 2), strides=(2, 2)))\n\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(256, 3, 3, activation='relu'))\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(256, 3, 3, activation='relu'))\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(256, 3, 3, activation='relu'))\n    model.add(MaxPooling2D((2, 2), strides=(2, 2)))\n\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(512, 3, 3, activation='relu'))\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(512, 3, 3, activation='relu'))\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(512, 3, 3, activation='relu'))\n    model.add(MaxPooling2D((2, 2), strides=(2, 2)))\n\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(512, 3, 3, activation='relu'))\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(512, 3, 3, activation='relu'))\n    model.add(ZeroPadding2D((1, 1)))\n    model.add(Convolution2D(512, 3, 3, activation='relu'))\n    model.add(MaxPooling2D((2, 2), strides=(2, 2)))\n\n    model.add(Flatten())\n    model.add(Dense(4096, activation='relu'))\n    model.add(Dropout(0.5))\n    model.add(Dense(4096, activation='relu'))\n    model.add(Dropout(0.5))\n    model.add(Dense(1000, activation='softmax'))\n\n    model.load_weights('../input/vgg16_weights.h5')\n\n    # Code above loads pre-trained data and\n    model.layers.pop()\n    model.add(Dense(10, activation='softmax'))\n    # Learning rate is changed to 0.001\n    sgd = SGD(lr=1e-3, decay=1e-6, momentum=0.9, nesterov=True)\n    model.compile(optimizer=sgd, loss='categorical_crossentropy')\n    return model\n\n\ndef run_cross_validation(nfolds=10, nb_epoch=10, split=0.2, modelStr=''):\n\n    # Now it loads color image\n    # input image dimensions\n    img_rows, img_cols = 224, 224\n    batch_size = 64\n    random_state = 20\n\n    train_data, train_target, driver_id, unique_drivers = \\\n        read_and_normalize_and_shuffle_train_data(img_rows, img_cols,\n                                                  color_type_global)\n\n    # ishuf_train_data = []\n    # shuf_train_target = []\n    # index_shuf = range(len(train_target))\n    # shuffle(index_shuf)\n    # for i in index_shuf:\n    #     shuf_train_data.append(train_data[i])\n    #     shuf_train_target.append(train_target[i])\n\n    # yfull_train = dict()\n    # yfull_test = []\n    num_fold = 0\n    kf = KFold(len(unique_drivers), n_folds=nfolds,\n               shuffle=True, random_state=random_state)\n    for train_drivers, test_drivers in kf:\n        num_fold += 1\n        print('Start KFold number {} from {}'.format(num_fold, nfolds))\n        # print('Split train: ', len(X_train), len(Y_train))\n        # print('Split valid: ', len(X_valid), len(Y_valid))\n        # print('Train drivers: ', unique_list_train)\n        # print('Test drivers: ', unique_list_valid)\n        # model = create_model_v1(img_rows, img_cols, color_type_global)\n        # model = vgg_bn_model(img_rows, img_cols, color_type_global)\n        model = vgg_std16_model(img_rows, img_cols, color_type_global)\n\n        model.fit(train_data, train_target, batch_size=batch_size,\n                  nb_epoch=nb_epoch,\n                  show_accuracy=True, verbose=1,\n                  validation_split=split, shuffle=True)\n\n        # print('losses: ' + hist.history.losses[-1])\n\n        # print('Score log_loss: ', score[0])\n\n        save_model(model, num_fold, modelStr)\n\n        # predictions_valid = model.predict(X_valid, batch_size=128, verbose=1)\n        # score = log_loss(Y_valid, predictions_valid)\n        # print('Score log_loss: ', score)\n        # Store valid predictions\n        # for i in range(len(test_index)):\n        #    yfull_train[test_index[i]] = predictions_valid[i]\n\n    print('Start testing............')\n    test_data, test_id = read_and_normalize_test_data(img_rows, img_cols,\n                                                      color_type_global)\n    yfull_test = []\n\n    for index in range(1, num_fold + 1):\n        # 1,2,3,4,5\n        # Store test predictions\n        model = read_model(index, modelStr)\n        test_prediction = model.predict(test_data, batch_size=128, verbose=1)\n        yfull_test.append(test_prediction)\n\n    info_string = 'loss_' + modelStr \\\n                  + '_r_' + str(img_rows) \\\n                  + '_c_' + str(img_cols) \\\n                  + '_folds_' + str(nfolds) \\\n                  + '_ep_' + str(nb_epoch)\n\n    test_res = merge_several_folds_mean(yfull_test, nfolds)\n    create_submission(test_res, test_id, info_string)\n\n\ndef test_model_and_submit(start=1, end=1, modelStr=''):\n    img_rows, img_cols = 224, 224\n    # batch_size = 64\n    # random_state = 51\n    nb_epoch = 15\n\n    print('Start testing............')\n    test_data, test_id = read_and_normalize_test_data(img_rows, img_cols,\n                                                      color_type_global)\n    yfull_test = []\n\n    for index in range(start, end + 1):\n        # Store test predictions\n        model = read_model(index, modelStr)\n        test_prediction = model.predict(test_data, batch_size=128, verbose=1)\n        yfull_test.append(test_prediction)\n\n    info_string = 'loss_' + modelStr \\\n                  + '_r_' + str(img_rows) \\\n                  + '_c_' + str(img_cols) \\\n                  + '_folds_' + str(end - start + 1) \\\n                  + '_ep_' + str(nb_epoch)\n\n    test_res = merge_several_folds_mean(yfull_test, end - start + 1)\n    create_submission(test_res, test_id, info_string)\n\n\n# nfolds, nb_epoch, split\nrun_cross_validation(2, 20, 0.15, '_vgg_16_2x20')\n\n# nb_epoch, split\n# run_one_fold_cross_validation(10, 0.1)\n\n# test_model_and_submit(1, 10, 'high_epoch')\n"},{"cell_type":"code","execution_count":null,"metadata":{"collapsed":false},"outputs":[],"source":""}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"}},"nbformat":4,"nbformat_minor":0}