basedir="/Volumes/DataSets/";
ieee8023Metadata=basedir<>"covidx-datasets/ieee8023/metadata.csv";
figure1COVIDchestxraydata=basedir<>"covidx-datasets/Figure1-COVID-chestxray-dataset/metadata.csv";
(*https://github.com/agchung/Actualmed-COVID-chestxray-dataset*)

actualmedMetadata=basedir<>"covidx-datasets/actualmed/metadata.csv";

radiographyMetadata=basedir<>"covidx-datasets/radiography/COVID-19.metadata.xlsx";

rsnaMetadataClassinfo=basedir<>"covidx-datasets/RSNA/stage_2_detailed_class_info.csv";
rsnaMetadataTrainLabel=basedir<>"covidx-datasets/RSNA/stage_2_train_labels.csv";

labels={"COVID-19","NORMAL","PNEUMONIA"};

ieee8023Data

views = {"PA", "AP", "AP Supine","AP semi erect",
"AP erect"};
keywords = {"COVID-19","SARS","MERS",
"Streptococcus","Klebsiella","Chlamydophila",
"Legionella","Normal","Lung Opacity","1","Pneumonia"};

ieee8023Data=Import[ieee8023Metadata,"Dataset","HeaderLines"->1];
ieee8023XRayData=ieee8023Data[All,{"finding","folder","filename","view"}];
ieee8023XRayData =ieee8023XRayData[Select[StringContainsQ[#finding,keywords,IgnoreCase->True] &]];
ieee8023XRayData =ieee8023XRayData[Select[StringContainsQ[#view,views,IgnoreCase->True] &]];
ieee8023XRayData[GroupBy["view"]]

ieee8023CleanDataSets={};
imageDir=basedir<>"covidx-datasets/ieee8023/images/";
filter[sample_]:=Module[{findingKey,datasets=ieee8023CleanDataSets},If[StringContainsQ[sample["finding"],"COVID",IgnoreCase->True]&&sample["folder"]=="images",datasets=Append[datasets,File[imageDir<>sample["filename"]]->"COVID-19"],If[StringContainsQ[sample["finding"],"NORMAL",IgnoreCase->True]&&sample["folder"]=="images",datasets=Append[datasets,File[imageDir<>sample["filename"]]->"NORMAL"],If[sample["folder"]=="images",datasets=Append[datasets,File[imageDir<>sample["filename"]]->"PNEUMONIA"]]]];
ieee8023CleanDataSets=datasets]

filter/@ieee8023XRayData;

RandomSample[ieee8023CleanDataSets,10];

Length[ieee8023CleanDataSets]

Figure1-COVID-chest-x-ray-dataset

figure1COVIDchestxray=Import[figure1COVIDchestxraydata,"Dataset","HeaderLines"->1];
figure1COVIDchestxray[GroupBy["finding"]];

figure1COVIDchestxrayDatasets=figure1COVIDchestxray[Select[#finding=="COVID-19"||#finding=="Pneumonia"&],{"patientid","finding"}];

figure1Datasets={};
imageDir=basedir<>"covidx-datasets/Figure1-COVID-chestxray-dataset/images/";
figureMapFilter[sample_]:=Module[{datasets=figure1Datasets},If[FileExistsQ[imageDir<>sample["patientid"]<>".jpg"],AppendTo[datasets,File[imageDir<>sample["patientid"]<>".jpg"]->ToUpperCase@sample["finding"]],If[FileExistsQ[imageDir<>sample["patientid"]<>".png"],AppendTo[datasets,File[imageDir<>sample["patientid"]<>".png"]->ToUpperCase@sample["finding"]],AppendTo[datasets,File[imageDir<>sample["patientid"]]->ToUpperCase@sample["finding"]]]];
figure1Datasets=datasets]

figureMapFilter/@figure1COVIDchestxrayDatasets;

Union[Values[figure1Datasets]]

Length[figure1COVIDchestxrayDatasets]

RandomSample[figure1Datasets,2];

Actualmed Data Sets

actualmedXrayData=Import[actualmedMetadata,"Dataset","HeaderLines"->1];

actualmedXrayData[GroupBy["finding"]];
actualmedXrayData=actualmedXrayData[Select[#finding=="COVID-19"&],{"patientid","finding","imagename"}];
actualmedDataSets={};
imageDir=basedir<>"covidx-datasets/actualmed/images/";
actualmedFilterMap[sample_]:=Module[{datasets=actualmedDataSets},AppendTo[datasets,File[imageDir<>sample["imagename"]]->sample["finding"]];
actualmedDataSets=datasets]

actualmedFilterMap/@actualmedXrayData;

Union[Values[actualmedDataSets]]

RandomSample[actualmedDataSets,3];

radiography datasets

filesLabelMap[datafile_,label_]:=Module[{},File[#]->label&/@datafile]

radiographyDir=basedir<>"covidx-datasets/radiography/"

covid19Files=FileNames[All,radiographyDir<>"COVID-19"];
noramlFiles=FileNames[All,radiographyDir<>"NORMAL"];
pneumoniaFiles=FileNames[All,radiographyDir<>"PNEUMONIA"];

Union[FileExistsQ/@pneumoniaFiles]

Length/@{covid19Files,noramlFiles,pneumoniaFiles}

radiographyDataSets=Join[filesLabelMap[covid19Files,"COVID-19"],filesLabelMap[noramlFiles,"NORMAL"],filesLabelMap[pneumoniaFiles,"PNEUMONIA"]];

Length[radiographyDataSets]

RandomSample[radiographyDataSets,10];

Union[Values[radiographyDataSets]]

RSNA Datasets

rsnaClassinfo=Import[rsnaMetadataClassinfo,"Dataset","HeaderLines"->1];

rsnaClassinfo[GroupBy["class"]];
rsnaNormal=Normal@rsnaClassinfo[Select[#class=="Normal"&],"patientId"];
rsnaTrainLabel=Import[rsnaMetadataTrainLabel,"Dataset","HeaderLines"->1];
rsnaPneumonia=Normal[rsnaTrainLabel[Select[#Target==1&],"patientId"]];
Length[rsnaPneumonia]

imageDir=basedir<>"covidx-datasets/RSNA/stage_2_train_images/";
rsnaDataSets=Join[File[imageDir<>#1<>".dcm"]->"PNEUMONIA"&/@rsnaPneumonia,File[imageDir<>#1<>".dcm"]->"NORMAL"&/@rsnaNormal];

Length[rsnaPneumonia]+Length[rsnaNormal]

RandomSample[rsnaDataSets,5];

Gen Datasets and clean datasets

cleandatasetsDir = "/Volumes/DataSets/cleandatasets/";

genDatasets[origindataset_] := Module[{file,label,img,basename,dims},
file = Keys[origindataset];
label = Values[origindataset];
basename = FileBaseName[List@@file[[1]]];
If[Not@DirectoryQ[cleandatasetsDir <> label],
CreateDirectory[cleandatasetsDir <> label]];
img = Import@file;
Export[cleandatasetsDir <> label <>"/" <> basename <>"_rotate"<> ".png" ,
ImageRotate[img,RandomReal[] * 2π,Background->Transparent]];
Export[cleandatasetsDir <> label <> "/" <> basename <> "_reflect" <> ".png",
ImageReflect[img,Left]];
Export[cleandatasetsDir <> label <> "/" <> basename <> ".png",
img];
]

Enhance Datasets

ParallelMap[genDatasets,ieee8023CleanDataSets];
ParallelMap[genDatasets,figure1Datasets];
ParallelMap[genDatasets,actualmedDataSets];
ParallelMap[genDatasets,radiographyDataSets];

SetDirectory["/Volumes/DataSets/cleandatasets"];
covid19DataFiles = FileNames["*.png", "COVID-19/"];
normalDataFiles = FileNames["*.png", "NORMAL/"];
pneumoniaDataFiles = FileNames["*.png", "PNEUMONIA/"];
filesLabelMap[datafile_,label_]:=Module[{},File[#]->label&/@datafile]
covid19 = filesLabelMap[covid19DataFiles,"COVID-19"];
normal = filesLabelMap[normalDataFiles,"NORMAL"];
pneumonia = filesLabelMap[pneumoniaDataFiles,"PNEUMONIA"];
datasets = Join[covid19,pneumonia,normal];
datasets = RandomSample[datasets];

traingDataSets=datasets[[1;;Floor[0.9*Length[datasets]]]];
validationDataSets=datasets[[Floor[0.9*Length[datasets]]+1;;Length[datasets]]];

Create Model

pepxModel[inChannel_,outChannel_]:=Module[{model},model=NetChain[{ConvolutionLayer[Floor[inChannel/2],{1,1}],BatchNormalizationLayer[],Ramp,ConvolutionLayer[IntegerPart[3*inChannel/4],{1,1}],BatchNormalizationLayer[],Ramp,ConvolutionLayer[IntegerPart[3*inChannel/4],{3,3},PaddingSize->{1,1}],BatchNormalizationLayer[],Ramp,ConvolutionLayer[Floor[inChannel/2],{1,1}],ConvolutionLayer[outChannel,{1,1}],BatchNormalizationLayer[]}];
model]

pepxModule1:=NetGraph[<|"inputConv1"->NetChain[{ConvolutionLayer[56,{7,7},"Stride"->{2,2},PaddingSize->{3,3}],BatchNormalizationLayer[],Ramp,PoolingLayer[{3,3},PaddingSize->{1,1}]}],(*block 1*)"pepx1.1"->pepxModel[56,56],"pepx1.2"->pepxModel[56,56],"pepx1.3"->pepxModel[56,56],"conv1_1*1"->NetChain[{ConvolutionLayer[56,{1,1},"Stride"->{2,2}],BatchNormalizationLayer[]}],"conv1_1*1+pepx1.1"->TotalLayer[],"conv1_1*1+pepx1.{1,2}"->TotalLayer[],"Total"->TotalLayer[],"poolingpepx1.1"->PoolingLayer[2,2],"poolingpepx1.2"->PoolingLayer[2,2],"poolingpepx1.3"->PoolingLayer[2,2],"poolingconv1_1*1"->PoolingLayer[2,2],"poolingTotal"->TotalLayer[]|>,{"inputConv1"->"conv1_1*1"->"pepx1.1",{"pepx1.1","conv1_1*1"}->"conv1_1*1+pepx1.1"->"pepx1.2",{"pepx1.1","conv1_1*1","pepx1.2"}->"conv1_1*1+pepx1.{1,2}"->"pepx1.3",{"conv1_1*1+pepx1.{1,2}","pepx1.3"}->"Total"->NetPort["Total1"],{"pepx1.1"->"poolingpepx1.1","pepx1.2"->"poolingpepx1.2","pepx1.3"->"poolingpepx1.3","conv1_1*1"->"poolingconv1_1*1"}->"poolingTotal"->NetPort["PTotal1"]}]

pepxModule2:=NetGraph[<|"pepxModule1"->pepxModule1,"pepx2.1"->pepxModel[112,112],"pepx2.2"->pepxModel[112,112],"pepx2.3"->pepxModel[112,112],"pepx2.4"->pepxModel[112,112],"conv2_1*1"->NetChain[{ConvolutionLayer[112,{1,1}],BatchNormalizationLayer[],Ramp,PoolingLayer[2,2]}],"conv2_1*1+pepx2.1"->TotalLayer[],"conv2_1*1+pepx2.{1,2}"->TotalLayer[],"conv2_1*1+pepx2.{1,2,3}"->TotalLayer[],"Total"->TotalLayer[],"PTotal"->TotalLayer[],"poolingpepx2.1"->PoolingLayer[2,2],"poolingpepx2.2"->PoolingLayer[2,2],"poolingpepx2.3"->PoolingLayer[2,2],"poolingpepx2.4"->PoolingLayer[2,2],"poolingconv2_1*1"->PoolingLayer[2,2]|>,{NetPort["pepxModule1","Total1"]->"conv2_1*1",NetPort["pepxModule1","PTotal1"]->"pepx2.1",{"conv2_1*1","pepx2.1"}->"conv2_1*1+pepx2.1"->"pepx2.2",{"conv2_1*1+pepx2.1","pepx2.2"}->"conv2_1*1+pepx2.{1,2}"->"pepx2.3",{"conv2_1*1+pepx2.{1,2}","pepx2.3"}->"conv2_1*1+pepx2.{1,2,3}"->"pepx2.4",{"conv2_1*1+pepx2.{1,2,3}","pepx2.4"}->"Total"->NetPort["Total2"],{"pepx2.1"->"poolingpepx2.1","pepx2.2"->"poolingpepx2.2","pepx2.3"->"poolingpepx2.3","pepx2.4"->"poolingpepx2.4","conv2_1*1"->"poolingconv2_1*1"}->"PTotal"->NetPort["PTotal2"]}]

pepxModule3:=NetGraph[<|"pepxModule2"->pepxModule2,"conv3_1*1"->NetChain[{ConvolutionLayer[224,{1,1}],BatchNormalizationLayer[],Ramp,PoolingLayer[2,2]}],"pepx3.1"->pepxModel[112,224],"pepx3.2"->pepxModel[224,224],"pepx3.3"->pepxModel[224,224],"pepx3.4"->pepxModel[224,224],"pepx3.5"->pepxModel[224,224],"pepx3.6"->pepxModel[224,224],"conv3_1*1+pepx3.1"->TotalLayer[],"conv3_1*1+pepx3{1,2}"->TotalLayer[],"conv3_1*1+pepx3{1,2,3}"->TotalLayer[],"conv3_1*1+pepx3{1,2,3,4}"->TotalLayer[],"conv3_1*1+pepx3{1,2,3,4,5}"->TotalLayer[],"Total"->TotalLayer[],"PTotal"->TotalLayer[],"poolingpepx3.1"->PoolingLayer[2,2],"poolingpepx3.2"->PoolingLayer[2,2],"poolingpepx3.3"->PoolingLayer[2,2],"poolingpepx3.4"->PoolingLayer[2,2],"poolingpepx3.5"->PoolingLayer[2,2],"poolingpepx3.6"->PoolingLayer[2,2],"poolingconv3_1*1"->PoolingLayer[2,2]|>,{NetPort["pepxModule2","Total2"]->"conv3_1*1",NetPort["pepxModule2","PTotal2"]->"pepx3.1",{"pepx3.1","conv3_1*1"}->"conv3_1*1+pepx3.1"->"pepx3.2",{"conv3_1*1+pepx3.1","pepx3.2"}->"conv3_1*1+pepx3{1,2}"->"pepx3.3",{"conv3_1*1+pepx3{1,2}","pepx3.3"}->"conv3_1*1+pepx3{1,2,3}"->"pepx3.4",{"conv3_1*1+pepx3{1,2,3}","pepx3.4"}->"conv3_1*1+pepx3{1,2,3,4}"->"pepx3.5",{"conv3_1*1+pepx3{1,2,3,4}","pepx3.5"}->"conv3_1*1+pepx3{1,2,3,4,5}"->"pepx3.6",{"conv3_1*1+pepx3{1,2,3,4,5}","pepx3.6"}->"Total"->NetPort["Total3"],{"pepx3.1"->"poolingpepx3.1","pepx3.2"->"poolingpepx3.2","pepx3.3"->"poolingpepx3.3","pepx3.4"->"poolingpepx3.4","pepx3.5"->"poolingpepx3.5","pepx3.6"->"poolingpepx3.6","conv3_1*1"->"poolingconv3_1*1"}->"PTotal"->NetPort["PTotal3"]}]

pepxModule4:=NetGraph[<|"pepxModule3"->pepxModule3,"conv4_1*1"->NetChain[{ConvolutionLayer[424,{1,1}],BatchNormalizationLayer[],Ramp,PoolingLayer[2,2]}],"pepx4.1"->pepxModel[224,424],"pepx4.2"->pepxModel[424,424],"pepx4.3"->pepxModel[424,424],"conv4_1*1+pepx4.1"->TotalLayer[],"conv4_1*1+pepx4.{1,2}"->TotalLayer[],"conv4_1*1+pepx4.{1,2,3}"->TotalLayer[]|>,{NetPort["pepxModule3","Total3"]->"conv4_1*1",NetPort["pepxModule3","PTotal3"]->"pepx4.1",{"pepx4.1","conv4_1*1"}->"conv4_1*1+pepx4.1"->"pepx4.2",{"conv4_1*1+pepx4.1","pepx4.2"}->"conv4_1*1+pepx4.{1,2}"->"pepx4.3",{"conv4_1*1+pepx4.{1,2}","pepx4.3"}->"conv4_1*1+pepx4.{1,2,3}"}]

covidNet=NetInitialize[NetGraph[<|"imageAug"->ImageAugmentationLayer[{224,224}],"pepxPipelines"->pepxModule4,"fc0"->FlattenLayer[],"topLayers"->NetChain[{LinearLayer[1024],Ramp,LinearLayer[256],Ramp,LinearLayer[3],SoftmaxLayer[]}]|>,{"imageAug"->"pepxPipelines"->"fc0"->"topLayers"},"Input"->NetEncoder[{"Image",{224,224},ColorSpace->"Grayscale"}],"Output"->NetDecoder[{"Class",labels}]],Method->{"Xavier","Distribution"->"Uniform"}]

covidNet=NetInitialize[NetGraph[<|"pepxPipelines"->pepxModule4,"fc0"->FlattenLayer[],"topLayers"->NetChain[{LinearLayer[1024],Ramp,LinearLayer[256],Ramp,LinearLayer[3],SoftmaxLayer[]}]|>,{"pepxPipelines"->"fc0"->"topLayers"},"Input"->NetEncoder[{"Image",{224,224},ColorSpace->"Grayscale"}],"Output"->NetDecoder[{"Class",labels}]],Method->{"Xavier","Distribution"->"Uniform"}]

Training Model

dir=CreateDirectory["/Volumes/DataSets/models"]; (*training checkpoint*)
covidtestNetTrained=NetTrain[covidNet,traingDataSets,All,ValidationSet->validationDataSets,TrainingProgressCheckpointing->{"Directory",dir},TrainingProgressReporting->"Panel",BatchSize->32,TrainingStoppingCriterion-><|"Criterion"->"Loss","Patience"->10|>,TimeGoal->3600]
net=covidtestNetTrained["TrainedNet"];
NetMeasurements[net,validationDataSets,{"ConfusionMatrixPlot","Accuracy"}]