Aidemyで新型コロナによる感染性肺炎診断支援アプリ 「COVID-19 AI Diagnostic support App」つくってみた!
経済貿易の促進をしているのですが、医療分野は今後の重点産業となる為、AIを活用した画像診断技術については、前々から興味を持っていました。また、新薬開発において、様々な臨床実験を経て得られるデータが多い為、データ分析による切り口は、医学への新たな貢献と少しでも実験による命の犠牲を減らせるのではないかと思い、医療×AIのアプリ制作をつくってみようと思いました。
今回はKaggleにあるカナダの国立モントリオール大学が提供して下さった5939枚の胸部X線データ「CoronaHack -Chest X-Ray-Dataset」を活用し、新型コロナウィルスに罹患し、肺炎を引き起こした患者と正常な肺のレントゲン画像分類アプリ「 COVID-19 AI Diagnostic support App」の制作を行います。
胸部レントゲン画像の分類は、医療現場の診断をサポートし、一人でも多くの助けになれたら嬉しいです。アプリは以下のリンクをご覧ください。
COVID-19 AI Diagnostic support App (感染性肺炎診断支援アプリ)
https://covid19aidiagnostic.herokuapp.com/
正常な肺と肺炎画像の機械学習 Val Accuraryの精度は90%以上
色々と大きな考えを述べましたが、やはり自分の力では何ともならない為、Aidemyチューターの助けを経て、コース内にあるコードで、機械学習とアプリ制作の2つのステップに分け、アプリ制作を進めていきます。まずはデータを読み込み、正常な肺と肺炎画像を学習させます。
手順は以下の通りです。
①KaggleからCoronaHack -Chest X-Ray-Datasetのデータをダウンロードする。
②Google driveにダウンロードしたZipファイルを入れる。
③新規のGoogle Coraboratoryを開き、Googleドライブから読み込む。
%cd /content/drive/MyDrive/
④ZipファイルをCoraboratory開く。
!unzip archive.zip
⑤カレントディレクトリーで直接データを取り出す。
%cd Coronahack-Chest-XRay-Dataset/Coronahack-Chest-XRay-Dataset/
⑥カレントディレクトリーの中のデータを見る。
!ls
⑦Pandasでデータを読み込む。dfという変数の中に、データが読み込まれる。
import pandas as pd
df=pd.read_csv("Chest_xray_Corona_Metadata.csv")
df
⑧データフレームの中に、どれくらいあるかをlen関数を使って数え、iで数値を取り出す。ilocで番号による参照を行う。ilocの中の i が行番号、:は全部を取ります。
参考-Aidemy ライブラリ「Pandas」基礎(表計算)1.3.7 番号による参照。
for i in range(len(df)):
print(df.iloc[i,:])
⑨データの読み込みが終わったが、ダウンロードした画像は、X線だけでなく、CTスキャンの画像もあった為、X_ray_image_nameだけを取り出し、画像データを読み込みます。ただ、どのデータがどのデータかがわからないので、辞書型にし、Normalはラベル0、Pnemonia(肺炎)はラベル1をつけます。そして、Testタイプから読み込むのか、Trainから読み込むのかを指示します。
import cv2
folder_dic = {"TRAIN":"train", "TEST":"test"}
label_dic = {"Normal":0, "Pnemonia":1}
X = []
y = []
for i in range(len(df)):
img_path = "Coronahack-Chest-XRay-Dataset/Coronahack-Chest-XRay-Dataset/{}/{}".format(foloder_dic[df.iloc[i,3]] , df.iloc[i,1])
img = cv2.imread(img_path)
img = cv2.resize(img, (50,50)
X.append(img)
y.append(label_dic[df.iloc[i,2]])
⑩Aidemy 男女識別コースの添削課題にあるコードを応用します。学習結果は以下の通りとなりました。Accuracyは学習用データに対する精度で80%以上となり、Val_Accuraryはテストデータに対する精度ですが、90%以上です。
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.layers import Dense, Dropout, Flatten, Input
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras import optimizers
X = np.array(X)
y = np.array(y)
rand_index = np.random.permutation(np.arange(len(X)))
X = X[rand_index]
y = y[rand_index]
# データの分割
X_train = X[:int(len(X)*0.8)]
y_train = y[:int(len(y)*0.8)]
X_test = X[int(len(X)*0.8):]
y_test = y[int(len(y)*0.8):]
# 正解ラベルをone-hotの形にします
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
# モデルにvggを使います
input_tensor = Input(shape=(50, 50, 3))
vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)
# vggのoutputを受け取り、2クラス分類する層を定義します
# その際中間層を下のようにいくつか入れると精度が上がります
top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.5))top_model.add(Dense(2, activation='softmax'))
# vggと、top_modelを連結します
model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))
# vggの層の重みを変更不能にします
for layer in model.layers[:19]:
layer.trainable = False
# コンパイルします
model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
# 学習を行います
model.fit(X_train, y_train, batch_size=100, epochs=10, validation_data=(X_test, y_test))
model.save("test.h5")
アプリを作成 Herokuへデプロイ
次いで、機械学習させたデータを用いて、アプリを制作します。
①COVID-19で新しいフォルダを作成します。
②COVID-19フォルダの中にcovid.pyを作成し、コードを記入します。
import os
from flask import Flask, request, redirect, render_template, flash
from werkzeug.utils import secure_filename
from tensorflow.keras.models import Sequential, load_model
from tensorflow.keras.preprocessing import image
import numpy as np
classes = ["正常な肺","肺炎"]
image_size = 50
UPLOAD_FOLDER = "uploads"
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
app = Flask(__name__)
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
model = load_model('./model.h5')
#学習済みモデルをロード
@app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
if 'file' not in request.files:
flash('ファイルがありません')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('ファイルがありません')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(UPLOAD_FOLDER, filename))
filepath = os.path.join(UPLOAD_FOLDER, filename)
#受け取った画像を読み込み、np形式に変換
img = image.load_img(filepath, grayscale=True, target_size=(image_size,image_size))
img = image.img_to_array(img)
data = np.array([img])
#変換したデータをモデルに渡して予測する
result = model.predict(data)[0]
predicted = result.argmax()
pred_answer = "これは " + classes[predicted] + " です"
return render_template("index.html",answer=pred_answer)return render_template("index.html",answer="")
if __name__ == "__main__":
app.run()if __name__ == "__main__":
port = int(os.environ.get('PORT', 8080))
app.run(host ='0.0.0.0',port = port)
③COVID-19フォルダの中にtemplatesフォルダを作成し、その中にindex.htmlを作成します。参考-Flask入門のためのHTML&CSS 1.2.1 HTMLテンプレートの解説1/5のコード
④COVID-19フォルダの中にstaticフォルダを作成し、その中にstylesheet.cssを作成します。参考-Flask入門のためのHTML&CSS 1.3.1 CSSテンプレートの解説1/5のコード
⑤COVID-19フォルダの中にuploadsフォルダを作成します。適当なレントゲン画像を1枚入れます。
⑥COVID-19フォルダの中に、機械学習させたレントゲンモデルmodel.h5を入れます。
⑦ターミナルにpython covid.pyと入力して実行してみます。
⑧Herokuへデプロイし、世界にアプリを公開。
エラーに挫折せず 目的を持ってAidemy Gritで長期学習を
今回は仕事にも通ずる医療×AIのアプリ制作を実施しましたが、学び始めた頃は、趣味の映像制作にAIを応用したいとも考えていました。過去に映画づくりを通して感じたのは、一つの作品づくるのに多くの制約があり、膨大な時間と人手、経費が掛かることです。もしAIを通して、様々な課題解決がなされ、違った切り口の作品がつくられれば、新たなイノベーションが起こせるのではないかと思います。
そして、一口にAIと言っても、4年制大学で学べるほどの学問である為、3ヵ月の学習期間は非常に短く、表層的なことしか理解できませんでした。また、プログラミングは一朝一夕でできるものではなく、沢山のトライ&エラーを経て、学び続けるしかないと実感しています。今回は新たな学問へのきっかけと捉え、今後はエラーで挫折しないために、Aidemy Gritというサービスを用いて、継続的な学習が行えればと考えています。
デジタル化やIT推進は最重要課題 全員がプログラミングを学べば未来は明るい
日本は経済大国であり、長い歴史と文化を持ち合わせ、インフラから経済に至るまで、全ての基盤がしっかりしています。それ故に、他国に比べると、デジタル推進が遅れているとのことです。これは、大国の宿命ですが、これから迎える高齢化社会、人口減少に対して危機感をもち、未来を見据え、国と企業、個人が変わっていかなければなりません。
スウェーデンを見れば、日本でのデジタル化やIT推進は最重要課題という事がよくわかります。今回の新型コロナは生き長らえた者として、長期的な視点では、人類が様々なスキル、生活を向上させる為のいい機会だったのではないかと思います。一個人での力は限られていますが、もし全員がプログラミングを学び、また国と組織を統率する者がリーダーシップを発揮し、IT推進について腰を据えて行う事ができるならば、日本の未来は非常に明るいと思います。