{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# BirdClef2023 Mel Classify Fastai\n","metadata":{"papermill":{"duration":0.00776,"end_time":"2023-04-01T15:20:13.048015","exception":false,"start_time":"2023-04-01T15:20:13.040255","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# install fastkaggle if not available\ntry: import fastkaggle\nexcept ModuleNotFoundError:\n    !pip install -Uq fastkaggle\nfrom fastkaggle import *","metadata":{"_kg_hide-input":false,"_kg_hide-output":true,"papermill":{"duration":10.279577,"end_time":"2023-04-01T15:20:23.333046","exception":false,"start_time":"2023-04-01T15:20:13.053469","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:40.066722Z","iopub.execute_input":"2023-04-11T02:25:40.067182Z","iopub.status.idle":"2023-04-11T02:25:40.074411Z","shell.execute_reply.started":"2023-04-11T02:25:40.067143Z","shell.execute_reply":"2023-04-11T02:25:40.073015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\nfrom fastai.vision.all import *\nfrom fastcore.parallel import *\nfrom sklearn.metrics import classification_report","metadata":{"papermill":{"duration":4.556993,"end_time":"2023-04-01T15:20:27.895399","exception":false,"start_time":"2023-04-01T15:20:23.338406","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:40.077042Z","iopub.execute_input":"2023-04-11T02:25:40.078285Z","iopub.status.idle":"2023-04-11T02:25:40.088217Z","shell.execute_reply.started":"2023-04-11T02:25:40.078231Z","shell.execute_reply":"2023-04-11T02:25:40.087228Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset","metadata":{"papermill":{"duration":0.005138,"end_time":"2023-04-01T15:20:27.907166","exception":false,"start_time":"2023-04-01T15:20:27.902028","status":"completed"},"tags":[]}},{"cell_type":"code","source":"comp = 'birdclef2023-sound-j-0-to-mel/mel'\npath = setup_comp(comp, install='fastai \"timm>=0.6.2.dev0\"')\ndisplay(path)","metadata":{"_kg_hide-output":true,"papermill":{"duration":11.130141,"end_time":"2023-04-01T15:20:39.042463","exception":false,"start_time":"2023-04-01T15:20:27.912322","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:40.090077Z","iopub.execute_input":"2023-04-11T02:25:40.091219Z","iopub.status.idle":"2023-04-11T02:25:51.203110Z","shell.execute_reply.started":"2023-04-11T02:25:40.091180Z","shell.execute_reply":"2023-04-11T02:25:51.201870Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"set_seed(42)\npath.ls()","metadata":{"_kg_hide-output":true,"papermill":{"duration":0.15837,"end_time":"2023-04-01T15:20:39.206442","exception":false,"start_time":"2023-04-01T15:20:39.048072","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:51.204987Z","iopub.execute_input":"2023-04-11T02:25:51.205310Z","iopub.status.idle":"2023-04-11T02:25:51.219985Z","shell.execute_reply.started":"2023-04-11T02:25:51.205278Z","shell.execute_reply":"2023-04-11T02:25:51.218817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trn_path = path\nfiles = get_image_files(trn_path)\ntst_path = path","metadata":{"papermill":{"duration":0.019176,"end_time":"2023-04-01T15:20:39.231195","exception":false,"start_time":"2023-04-01T15:20:39.212019","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:51.223092Z","iopub.execute_input":"2023-04-11T02:25:51.223458Z","iopub.status.idle":"2023-04-11T02:25:51.291233Z","shell.execute_reply.started":"2023-04-11T02:25:51.223422Z","shell.execute_reply":"2023-04-11T02:25:51.289925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img = PILImage.create(files[0])\nprint(img.size)\nimg.to_thumb(128)","metadata":{"papermill":{"duration":0.038116,"end_time":"2023-04-01T15:20:39.274667","exception":false,"start_time":"2023-04-01T15:20:39.236551","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:51.292813Z","iopub.execute_input":"2023-04-11T02:25:51.293872Z","iopub.status.idle":"2023-04-11T02:25:51.317911Z","shell.execute_reply.started":"2023-04-11T02:25:51.293822Z","shell.execute_reply":"2023-04-11T02:25:51.317044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from fastcore.parallel import *\ndef f(o): return PILImage.create(o).size\nsizes = parallel(f, files, n_workers=8)\npd.Series(sizes).value_counts()","metadata":{"_kg_hide-output":true,"papermill":{"duration":3.303689,"end_time":"2023-04-01T15:20:42.584571","exception":false,"start_time":"2023-04-01T15:20:39.280882","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:51.319117Z","iopub.execute_input":"2023-04-11T02:25:51.319689Z","iopub.status.idle":"2023-04-11T02:25:54.543155Z","shell.execute_reply.started":"2023-04-11T02:25:51.319654Z","shell.execute_reply":"2023-04-11T02:25:54.541741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"paths=[]\nlabels=[]\nfor dirname, _, filenames in os.walk('../input/birdclef2023-sound-j-0-to-mel/mel'):\n    for filename in filenames:\n        if filename[-4:]=='.png':\n            path=os.path.join(dirname, filename)\n            paths+=[path]\n            label=filename.split('_')[0]\n            labels+=[label]\nprint(labels[0:3])","metadata":{"papermill":{"duration":0.01944,"end_time":"2023-04-01T15:20:42.633270","exception":false,"start_time":"2023-04-01T15:20:42.613830","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:54.545329Z","iopub.execute_input":"2023-04-11T02:25:54.546150Z","iopub.status.idle":"2023-04-11T02:25:54.559594Z","shell.execute_reply.started":"2023-04-11T02:25:54.546094Z","shell.execute_reply":"2023-04-11T02:25:54.558435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df=pd.DataFrame(columns=['path','label'])\ndf['path']=paths\ndf['label']=labels\ndisplay(df['label'].value_counts())\ndf=df[df['label']!='crefra2'].reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2023-04-11T02:25:54.561322Z","iopub.execute_input":"2023-04-11T02:25:54.562108Z","iopub.status.idle":"2023-04-11T02:25:54.578029Z","shell.execute_reply.started":"2023-04-11T02:25:54.562063Z","shell.execute_reply":"2023-04-11T02:25:54.577077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Name=sorted(df['label'].unique().tolist())\nprint(len(Name))\nN=list(range(len(Name)))\nnormal_mapping=dict(zip(Name,N)) \nreverse_mapping=dict(zip(N,Name))\ndf['labeli']=df['label'].map(normal_mapping)\ndisplay(df)\nprint(normal_mapping)\ndisplay(df[['label','labeli']].drop_duplicates())","metadata":{"execution":{"iopub.status.busy":"2023-04-11T02:25:54.579828Z","iopub.execute_input":"2023-04-11T02:25:54.580601Z","iopub.status.idle":"2023-04-11T02:25:54.603690Z","shell.execute_reply.started":"2023-04-11T02:25:54.580555Z","shell.execute_reply":"2023-04-11T02:25:54.602387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"idx = np.random.permutation(len(df))\ntrain_size = int(len(df)*0.6)\ntrain_idx, test_idx = idx[:train_size], idx[train_size:]\ntrain_df, test_df = df.iloc[train_idx], df.iloc[test_idx]","metadata":{"papermill":{"duration":0.023245,"end_time":"2023-04-01T15:20:42.662639","exception":false,"start_time":"2023-04-01T15:20:42.639394","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:54.609457Z","iopub.execute_input":"2023-04-11T02:25:54.610063Z","iopub.status.idle":"2023-04-11T02:25:54.618023Z","shell.execute_reply.started":"2023-04-11T02:25:54.610015Z","shell.execute_reply":"2023-04-11T02:25:54.616544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## ImageDataLoaders.from_df","metadata":{"papermill":{"duration":0.005922,"end_time":"2023-04-01T15:20:42.674695","exception":false,"start_time":"2023-04-01T15:20:42.668773","status":"completed"},"tags":[]}},{"cell_type":"code","source":"dls = ImageDataLoaders.from_df(train_df,\n                               fn_col=0,\n                               label_col=1,\n                               valid_pct=0.4,\n                               folder='',\n                               item_tfms=Resize(100),\n                               label_delim=None,\n                               y_block=CategoryBlock(vocab=train_df['label'].unique()) \n                              )\ndls.show_batch(max_n=16)","metadata":{"execution":{"iopub.status.busy":"2023-04-11T02:25:54.620096Z","iopub.execute_input":"2023-04-11T02:25:54.620553Z","iopub.status.idle":"2023-04-11T02:25:56.248562Z","shell.execute_reply.started":"2023-04-11T02:25:54.620506Z","shell.execute_reply":"2023-04-11T02:25:56.247677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model","metadata":{"papermill":{"duration":0.022347,"end_time":"2023-04-01T15:20:47.291097","exception":false,"start_time":"2023-04-01T15:20:47.268750","status":"completed"},"tags":[]}},{"cell_type":"code","source":"learn = vision_learner(dls, 'resnet26', metrics=error_rate, path='.').to_fp16()\n\nlearn.lr_find(suggest_funcs=(valley, slide))\n\nlearn.fine_tune(10,0.01)","metadata":{"_kg_hide-output":true,"papermill":{"duration":2.257624,"end_time":"2023-04-01T15:20:49.569286","exception":false,"start_time":"2023-04-01T15:20:47.311662","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:56.260049Z","iopub.status.idle":"2023-04-11T02:25:56.260591Z","shell.execute_reply.started":"2023-04-11T02:25:56.260278Z","shell.execute_reply":"2023-04-11T02:25:56.260302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predict","metadata":{"papermill":{"duration":0.021961,"end_time":"2023-04-01T15:21:57.407948","exception":false,"start_time":"2023-04-01T15:21:57.385987","status":"completed"},"tags":[]}},{"cell_type":"code","source":"tst_dl = dls.test_dl(test_df)\ntst_files = get_image_files(tst_path).sorted()\n#tst_dl = dls.test_dl(tst_files)","metadata":{"_kg_hide-output":true,"papermill":{"duration":0.041672,"end_time":"2023-04-01T15:21:57.471590","exception":false,"start_time":"2023-04-01T15:21:57.429918","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:56.268120Z","iopub.status.idle":"2023-04-11T02:25:56.268681Z","shell.execute_reply.started":"2023-04-11T02:25:56.268364Z","shell.execute_reply":"2023-04-11T02:25:56.268394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"probs,_,idxs = learn.get_preds(dl=tst_dl, with_decoded=True)","metadata":{"papermill":{"duration":0.774747,"end_time":"2023-04-01T15:21:58.268609","exception":false,"start_time":"2023-04-01T15:21:57.493862","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:56.271287Z","iopub.status.idle":"2023-04-11T02:25:56.272543Z","shell.execute_reply.started":"2023-04-11T02:25:56.272251Z","shell.execute_reply":"2023-04-11T02:25:56.272282Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#print(idxs)\nprint(dls.vocab)\nnormal_mapping = dict(enumerate(dls.vocab))\n#print(normal_mapping)\nreverse_mapping = dict(zip(dls.vocab,list(range(len(dls.vocab)))))\n#print(reverse_mapping)","metadata":{"_kg_hide-output":true,"papermill":{"duration":0.034966,"end_time":"2023-04-01T15:21:58.326245","exception":false,"start_time":"2023-04-01T15:21:58.291279","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:56.274065Z","iopub.status.idle":"2023-04-11T02:25:56.275272Z","shell.execute_reply.started":"2023-04-11T02:25:56.274958Z","shell.execute_reply":"2023-04-11T02:25:56.274990Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#results = idxs.numpy()\ntest_pred=idxs.tolist()\nprint(pd.Series(test_pred).value_counts())","metadata":{"_kg_hide-output":true,"papermill":{"duration":0.03316,"end_time":"2023-04-01T15:21:58.381793","exception":false,"start_time":"2023-04-01T15:21:58.348633","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:56.276857Z","iopub.status.idle":"2023-04-11T02:25:56.277982Z","shell.execute_reply.started":"2023-04-11T02:25:56.277675Z","shell.execute_reply":"2023-04-11T02:25:56.277708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_true = test_df['labeli'].tolist()\nprint(test_df['labeli'].value_counts())","metadata":{"_kg_hide-output":true,"papermill":{"duration":0.036373,"end_time":"2023-04-01T15:21:58.440369","exception":false,"start_time":"2023-04-01T15:21:58.403996","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:56.281453Z","iopub.status.idle":"2023-04-11T02:25:56.282007Z","shell.execute_reply.started":"2023-04-11T02:25:56.281725Z","shell.execute_reply":"2023-04-11T02:25:56.281755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result=pd.DataFrame(columns=['true','pred','check'])\nresult['true']=test_true\nresult['pred']=test_pred\nfor i in range(len(result)):\n    result.loc[i,'check']=(result.loc[i,'true']==result.loc[i,'pred'])\ndisplay(result)\ndisplay(result['check'].value_counts())","metadata":{"execution":{"iopub.status.busy":"2023-04-11T02:25:56.283402Z","iopub.status.idle":"2023-04-11T02:25:56.283967Z","shell.execute_reply.started":"2023-04-11T02:25:56.283678Z","shell.execute_reply":"2023-04-11T02:25:56.283708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trueset=set(result['true'].unique().tolist())\npredset=set(result['pred'].unique().tolist())\nallset=trueset | predset\nprint(len(trueset),len(predset),len(allset))\nprint(trueset-predset,predset-trueset)","metadata":{"execution":{"iopub.status.busy":"2023-04-11T02:25:56.285665Z","iopub.status.idle":"2023-04-11T02:25:56.286192Z","shell.execute_reply.started":"2023-04-11T02:25:56.285912Z","shell.execute_reply":"2023-04-11T02:25:56.285940Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import classification_report\nprint(classification_report(test_true,test_pred,target_names=Name,digits=4))","metadata":{"execution":{"iopub.status.busy":"2023-04-11T02:25:56.287364Z","iopub.status.idle":"2023-04-11T02:25:56.287934Z","shell.execute_reply.started":"2023-04-11T02:25:56.287626Z","shell.execute_reply":"2023-04-11T02:25:56.287679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n# [Option] Convert the trained model to various formats","metadata":{"papermill":{"duration":0.023137,"end_time":"2023-04-01T15:21:58.549238","exception":false,"start_time":"2023-04-01T15:21:58.526101","status":"completed"},"tags":[]}},{"cell_type":"code","source":"!pip install tensorflow onnx\n!pip install onnx-tf","metadata":{"_kg_hide-output":true,"papermill":{"duration":37.72798,"end_time":"2023-04-01T15:22:36.300860","exception":false,"start_time":"2023-04-01T15:21:58.572880","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:56.289632Z","iopub.status.idle":"2023-04-11T02:25:56.290187Z","shell.execute_reply.started":"2023-04-11T02:25:56.289901Z","shell.execute_reply":"2023-04-11T02:25:56.289930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#save as onnx\nbatch_size = 1\ninput_shape = (3,100,100)\ntorch.onnx.export(learn.model.eval().cpu(), \n                  torch.randn(batch_size, *input_shape), \n                  \"model.onnx\", opset_version=11)\n\n#save as　tf\nimport onnx\nimport tensorflow as tf\nfrom onnx_tf.backend import prepare\nonnx_model = onnx.load('model.onnx')\ntf_graph = prepare(onnx_model)\ntf_graph.export_graph('tf_models')\n\n#save as　tflite\nconverter = tf.lite.TFLiteConverter.from_saved_model('tf_models')\ntflite_model = converter.convert()\nopen(\"model.tflite\", \"wb\").write(tflite_model)","metadata":{"papermill":{"duration":25.326073,"end_time":"2023-04-01T15:23:01.651792","exception":false,"start_time":"2023-04-01T15:22:36.325719","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T02:25:56.291402Z","iopub.status.idle":"2023-04-11T02:25:56.291976Z","shell.execute_reply.started":"2023-04-11T02:25:56.291688Z","shell.execute_reply":"2023-04-11T02:25:56.291719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"papermill":{"duration":0.024445,"end_time":"2023-04-01T15:23:01.700853","exception":false,"start_time":"2023-04-01T15:23:01.676408","status":"completed"},"tags":[]},"execution_count":null,"outputs":[]}]}