2
Help us understand the problem. What are the problem?

posted at

updated at

はじめて1年で「Covid19鑑別精度90%越のAI」を作った話

MediTech代表の稲森です。
MediTech様_logo-yoko.jpg

◎自己紹介
 ➡21歳
 ➡鹿児島出身
 ➡診療放射線技術学科学生

MediTechは、AIやプログラミングに対する敷居の高さを払拭するために
AIやプログラミングについて自由に学ぶことのできる場所、
多くの人と繋がることのできる場所を目的として立ち上げたコミュニティです。
よろしくお願いします。

0. はじめに

 
今回の記事は、はじめて1年で「Covid19鑑別精度90%越のAI」を作った話です!

僕は、ちょうど1年前くらいにプログラミングをはじめました。

僕が診療放射線技術学科の学生であるということで、CTの画像からCovid19を予測するAIを作りました。

昨年から世界的に影響を与えているCovid19ですが、医師でない僕には画像を見ても

Covid19を判断することは出来ません・・・

しかし、今回90%を超える精度で鑑別することが出来ました🎉

目次

タイトル 備考
0 はじめに
1 データセットの準備
2 環境構築(Google Colaboratory) 初めてGoogleColaboを使う人向けです
3 Python実装コード 本記事のメインコンテンツです
4 実装結果
5 参考
6 おわりに
7 参照

1. データセットの準備

精度の良いモデルを作成するには、大量のデータセットが必要です。

そこで、今回はCT画像からCovid19の鑑別を行うにあたって、
大量のデータセットをKaggleからダウンロードしました。

データセットのKaggleリンクはこちら↓
SARS-COV-2 Ct-Scan Dataset

今回使ったデータセットのダウンロードはこちら

これからソースコードも記述していきますが、Githubにも載せています。

2. 環境構築(Google Colaboratory)

今回は、全ての方に簡単に実装していただくために
Google Colaboratoryを用いていきます。
colabo.PNG
これから、初めてGoogle Colaboratoryを使う方向けに少し手順を書いていきます。

① 新規ボタンを押す
    ↓
② その他の中にGoogle Colaboratoryがあればクリックして始める
    ↓
③ ない場合、アプリを追加を押してGoogle Colaboratoryと検索してインストール
 colabo2.PNG colabo4.PNG
④ これでコードを書いていく場所の準備は出来ました。
⑤ あとは、データセットをzip形式でGoogleDriveにアップロードしておきます。(ドラッグ&ドロップ)

詳しいGoogle Colaboratoryの使い方はこちらの記事を参考にしてみてください。
【秒速で無料GPUを使う】深層学習実践Tips on Colaboratory

3. Python実装コード

これから実際のソースコードを書いていきたいと思います。
jyujyutukaisen.zipをダウンロードしたら、
Google Driveにアップロードしておきましょう。

# Googleドライブをマウント
from google.colab import drive
drive.mount('/content/drive')

.zipのままGoogle Driveにアップロードしてください!

# Google ColaboratoryでZipファイルを解凍
from zipfile import ZipFile
file_name = '/content/drive/My Drive/jyujyutukaisen.zip'

with ZipFile(file_name, 'r') as zip:
zip.extractall()

zipファイルのままアップロードして、ここで解凍した方が時間短縮になります。

%tensorflow_version 1.x
import numpy as np
import keras
from keras.utils import np_utils
from keras.models import Sequential, Model, model_from_json
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.core import Dense, Dropout, Activation, Flatten
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc
from PIL import Image
import glob
%matplotlib inline

必要なライブラリをimportします。

folder = ["COVID", "non-COVID"]
image_size = 120

X_train = []
y_train = []
X_test = []
y_test = []


for index, name in enumerate(folder):
    dir = "/content/Covid19/train/" + name
    files = glob.glob(dir + "/*.png")
    for i, file in enumerate(files):
        image = Image.open(file)
        image = image.convert("RGB")
        image = image.resize((image_size, image_size))
        data = np.asarray(image)
        X_train.append(data)
        y_train.append(index)
        shuffle=True


for index, name in enumerate(folder):
    dir = "/content/Covid19/validation/" + name
    files = glob.glob(dir + "/*.png")
    for i, file in enumerate(files):
        image = Image.open(file)
        image = image.convert("RGB")
        image = image.resize((image_size, image_size))
        data = np.asarray(image)
        X_test.append(data)
        y_test.append(index)
        shuffle=True


X_train = np.array(X_train)
y_train = np.array(y_train)
X_test = np.array(X_test)
y_test = np.array(y_test)

X_train = X_train.astype('float32')
X_train = X_train / 255.0

X_test = X_test.astype('float32')
X_test = X_test / 255.0

# 正解ラベルの形式を変換
y_train = np_utils.to_categorical(y_train, 2)
y_test = np_utils.to_categorical(y_test,2)

それぞれフォルダ内の画像のリサイズ、正規化を行います。
また、
X_train
y_train
X_test
y_test
にそれぞれ格納していきます。

