2020年6月6日土曜日

fast.aiでCOVID-19 Xray Dataset (Train & Test Sets)をClassification

コロナウイルスで自粛ムードの真っ只中、Kaggleで『COVID-19 Xray Dataset (Train & Test Sets)』というデータセットを見つけました。
前回に続いて、このデータを分析してみます。

元データでは、Train用とTest用に分かれていましたが、1つにまとめてdataフォルダー下に'NORMAL'と'PNEUMONIA'のフォルダーとして保存しました。


%reload_ext autoreload
%autoreload 2
%matplotlib inline


from fastai.vision import *
from fastai.metrics import accuracy


Data Preparation

tfms = get_transforms(do_flip=False)


path = './data'; path


data=ImageDataBunch.from_folder(path,valid_pct=0.2,ds_tfms=tfms,size=224,bs=16)
data.normalize(imagenet_stats)


サンプルデータの表示

data.show_batch(rows=3,figsize=(5,5))



クラス名とクラス数の確認

print(data.classes)

  ['NORMAL', 'PNEUMONIA']


len(data.classes)

  2

modelの作成

import torchvision.models as models


learn1 = cnn_learner(data, models.resnet101, metrics=accuracy,callback_fns=ShowGraph)


Learning rate finder

earn1 = cnn_learner(data, models.resnet101, metrics=accuracy, callback_fns=ShowGraph)
learn1.unfreeze()
learn1.lr_find()
learn1.recorder.plot()
learn1.recorder.plot_lr()



Training

learn1 = cnn_learner(data, models.resnet101, metrics=accuracy, callback_fns=ShowGraph)
learn1.unfreeze()
learn1.fit_one_cycle(20, slice(1e-5,1e-4), pct_start=0.10)
learn1.recorder.plot_lr()

epochtrain_lossvalid_lossaccuracytime
01.1046080.6815580.59459500:06
10.9099590.1502440.91891900:06
20.6608420.0831280.94594600:06
30.5137640.1265560.94594600:06
40.3914560.1370530.94594600:07
50.3249140.1268450.97297300:06
60.2684650.0965470.97297300:06
70.2235950.0171471.00000000:06
80.1880710.1054460.97297300:07
90.1606100.0206551.00000000:06
100.1396890.0214691.00000000:07
110.1163900.0148321.00000000:06
120.1108000.0177431.00000000:06
130.1118020.1564240.94594600:06
140.0989270.1569560.94594600:06
150.0910040.0470440.97297300:06
160.0854180.0247390.97297300:06
170.0742400.0079741.00000000:06
180.0754800.0044381.00000000:06
190.0732070.0028891.00000000:06



あまり良い学習は出来てないようです。


training結果の分析

Load pre-trained weights

learn = learn.load("covid19-res101")


trainingの結果

interp = ClassificationInterpretation.from_learner(learn)

losses,idxs = interp.top_losses()

len(data.valid_ds)==len(losses)==len(idxs)

  True

interp.plot_top_losses(16, figsize=(15,11))



Confusion matrix
interp.plot_confusion_matrix(figsize=(12,12), dpi=60)

分類は100%出来ているようです。


検証データのクラス毎のaccuracy(取り敢えず・・・)

import numpy as np

res_corr=interp.confusion_matrix()

#classの数
class_num=data.c

#class毎のデータ総数
class_sum=np.sum(res_corr, axis=1)

for i in range(class_num):
    print(data.classes[i],':','{:.4f}'.format(res_corr[i,i]/class_sum[i]))

  NORMAL : 1.0000
  PNEUMONIA : 1.0000