{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nfrom keras.preprocessing import image\nfrom tqdm import tqdm\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"nrows=None# for debug.\ntrain=pd.read_csv(\"../input/train.csv\",nrows=nrows)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8eedb0df3a6c283f7d058b0fdf9f57706ea03f89"},"cell_type":"code","source":"train.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6a97e351493e36e33e89c83468e0b7af177e6d28"},"cell_type":"code","source":"\nid_counts=train.Id.value_counts()\nprint(\"there are {} unique whale ids\".format(train.Id.unique().size))\nprint(\"average images number:{}\".format(id_counts.mean()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3390123746f756d941541d3f12ac878c63025d9a"},"cell_type":"code","source":"def load_imgs(names,base_dir,target_size=[100,100],limit=-1):\n    if limit!=-1:\n        names=names[:limit]\n    print(\"loading {} images\".format(limit))\n    N=len(names)\n    X=np.zeros([N]+target_size+[3,])\n    for i,name in enumerate(tqdm(names)):\n        img=image.load_img(os.path.join(base_dir,name),target_size=target_size)\n        X[i]=img\n    return X/255\nX=load_imgs(train.Image,\"../input/train\")\nY=pd.get_dummies(train.Id)\nid_names=Y.columns\nY=Y.values\nprint(\"Dataset prepared!\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0b8fb982d05645b5c6b41ff5d2310c3b5b58dd1f"},"cell_type":"code","source":"assert X.max()<=1,\"images should in range [0,1]\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e9f22bd2eaf73601ed18509e61055e905612e882"},"cell_type":"code","source":"def topn(m:np.array,n:int):\n    # from bigger to smaller.\n    return np.argsort(-m,axis=1)[:,:n]\ndef map5(y_true:np.ndarray,y_pred:np.ndarray):\n    \"\"\"\n    @param y_true: shape=[N,features] one hot encoding.\n    @param y_pred: shape=[N,features] softmax probability\n    @returns the competition metrics.\n    \"\"\"\n    target_index=np.argmax(y_true,axis=1)\n    top5_indexs=topn(y_pred,5)\n    N=y_pred.shape[0]\n    isin=np.zeros(N)\n    for i in range(N):\n        if target_index[i] in top5_indexs[i]:\n            isin[i]=1\n    return isin.mean().astype(np.float32)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"055f1b45bd8220b530f5917a98a3e8c52639dc2c"},"cell_type":"code","source":"print(\"test map5\")\ny1=np.random.randn(50000,100)\ny2=np.random.randn(50000,100)\nprint(\"shold close to 0.05(5/100)\")\nmap5(y1,y2)  # shold be close to 5/100","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"271cf930affbf5c80432cfdbacf42de962266314"},"cell_type":"code","source":"randomY=np.zeros([Y.shape[0],Y.shape[1]])\nrandomY[:,:]=Y.sum(axis=0)\nrandom_score=map5(Y,randomY)\nprint(\"random score is:\",random_score,\",a good model should above this value\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"939e900d5c863baef246a0d364113f6b916cb501"},"cell_type":"code","source":"from keras.layers import Conv2D,Dense,Input,BatchNormalization\nfrom keras import layers,models,losses,optimizers,metrics\nfrom keras import backend\nimport keras\nimport tensorflow as tf","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d01178968f1509362a8eddccc90ec72176abafee"},"cell_type":"code","source":"def tf_map5(y_true,y_pred):\n    \"\"\"\n    wappper of map5,to be a tensor operation\n    @param y_true: tensor.\n    @param y_pred: tensor.\n    \"\"\"\n    return tf.py_func(map5,[y_true,y_pred],tf.float32)\n    \n    \nclasses=Y.shape[1]\ndef build_model():\n\n    input_layer=layers.Input((100,100,3))\n    x=layers.Conv2D(32,(3,3),padding=\"same\",activation=\"relu\")(input_layer)\n    x=layers.Conv2D(32,(3,3),padding=\"same\")(x)\n    x=layers.BatchNormalization()(x)\n    x=layers.Activation(\"relu\")(x)\n    x=layers.MaxPooling2D(pool_size=(2,2),strides=[2,2])(x)\n\n    x=layers.Conv2D(64,(3,3),padding=\"same\",activation=\"relu\")(x)\n    x=layers.Conv2D(64,(3,3),padding=\"same\")(x)\n    x=layers.BatchNormalization()(x)\n    x=layers.Activation(\"relu\")(x)\n    x=layers.MaxPooling2D(pool_size=(2,2),strides=[2,2])(x)\n\n    x=layers.Conv2D(128,(3,3),padding=\"same\",activation=\"relu\")(x)\n    x=layers.Conv2D(128,(3,3),padding=\"same\")(x)\n    x=layers.BatchNormalization()(x)\n    x=layers.Activation(\"relu\")(x)\n    x=layers.MaxPooling2D(pool_size=(2,2),strides=[2,2])(x)\n    x=layers.Flatten()(x)\n    x=layers.Dense(units=classes,activation=\"softmax\")(x)\n\n    model=models.Model(input_layer,x)\n    return model\nkeras.backend.clear_session()\nmodel=build_model()\n# the learning_rate 0.001 is choose by fitting on the small batch(200).......\n\nmodel.compile(loss=losses.categorical_crossentropy,optimizer=optimizers.SGD(lr=0.001,momentum=0.9),metrics=[tf_map5])\nmodel.fit(X,Y,validation_split=0.2,epochs=3,batch_size=16)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"54b12bd37b2bafca12f2cd44f2b5039d417b1822"},"cell_type":"code","source":"# Train on 20288 samples, validate on 5073 samples\n# Epoch 1/10\n# 20288/20288 [==============================] - 141s 7ms/step - loss: 6.3519 - tf_map5: 0.3781 - val_loss: 6.0332 - val_tf_map5: 0.3860\n# Epoch 2/10\n# 20288/20288 [==============================] - 137s 7ms/step - loss: 5.3938 - tf_map5: 0.4115 - val_loss: 5.8058 - val_tf_map5: 0.4037\n# Epoch 3/10\n# 20288/20288 [==============================] - 137s 7ms/step - loss: 4.9662 - tf_map5: 0.4365 - val_loss: 5.7757 - val_tf_map5: 0.4140\n# Epoch 4/10\n# 20288/20288 [==============================] - 137s 7ms/step - loss: 4.3962 - tf_map5: 0.4833 - val_loss: 6.0837 - val_tf_map5: 0.3871\n# Epoch 5/10\n# 20288/20288 [==============================] - 137s 7ms/step - loss: 3.5756 - tf_map5: 0.5872 - val_loss: 5.8405 - val_tf_map5: 0.4193\n# Epoch 6/10\n# 20288/20288 [==============================] - 137s 7ms/step - loss: 2.6407 - tf_map5: 0.7620 - val_loss: 6.5429 - val_tf_map5: 0.3964\n# Epoch 7/10\n# 20288/20288 [==============================] - 137s 7ms/step - loss: 1.6129 - tf_map5: 0.8979 - val_loss: 7.5491 - val_tf_map5: 0.3830\n# Epoch 8/10\n# 20288/20288 [==============================] - 137s 7ms/step - loss: 0.9963 - tf_map5: 0.9485 - val_loss: 9.0888 - val_tf_map5: 0.2567\n# Epoch 9/10\n#  3520/20288 [====>.........................] - ETA: 1:46 - loss: 0.6372 - tf_map5: 0.9707","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ced443cd9129c3d5c3b2df00dc51af6e59513901"},"cell_type":"code","source":"import os\ntest_names=os.listdir(\"../input/test\")\nlimit=-1\nif limit!=-1:\n    test_names=test_names[:limit]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"217d2328ee26f6b5767c520f8a242326986cfa66"},"cell_type":"code","source":"import gc\ndel X\ndel Y\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"310180e8b088ddf0f5d556cc79583bfdfbfe17c8"},"cell_type":"code","source":"testX=load_imgs(test_names,\"../input/test\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b11c3cb49566aa9aab5c61758b0776caf9fc2108"},"cell_type":"code","source":"testY=model.predict(testX)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eec95f5b3ce74a0f2d479cec21808a5a5136b1cb"},"cell_type":"code","source":"print(\"make submission data frame\")\ntestY_5=topn(testY,5)\nID5=[] # the five id names\nfor i in range(len(testY_5)):\n    names=[]\n    for j in range(5):\n        names.append(id_names[testY_5[i][j]])\n    ID5.append(\" \".join(names))\ndf=pd.DataFrame()\ndf[\"Image\"]=test_names\ndf[\"Id\"]=ID5\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9b83006d276980018a71384633c30569af0ada2a"},"cell_type":"code","source":"del testX\ndel testY\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bc60a8b87f4c9b5763c70abc448296e71a6bd682"},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"15c0b5f7bb7bcd202aafa2a564ada9650ba1727b"},"cell_type":"code","source":"id_counts[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"71953922647f5077d202907261b842867b99f79b"},"cell_type":"code","source":"df.to_csv(\"submission.csv\",index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9a8f5831e84a0242457c164b0887969a1adf62ba"},"cell_type":"code","source":"!head -5 submission.csv","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"106a21bdbe4cfb204083732dd56264b893fe87a5"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ba64231893490dae1034c54f8169b057c7124139"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"14b4f545f72af0ce648b83c09fcc44eca249ea1f"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e3fdd2a94e018eed60b009bcd9d1009d6c80ac10"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}