def model_train(X_train, y_train):
    model = Sequential()

    model.add(Conv2D(32, (3, 3), padding='same',input_shape=X_train.shape[1:]))
    model.add(Activation('relu'))
    model.add(Conv2D(32, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.20))

    model.add(Conv2D(64, (3, 3), padding='same'))
    model.add(Activation('relu'))
    model.add(Conv2D(64, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.20))

    model.add(Conv2D(64, (3, 3), padding='same'))
    model.add(Activation('relu'))
    model.add(Conv2D(64, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.20)) 

    model.add(Flatten())
    model.add(Dense(64))
    model.add(Activation('relu'))
    model.add(Dropout(0.5))
    model.add(Dense(2))
    model.add(Activation('softmax'))
    opt = keras.optimizers.adam(lr=0.0001, decay=1e-6)
    model.compile(loss='categorical_crossentropy',optimizer= opt,metrics=['accuracy'])
    return model

モデルの作成を行います。
以上のようなモデルにしています。

def plot_history(history):
    plt.plot(history.history['accuracy'],"o-",label="accuracy")
    plt.plot(history.history['val_accuracy'],"o-",label="val_acc")
    plt.title('model accuracy')
    plt.xlabel('epoch')
    plt.ylabel('accuracy')
    plt.legend(loc="lower right")
    plt.show()

    plt.plot(history.history['loss'],"o-",label="loss",)
    plt.plot(history.history['val_loss'],"o-",label="val_loss")
    plt.title('model loss')
    plt.xlabel('epoch')
    plt.ylabel('loss')
    plt.legend(loc='lower right')
    plt.show()

accuracy , validation_accuracy , loss , validation_lossを描画する
ための定義を行います。

#ROCを定義    
def plot_roc(pred,y):
    fpr, tpr, _ = roc_curve(y, pred)
    roc_auc = auc(fpr, tpr)

    plt.figure()
    plt.plot(fpr, tpr, label='ROC curve (area = %0.2f)' % roc_auc) # %0.2fで小数点第2位まで表示を指示
    plt.plot([0, 1], [0, 1], 'k--')
    plt.xlim([0.0, 1.0])
    plt.ylim([0.0, 1.05])
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('Receiver Operating Characteristic (ROC)')
    plt.legend(loc="lower right")
    plt.show()

ここでROC曲線を描くための定義を行います。

if __name__ == "__main__":
    model = model_train(X_train, y_train)
    history = model.fit(X_train, y_train, 
        epochs=100,
        batch_size=128,
        validation_data=(X_test, y_test),
             )
    json_string = model.to_json()
    open('Covid19.json', 'w').write(json_string)
    model.save_weights('Covid19hdf5')
    model.save("Covid19.h5")
    score = model.evaluate(X_train, y_train)

    print("test loss", score[0])
    print("test acc",  score[1])

    plot_history(history)

    #ROC
    pred = model.predict(X_test)
    pred = np.argmax(pred,axis=1)
    y_compare = np.argmax(y_test,axis=1)
    pred = pred[:] # Only positive cases
    plot_roc(pred,y_compare)

実際に、学習を行います。
さらに、学習曲線ROC曲線も描きます。

4. 実装結果

学習を終えた実装結果です。
計算時間は30~40分くらいだったと思います。

test loss:0.029283724984364403
test acc:0.9919354915618896

acc.png
loss.png
roc.png

結構良い精度の物が出来たのではないかと思っています。

5. 参考

過学習を防ぐために行った工夫

元々のkaggleのデータセットを用いて、順番に画像を分割して学習を行った場合
ロバスト性が低い結果となり、過学習が起きてしまいました…

そこで

ランダムtraining / Validation の振り分けを行い、過学習が改善されました。

似たようなデータが並んでいる場合、主観的に順番に分割するとtestとvalidationに
データの偏りが出来てしまい過学習が起きてしまうと考えられます。

ランダムなデータの分割にはこちらを参考にしました。
画像ディレクトリをtrain_test_splitする関数

ROC曲線(その他評価関数)

こちらの記事を参考にしてみてください。
       ↓
機械学習で使われる評価関数まとめ

モデルを評価するという事はとても重要な部分になるので、理解は重要です。

機械学習について

機械学習については、
機械学習って何?という記事にも書いています。
もし良ければ、読んでみてください。

6. おわりに

今回は、はじめて1年で「Covid19鑑別精度90%越のAI」を作った話
についての記事を書きました。

僕自身、まだプログラミングを初めて1年程です。

今回の記事にも間違い等や不足があるかと思います。
その場合は、教えていただけるとありがたいです。

しかし、はじめて1年の初学者でも作れるAIもあるということが伝えられたのではないかと思います。

また、MediTechを立ち上げプログラミングをもっと世の中に広めていきたいと思っています。

LGTMもしてくださると嬉しいです!

ぜひMediTechの方もよろしくお願いします。

7. 参照

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
2
Help us understand the problem. What are the problem?